* NEWS: Mention this. * COPYING: Replace by GPL v3. * src/sanity/style.test: Check files with the wrong license, in case we forgot to update it during a merge. * Makefile.am, bench/Makefile.am, bench/emptchk/Makefile.am, bench/emptchk/defs.in, bench/emptchk/ltl-human.sh, bench/emptchk/ltl-random.sh, bench/emptchk/pml-clserv.sh, bench/emptchk/pml-eeaean.sh, bench/emptchk/pml2tgba.pl, bench/ltl2tgba/big, bench/ltl2tgba/defs.in, bench/ltl2tgba/known, bench/ltl2tgba/lbtt2csv.pl, bench/ltl2tgba/ltl2baw.in, bench/ltl2tgba/parseout.pl, bench/ltl2tgba/small, bench/ltlclasses/Makefile.am, bench/ltlclasses/defs.in, bench/ltlclasses/run, bench/ltlcounter/Makefile.am, bench/ltlcounter/defs.in, bench/ltlcounter/run, bench/scc-stats/Makefile.am, bench/scc-stats/stats.cc, bench/split-product/Makefile.am, bench/split-product/cutscc.cc, bench/split-product/pml2tgba.pl, bench/wdba/Makefile.am, bench/wdba/defs.in, bench/wdba/run, configure.ac, doc/Makefile.am, doc/dot.in, doc/tl/Makefile.am, iface/Makefile.am, iface/dve2/Makefile.am, iface/dve2/defs.in, iface/dve2/dve2.cc, iface/dve2/dve2.hh, iface/dve2/dve2check.cc, iface/dve2/dve2check.test, iface/dve2/finite.test, iface/dve2/kripke.test, iface/gspn/Makefile.am, iface/gspn/common.cc, iface/gspn/common.hh, iface/gspn/dcswave.test, iface/gspn/dcswaveeltl.test, iface/gspn/dcswavefm.test, iface/gspn/dcswaveltl.test, iface/gspn/dottygspn.cc, iface/gspn/dottyssp.cc, iface/gspn/gspn.cc, iface/gspn/gspn.hh, iface/gspn/ltlgspn.cc, iface/gspn/simple.test, iface/gspn/ssp.cc, iface/gspn/ssp.hh, iface/gspn/udcsefm.test, iface/gspn/udcseltl.test, iface/gspn/udcsfm.test, iface/gspn/udcsltl.test, src/Makefile.am, src/bin/Makefile.am, src/bin/common_cout.cc, src/bin/common_cout.hh, src/bin/common_finput.cc, src/bin/common_finput.hh, src/bin/common_output.cc, src/bin/common_output.hh, src/bin/common_post.cc, src/bin/common_post.hh, src/bin/common_r.cc, src/bin/common_r.hh, src/bin/common_range.cc, src/bin/common_range.hh, src/bin/common_setup.cc, src/bin/common_setup.hh, src/bin/common_sys.hh, src/bin/genltl.cc, src/bin/ltl2tgba.cc, src/bin/ltl2tgta.cc, src/bin/ltlfilt.cc, src/bin/man/Makefile.am, src/bin/randltl.cc, src/eltlparse/Makefile.am, src/eltlparse/eltlparse.yy, src/eltlparse/eltlscan.ll, src/eltlparse/fmterror.cc, src/eltlparse/parsedecl.hh, src/eltlparse/public.hh, src/eltltest/Makefile.am, src/eltltest/acc.cc, src/eltltest/acc.test, src/eltltest/defs.in, src/eltltest/nfa.cc, src/eltltest/nfa.test, src/evtgba/Makefile.am, src/evtgba/evtgba.cc, src/evtgba/evtgba.hh, src/evtgba/evtgbaiter.hh, src/evtgba/explicit.cc, src/evtgba/explicit.hh, src/evtgba/product.cc, src/evtgba/product.hh, src/evtgba/symbol.cc, src/evtgba/symbol.hh, src/evtgbaalgos/Makefile.am, src/evtgbaalgos/dotty.cc, src/evtgbaalgos/dotty.hh, src/evtgbaalgos/reachiter.cc, src/evtgbaalgos/reachiter.hh, src/evtgbaalgos/save.cc, src/evtgbaalgos/save.hh, src/evtgbaalgos/tgba2evtgba.cc, src/evtgbaalgos/tgba2evtgba.hh, src/evtgbaparse/Makefile.am, src/evtgbaparse/evtgbaparse.yy, src/evtgbaparse/evtgbascan.ll, src/evtgbaparse/fmterror.cc, src/evtgbaparse/parsedecl.hh, src/evtgbaparse/public.hh, src/evtgbatest/Makefile.am, src/evtgbatest/defs.in, src/evtgbatest/explicit.cc, src/evtgbatest/explicit.test, src/evtgbatest/ltl2evtgba.cc, src/evtgbatest/ltl2evtgba.test, src/evtgbatest/product.cc, src/evtgbatest/product.test, src/evtgbatest/readsave.cc, src/evtgbatest/readsave.test, src/kripke/Makefile.am, src/kripke/fairkripke.cc, src/kripke/fairkripke.hh, src/kripke/kripke.cc, src/kripke/kripke.hh, src/kripke/kripkeexplicit.cc, src/kripke/kripkeexplicit.hh, src/kripke/kripkeprint.cc, src/kripke/kripkeprint.hh, src/kripkeparse/Makefile.am, src/kripkeparse/fmterror.cc, src/kripkeparse/kripkeparse.yy, src/kripkeparse/kripkescan.ll, src/kripkeparse/parsedecl.hh, src/kripkeparse/public.hh, src/kripkeparse/scankripke.ll, src/kripketest/Makefile.am, src/kripketest/bad_parsing.test, src/kripketest/defs.in, src/kripketest/kripke.test, src/kripketest/parse_print_test.cc, src/ltlast/Makefile.am, src/ltlast/allnodes.hh, src/ltlast/atomic_prop.cc, src/ltlast/atomic_prop.hh, src/ltlast/automatop.cc, src/ltlast/automatop.hh, src/ltlast/binop.cc, src/ltlast/binop.hh, src/ltlast/bunop.cc, src/ltlast/bunop.hh, src/ltlast/constant.cc, src/ltlast/constant.hh, src/ltlast/formula.cc, src/ltlast/formula.hh, src/ltlast/formula_tree.cc, src/ltlast/formula_tree.hh, src/ltlast/multop.cc, src/ltlast/multop.hh, src/ltlast/nfa.cc, src/ltlast/nfa.hh, src/ltlast/predecl.hh, src/ltlast/refformula.cc, src/ltlast/refformula.hh, src/ltlast/unop.cc, src/ltlast/unop.hh, src/ltlast/visitor.hh, src/ltlenv/Makefile.am, src/ltlenv/declenv.cc, src/ltlenv/declenv.hh, src/ltlenv/defaultenv.cc, src/ltlenv/defaultenv.hh, src/ltlenv/environment.hh, src/ltlparse/Makefile.am, src/ltlparse/fmterror.cc, src/ltlparse/ltlfile.cc, src/ltlparse/ltlfile.hh, src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll, src/ltlparse/parsedecl.hh, src/ltlparse/public.hh, src/ltltest/Makefile.am, src/ltltest/consterm.cc, src/ltltest/consterm.test, src/ltltest/defs.in, src/ltltest/equals.cc, src/ltltest/equals.test, src/ltltest/kind.cc, src/ltltest/kind.test, src/ltltest/length.cc, src/ltltest/length.test, src/ltltest/lunabbrev.test, src/ltltest/nenoform.test, src/ltltest/parse.test, src/ltltest/parseerr.test, src/ltltest/readltl.cc, src/ltltest/reduc.cc, src/ltltest/reduc.test, src/ltltest/reduccmp.test, src/ltltest/reducpsl.test, src/ltltest/syntimpl.cc, src/ltltest/syntimpl.test, src/ltltest/tostring.cc, src/ltltest/tostring.test, src/ltltest/tunabbrev.test, src/ltltest/tunenoform.test, src/ltltest/utf8.test, src/ltltest/uwrm.test, src/ltlvisit/Makefile.am, src/ltlvisit/apcollect.cc, src/ltlvisit/apcollect.hh, src/ltlvisit/clone.cc, src/ltlvisit/clone.hh, src/ltlvisit/contain.cc, src/ltlvisit/contain.hh, src/ltlvisit/destroy.cc, src/ltlvisit/destroy.hh, src/ltlvisit/dotty.cc, src/ltlvisit/dotty.hh, src/ltlvisit/dump.cc, src/ltlvisit/dump.hh, src/ltlvisit/lbt.cc, src/ltlvisit/lbt.hh, src/ltlvisit/length.cc, src/ltlvisit/length.hh, src/ltlvisit/lunabbrev.cc, src/ltlvisit/lunabbrev.hh, src/ltlvisit/mark.cc, src/ltlvisit/mark.hh, src/ltlvisit/nenoform.cc, src/ltlvisit/nenoform.hh, src/ltlvisit/postfix.cc, src/ltlvisit/postfix.hh, src/ltlvisit/randomltl.cc, src/ltlvisit/randomltl.hh, src/ltlvisit/reduce.cc, src/ltlvisit/reduce.hh, src/ltlvisit/relabel.cc, src/ltlvisit/relabel.hh, src/ltlvisit/simpfg.cc, src/ltlvisit/simpfg.hh, src/ltlvisit/simplify.cc, src/ltlvisit/simplify.hh, src/ltlvisit/snf.cc, src/ltlvisit/snf.hh, src/ltlvisit/tostring.cc, src/ltlvisit/tostring.hh, src/ltlvisit/tunabbrev.cc, src/ltlvisit/tunabbrev.hh, src/ltlvisit/wmunabbrev.cc, src/ltlvisit/wmunabbrev.hh, src/misc/Makefile.am, src/misc/acccompl.cc, src/misc/acccompl.hh, src/misc/accconv.cc, src/misc/accconv.hh, src/misc/bareword.cc, src/misc/bareword.hh, src/misc/bddalloc.cc, src/misc/bddalloc.hh, src/misc/bddlt.hh, src/misc/bddop.cc, src/misc/bddop.hh, src/misc/casts.hh, src/misc/escape.cc, src/misc/escape.hh, src/misc/fixpool.hh, src/misc/freelist.cc, src/misc/freelist.hh, src/misc/hash.hh, src/misc/hashfunc.hh, src/misc/intvcmp2.cc, src/misc/intvcmp2.hh, src/misc/intvcomp.cc, src/misc/intvcomp.hh, src/misc/ltstr.hh, src/misc/memusage.cc, src/misc/memusage.hh, src/misc/minato.cc, src/misc/minato.hh, src/misc/modgray.cc, src/misc/modgray.hh, src/misc/mspool.hh, src/misc/optionmap.cc, src/misc/optionmap.hh, src/misc/random.cc, src/misc/random.hh, src/misc/timer.cc, src/misc/timer.hh, src/misc/unique_ptr.hh, src/misc/version.cc, src/misc/version.hh, src/neverparse/Makefile.am, src/neverparse/fmterror.cc, src/neverparse/neverclaimparse.yy, src/neverparse/neverclaimscan.ll, src/neverparse/parsedecl.hh, src/neverparse/public.hh, src/saba/Makefile.am, src/saba/explicitstateconjunction.cc, src/saba/explicitstateconjunction.hh, src/saba/saba.cc, src/saba/saba.hh, src/saba/sabacomplementtgba.cc, src/saba/sabacomplementtgba.hh, src/saba/sabastate.hh, src/saba/sabasucciter.hh, src/sabaalgos/Makefile.am, src/sabaalgos/sabadotty.cc, src/sabaalgos/sabadotty.hh, src/sabaalgos/sabareachiter.cc, src/sabaalgos/sabareachiter.hh, src/sabatest/Makefile.am, src/sabatest/defs.in, src/sabatest/sabacomplementtgba.cc, src/sanity/Makefile.am, src/sanity/readme.test, src/sanity/style.test, src/ta/Makefile.am, src/ta/ta.cc, src/ta/ta.hh, src/ta/taexplicit.cc, src/ta/taexplicit.hh, src/ta/taproduct.cc, src/ta/taproduct.hh, src/ta/tgta.cc, src/ta/tgta.hh, src/ta/tgtaexplicit.cc, src/ta/tgtaexplicit.hh, src/ta/tgtaproduct.cc, src/ta/tgtaproduct.hh, src/taalgos/Makefile.am, src/taalgos/dotty.cc, src/taalgos/dotty.hh, src/taalgos/emptinessta.cc, src/taalgos/emptinessta.hh, src/taalgos/minimize.cc, src/taalgos/minimize.hh, src/taalgos/reachiter.cc, src/taalgos/reachiter.hh, src/taalgos/statessetbuilder.cc, src/taalgos/statessetbuilder.hh, src/taalgos/stats.cc, src/taalgos/stats.hh, src/taalgos/tgba2ta.cc, src/taalgos/tgba2ta.hh, src/tgba/Makefile.am, src/tgba/bdddict.cc, src/tgba/bdddict.hh, src/tgba/bddprint.cc, src/tgba/bddprint.hh, src/tgba/formula2bdd.cc, src/tgba/formula2bdd.hh, src/tgba/futurecondcol.cc, src/tgba/futurecondcol.hh, src/tgba/public.hh, src/tgba/sba.hh, src/tgba/state.hh, src/tgba/statebdd.cc, src/tgba/statebdd.hh, src/tgba/succiter.hh, src/tgba/succiterconcrete.cc, src/tgba/succiterconcrete.hh, src/tgba/taatgba.cc, src/tgba/taatgba.hh, src/tgba/tgba.cc, src/tgba/tgba.hh, src/tgba/tgbabddconcrete.cc, src/tgba/tgbabddconcrete.hh, src/tgba/tgbabddconcretefactory.cc, src/tgba/tgbabddconcretefactory.hh, src/tgba/tgbabddconcreteproduct.cc, src/tgba/tgbabddconcreteproduct.hh, src/tgba/tgbabddcoredata.cc, src/tgba/tgbabddcoredata.hh, src/tgba/tgbabddfactory.hh, src/tgba/tgbaexplicit.cc, src/tgba/tgbaexplicit.hh, src/tgba/tgbakvcomplement.cc, src/tgba/tgbakvcomplement.hh, src/tgba/tgbaproduct.cc, src/tgba/tgbaproduct.hh, src/tgba/tgbasafracomplement.cc, src/tgba/tgbasafracomplement.hh, src/tgba/tgbascc.cc, src/tgba/tgbascc.hh, src/tgba/tgbasgba.cc, src/tgba/tgbasgba.hh, src/tgba/tgbatba.cc, src/tgba/tgbatba.hh, src/tgba/tgbaunion.cc, src/tgba/tgbaunion.hh, src/tgba/wdbacomp.cc, src/tgba/wdbacomp.hh, src/tgbaalgos/Makefile.am, src/tgbaalgos/bfssteps.cc, src/tgbaalgos/bfssteps.hh, src/tgbaalgos/cutscc.cc, src/tgbaalgos/cutscc.hh, src/tgbaalgos/cycles.cc, src/tgbaalgos/cycles.hh, src/tgbaalgos/degen.cc, src/tgbaalgos/degen.hh, src/tgbaalgos/dotty.cc, src/tgbaalgos/dotty.hh, src/tgbaalgos/dottydec.cc, src/tgbaalgos/dottydec.hh, src/tgbaalgos/dupexp.cc, src/tgbaalgos/dupexp.hh, src/tgbaalgos/eltl2tgba_lacim.cc, src/tgbaalgos/eltl2tgba_lacim.hh, src/tgbaalgos/emptiness.cc, src/tgbaalgos/emptiness.hh, src/tgbaalgos/emptiness_stats.hh, src/tgbaalgos/gtec/Makefile.am, src/tgbaalgos/gtec/ce.cc, src/tgbaalgos/gtec/ce.hh, src/tgbaalgos/gtec/explscc.cc, src/tgbaalgos/gtec/explscc.hh, src/tgbaalgos/gtec/gtec.cc, src/tgbaalgos/gtec/gtec.hh, src/tgbaalgos/gtec/nsheap.cc, src/tgbaalgos/gtec/nsheap.hh, src/tgbaalgos/gtec/sccstack.cc, src/tgbaalgos/gtec/sccstack.hh, src/tgbaalgos/gtec/status.cc, src/tgbaalgos/gtec/status.hh, src/tgbaalgos/gv04.cc, src/tgbaalgos/gv04.hh, src/tgbaalgos/isdet.cc, src/tgbaalgos/isdet.hh, src/tgbaalgos/isweakscc.cc, src/tgbaalgos/isweakscc.hh, src/tgbaalgos/lbtt.cc, src/tgbaalgos/lbtt.hh, src/tgbaalgos/ltl2taa.cc, src/tgbaalgos/ltl2taa.hh, src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/ltl2tgba_fm.hh, src/tgbaalgos/ltl2tgba_lacim.cc, src/tgbaalgos/ltl2tgba_lacim.hh, src/tgbaalgos/magic.cc, src/tgbaalgos/magic.hh, src/tgbaalgos/minimize.cc, src/tgbaalgos/minimize.hh, src/tgbaalgos/ndfs_result.hxx, src/tgbaalgos/neverclaim.cc, src/tgbaalgos/neverclaim.hh, src/tgbaalgos/postproc.cc, src/tgbaalgos/postproc.hh, src/tgbaalgos/powerset.cc, src/tgbaalgos/powerset.hh, src/tgbaalgos/projrun.cc, src/tgbaalgos/projrun.hh, src/tgbaalgos/randomgraph.cc, src/tgbaalgos/randomgraph.hh, src/tgbaalgos/reachiter.cc, src/tgbaalgos/reachiter.hh, src/tgbaalgos/reducerun.cc, src/tgbaalgos/reducerun.hh, src/tgbaalgos/reductgba_sim.cc, src/tgbaalgos/reductgba_sim.hh, src/tgbaalgos/replayrun.cc, src/tgbaalgos/replayrun.hh, src/tgbaalgos/rundotdec.cc, src/tgbaalgos/rundotdec.hh, src/tgbaalgos/safety.cc, src/tgbaalgos/safety.hh, src/tgbaalgos/save.cc, src/tgbaalgos/save.hh, src/tgbaalgos/scc.cc, src/tgbaalgos/scc.hh, src/tgbaalgos/sccfilter.cc, src/tgbaalgos/sccfilter.hh, src/tgbaalgos/se05.cc, src/tgbaalgos/se05.hh, src/tgbaalgos/simulation.cc, src/tgbaalgos/simulation.hh, src/tgbaalgos/stats.cc, src/tgbaalgos/stats.hh, src/tgbaalgos/tau03.cc, src/tgbaalgos/tau03.hh, src/tgbaalgos/tau03opt.cc, src/tgbaalgos/tau03opt.hh, src/tgbaalgos/weight.cc, src/tgbaalgos/weight.hh, src/tgbaparse/Makefile.am, src/tgbaparse/fmterror.cc, src/tgbaparse/parsedecl.hh, src/tgbaparse/public.hh, src/tgbaparse/tgbaparse.yy, src/tgbaparse/tgbascan.ll, src/tgbatest/Makefile.am, src/tgbatest/babiak.test, src/tgbatest/bddprod.test, src/tgbatest/complementation.cc, src/tgbatest/complementation.test, src/tgbatest/cycles.test, src/tgbatest/defs.in, src/tgbatest/degendet.test, src/tgbatest/degenid.test, src/tgbatest/dfs.test, src/tgbatest/dupexp.test, src/tgbatest/eltl2tgba.test, src/tgbatest/emptchk.test, src/tgbatest/emptchke.test, src/tgbatest/emptchkr.test, src/tgbatest/explicit.cc, src/tgbatest/explicit.test, src/tgbatest/explicit2.cc, src/tgbatest/explicit2.test, src/tgbatest/explpro2.test, src/tgbatest/explpro3.test, src/tgbatest/explpro4.test, src/tgbatest/explprod.cc, src/tgbatest/explprod.test, src/tgbatest/intvcmp2.cc, src/tgbatest/intvcomp.cc, src/tgbatest/intvcomp.test, src/tgbatest/kv.test, src/tgbatest/ltl2neverclaim.test, src/tgbatest/ltl2ta.test, src/tgbatest/ltl2tgba.cc, src/tgbatest/ltl2tgba.test, src/tgbatest/ltlcounter.test, src/tgbatest/ltlprod.cc, src/tgbatest/ltlprod.test, src/tgbatest/mixprod.cc, src/tgbatest/mixprod.test, src/tgbatest/neverclaimread.test, src/tgbatest/nondet.test, src/tgbatest/obligation.test, src/tgbatest/powerset.cc, src/tgbatest/randpsl.test, src/tgbatest/randtgba.cc, src/tgbatest/randtgba.test, src/tgbatest/readsave.test, src/tgbatest/renault.test, src/tgbatest/scc.test, src/tgbatest/sccsimpl.test, src/tgbatest/spotlbtt.test, src/tgbatest/spotlbtt2.test, src/tgbatest/taatgba.cc, src/tgbatest/taatgba.test, src/tgbatest/tgbaread.cc, src/tgbatest/tgbaread.test, src/tgbatest/tripprod.cc, src/tgbatest/tripprod.test, src/tgbatest/wdba.test, src/tgbatest/wdba2.test, wrap/Makefile.am, wrap/python/Makefile.am, wrap/python/ajax/Makefile.am, wrap/python/ajax/spot.in, wrap/python/buddy.i, wrap/python/spot.i, wrap/python/tests/Makefile.am, wrap/python/tests/alarm.py, wrap/python/tests/bddnqueen.py, wrap/python/tests/implies.py, wrap/python/tests/interdep.py, wrap/python/tests/ltl2tgba.py, wrap/python/tests/ltl2tgba.test, wrap/python/tests/ltlparse.py, wrap/python/tests/ltlsimple.py, wrap/python/tests/minato.py, wrap/python/tests/modgray.py, wrap/python/tests/optionmap.py, wrap/python/tests/parsetgba.py, wrap/python/tests/run.in, wrap/python/tests/setxor.py: Update licence version, and replace the FSF address by a URL.
790 lines
26 KiB
Python
Executable file
790 lines
26 KiB
Python
Executable file
#!@PYTHON@
|
|
# -*- mode: python; coding: utf-8 -*-
|
|
# Copyright (C) 2011, 2012 Laboratoire de Recherche et Développement
|
|
# de l'Epita (LRDE).
|
|
#
|
|
# This file is part of Spot, a model checking library.
|
|
#
|
|
# Spot is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
# License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
import sys
|
|
|
|
script = ('SCRIPT_NAME' in os.environ)
|
|
|
|
if script:
|
|
# 3600s = 1h
|
|
sys.stdout.write("""Cache-Control: max-age=3600
|
|
Content-Type: text/html
|
|
|
|
""")
|
|
|
|
# Directory for temporary files (images and other auxiliary files).
|
|
imgdir = 'spotimg'
|
|
|
|
# Cache lookup for the QUERY_STRING
|
|
qs = os.getenv('QUERY_STRING')
|
|
if qs:
|
|
import hashlib
|
|
# We (optimistically) assume no collision from sha1(qs)
|
|
cachedir = imgdir + '/' + hashlib.sha1(qs.encode('utf-8')).hexdigest()
|
|
cachename = cachedir + '/html'
|
|
try:
|
|
# Is this a request we have already processed?
|
|
cache = open(cachename, "rb", 0)
|
|
if hasattr(sys.stdout, 'buffer'):
|
|
# Python 3+
|
|
sys.stdout.buffer.write(cache.read())
|
|
else:
|
|
# Python 2.x
|
|
sys.stdout.write(cache.read())
|
|
# Touch the directory containing the files we used, so
|
|
# it that it survives the browser's cache.
|
|
os.utime(cachedir, None)
|
|
exit(0)
|
|
except IOError:
|
|
# We failed to open the file.
|
|
# Let's run the rest of the script to create it.
|
|
pass
|
|
elif script:
|
|
sys.stdout.write("<b>QUERY_STRING unset!</b>\n")
|
|
exit(0)
|
|
|
|
# Location of the dot command
|
|
dot = '@DOT@'
|
|
dot_bgcolor = '-Gbgcolor=#FFFFFF00'
|
|
|
|
svg_output = False # SVG output used to working well with Firefox
|
|
# only. It now seems to work with recent Chrome
|
|
# versions as well, but it is still a problem with
|
|
# Safari, and IE.
|
|
output_both = True # Create both PNG and SVG. If svg_output is False,
|
|
# the SVG will be given as a link under the PNG.
|
|
# Otherwise the PNG is used as alternate contents
|
|
# for the SVG object.
|
|
|
|
if not script:
|
|
# If this is not run as a cgi script, let's start an HTTP server.
|
|
try:
|
|
# Python 3+
|
|
from http.server import CGIHTTPRequestHandler, HTTPServer
|
|
except ImportError:
|
|
# Python 2.x
|
|
from CGIHTTPServer import CGIHTTPRequestHandler
|
|
from BaseHTTPServer import HTTPServer
|
|
|
|
class MyHandler(CGIHTTPRequestHandler):
|
|
def is_cgi(self):
|
|
if self.path.startswith('/cgi-bin/spot.py'):
|
|
self.cgi_info = '', self.path[9:]
|
|
return True
|
|
return False
|
|
|
|
server_address=('',8000)
|
|
if not os.access(imgdir, os.F_OK):
|
|
# 493 = 0755 but we would have to write 0755 or 0o755
|
|
# depending on the python version...
|
|
os.mkdir(imgdir, 493)
|
|
sys.stdout.write("Directory spotimg/ created.\n")
|
|
httpd = HTTPServer(server_address, MyHandler)
|
|
sys.stdout.write("Point your browser to http://localhost:8000/ltl2tgba.html\n")
|
|
httpd.serve_forever()
|
|
|
|
import cgi
|
|
import cgitb; cgitb.enable()
|
|
import signal
|
|
import time
|
|
import os.path
|
|
|
|
# We do not output in cachedir directely, in case two
|
|
# CGI scripts process the same request concurrently.
|
|
tmpdir = cachedir + '-' + str(os.getpid())
|
|
cachename = tmpdir + '/html'
|
|
|
|
sys.stdout.flush()
|
|
# Reopen stdout without buffering
|
|
sys.stdout = os.fdopen(sys.stdout.fileno(), "wb", 0)
|
|
|
|
# Redirect stderr to stdout at a low level (so that
|
|
# even errors from subprocesses get printed).
|
|
os.dup2(sys.stdout.fileno(), sys.stderr.fileno())
|
|
|
|
# Create the temporary cache directory
|
|
os.mkdir(tmpdir, 493) # See comment above about 0o755 or 0755.
|
|
|
|
# Redirect stdout to the cache file, at a low level
|
|
# for similar reason.
|
|
fd = os.open(cachename, os.O_CREAT | os.O_WRONLY, 420) # 420 = 0644
|
|
os.dup2(fd, sys.stdout.fileno())
|
|
|
|
# We had to reopen stdout in binary mode to enable unbuffered output,
|
|
# (disallowed on text I/O by Python 3.x) so starting now, we are not
|
|
# allowed to send strings to sys.stdout. Always use the following
|
|
# method instead.
|
|
def unbufprint(s):
|
|
if sys.getdefaultencoding() != 'ascii':
|
|
sys.stdout.write(s.encode("utf-8"))
|
|
else:
|
|
sys.stdout.write(s)
|
|
|
|
def finish(kill = False):
|
|
# Output the result and exit.
|
|
os.dup2(sys.stderr.fileno(), sys.stdout.fileno())
|
|
|
|
cache = open(cachename, "rb", 0)
|
|
sys.stdout.write(cache.read())
|
|
|
|
# Rename tmpdir to its permanent name for caching purpose.
|
|
# os.rename will fail if cachedir already exist. Since we tested
|
|
# that initially, it can only happen when two CGI script are
|
|
# processing the same request concurrently. In that case the
|
|
# other result is as good as ours, so we just ignore the error.
|
|
# (We don't bother removing the temporary directory -- it will be
|
|
# removed by the next cache prune and cannot be created again in
|
|
# the meantime.)
|
|
try:
|
|
os.rename(tmpdir, cachedir)
|
|
except OSError:
|
|
pass
|
|
|
|
if kill:
|
|
# Kill all children
|
|
os.kill(0, signal.SIGTERM)
|
|
# Should we prune the cache?
|
|
stamp = imgdir + '/cache.stamp'
|
|
now = time.time()
|
|
try:
|
|
# Prune at most once every hour
|
|
if now - os.path.getmtime(stamp) < 3600:
|
|
exit(0)
|
|
except OSError:
|
|
# It's OK if the file did not exist.
|
|
# We will create it.
|
|
pass
|
|
# Erase all directories that are older than 2 hours, and all
|
|
# files that have only one hardlinks. Files that have more than
|
|
# one hardlinks are referenced to by directories; so the hardlink
|
|
# count will decrease when the directory is purged.
|
|
os.system('find ' + imgdir + ' -mindepth 1 -maxdepth 1 -mmin +120 '
|
|
+ '\( -type d -o -links 1 \) -exec rm -rf {} +')
|
|
# Create or update the stamp so we know when to run the next prune.
|
|
open(stamp, "wb", 0)
|
|
exit(0)
|
|
|
|
# Assume Spot is installed
|
|
sys.path.insert(0, '@pythondir@')
|
|
|
|
if ('SERVER_SOFTWARE' in os.environ and
|
|
os.environ['SERVER_SOFTWARE'].startswith('SimpleHTTP')):
|
|
# We might be running from the build tree (but it's not sure).
|
|
# Add the build and source directories first in the search path.
|
|
# If we are not in the right place, python will find the installed
|
|
# libraries later.
|
|
sys.path.insert(0, '@srcdir@/../.libs')
|
|
sys.path.insert(0, '@srcdir@/..')
|
|
sys.path.insert(0, '../.libs')
|
|
sys.path.insert(0, '..')
|
|
# Darwin needs some help in figuring out where non-installed libtool
|
|
# libraries are (on this platform libtool encodes the expected final
|
|
# path of dependent libraries in each library).
|
|
m = '../.libs:@top_builddir@/src/.libs:@top_builddir@/buddy/src/.libs'
|
|
os.environ['DYLD_LIBRARY_PATH'] = m
|
|
|
|
try:
|
|
# execfile('ltl2tgba.opt') no longuer work with Python 3.
|
|
exec(compile(open("ltl2tgba.opt").read(), "ltl2tgba.opt", 'exec'))
|
|
except IOError:
|
|
pass
|
|
|
|
import spot
|
|
import buddy
|
|
|
|
def alarm_handler(signum, frame):
|
|
unbufprint("""<p><font color="red">The script was aborted because
|
|
it has been running for too long.</font> Please try a shorter formula,
|
|
or different options.
|
|
If you want to benchmark big formulae it is
|
|
better to install Spot on your own computer.</p>\n""")
|
|
finish(kill = True)
|
|
|
|
def run_dot(basename, ext):
|
|
outname = basename + '.' + ext
|
|
# Do not call "dot" to generate a file that already exists.
|
|
if not os.access(outname, os.F_OK):
|
|
os.spawnlp(os.P_WAIT, dot, dot, dot_bgcolor, '-T' + ext,
|
|
'-Gsize=8.2,8.2', '-o', outname, basename + '.txt')
|
|
# Create a unused hardlink that points to the output picture
|
|
# just to remember how many cache entries are sharing it.
|
|
os.link(outname, tmpdir + "/" + ext)
|
|
|
|
def render_dot(basename):
|
|
unbufprint('<div class="dot">')
|
|
b = cgi.escape(basename)
|
|
|
|
if svg_output or output_both:
|
|
run_dot(basename, 'svg')
|
|
if not svg_output or output_both:
|
|
run_dot(basename, 'png')
|
|
pngstr = '<img src="' + b + '.png">'
|
|
|
|
if svg_output:
|
|
unbufprint('<object type="image/svg+xml" data="' + b + '.svg">')
|
|
if output_both:
|
|
unbufprint(pngstr)
|
|
else:
|
|
unbufprint('Your browser does not support SVG.')
|
|
unbufprint('</object>' + '<br>(<a href="' + b
|
|
+ '.txt">dot</a>)')
|
|
else:
|
|
unbufprint('<img src="' + b + '.png"><br>(<a href="' + b
|
|
+ '.txt">dot</a>)')
|
|
if output_both:
|
|
unbufprint(' (<a href="' + b + '.svg">svg</a>)')
|
|
unbufprint('</div>\n')
|
|
|
|
def render_dot_maybe(dotsrc, dont_run_dot):
|
|
# The dot output is named after the SHA1 of the dot source.
|
|
# This way we can cache two different requests that generate
|
|
# the same automaton (e.g., when changing a simplification
|
|
# option that has no influence).
|
|
if sys.getdefaultencoding() != 'ascii':
|
|
dotsrc = dotsrc.encode('utf-8')
|
|
# If the text rendering engine (usually Pango) used by dot does
|
|
# not draw overlines correctly, uncomment the following two
|
|
# lines. Pango 1.28.4 seems not to support combining overline
|
|
# while 1.30 does.
|
|
#import re
|
|
#dotsrc = re.sub(r'(.)(̅|̄)', r'¬\1', dotsrc);
|
|
autprefix = (imgdir + '/' + hashlib.sha1(dotsrc).hexdigest())
|
|
dotname = autprefix + '.txt'
|
|
if not os.access(dotname, os.F_OK):
|
|
dotout = open(dotname, "wb", 0)
|
|
dotout.write(dotsrc)
|
|
dotout.close()
|
|
# Create a unused hardlink that points to the output picture
|
|
# just to remember how many cache entries are sharing it.
|
|
os.link(dotname, tmpdir + "/txt")
|
|
|
|
if dont_run_dot:
|
|
unbufprint('<p>' + dont_run_dot + ''' to be rendered on-line.
|
|
However you may download the <a href="''' + cgi.escape(autprefix)
|
|
+ '.txt">source in dot format</a> and render it yourself.</p>\n')
|
|
else:
|
|
render_dot(autprefix)
|
|
|
|
def render_automaton(automaton, dont_run_dot, issba, deco = None):
|
|
dotsrc = spot.ostringstream()
|
|
if isinstance(automaton, spot.ta): # TA/GTA
|
|
spot.dotty_reachable(dotsrc, automaton)
|
|
elif hasattr(automaton, 'get_ta'): # TGTA
|
|
spot.dotty_reachable(dotsrc, automaton.get_ta())
|
|
else: # TGBA
|
|
spot.dotty_reachable(dotsrc, automaton, issba, deco)
|
|
render_dot_maybe(dotsrc.str(), dont_run_dot)
|
|
|
|
def render_formula(f):
|
|
dotsrc = spot.ostringstream()
|
|
spot.dotty(dotsrc, f)
|
|
render_dot_maybe(dotsrc.str(), False)
|
|
|
|
def print_stats(automaton, detinfo = False):
|
|
stats = spot.stats_reachable(automaton)
|
|
unbufprint("<p>%d state" % stats.states)
|
|
if stats.states > 1:
|
|
unbufprint("s")
|
|
if detinfo:
|
|
nondet = spot.count_nondet_states(automaton)
|
|
if nondet == 0:
|
|
unbufprint(" (deterministic)")
|
|
else:
|
|
unbufprint(" (%d nondeterministic)" % nondet)
|
|
unbufprint(", %d transition" % stats.transitions)
|
|
if stats.transitions > 1:
|
|
unbufprint("s")
|
|
if hasattr(automaton, 'number_of_acceptance_conditions'):
|
|
count = automaton.number_of_acceptance_conditions()
|
|
if count > 0:
|
|
unbufprint(", %d acceptance condition" % count)
|
|
if count > 1:
|
|
unbufprint("s")
|
|
acc = automaton.all_acceptance_conditions()
|
|
unbufprint(": " + spot.bdd_format_accset(automaton.get_dict(), acc))
|
|
else:
|
|
unbufprint(", no acceptance condition (all cycles are accepting)")
|
|
unbufprint("</p>\n")
|
|
# Decide whether we will render the automaton or not.
|
|
# (A webserver is not a computation center...)
|
|
if stats.states > 64:
|
|
return "Automaton has too much states"
|
|
if float(stats.transitions)/stats.states > 10:
|
|
return "Automaton has too much transitions per state"
|
|
return False
|
|
|
|
def format_formula(f, kind='div'):
|
|
if utf8:
|
|
s = spot.to_utf8_string(f)
|
|
else:
|
|
s = str(f)
|
|
return '<%s class="formula spot-format">%s</%s>' % (kind, s, kind)
|
|
|
|
form = cgi.FieldStorage()
|
|
|
|
output_type = form.getfirst('o', 'v');
|
|
|
|
# Version requested.
|
|
if output_type == 'v':
|
|
unbufprint('Spot version %s\n' % spot.version())
|
|
finish()
|
|
|
|
# ltl3ba's version
|
|
if output_type == 'v3':
|
|
import subprocess
|
|
try:
|
|
l3proc = subprocess.Popen(['@LTL3BA@', '-v'], stdout=subprocess.PIPE)
|
|
(ver, err) = l3proc.communicate()
|
|
err = l3proc.returncode
|
|
except:
|
|
err = 1
|
|
if err != 0:
|
|
unbufprint('not available')
|
|
else:
|
|
unbufprint(ver.replace("\n", "<br>"))
|
|
finish()
|
|
|
|
spot.unblock_signal(signal.SIGALRM)
|
|
spot.unblock_signal(signal.SIGTERM)
|
|
os.setpgrp()
|
|
|
|
child = os.fork()
|
|
if child != 0:
|
|
# In parent. We are just waiting for the termination of the
|
|
# child, or for the timeout alarm. On SIGALRM, we will kill the
|
|
# child.
|
|
#
|
|
# We cannot avoid forking, because Python will not deliver a
|
|
# signal when a C function is running. So if Spot takes too long
|
|
# to translate some formula, it would not get interrupted.
|
|
signal.signal(signal.SIGALRM, alarm_handler)
|
|
signal.alarm(30)
|
|
os.waitpid(child, 0)
|
|
exit(0)
|
|
|
|
# Global options
|
|
utf8 = False
|
|
for g in form.getlist('g'):
|
|
if g == '8':
|
|
utf8 = True
|
|
spot.enable_utf8()
|
|
|
|
formula = form.getfirst('f', '')
|
|
|
|
env = spot.default_environment.instance()
|
|
pel = spot.empty_parse_error_list()
|
|
f = spot.parse(formula, pel, env)
|
|
|
|
if pel:
|
|
unbufprint('<div class="parse-error">')
|
|
err = spot.format_parse_errors(spot.get_cout(), formula, pel)
|
|
unbufprint('</div>')
|
|
|
|
# Do not continue if we could not parse anything sensible.
|
|
if not f:
|
|
finish()
|
|
|
|
# Formula simplifications
|
|
simpopt = spot.ltl_simplifier_options(False, False, False,
|
|
False, False, False, True)
|
|
dored = False
|
|
for r in form.getlist('r'):
|
|
dored = True
|
|
if r == 'br':
|
|
simpopt.reduce_basics = True
|
|
elif r == 'lf':
|
|
simpopt.reduce_size_strictly = False
|
|
elif r == 'si':
|
|
simpopt.synt_impl = True
|
|
elif r == 'eu':
|
|
simpopt.event_univ = True
|
|
elif r == 'lc':
|
|
simpopt.containment_checks = True
|
|
simpopt.containment_checks_stronger = True
|
|
if dored:
|
|
simp = spot.ltl_simplifier(simpopt)
|
|
f2 = simp.simplify(f)
|
|
f.destroy()
|
|
f = f2
|
|
# This also clears the as_bdd() cache.
|
|
simp = None
|
|
|
|
# Formula manipulation only.
|
|
if output_type == 'f':
|
|
formula_format = form.getfirst('ff', 'o')
|
|
# o = Spot, i = Spin, g = GraphViz, p = properties
|
|
if formula_format == 'o':
|
|
unbufprint(format_formula(f))
|
|
elif formula_format == 'i':
|
|
unbufprint('<div class="formula spin-format">'
|
|
+ spot.to_spin_string(f) + '</div>')
|
|
if f.is_psl_formula() and not f.is_ltl_formula():
|
|
s = ''
|
|
if simpopt.reduce_size_strictly:
|
|
s = '<br><b>Try enabling larger formula rewritings.</b>'
|
|
unbufprint('<div class="error">The above formula contains PSL operators that Spin will not understand.%s</div>' % s)
|
|
elif formula_format == 'g':
|
|
render_formula(f)
|
|
elif formula_format == 'p':
|
|
if utf8:
|
|
s = spot.to_utf8_string(f)
|
|
else:
|
|
s = str(f)
|
|
unbufprint('Properties for ' + format_formula(f, 'span') + '<ul>\n')
|
|
for p in spot.list_formula_props(f):
|
|
unbufprint('<li>%s</li>\n' % p)
|
|
|
|
# Attempt to refine the hierarchy class using WDBA minimization
|
|
if not f.is_syntactic_safety() or not f.is_syntactic_guarantee():
|
|
dict = spot.bdd_dict()
|
|
automaton = spot.ltl_to_tgba_fm(f, dict, False, True)
|
|
minimized = spot.minimize_obligation_new(automaton, f)
|
|
if minimized:
|
|
g = spot.is_guarantee_automaton(minimized)
|
|
s = spot.is_safety_mwdba(minimized)
|
|
if s and not f.is_syntactic_safety():
|
|
unbufprint('<li>pathologic safety</li>')
|
|
if g and not f.is_syntactic_guarantee():
|
|
unbufprint('<li>pathologic guarantee</li>')
|
|
if not f.is_syntactic_obligation():
|
|
unbufprint('<li>obligation (although not syntactically)</li>')
|
|
else:
|
|
unbufprint('<li>not an obligation</li>')
|
|
minimized = 0
|
|
automaton = 0
|
|
unbufprint('</ul>\n')
|
|
finish()
|
|
|
|
# Formula translation.
|
|
translator = form.getfirst('t', 'fm')
|
|
|
|
if f.is_psl_formula() and not f.is_ltl_formula() and translator != 'fm':
|
|
unbufprint('''<div class="error">The PSL formula %s
|
|
cannot be translated using this algorithm. Please use Couveur/FM.'''
|
|
% format_formula(f, 'span'))
|
|
finish()
|
|
|
|
dict = spot.bdd_dict()
|
|
|
|
if output_type == 't' and not (f.is_ltl_formula() and f.is_X_free()):
|
|
unbufprint('<b>Warning:</b> The following result assumes the input formula is stuttering insensitive.</br>')
|
|
|
|
# Should the automaton be displayed as a SBA?
|
|
issba = False
|
|
|
|
if translator == 'fm':
|
|
exprop = False
|
|
symb_merge = False
|
|
branching_postponement = False
|
|
fair_loop_approx = False
|
|
for fm in form.getlist('fm'):
|
|
if fm == 'od':
|
|
exprop = True
|
|
elif fm == 'sm':
|
|
symb_merge = True
|
|
elif fm == 'bp':
|
|
branching_postponement = True
|
|
elif fm == 'fl':
|
|
fair_loop_approx = True
|
|
automaton = spot.ltl_to_tgba_fm(f, dict,
|
|
exprop, symb_merge,
|
|
branching_postponement, fair_loop_approx)
|
|
elif translator == 'la':
|
|
automaton = spot.ltl_to_tgba_lacim(f, dict)
|
|
if form.getfirst('la', '') == 'sp':
|
|
automaton.delete_unaccepting_scc()
|
|
elif translator == 'ta':
|
|
refined_rules = False
|
|
if form.getfirst('ta', '') == 'lc':
|
|
refined_rules = True
|
|
automaton = spot.ltl_to_taa(f, dict, refined_rules)
|
|
elif translator == 'l3':
|
|
l3out = '-T'
|
|
l3opt = { '-l', '-P', '-A', '-c', '-C', '-o', '-p' }
|
|
for lo in form.getfirst('lo', 'T'):
|
|
if lo == 'U':
|
|
l3out = '-U'
|
|
issba = True
|
|
for l3 in form.getlist('l3'):
|
|
if l3 == 'l':
|
|
l3opt.remove('-l')
|
|
elif l3 == 'P':
|
|
l3opt.remove('-P')
|
|
elif l3 == 'A':
|
|
l3opt.remove('-A')
|
|
elif l3 == 'C':
|
|
l3opt.remove('-C')
|
|
l3opt.remove('-c')
|
|
elif l3 == 'M':
|
|
l3opt.add('-M')
|
|
elif l3 == 'S':
|
|
l3opt.add('-S')
|
|
elif l3 == 'o':
|
|
l3opt.remove('-o')
|
|
elif l3 == 'p':
|
|
l3opt.remove('-p')
|
|
args = ["@LTL3BA@", l3out]
|
|
args.extend(l3opt)
|
|
args.extend(['-f', spot.to_spin_string(f)])
|
|
import subprocess
|
|
l3file = tmpdir + "/aut"
|
|
l3aut = open(l3file, "w+")
|
|
try:
|
|
l3proc = subprocess.Popen(args, stdout=l3aut)
|
|
ret = l3proc.wait()
|
|
except:
|
|
unbufprint('<div class="error">Failed to run ltl3ba. Is it installed?</div>')
|
|
finish()
|
|
if ret != 0:
|
|
unbufprint('<div class="error">ltl3ba exited with error %s</div>' % ret)
|
|
finish()
|
|
l3aut.close()
|
|
tpel = spot.empty_tgba_parse_error_list()
|
|
automaton = spot.tgba_parse(l3file, tpel, dict, env)
|
|
if tpel:
|
|
unbufprint('''<div class="error">failed to read ltl3ba's output</div>''')
|
|
unbufprint('<div class="parse-error">')
|
|
err = spot.format_tgba_parse_errors(spot.get_cout(), "output", tpel)
|
|
unbufprint('</div>')
|
|
automaton = 0
|
|
finish()
|
|
|
|
# Monitor output
|
|
if output_type == 'm':
|
|
issba = False
|
|
automaton = spot.scc_filter(automaton)
|
|
automaton = spot.minimize_monitor(automaton)
|
|
unbufprint('<div class="automata-stats">')
|
|
dont_run_dot = print_stats(automaton)
|
|
unbufprint('</div>')
|
|
render_automaton(automaton, dont_run_dot, issba)
|
|
automaton = 0
|
|
finish()
|
|
|
|
# Automaton simplifications
|
|
prune_scc = False
|
|
wdba_minimize = False
|
|
direct_simul = False
|
|
reverse_simul = False
|
|
iterated_simul = False
|
|
for s in form.getlist('as'):
|
|
if s == 'ps':
|
|
prune_scc = True
|
|
elif s == 'wd':
|
|
wdba_minimize = True
|
|
elif s == 'ds':
|
|
direct_simul = True
|
|
elif s == 'rs':
|
|
reverse_simul = True
|
|
elif s == 'is':
|
|
iterated_simul = True
|
|
|
|
ta_type = None
|
|
buchi_type = None
|
|
|
|
if output_type == 'a':
|
|
buchi_type = form.getfirst('af', 't')
|
|
elif output_type == 'r':
|
|
buchi_type = form.getfirst('ra', 't')
|
|
elif output_type == 't':
|
|
ta_type = form.getfirst('tf', 't')
|
|
else:
|
|
unbufprint("Unkown output type 'o=%s'.\n" % output_type)
|
|
automaton = 0
|
|
finish()
|
|
|
|
degen = False
|
|
neverclaim = False
|
|
|
|
if buchi_type == 's' or ta_type == 't':
|
|
degen = True
|
|
elif buchi_type == 'i':
|
|
degen = True
|
|
neverclaim = True
|
|
|
|
if output_type == 't':
|
|
ta_type = form.getfirst('tf', 't')
|
|
if ta_type == 't':
|
|
degen = True
|
|
|
|
if prune_scc:
|
|
# Do not suppress all useless acceptance conditions if
|
|
# degeneralization or simulation is requested: keeping those that
|
|
# lead to accepting states usually helps.
|
|
automaton = spot.scc_filter(automaton, not (degen
|
|
or direct_simul
|
|
or reverse_simul
|
|
or iterated_simul))
|
|
issba = False
|
|
|
|
if wdba_minimize:
|
|
minimized = spot.minimize_obligation_new(automaton, f)
|
|
if minimized:
|
|
automaton = minimized
|
|
minimized = 0
|
|
degen = False # No need to degeneralize anymore
|
|
issba = True
|
|
direct_simul = False # No need to simulate anymore
|
|
reverse_simul = False
|
|
iterated_simul = False
|
|
|
|
if direct_simul and not iterated_simul:
|
|
automaton = spot.simulation(automaton)
|
|
issba = False
|
|
if reverse_simul and not iterated_simul:
|
|
automaton = spot.cosimulation(automaton)
|
|
issba = False
|
|
if iterated_simul:
|
|
automaton = spot.iterated_simulations(automaton)
|
|
issba = False
|
|
|
|
if prune_scc and (direct_simul or reverse_simul):
|
|
# Make a second pass after the simulation, since these might leave
|
|
# extra acceptance conditions.
|
|
automaton = spot.scc_filter(automaton, not degen)
|
|
|
|
if degen or neverclaim:
|
|
degen = spot.degeneralize(automaton)
|
|
issba = True
|
|
else:
|
|
degen = automaton
|
|
|
|
if utf8:
|
|
spot.tgba_enable_utf8(degen)
|
|
|
|
# Buchi Automaton Output
|
|
if output_type == 'a':
|
|
if buchi_type == 'i':
|
|
s = spot.ostringstream()
|
|
spot.never_claim_reachable(s, degen, f)
|
|
unbufprint('<div class="neverclaim">%s</div>' % cgi.escape(s.str()))
|
|
del s
|
|
else: # 't' or 's'
|
|
dont_run_dot = print_stats(degen, True)
|
|
render_automaton(degen, dont_run_dot, issba)
|
|
degen = 0
|
|
automaton = 0
|
|
finish()
|
|
|
|
# Testing automaton Output
|
|
if output_type == 't':
|
|
livelock = False
|
|
singlepass = False
|
|
bisimulation = False
|
|
for to in form.getlist('to'):
|
|
if to == 'l':
|
|
livelock = True
|
|
elif to == 's':
|
|
singlepass = True
|
|
elif to == 'm':
|
|
bisimulation = True
|
|
propset = spot.atomic_prop_collect_as_bdd(f, automaton)
|
|
if ta_type == 'a':
|
|
tautomaton = spot.tgba_to_tgta(degen, propset)
|
|
if bisimulation:
|
|
tautomaton = spot.minimize_tgta(tautomaton)
|
|
issba = False
|
|
else:
|
|
tautomaton = spot.tgba_to_ta(degen, propset,
|
|
issba, True, singlepass, livelock)
|
|
if bisimulation:
|
|
tautomaton = spot.minimize_ta(tautomaton)
|
|
dont_run_dot = print_stats(tautomaton)
|
|
render_automaton(tautomaton, dont_run_dot, issba)
|
|
tautomaton = 0
|
|
degen = 0
|
|
automaton = 0
|
|
finish()
|
|
|
|
# Buchi Run Output
|
|
if output_type == 'r':
|
|
|
|
print_acc_run = False
|
|
draw_acc_run = False
|
|
s = form.getfirst('rf', 'd')
|
|
if s == 'p':
|
|
print_acc_run = True
|
|
elif s == 'd':
|
|
draw_acc_run = True
|
|
|
|
|
|
err = ""
|
|
opt = (form.getfirst('ec', 'Cou99') + "(" +
|
|
form.getfirst('eo', '') + ")")
|
|
eci, err = spot.emptiness_check_instantiator.construct(opt)
|
|
|
|
if not eci:
|
|
unbufprint('<div class="parse-error">Cannot parse "' + opt
|
|
+ '" near "' + err + '".</div>')
|
|
ec = 0
|
|
else:
|
|
ec_a = 0
|
|
n_acc = degen.number_of_acceptance_conditions()
|
|
n_max = eci.max_acceptance_conditions()
|
|
n_min = eci.min_acceptance_conditions()
|
|
if (n_acc <= n_max):
|
|
if (n_acc >= n_min):
|
|
ec_a = degen
|
|
else:
|
|
unbufprint('<div class="ec-error">Cannot run ' + opt
|
|
+ ' on automata with less than ' + str(n_min)
|
|
+ ' acceptance condition.<br/>Please build '
|
|
+ 'a degeneralized Büchi automaton if you '
|
|
+ 'want to try this algorithm.</div>')
|
|
else:
|
|
unbufprint('<div class="ec-error">Cannot run ' + opt
|
|
+ ' on automata with more than ' + str(n_max)
|
|
+ ' acceptance condition.<br/>Please build '
|
|
+ 'a degeneralized Büchi automaton if you '
|
|
+ 'want to try this algorithm.</div>')
|
|
if ec_a:
|
|
ec = eci.instantiate(ec_a)
|
|
else:
|
|
ec = 0
|
|
|
|
if ec:
|
|
ec_res = ec.check()
|
|
if not ec_res:
|
|
unbufprint('<div class="ec">No accepting run found.</div>')
|
|
else:
|
|
ec_run = ec_res.accepting_run()
|
|
unbufprint('<div class="ec">An accepting run was found.<br/>')
|
|
if ec_run:
|
|
if print_acc_run:
|
|
s = spot.ostringstream()
|
|
spot.print_tgba_run(s, ec_a, ec_run)
|
|
unbufprint('<div class="accrun">%s</div>' %
|
|
cgi.escape(s.str()))
|
|
del s
|
|
|
|
if draw_acc_run:
|
|
deco = spot.tgba_run_dotty_decorator(ec_run)
|
|
dont_run_dot = print_stats(ec_a)
|
|
render_automaton(ec_a, dont_run_dot, issba, deco)
|
|
del deco
|
|
del ec_run
|
|
del ec_res
|
|
unbufprint('</div>')
|
|
del ec
|
|
del ec_a
|
|
degen = 0
|
|
automaton = 0
|
|
finish()
|