diff --git a/ChangeLog b/ChangeLog index 2e778ff06..19999734c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2003-07-31 Alexandre Duret-Lutz + * configure.ac: Output wrap/python/tests/Makefile + and wrap/python/tests/run. + * wrap/python/Makefile.am (SUBDIRS): New variable. + * wrap/python/spot.i: Include all formulae headers from ltlast/, + as well as ltlvisit/destroy.hh. + (spot::ltl::formula::__cmp__, spot::ltl::formula::__str__): New + functions. + * wrap/python/tests/Makefile.am, wrap/python/tests/ltlsimple.py, + wrap/python/tests/run.in: New files. + * wrap/python/ltihooks.py: New file. * wrap/python/Makefile.am (EXTRA_DIST): Add ltihooks.py. diff --git a/configure.ac b/configure.ac index db4869a8d..2ba0e162b 100644 --- a/configure.ac +++ b/configure.ac @@ -44,5 +44,7 @@ AC_CONFIG_FILES([ src/misc/Makefile wrap/Makefile wrap/python/Makefile + wrap/python/tests/Makefile ]) +AC_CONFIG_FILES([wrap/python/tests/run], [chmod +x wrap/python/tests/run]) AC_OUTPUT diff --git a/wrap/python/.cvsignore b/wrap/python/.cvsignore index 50dd12bdb..7ba05f8a6 100644 --- a/wrap/python/.cvsignore +++ b/wrap/python/.cvsignore @@ -7,3 +7,4 @@ spot.py* *.lo *.loT spot_wrap.cxx +*.pyc diff --git a/wrap/python/Makefile.am b/wrap/python/Makefile.am index dd1a548e9..2dcf18197 100644 --- a/wrap/python/Makefile.am +++ b/wrap/python/Makefile.am @@ -1,3 +1,4 @@ +SUBDIRS = tests AM_CPPFLAGS = -I$(PYTHONINC) -I$(top_srcdir)/src diff --git a/wrap/python/spot.i b/wrap/python/spot.i index d465beede..c7f554c08 100644 --- a/wrap/python/spot.i +++ b/wrap/python/spot.i @@ -4,59 +4,96 @@ %include "std_list.i" %{ -#include "ltlenv/environment.hh" -#include "ltlenv/defaultenv.hh" #include "ltlast/formula.hh" -#include "ltlparse/public.hh" +#include "ltlast/refformula.hh" +#include "ltlast/atomic_prop.hh" +#include "ltlast/binop.hh" +#include "ltlast/constant.hh" +#include "ltlast/multop.hh" +#include "ltlast/unop.hh" #include "ltlast/visitor.hh" +#include "ltlenv/environment.hh" +#include "ltlenv/defaultenv.hh" + +#include "ltlparse/public.hh" + #include "ltlvisit/clone.hh" +#include "ltlvisit/destroy.hh" #include "ltlvisit/dotty.hh" #include "ltlvisit/dump.hh" #include "ltlvisit/lunabbrev.hh" -#include "ltlvisit/tunabbrev.hh" #include "ltlvisit/nenoform.hh" #include "ltlvisit/tostring.hh" +#include "ltlvisit/tunabbrev.hh" using namespace spot::ltl; %} -%include "ltlenv/environment.hh" -%include "ltlenv/defaultenv.hh" %include "ltlast/formula.hh" -%include "ltlparse/public.hh" +%include "ltlast/refformula.hh" +%include "ltlast/atomic_prop.hh" +%include "ltlast/binop.hh" +%include "ltlast/constant.hh" +%include "ltlast/multop.hh" +%include "ltlast/unop.hh" %include "ltlast/visitor.hh" +%include "ltlenv/environment.hh" +%include "ltlenv/defaultenv.hh" + +%include "ltlparse/public.hh" + %include "ltlvisit/clone.hh" +%include "ltlvisit/destroy.hh" %include "ltlvisit/dotty.hh" %include "ltlvisit/dump.hh" %include "ltlvisit/lunabbrev.hh" -%include "ltlvisit/tunabbrev.hh" %include "ltlvisit/nenoform.hh" %include "ltlvisit/tostring.hh" +%include "ltlvisit/tunabbrev.hh" + + +%extend spot::ltl::formula { + + // When comparing formula, make sure Python compare our + // pointers, not the pointers to its wrappers. + int + __cmp__(const spot::ltl::formula* b) + { + return b - self; + } + + std::string + __str__(void) + { + return spot::ltl::to_string(self); + } + +} %inline %{ -spot::ltl::parse_error_list +spot::ltl::parse_error_list empty_parse_error_list() { parse_error_list l; return l; } -std::ostream& +std::ostream& get_cout() { return std::cout; } -std::ostream& +std::ostream& get_cerr() { return std::cerr; } -void +void print_on(std::ostream& on, const std::string& what) { on << what; diff --git a/wrap/python/tests/.cvsignore b/wrap/python/tests/.cvsignore new file mode 100644 index 000000000..bef05ca47 --- /dev/null +++ b/wrap/python/tests/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +run diff --git a/wrap/python/tests/Makefile.am b/wrap/python/tests/Makefile.am new file mode 100644 index 000000000..5c10e3ec9 --- /dev/null +++ b/wrap/python/tests/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = $(TESTS) + +TESTS_ENVIRONMENT = ./run +# ensure run is rebuilt before the tests are run. +check_SCRIPTS = run + +TESTS = \ + ltlsimple.py diff --git a/wrap/python/tests/ltlsimple.py b/wrap/python/tests/ltlsimple.py new file mode 100755 index 000000000..dbc8199a7 --- /dev/null +++ b/wrap/python/tests/ltlsimple.py @@ -0,0 +1,100 @@ +import ltihooks +import spot + +clone = spot.clone + +e = spot.default_environment.instance() + +#---------------------------------------------------------------------- +a = e.require('a') +b = e.require('b') +c = e.require('c') +c2 = e.require('c') + +assert c == c2 +assert spot.atomic_prop.instance_count() == 3 + +op = spot.multop.instance(spot.multop.And, clone(a), clone(b)) +op2 = spot.multop.instance(spot.multop.And, op, c) + +# The symbol for a subformula which hasn't been cloned is better +# suppressed, so we don't attempt to reuse it elsewhere. +del op, c + +print 'op2 =', op2 + +op3 = spot.multop.instance(spot.multop.And, b, + spot.multop.instance(spot.multop.And, c2, a)) +del a, b, c2 + +print 'op3 =', op3 +assert op2 == op3 + +op4 = spot.multop.instance(spot.multop.Or, op2, op3) + +print 'op4 =', op4 +assert op4.nth(0) == op2 + +del op2, op3 + +assert spot.atomic_prop.instance_count() == 3 +assert spot.multop.instance_count() == 2 + +spot.destroy(op4) +del op4 + +assert spot.atomic_prop.instance_count() == 0 +assert spot.multop.instance_count() == 0 + +#---------------------------------------------------------------------- +a = e.require('a') +b = e.require('b') +c = e.require('c') +T = spot.constant.true_instance() +F = spot.constant.false_instance() + +f1 = spot.binop.instance(spot.binop.Equiv, T, clone(a)) +f2 = spot.binop.instance(spot.binop.Implies, F, clone(b)) +f3 = spot.binop.instance(spot.binop.Xor, F, clone(c)) +f4 = spot.unop.instance(spot.unop.Not, f3); del f3 + +assert spot.atomic_prop.instance_count() == 3 +assert spot.binop.instance_count() == 3 +assert spot.unop.instance_count() == 1 +assert spot.multop.instance_count() == 0 + +spot.destroy(a) +del a +spot.destroy(b) +del b +spot.destroy(c) +del c + +assert spot.atomic_prop.instance_count() == 3 +assert spot.binop.instance_count() == 3 +assert spot.unop.instance_count() == 1 +assert spot.multop.instance_count() == 0 + +spot.destroy(f1) +del f1 + +assert spot.atomic_prop.instance_count() == 2 +assert spot.binop.instance_count() == 2 +assert spot.unop.instance_count() == 1 +assert spot.multop.instance_count() == 0 + +spot.destroy(f4) +del f4 + +assert spot.atomic_prop.instance_count() == 1 +assert spot.binop.instance_count() == 1 +assert spot.unop.instance_count() == 0 +assert spot.multop.instance_count() == 0 + +spot.destroy(f2) +del f2 + +assert spot.atomic_prop.instance_count() == 0 +assert spot.binop.instance_count() == 0 +assert spot.unop.instance_count() == 0 +assert spot.multop.instance_count() == 0 diff --git a/wrap/python/tests/run.in b/wrap/python/tests/run.in new file mode 100644 index 000000000..519b9f0b1 --- /dev/null +++ b/wrap/python/tests/run.in @@ -0,0 +1,7 @@ +#!/bin/sh + +# If we are running from make check (srcdir is set), and VERBOSE is +# unset, be quiet. +test -n "$srcdir" && test -z "$VERBOSE" && exec >/dev/null 2>&1 + +PYTHONPATH=..:@srcdir@/.. exec @PYTHON@ ${1+"$@"}