Fixes #539. * AUTHORS: Update by indicating the status of each contributor. * Makefile.am, bench/Makefile.am, bench/dtgbasat/Makefile.am, bench/dtgbasat/gen.py, bench/emptchk/Makefile.am, bench/emptchk/defs.in, bench/ltl2tgba/Makefile.am, bench/ltl2tgba/defs.in, bench/ltl2tgba/sum.py, bench/ltlclasses/Makefile.am, bench/ltlcounter/Makefile.am, bench/spin13/Makefile.am, bench/stutter/Makefile.am, bench/stutter/stutter_invariance_formulas.cc, bench/stutter/stutter_invariance_randomgraph.cc, bench/wdba/Makefile.am, bin/Makefile.am, bin/autcross.cc, bin/autfilt.cc, bin/common_aoutput.cc, bin/common_aoutput.hh, bin/common_color.cc, bin/common_color.hh, bin/common_conv.cc, bin/common_conv.hh, bin/common_cout.cc, bin/common_cout.hh, bin/common_file.cc, bin/common_file.hh, bin/common_finput.cc, bin/common_finput.hh, bin/common_hoaread.cc, bin/common_hoaread.hh, bin/common_output.cc, bin/common_output.hh, bin/common_post.cc, bin/common_post.hh, bin/common_r.cc, bin/common_r.hh, bin/common_range.cc, bin/common_range.hh, bin/common_setup.cc, bin/common_setup.hh, bin/common_sys.hh, bin/common_trans.cc, bin/common_trans.hh, bin/dstar2tgba.cc, bin/genaut.cc, bin/genltl.cc, bin/ltl2tgba.cc, bin/ltl2tgta.cc, bin/ltlcross.cc, bin/ltldo.cc, bin/ltlfilt.cc, bin/ltlgrind.cc, bin/ltlsynt.cc, bin/man/Makefile.am, bin/options.py, bin/randaut.cc, bin/randltl.cc, bin/spot-x.cc, bin/spot.cc, configure.ac, debian/copyright, doc/Makefile.am, doc/tl/Makefile.am, elisp/Makefile.am, python/Makefile.am, python/buddy.i, python/spot/__init__.py, python/spot/aux_.py, python/spot/gen.i, python/spot/impl.i, python/spot/jupyter.py, python/spot/ltsmin.i, spot/Makefile.am, spot/gen/Makefile.am, spot/gen/automata.cc, spot/gen/automata.hh, spot/gen/formulas.cc, spot/gen/formulas.hh, spot/graph/Makefile.am, spot/graph/graph.hh, spot/graph/ngraph.hh, spot/kripke/Makefile.am, spot/kripke/fairkripke.cc, spot/kripke/fairkripke.hh, spot/kripke/fwd.hh, spot/kripke/kripke.cc, spot/kripke/kripke.hh, spot/kripke/kripkegraph.hh, spot/ltsmin/Makefile.am, spot/ltsmin/ltsmin.cc, spot/ltsmin/ltsmin.hh, spot/ltsmin/spins_interface.cc, spot/ltsmin/spins_interface.hh, spot/ltsmin/spins_kripke.hh, spot/ltsmin/spins_kripke.hxx, spot/mc/Makefile.am, spot/mc/bloemen.hh, spot/mc/bloemen_ec.hh, spot/mc/cndfs.hh, spot/mc/deadlock.hh, spot/mc/intersect.hh, spot/mc/lpar13.hh, spot/mc/mc.hh, spot/mc/mc_instanciator.hh, spot/mc/unionfind.cc, spot/mc/unionfind.hh, spot/mc/utils.hh, spot/misc/Makefile.am, spot/misc/bareword.cc, spot/misc/bareword.hh, spot/misc/bddlt.hh, spot/misc/bitset.cc, spot/misc/bitset.hh, spot/misc/bitvect.cc, spot/misc/bitvect.hh, spot/misc/casts.hh, spot/misc/clz.hh, spot/misc/common.hh, spot/misc/escape.cc, spot/misc/escape.hh, spot/misc/fixpool.hh, spot/misc/formater.cc, spot/misc/formater.hh, spot/misc/hash.hh, spot/misc/hashfunc.hh, spot/misc/intvcmp2.cc, spot/misc/intvcmp2.hh, spot/misc/intvcomp.cc, spot/misc/intvcomp.hh, spot/misc/ltstr.hh, spot/misc/memusage.cc, spot/misc/memusage.hh, spot/misc/minato.cc, spot/misc/minato.hh, spot/misc/mspool.hh, spot/misc/optionmap.cc, spot/misc/optionmap.hh, spot/misc/random.cc, spot/misc/random.hh, spot/misc/satsolver.cc, spot/misc/satsolver.hh, spot/misc/timer.cc, spot/misc/timer.hh, spot/misc/tmpfile.cc, spot/misc/tmpfile.hh, spot/misc/trival.hh, spot/misc/version.cc, spot/misc/version.hh, spot/parseaut/Makefile.am, spot/parseaut/fmterror.cc, spot/parseaut/parseaut.yy, spot/parseaut/parsedecl.hh, spot/parseaut/public.hh, spot/parseaut/scanaut.ll, spot/parsetl/Makefile.am, spot/parsetl/fmterror.cc, spot/parsetl/parsedecl.hh, spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll, spot/priv/Makefile.am, spot/priv/accmap.hh, spot/priv/bddalloc.cc, spot/priv/bddalloc.hh, spot/priv/freelist.cc, spot/priv/freelist.hh, spot/priv/partitioned_relabel.cc, spot/priv/partitioned_relabel.hh, spot/priv/satcommon.cc, spot/priv/satcommon.hh, spot/priv/trim.cc, spot/priv/trim.hh, spot/priv/weight.cc, spot/priv/weight.hh, spot/ta/Makefile.am, spot/ta/ta.cc, spot/ta/ta.hh, spot/ta/taexplicit.cc, spot/ta/taexplicit.hh, spot/ta/taproduct.cc, spot/ta/taproduct.hh, spot/ta/tgta.hh, spot/ta/tgtaexplicit.cc, spot/ta/tgtaexplicit.hh, spot/ta/tgtaproduct.cc, spot/ta/tgtaproduct.hh, spot/taalgos/Makefile.am, spot/taalgos/dot.cc, spot/taalgos/dot.hh, spot/taalgos/emptinessta.cc, spot/taalgos/emptinessta.hh, spot/taalgos/minimize.cc, spot/taalgos/minimize.hh, spot/taalgos/reachiter.cc, spot/taalgos/reachiter.hh, spot/taalgos/statessetbuilder.cc, spot/taalgos/statessetbuilder.hh, spot/taalgos/stats.cc, spot/taalgos/stats.hh, spot/taalgos/tgba2ta.cc, spot/taalgos/tgba2ta.hh, spot/tl/Makefile.am, spot/tl/apcollect.cc, spot/tl/apcollect.hh, spot/tl/contain.cc, spot/tl/contain.hh, spot/tl/declenv.cc, spot/tl/declenv.hh, spot/tl/defaultenv.cc, spot/tl/defaultenv.hh, spot/tl/dot.cc, spot/tl/dot.hh, spot/tl/environment.hh, spot/tl/exclusive.cc, spot/tl/exclusive.hh, spot/tl/formula.cc, spot/tl/formula.hh, spot/tl/hierarchy.cc, spot/tl/hierarchy.hh, spot/tl/length.cc, spot/tl/length.hh, spot/tl/ltlf.cc, spot/tl/ltlf.hh, spot/tl/mark.cc, spot/tl/mark.hh, spot/tl/mutation.cc, spot/tl/mutation.hh, spot/tl/nenoform.cc, spot/tl/nenoform.hh, spot/tl/parse.hh, spot/tl/print.cc, spot/tl/print.hh, spot/tl/randomltl.cc, spot/tl/randomltl.hh, spot/tl/relabel.cc, spot/tl/relabel.hh, spot/tl/remove_x.cc, spot/tl/remove_x.hh, spot/tl/simplify.cc, spot/tl/simplify.hh, spot/tl/snf.cc, spot/tl/snf.hh, spot/tl/sonf.cc, spot/tl/sonf.hh, spot/tl/unabbrev.cc, spot/tl/unabbrev.hh, spot/twa/Makefile.am, spot/twa/acc.cc, spot/twa/acc.hh, spot/twa/bdddict.cc, spot/twa/bdddict.hh, spot/twa/bddprint.cc, spot/twa/bddprint.hh, spot/twa/formula2bdd.cc, spot/twa/formula2bdd.hh, spot/twa/fwd.hh, spot/twa/taatgba.cc, spot/twa/taatgba.hh, spot/twa/twa.cc, spot/twa/twa.hh, spot/twa/twagraph.cc, spot/twa/twagraph.hh, spot/twa/twaproduct.cc, spot/twa/twaproduct.hh, spot/twaalgos/Makefile.am, spot/twaalgos/aiger.cc, spot/twaalgos/aiger.hh, spot/twaalgos/alternation.cc, spot/twaalgos/alternation.hh, spot/twaalgos/are_isomorphic.cc, spot/twaalgos/are_isomorphic.hh, spot/twaalgos/bfssteps.cc, spot/twaalgos/bfssteps.hh, spot/twaalgos/canonicalize.cc, spot/twaalgos/canonicalize.hh, spot/twaalgos/cleanacc.cc, spot/twaalgos/cleanacc.hh, spot/twaalgos/cobuchi.cc, spot/twaalgos/cobuchi.hh, spot/twaalgos/complement.cc, spot/twaalgos/complement.hh, spot/twaalgos/complete.cc, spot/twaalgos/complete.hh, spot/twaalgos/compsusp.cc, spot/twaalgos/compsusp.hh, spot/twaalgos/contains.cc, spot/twaalgos/contains.hh, spot/twaalgos/copy.hh, spot/twaalgos/couvreurnew.cc, spot/twaalgos/couvreurnew.hh, spot/twaalgos/cycles.cc, spot/twaalgos/cycles.hh, spot/twaalgos/dbranch.cc, spot/twaalgos/dbranch.hh, spot/twaalgos/degen.cc, spot/twaalgos/degen.hh, spot/twaalgos/determinize.cc, spot/twaalgos/determinize.hh, spot/twaalgos/dot.cc, spot/twaalgos/dot.hh, spot/twaalgos/dtbasat.cc, spot/twaalgos/dtbasat.hh, spot/twaalgos/dtwasat.cc, spot/twaalgos/dtwasat.hh, spot/twaalgos/dualize.cc, spot/twaalgos/dualize.hh, spot/twaalgos/emptiness.cc, spot/twaalgos/emptiness.hh, spot/twaalgos/emptiness_stats.hh, spot/twaalgos/forq_contains.cc, spot/twaalgos/forq_contains.hh, spot/twaalgos/game.cc, spot/twaalgos/game.hh, spot/twaalgos/genem.cc, spot/twaalgos/genem.hh, spot/twaalgos/gfguarantee.cc, spot/twaalgos/gfguarantee.hh, spot/twaalgos/gtec/Makefile.am, spot/twaalgos/gtec/ce.cc, spot/twaalgos/gtec/ce.hh, spot/twaalgos/gtec/gtec.cc, spot/twaalgos/gtec/gtec.hh, spot/twaalgos/gtec/sccstack.cc, spot/twaalgos/gtec/sccstack.hh, spot/twaalgos/gtec/status.cc, spot/twaalgos/gtec/status.hh, spot/twaalgos/gv04.cc, spot/twaalgos/gv04.hh, spot/twaalgos/hoa.cc, spot/twaalgos/hoa.hh, spot/twaalgos/iscolored.cc, spot/twaalgos/iscolored.hh, spot/twaalgos/isdet.cc, spot/twaalgos/isdet.hh, spot/twaalgos/isunamb.cc, spot/twaalgos/isunamb.hh, spot/twaalgos/isweakscc.cc, spot/twaalgos/isweakscc.hh, spot/twaalgos/langmap.cc, spot/twaalgos/langmap.hh, spot/twaalgos/lbtt.cc, spot/twaalgos/lbtt.hh, spot/twaalgos/ltl2taa.cc, spot/twaalgos/ltl2taa.hh, spot/twaalgos/ltl2tgba_fm.cc, spot/twaalgos/ltl2tgba_fm.hh, spot/twaalgos/magic.cc, spot/twaalgos/magic.hh, spot/twaalgos/mask.cc, spot/twaalgos/mask.hh, spot/twaalgos/mealy_machine.cc, spot/twaalgos/mealy_machine.hh, spot/twaalgos/minimize.cc, spot/twaalgos/minimize.hh, spot/twaalgos/ndfs_result.hxx, spot/twaalgos/neverclaim.cc, spot/twaalgos/neverclaim.hh, spot/twaalgos/parity.cc, spot/twaalgos/parity.hh, spot/twaalgos/postproc.cc, spot/twaalgos/postproc.hh, spot/twaalgos/powerset.cc, spot/twaalgos/powerset.hh, spot/twaalgos/product.cc, spot/twaalgos/product.hh, spot/twaalgos/randomgraph.cc, spot/twaalgos/randomgraph.hh, spot/twaalgos/randomize.cc, spot/twaalgos/randomize.hh, spot/twaalgos/reachiter.cc, spot/twaalgos/reachiter.hh, spot/twaalgos/relabel.cc, spot/twaalgos/relabel.hh, spot/twaalgos/remfin.cc, spot/twaalgos/remfin.hh, spot/twaalgos/remprop.cc, spot/twaalgos/remprop.hh, spot/twaalgos/sbacc.cc, spot/twaalgos/sbacc.hh, spot/twaalgos/sccfilter.cc, spot/twaalgos/sccfilter.hh, spot/twaalgos/sccinfo.cc, spot/twaalgos/sccinfo.hh, spot/twaalgos/se05.cc, spot/twaalgos/se05.hh, spot/twaalgos/sepsets.cc, spot/twaalgos/sepsets.hh, spot/twaalgos/simulation.cc, spot/twaalgos/simulation.hh, spot/twaalgos/split.cc, spot/twaalgos/split.hh, spot/twaalgos/stats.cc, spot/twaalgos/stats.hh, spot/twaalgos/strength.cc, spot/twaalgos/strength.hh, spot/twaalgos/stripacc.cc, spot/twaalgos/stripacc.hh, spot/twaalgos/stutter.cc, spot/twaalgos/stutter.hh, spot/twaalgos/sum.cc, spot/twaalgos/sum.hh, spot/twaalgos/synthesis.cc, spot/twaalgos/synthesis.hh, spot/twaalgos/tau03.cc, spot/twaalgos/tau03.hh, spot/twaalgos/tau03opt.cc, spot/twaalgos/tau03opt.hh, spot/twaalgos/toparity.cc, spot/twaalgos/toparity.hh, spot/twaalgos/totgba.cc, spot/twaalgos/totgba.hh, spot/twaalgos/toweak.cc, spot/twaalgos/toweak.hh, spot/twaalgos/translate.cc, spot/twaalgos/translate.hh, spot/twaalgos/word.cc, spot/twaalgos/word.hh, spot/twaalgos/zlktree.cc, spot/twaalgos/zlktree.hh, spot/twacube/Makefile.am, spot/twacube/cube.cc, spot/twacube/cube.hh, spot/twacube/fwd.hh, spot/twacube/twacube.cc, spot/twacube/twacube.hh, spot/twacube_algos/Makefile.am, spot/twacube_algos/convert.cc, spot/twacube_algos/convert.hh, tests/Makefile.am, tests/core/385.test, tests/core/500.test, tests/core/521.test, tests/core/522.test, tests/core/acc.cc, tests/core/acc.test, tests/core/acc2.test, tests/core/acc_word.test, tests/core/accsimpl.test, tests/core/alternating.test, tests/core/autcross.test, tests/core/autcross2.test, tests/core/autcross3.test, tests/core/autcross4.test, tests/core/autcross5.test, tests/core/babiak.test, tests/core/bare.test, tests/core/basimul.test, tests/core/bdd.test, tests/core/bdddict.cc, tests/core/bdddict.test, tests/core/bitvect.cc, tests/core/bitvect.test, tests/core/bricks.cc, tests/core/bricks.test, tests/core/checkpsl.cc, tests/core/checkta.cc, tests/core/complement.test, tests/core/complementation.test, tests/core/complete.test, tests/core/consterm.cc, tests/core/consterm.test, tests/core/cube.cc, tests/core/cube.test, tests/core/cycles.test, tests/core/dbacomp.test, tests/core/dca.test, tests/core/dca2.test, tests/core/defs.in, tests/core/degendet.test, tests/core/degenid.test, tests/core/degenlskip.test, tests/core/degenscc.test, tests/core/det.test, tests/core/dfs.test, tests/core/dnfstreett.test, tests/core/dot2tex.test, tests/core/dra2dba.test, tests/core/dstar.test, tests/core/dualize.test, tests/core/dupexp.test, tests/core/emptchk.cc, tests/core/emptchk.test, tests/core/emptchke.test, tests/core/emptchkr.test, tests/core/equals.test, tests/core/equalsf.cc, tests/core/eventuniv.test, tests/core/exclusive-ltl.test, tests/core/exclusive-tgba.test, tests/core/explpro2.test, tests/core/explpro3.test, tests/core/explpro4.test, tests/core/explprod.test, tests/core/explsum.test, tests/core/format.test, tests/core/full.test, tests/core/gamehoa.test, tests/core/genaut.test, tests/core/genltl.test, tests/core/gragsa.test, tests/core/graph.cc, tests/core/graph.test, tests/core/hierarchy.test, tests/core/highlightstate.test, tests/core/ikwiad.cc, tests/core/included.test, tests/core/intvcmp2.cc, tests/core/intvcomp.cc, tests/core/intvcomp.test, tests/core/isomorph.test, tests/core/isop.test, tests/core/kind.cc, tests/core/kind.test, tests/core/kripke.test, tests/core/kripkecat.cc, tests/core/latex.test, tests/core/lbt.test, tests/core/lbttparse.test, tests/core/length.cc, tests/core/length.test, tests/core/lenient.test, tests/core/ltl2dstar.test, tests/core/ltl2dstar2.test, tests/core/ltl2dstar3.test, tests/core/ltl2dstar4.test, tests/core/ltl2neverclaim-lbtt.test, tests/core/ltl2neverclaim.test, tests/core/ltl2ta.test, tests/core/ltl2ta2.test, tests/core/ltl2tgba.test, tests/core/ltl2tgba2.test, tests/core/ltl3ba.test, tests/core/ltl3dra.test, tests/core/ltlcounter.test, tests/core/ltlcross.test, tests/core/ltlcross2.test, tests/core/ltlcross3.test, tests/core/ltlcross4.test, tests/core/ltlcross5.test, tests/core/ltlcross6.test, tests/core/ltlcrossce.test, tests/core/ltlcrossce2.test, tests/core/ltlcrossgrind.test, tests/core/ltldo.test, tests/core/ltldo2.test, tests/core/ltlf.test, tests/core/ltlfilt.test, tests/core/ltlgrind.test, tests/core/ltlrel.cc, tests/core/ltlrel.test, tests/core/ltlsynt-pgame.test, tests/core/ltlsynt.test, tests/core/ltlsynt2.test, tests/core/lunabbrev.test, tests/core/maskacc.test, tests/core/maskkeep.test, tests/core/mempool.cc, tests/core/mempool.test, tests/core/minterm.cc, tests/core/minterm.test, tests/core/minusx.test, tests/core/monitor.test, tests/core/nenoform.test, tests/core/neverclaimread.test, tests/core/ngraph.cc, tests/core/ngraph.test, tests/core/nondet.test, tests/core/obligation.test, tests/core/optba.test, tests/core/parity.cc, tests/core/parity.test, tests/core/parity2.test, tests/core/parse.test, tests/core/parseaut.test, tests/core/parseerr.test, tests/core/pdegen.test, tests/core/pgsolver.test, tests/core/prodchain.test, tests/core/prodor.test, tests/core/rabin2parity.test, tests/core/rand.test, tests/core/randaut.test, tests/core/randomize.test, tests/core/randpsl.test, tests/core/randtgba.cc, tests/core/randtgba.test, tests/core/readltl.cc, tests/core/readsave.test, tests/core/reduc.cc, tests/core/reduc.test, tests/core/reduc0.test, tests/core/reduccmp.test, tests/core/reducpsl.test, tests/core/remfin.test, tests/core/remove_x.test, tests/core/remprop.test, tests/core/renault.test, tests/core/safra.cc, tests/core/safra.test, tests/core/satmin.test, tests/core/satmin2.test, tests/core/satmin3.test, tests/core/sbacc.test, tests/core/scc.test, tests/core/sccdot.test, tests/core/sccif.cc, tests/core/sccif.test, tests/core/sccsimpl.test, tests/core/semidet.test, tests/core/sepsets.test, tests/core/serial.test, tests/core/sim2.test, tests/core/sim3.test, tests/core/sonf.test, tests/core/split.test, tests/core/spotlbtt.test, tests/core/spotlbtt2.test, tests/core/streett.test, tests/core/strength.test, tests/core/stutter-ltl.test, tests/core/stutter-tgba.test, tests/core/sugar.test, tests/core/syfco.test, tests/core/syntimpl.cc, tests/core/syntimpl.test, tests/core/taatgba.cc, tests/core/taatgba.test, tests/core/tgbagraph.test, tests/core/tostring.cc, tests/core/tostring.test, tests/core/tripprod.test, tests/core/trival.cc, tests/core/trival.test, tests/core/tunabbrev.test, tests/core/tunenoform.test, tests/core/twacube.cc, tests/core/twacube.test, tests/core/twagraph.cc, tests/core/unabbrevwm.test, tests/core/unambig.test, tests/core/unambig2.test, tests/core/uniq.test, tests/core/utf8.test, tests/core/uwrm.test, tests/core/wdba.test, tests/core/wdba2.test, tests/ltsmin/check.test, tests/ltsmin/check2.test, tests/ltsmin/check3.test, tests/ltsmin/finite.test, tests/ltsmin/finite2.test, tests/ltsmin/finite3.test, tests/ltsmin/kripke.test, tests/ltsmin/modelcheck.cc, tests/ltsmin/testconvert.cc, tests/ltsmin/testconvert.test, tests/python/298.py, tests/python/341.py, tests/python/471.py, tests/python/acc.py, tests/python/accparse2.py, tests/python/aiger.py, tests/python/alarm.py, tests/python/aliases.py, tests/python/alternating.py, tests/python/bdddict.py, tests/python/bdditer.py, tests/python/bddnqueen.py, tests/python/bugdet.py, tests/python/complement_semidet.py, tests/python/dbranch.py, tests/python/declenv.py, tests/python/decompose_scc.py, tests/python/det.py, tests/python/dualize.py, tests/python/ecfalse.py, tests/python/except.py, tests/python/forq_contains.py, tests/python/game.py, tests/python/gen.py, tests/python/genem.py, tests/python/implies.py, tests/python/interdep.py, tests/python/intrun.py, tests/python/kripke.py, tests/python/langmap.py, tests/python/ltl2tgba.py, tests/python/ltl2tgba.test, tests/python/ltlf.py, tests/python/ltlparse.py, tests/python/ltlsimple.py, tests/python/mealy.py, tests/python/merge.py, tests/python/mergedge.py, tests/python/minato.py, tests/python/misc-ec.py, tests/python/optionmap.py, tests/python/origstate.py, tests/python/otfcrash.py, tests/python/parity.py, tests/python/parsetgba.py, tests/python/pdegen.py, tests/python/powerset.py, tests/python/prodexpt.py, tests/python/randgen.py, tests/python/relabel.py, tests/python/remfin.py, tests/python/removeap.py, tests/python/rs_like.py, tests/python/satmin.py, tests/python/sbacc.py, tests/python/sccfilter.py, tests/python/sccinfo.py, tests/python/sccsplit.py, tests/python/semidet.py, tests/python/setacc.py, tests/python/setxor.py, tests/python/simplacc.py, tests/python/simstate.py, tests/python/sonf.py, tests/python/split.py, tests/python/splitedge.py, tests/python/streett_totgba.py, tests/python/streett_totgba2.py, tests/python/stutter.py, tests/python/sum.py, tests/python/synthesis.py, tests/python/toparity.py, tests/python/toweak.py, tests/python/tra2tba.py, tests/python/trival.py, tests/python/twagraph.py, tests/python/zlktree.py, tests/run.in, tests/sanity/80columns.test, tests/sanity/bin.test, tests/sanity/getenv.test, tests/sanity/includes.test, tests/sanity/ipynb.pl, tests/sanity/namedprop.test, tests/sanity/private.test, tests/sanity/readme.pl, tests/sanity/style.test, tools/man2html.pl: Update all copyright headers.
925 lines
30 KiB
C++
925 lines
30 KiB
C++
// -*- coding: utf-8 -*-
|
||
// Copyright (C) by the Spot authors, see the AUTHORS file for details.
|
||
//
|
||
// 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/>.
|
||
|
||
#include "common_sys.hh"
|
||
|
||
#include <cstdlib>
|
||
#include <string>
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <argp.h>
|
||
#include <cstring>
|
||
#include "error.h"
|
||
|
||
#include "common_setup.hh"
|
||
#include "common_finput.hh"
|
||
#include "common_output.hh"
|
||
#include "common_cout.hh"
|
||
#include "common_conv.hh"
|
||
#include "common_r.hh"
|
||
#include "common_range.hh"
|
||
|
||
#include <spot/misc/hash.hh>
|
||
#include <spot/misc/timer.hh>
|
||
#include <spot/tl/simplify.hh>
|
||
#include <spot/tl/sonf.hh>
|
||
#include <spot/tl/length.hh>
|
||
#include <spot/tl/relabel.hh>
|
||
#include <spot/tl/unabbrev.hh>
|
||
#include <spot/tl/remove_x.hh>
|
||
#include <spot/tl/apcollect.hh>
|
||
#include <spot/tl/exclusive.hh>
|
||
#include <spot/tl/ltlf.hh>
|
||
#include <spot/tl/print.hh>
|
||
#include <spot/tl/hierarchy.hh>
|
||
#include <spot/twaalgos/isdet.hh>
|
||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||
#include <spot/twaalgos/minimize.hh>
|
||
#include <spot/twaalgos/postproc.hh>
|
||
#include <spot/twaalgos/product.hh>
|
||
#include <spot/twaalgos/remfin.hh>
|
||
#include <spot/twaalgos/strength.hh>
|
||
#include <spot/twaalgos/stutter.hh>
|
||
#include <spot/twaalgos/totgba.hh>
|
||
#include <spot/twaalgos/word.hh>
|
||
|
||
static const char argp_program_doc[] = "\
|
||
Read a list of formulas and output them back after some optional processing.\v\
|
||
Exit status:\n\
|
||
0 if some formulas were output (skipped syntax errors do not count)\n\
|
||
1 if no formulas were output (no match)\n\
|
||
2 if any error has been reported";
|
||
|
||
enum {
|
||
OPT_ACCEPT_WORD = 256,
|
||
OPT_AP_N,
|
||
OPT_BOOLEAN,
|
||
OPT_BOOLEAN_TO_ISOP,
|
||
OPT_BSIZE,
|
||
OPT_BSIZE_MAX,
|
||
OPT_BSIZE_MIN,
|
||
OPT_DEFINE,
|
||
OPT_DROP_ERRORS,
|
||
OPT_EQUIVALENT_TO,
|
||
OPT_EXCLUSIVE_AP,
|
||
OPT_EVENTUAL,
|
||
OPT_FROM_LTLF,
|
||
OPT_GUARANTEE,
|
||
OPT_IGNORE_ERRORS,
|
||
OPT_IMPLIED_BY,
|
||
OPT_IMPLY,
|
||
OPT_LIVENESS,
|
||
OPT_LTL,
|
||
OPT_NEGATE,
|
||
OPT_NNF,
|
||
OPT_OBLIGATION,
|
||
OPT_PERSISTENCE,
|
||
OPT_RECURRENCE,
|
||
OPT_REJECT_WORD,
|
||
OPT_RELABEL,
|
||
OPT_RELABEL_BOOL,
|
||
OPT_RELABEL_OVERLAP,
|
||
OPT_REMOVE_WM,
|
||
OPT_REMOVE_X,
|
||
OPT_SAFETY,
|
||
OPT_SIZE,
|
||
OPT_SIZE_MAX,
|
||
OPT_SIZE_MIN,
|
||
OPT_SKIP_ERRORS,
|
||
OPT_SONF,
|
||
OPT_SONF_APS,
|
||
OPT_STUTTER_INSENSITIVE,
|
||
OPT_SUSPENDABLE,
|
||
OPT_SYNTACTIC_GUARANTEE,
|
||
OPT_SYNTACTIC_OBLIGATION,
|
||
OPT_SYNTACTIC_PERSISTENCE,
|
||
OPT_SYNTACTIC_RECURRENCE,
|
||
OPT_SYNTACTIC_SAFETY,
|
||
OPT_SYNTACTIC_SI,
|
||
OPT_UNABBREVIATE,
|
||
OPT_UNIVERSAL,
|
||
};
|
||
|
||
static const argp_option options[] =
|
||
{
|
||
/**************************************************/
|
||
{ nullptr, 0, nullptr, 0, "Error handling:", 2 },
|
||
{ "skip-errors", OPT_SKIP_ERRORS, nullptr, 0,
|
||
"output erroneous lines as-is without processing", 0 },
|
||
{ "drop-errors", OPT_DROP_ERRORS, nullptr, 0,
|
||
"discard erroneous lines (default)", 0 },
|
||
{ "ignore-errors", OPT_IGNORE_ERRORS, nullptr, 0,
|
||
"do not report syntax errors", 0 },
|
||
/**************************************************/
|
||
{ nullptr, 0, nullptr, 0, "Transformation options:", 3 },
|
||
{ "negate", OPT_NEGATE, nullptr, 0, "negate each formula", 0 },
|
||
{ "nnf", OPT_NNF, nullptr, 0,
|
||
"rewrite formulas in negative normal form", 0 },
|
||
{ "sonf", OPT_SONF, "PREFIX", OPTION_ARG_OPTIONAL,
|
||
"rewrite formulas in suffix operator normal form", 0 },
|
||
{ "sonf-aps", OPT_SONF_APS, "FILENAME", OPTION_ARG_OPTIONAL,
|
||
"when used with --sonf, output the newly introduced atomic "
|
||
"propositions", 0 },
|
||
{ "relabel", OPT_RELABEL, "abc|pnn", OPTION_ARG_OPTIONAL,
|
||
"relabel all atomic propositions, alphabetically unless " \
|
||
"specified otherwise", 0 },
|
||
{ "relabel-bool", OPT_RELABEL_BOOL, "abc|pnn", OPTION_ARG_OPTIONAL,
|
||
"relabel Boolean subexpressions that do not share atomic propositions,"
|
||
" relabel alphabetically unless specified otherwise", 0 },
|
||
{ "relabel-overlapping-bool", OPT_RELABEL_OVERLAP, "abc|pnn",
|
||
OPTION_ARG_OPTIONAL,
|
||
"relabel Boolean subexpressions even if they share atomic propositions,"
|
||
" relabel alphabetically unless specified otherwise", 0 },
|
||
{ "define", OPT_DEFINE, "FILENAME", OPTION_ARG_OPTIONAL,
|
||
"when used with --relabel or --relabel-bool, output the relabeling map "
|
||
"using #define statements", 0 },
|
||
{ "remove-wm", OPT_REMOVE_WM, nullptr, 0,
|
||
"rewrite operators W and M using U and R (this is an alias for "
|
||
"--unabbreviate=WM)", 0 },
|
||
{ "boolean-to-isop", OPT_BOOLEAN_TO_ISOP, nullptr, 0,
|
||
"rewrite Boolean subformulas as irredundant sum of products "
|
||
"(implies at least -r1)", 0 },
|
||
{ "remove-x", OPT_REMOVE_X, nullptr, 0,
|
||
"remove X operators (valid only for stutter-insensitive properties)",
|
||
0 },
|
||
{ "unabbreviate", OPT_UNABBREVIATE, "STR", OPTION_ARG_OPTIONAL,
|
||
"remove all occurrences of the operators specified by STR, which "
|
||
"must be a substring of \"eFGiMRW^\", where 'e', 'i', and '^' stand "
|
||
"respectively for <->, ->, and xor. If no argument is passed, "
|
||
"the subset \"eFGiMW^\" is used.", 0 },
|
||
{ "exclusive-ap", OPT_EXCLUSIVE_AP, "AP,AP,...", 0,
|
||
"if any of those APs occur in the formula, add a term ensuring "
|
||
"two of them may not be true at the same time. Use this option "
|
||
"multiple times to declare independent groups of exclusive "
|
||
"propositions.", 0 },
|
||
{ "from-ltlf", OPT_FROM_LTLF, "alive", OPTION_ARG_OPTIONAL,
|
||
"transform LTLf (finite LTL) to LTL by introducing some 'alive'"
|
||
" proposition", 0 },
|
||
DECLARE_OPT_R,
|
||
LEVEL_DOC(4),
|
||
/**************************************************/
|
||
{ nullptr, 0, nullptr, 0,
|
||
"Filtering options (matching is done after transformation):", 5 },
|
||
{ "ltl", OPT_LTL, nullptr, 0,
|
||
"match only LTL formulas (no PSL operator)", 0 },
|
||
{ "boolean", OPT_BOOLEAN, nullptr, 0, "match Boolean formulas", 0 },
|
||
{ "eventual", OPT_EVENTUAL, nullptr, 0, "match pure eventualities", 0 },
|
||
{ "universal", OPT_UNIVERSAL, nullptr, 0,
|
||
"match purely universal formulas", 0 },
|
||
{ "suspendable", OPT_SUSPENDABLE, nullptr, 0,
|
||
"synonym for --universal --eventual", 0 },
|
||
{ "syntactic-safety", OPT_SYNTACTIC_SAFETY, nullptr, 0,
|
||
"match syntactic-safety formulas", 0 },
|
||
{ "syntactic-guarantee", OPT_SYNTACTIC_GUARANTEE, nullptr, 0,
|
||
"match syntactic-guarantee formulas", 0 },
|
||
{ "syntactic-obligation", OPT_SYNTACTIC_OBLIGATION, nullptr, 0,
|
||
"match syntactic-obligation formulas", 0 },
|
||
{ "syntactic-recurrence", OPT_SYNTACTIC_RECURRENCE, nullptr, 0,
|
||
"match syntactic-recurrence formulas", 0 },
|
||
{ "syntactic-persistence", OPT_SYNTACTIC_PERSISTENCE, nullptr, 0,
|
||
"match syntactic-persistence formulas", 0 },
|
||
{ "syntactic-stutter-invariant", OPT_SYNTACTIC_SI, nullptr, 0,
|
||
"match stutter-invariant formulas syntactically (LTL-X or siPSL)", 0 },
|
||
{ "nox", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||
{ "liveness", OPT_LIVENESS, nullptr, 0,
|
||
"match liveness properties", 0 },
|
||
{ "safety", OPT_SAFETY, nullptr, 0,
|
||
"match safety formulas (even pathological)", 0 },
|
||
{ "guarantee", OPT_GUARANTEE, nullptr, 0,
|
||
"match guarantee formulas (even pathological)", 0 },
|
||
{ "obligation", OPT_OBLIGATION, nullptr, 0,
|
||
"match obligation formulas (even pathological)", 0 },
|
||
{ "persistence", OPT_PERSISTENCE, nullptr, 0,
|
||
"match persistence formulas (even pathological)", 0 },
|
||
{ "recurrence", OPT_RECURRENCE, nullptr, 0,
|
||
"match recurrence formulas (even pathological)", 0 },
|
||
{ "size", OPT_SIZE, "RANGE", 0,
|
||
"match formulas with size in RANGE", 0},
|
||
// backward compatibility
|
||
{ "size-max", OPT_SIZE_MAX, "INT", OPTION_HIDDEN,
|
||
"match formulas with size <= INT", 0 },
|
||
// backward compatibility
|
||
{ "size-min", OPT_SIZE_MIN, "INT", OPTION_HIDDEN,
|
||
"match formulas with size >= INT", 0 },
|
||
{ "bsize", OPT_BSIZE, "RANGE", 0,
|
||
"match formulas with Boolean size in RANGE", 0 },
|
||
// backward compatibility
|
||
{ "bsize-max", OPT_BSIZE_MAX, "INT", OPTION_HIDDEN,
|
||
"match formulas with Boolean size <= INT", 0 },
|
||
// backward compatibility
|
||
{ "bsize-min", OPT_BSIZE_MIN, "INT", OPTION_HIDDEN,
|
||
"match formulas with Boolean size >= INT", 0 },
|
||
{ "implied-by", OPT_IMPLIED_BY, "FORMULA", 0,
|
||
"match formulas implied by FORMULA", 0 },
|
||
{ "imply", OPT_IMPLY, "FORMULA", 0,
|
||
"match formulas implying FORMULA", 0 },
|
||
{ "equivalent-to", OPT_EQUIVALENT_TO, "FORMULA", 0,
|
||
"match formulas equivalent to FORMULA", 0 },
|
||
{ "stutter-insensitive", OPT_STUTTER_INSENSITIVE, nullptr, 0,
|
||
"match stutter-insensitive LTL formulas", 0 },
|
||
{ "stutter-invariant", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||
{ "ap", OPT_AP_N, "RANGE", 0,
|
||
"match formulas with a number of atomic propositions in RANGE", 0 },
|
||
{ "nth", 'N', "RANGE", 0,
|
||
"assuming input formulas are numbered from 1, keep only those in RANGE",
|
||
0 },
|
||
{ "invert-match", 'v', nullptr, 0, "select non-matching formulas", 0},
|
||
{ "unique", 'u', nullptr, 0,
|
||
"drop formulas that have already been output (not affected by -v)", 0 },
|
||
{ "accept-word", OPT_ACCEPT_WORD, "WORD", 0,
|
||
"keep formulas that accept WORD", 0 },
|
||
{ "reject-word", OPT_REJECT_WORD, "WORD", 0,
|
||
"keep formulas that reject WORD", 0 },
|
||
RANGE_DOC_FULL,
|
||
WORD_DOC,
|
||
/**************************************************/
|
||
{ nullptr, 0, nullptr, 0, "Output options:", -20 },
|
||
{ "count", 'c', nullptr, 0, "print only a count of matched formulas", 0 },
|
||
{ "quiet", 'q', nullptr, 0, "suppress all normal output", 0 },
|
||
{ "max-count", 'n', "NUM", 0, "output at most NUM formulas", 0 },
|
||
{ nullptr, 0, nullptr, 0, "The FORMAT string passed to --format may use "\
|
||
"the following interpreted sequences:", -19 },
|
||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the formula (in the selected syntax)", 0 },
|
||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the name of the input file", 0 },
|
||
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the serial number of the output formula", 0 },
|
||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the original line number in the input file", 0 },
|
||
{ "%r", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"wall-clock time elapsed in seconds (excluding parsing)", 0 },
|
||
{ "%R, %[LETTERS]R", 0, nullptr,
|
||
OPTION_DOC | OPTION_NO_USAGE,
|
||
"CPU time (excluding parsing), in seconds; Add LETTERS to restrict to "
|
||
"(u) user time, (s) system time, (p) parent process, "
|
||
"or (c) children processes.", 0 },
|
||
{ "%<", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the part of the line before the formula if it "
|
||
"comes from a column extracted from a CSV file", 0 },
|
||
{ "%>", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"the part of the line after the formula if it "
|
||
"comes from a column extracted from a CSV file", 0 },
|
||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||
"a single %", 0 },
|
||
COMMON_LTL_OUTPUT_SPECS,
|
||
/**************************************************/
|
||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||
};
|
||
|
||
const struct argp_child children[] =
|
||
{
|
||
{ &finput_argp, 0, nullptr, 1 },
|
||
{ &output_argp, 0, nullptr, 0 },
|
||
{ &misc_argp, 0, nullptr, 0 },
|
||
{ nullptr, 0, nullptr, 0 }
|
||
};
|
||
|
||
static bool one_match = false;
|
||
|
||
enum error_style_t { drop_errors, skip_errors };
|
||
static error_style_t error_style = drop_errors;
|
||
static bool ignore_errors = false;
|
||
static bool nnf = false;
|
||
static bool negate = false;
|
||
static bool boolean_to_isop = false;
|
||
static bool unique = false;
|
||
static bool psl = false;
|
||
static bool liveness = false;
|
||
static bool ltl = false;
|
||
static bool invert = false;
|
||
static bool boolean = false;
|
||
static bool universal = false;
|
||
static bool eventual = false;
|
||
static bool syntactic_safety = false;
|
||
static bool syntactic_guarantee = false;
|
||
static bool syntactic_obligation = false;
|
||
static bool syntactic_recurrence = false;
|
||
static bool syntactic_persistence = false;
|
||
static bool syntactic_si = false;
|
||
static bool safety = false;
|
||
static bool guarantee = false;
|
||
static bool obligation = false;
|
||
static bool recurrence = false;
|
||
static bool persistence = false;
|
||
static range size = { -1, -1 };
|
||
static range bsize = { -1, -1 };
|
||
enum relabeling_mode { NoRelabeling = 0,
|
||
ApRelabeling,
|
||
BseRelabeling,
|
||
OverlappingRelabeling };
|
||
static relabeling_mode relabeling = NoRelabeling;
|
||
static spot::relabeling_style style = spot::Abc;
|
||
static bool remove_x = false;
|
||
static bool stutter_insensitive = false;
|
||
static range ap_n = { -1, -1 };
|
||
static range opt_nth = { 0, std::numeric_limits<int>::max() };
|
||
static int opt_max_count = -1;
|
||
static long int match_count = 0;
|
||
static const char* from_ltlf = nullptr;
|
||
static const char* sonf = nullptr;
|
||
|
||
|
||
// We want all these variables to be destroyed when we exit main, to
|
||
// make sure it happens before all other global variables (like the
|
||
// atomic propositions maps) are destroyed. Otherwise we risk
|
||
// accessing deleted stuff.
|
||
static struct opt_t
|
||
{
|
||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||
spot::exclusive_ap excl_ap;
|
||
std::unique_ptr<output_file> output_define = nullptr;
|
||
std::unique_ptr<output_file> output_sonf = nullptr;
|
||
spot::formula implied_by = nullptr;
|
||
spot::formula imply = nullptr;
|
||
spot::formula equivalent_to = nullptr;
|
||
std::vector<spot::twa_graph_ptr> acc_words;
|
||
std::vector<spot::twa_graph_ptr> rej_words;
|
||
}* opt;
|
||
|
||
static std::string unabbreviate;
|
||
|
||
|
||
static spot::formula
|
||
parse_formula_arg(const std::string& input)
|
||
{
|
||
spot::parsed_formula pf = parse_formula(input);
|
||
if (pf.format_errors(std::cerr))
|
||
error(2, 0, "parse error when parsing an argument");
|
||
return pf.f;
|
||
}
|
||
|
||
static void
|
||
parse_relabeling_style(const char* arg, const char* optname)
|
||
{
|
||
if (!arg || !strncasecmp(arg, "abc", 6))
|
||
style = spot::Abc;
|
||
else if (!strncasecmp(arg, "pnn", 4))
|
||
style = spot::Pnn;
|
||
else
|
||
error(2, 0, "invalid argument for --relabel%s: '%s'\n"
|
||
"expecting 'abc' or 'pnn'", optname, arg);
|
||
}
|
||
|
||
|
||
static int
|
||
parse_opt(int key, char* arg, struct argp_state*)
|
||
{
|
||
// Called from C code, so should not raise any exception.
|
||
BEGIN_EXCEPTION_PROTECT;
|
||
// This switch is alphabetically-ordered.
|
||
switch (key)
|
||
{
|
||
case 'c':
|
||
output_format = count_output;
|
||
break;
|
||
case 'n':
|
||
opt_max_count = to_pos_int(arg, "-n/--max-count");
|
||
break;
|
||
case 'N':
|
||
opt_nth = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||
break;
|
||
case 'q':
|
||
output_format = quiet_output;
|
||
break;
|
||
case OPT_R:
|
||
parse_r(arg);
|
||
break;
|
||
case 'u':
|
||
unique = true;
|
||
break;
|
||
case 'v':
|
||
invert = true;
|
||
break;
|
||
case ARGP_KEY_ARG:
|
||
// FIXME: use stat() to distinguish filename from string?
|
||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||
break;
|
||
case OPT_ACCEPT_WORD:
|
||
try
|
||
{
|
||
opt->acc_words.push_back(spot::parse_word(arg, opt->dict)
|
||
->as_automaton());
|
||
}
|
||
catch (const spot::parse_error& e)
|
||
{
|
||
error(2, 0, "failed to parse the argument of --accept-word:\n%s",
|
||
e.what());
|
||
}
|
||
break;
|
||
case OPT_BOOLEAN:
|
||
boolean = true;
|
||
break;
|
||
case OPT_BOOLEAN_TO_ISOP:
|
||
boolean_to_isop = true;
|
||
break;
|
||
case OPT_BSIZE:
|
||
bsize = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||
break;
|
||
case OPT_BSIZE_MIN:
|
||
bsize.min = to_int(arg, "--bsize-min");
|
||
break;
|
||
case OPT_BSIZE_MAX:
|
||
bsize.max = to_int(arg, "--bsize-max");
|
||
break;
|
||
case OPT_DEFINE:
|
||
opt->output_define.reset(new output_file(arg ? arg : "-"));
|
||
break;
|
||
case OPT_DROP_ERRORS:
|
||
error_style = drop_errors;
|
||
break;
|
||
case OPT_EVENTUAL:
|
||
eventual = true;
|
||
break;
|
||
case OPT_EQUIVALENT_TO:
|
||
{
|
||
if (opt->equivalent_to)
|
||
error(2, 0, "only one --equivalent-to option can be given");
|
||
opt->equivalent_to = parse_formula_arg(arg);
|
||
break;
|
||
}
|
||
case OPT_EXCLUSIVE_AP:
|
||
opt->excl_ap.add_group(arg);
|
||
break;
|
||
case OPT_GUARANTEE:
|
||
guarantee = obligation = true;
|
||
break;
|
||
case OPT_IGNORE_ERRORS:
|
||
ignore_errors = true;
|
||
break;
|
||
case OPT_IMPLIED_BY:
|
||
{
|
||
spot::formula i = parse_formula_arg(arg);
|
||
// a→c∧b→c ≡ (a∨b)→c
|
||
opt->implied_by = spot::formula::Or({opt->implied_by, i});
|
||
break;
|
||
}
|
||
case OPT_IMPLY:
|
||
{
|
||
// a→b∧a→c ≡ a→(b∧c)
|
||
spot::formula i = parse_formula_arg(arg);
|
||
opt->imply = spot::formula::And({opt->imply, i});
|
||
break;
|
||
}
|
||
case OPT_LIVENESS:
|
||
liveness = true;
|
||
break;
|
||
case OPT_LTL:
|
||
ltl = true;
|
||
break;
|
||
case OPT_FROM_LTLF:
|
||
from_ltlf = arg ? arg : "alive";
|
||
break;
|
||
case OPT_NEGATE:
|
||
negate = true;
|
||
break;
|
||
case OPT_NNF:
|
||
nnf = true;
|
||
break;
|
||
case OPT_SONF:
|
||
sonf = arg ? arg : "sonf_";
|
||
break;
|
||
case OPT_SONF_APS:
|
||
opt->output_sonf.reset(new output_file(arg ? arg : "-"));
|
||
break;
|
||
case OPT_OBLIGATION:
|
||
obligation = true;
|
||
break;
|
||
case OPT_PERSISTENCE:
|
||
persistence = true;
|
||
break;
|
||
case OPT_RECURRENCE:
|
||
recurrence = true;
|
||
break;
|
||
case OPT_REJECT_WORD:
|
||
try
|
||
{
|
||
opt->rej_words.push_back(spot::parse_word(arg, opt->dict)
|
||
->as_automaton());
|
||
}
|
||
catch (const spot::parse_error& e)
|
||
{
|
||
error(2, 0, "failed to parse the argument of --reject-word:\n%s",
|
||
e.what());
|
||
}
|
||
break;
|
||
case OPT_RELABEL:
|
||
relabeling = ApRelabeling;
|
||
parse_relabeling_style(arg, "");
|
||
break;
|
||
case OPT_RELABEL_BOOL:
|
||
relabeling = BseRelabeling;
|
||
parse_relabeling_style(arg, "-bool");
|
||
break;
|
||
case OPT_RELABEL_OVERLAP:
|
||
relabeling = OverlappingRelabeling;
|
||
parse_relabeling_style(arg, "-overlapping-bool");
|
||
break;
|
||
case OPT_REMOVE_WM:
|
||
unabbreviate += "MW";
|
||
break;
|
||
case OPT_REMOVE_X:
|
||
remove_x = true;
|
||
break;
|
||
case OPT_SAFETY:
|
||
safety = obligation = true;
|
||
break;
|
||
case OPT_SIZE:
|
||
size = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||
break;
|
||
case OPT_SIZE_MIN:
|
||
size.min = to_int(arg, "--size-min");
|
||
break;
|
||
case OPT_SIZE_MAX:
|
||
size.max = to_int(arg, "--size-max");
|
||
break;
|
||
case OPT_SKIP_ERRORS:
|
||
error_style = skip_errors;
|
||
break;
|
||
case OPT_STUTTER_INSENSITIVE:
|
||
stutter_insensitive = true;
|
||
break;
|
||
case OPT_UNABBREVIATE:
|
||
if (arg)
|
||
unabbreviate += arg;
|
||
else
|
||
unabbreviate += spot::default_unabbrev_string;
|
||
break;
|
||
case OPT_AP_N:
|
||
ap_n = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||
break;
|
||
case OPT_SUSPENDABLE:
|
||
universal = true;
|
||
eventual = true;
|
||
break;
|
||
case OPT_SYNTACTIC_SAFETY:
|
||
syntactic_safety = true;
|
||
break;
|
||
case OPT_SYNTACTIC_GUARANTEE:
|
||
syntactic_guarantee = true;
|
||
break;
|
||
case OPT_SYNTACTIC_OBLIGATION:
|
||
syntactic_obligation = true;
|
||
break;
|
||
case OPT_SYNTACTIC_RECURRENCE:
|
||
syntactic_recurrence = true;
|
||
break;
|
||
case OPT_SYNTACTIC_PERSISTENCE:
|
||
syntactic_persistence = true;
|
||
break;
|
||
case OPT_SYNTACTIC_SI:
|
||
syntactic_si = true;
|
||
break;
|
||
case OPT_UNIVERSAL:
|
||
universal = true;
|
||
break;
|
||
default:
|
||
return ARGP_ERR_UNKNOWN;
|
||
}
|
||
END_EXCEPTION_PROTECT;
|
||
return 0;
|
||
}
|
||
|
||
typedef
|
||
std::unordered_set<spot::formula> fset_t;
|
||
|
||
namespace
|
||
{
|
||
class ltl_processor final: public job_processor
|
||
{
|
||
public:
|
||
spot::tl_simplifier& simpl;
|
||
fset_t unique_set;
|
||
spot::relabeling_map relmap;
|
||
|
||
explicit ltl_processor(spot::tl_simplifier& simpl)
|
||
: simpl(simpl)
|
||
{
|
||
}
|
||
|
||
int
|
||
process_string(const std::string& input,
|
||
const char* filename = nullptr, int linenum = 0) override
|
||
{
|
||
spot::parsed_formula pf = parse_formula(input);
|
||
|
||
if (!pf.f || !pf.errors.empty())
|
||
{
|
||
if (!ignore_errors)
|
||
{
|
||
if (filename)
|
||
error_at_line(0, 0, filename, linenum, "parse error:");
|
||
pf.format_errors(std::cerr);
|
||
}
|
||
|
||
if (error_style == skip_errors)
|
||
std::cout << input << '\n';
|
||
else
|
||
assert(error_style == drop_errors);
|
||
check_cout();
|
||
return !ignore_errors;
|
||
}
|
||
try
|
||
{
|
||
return process_formula(pf.f, filename, linenum);
|
||
}
|
||
catch (const std::runtime_error& e)
|
||
{
|
||
error_at_line(2, 0, filename, linenum, "%s", e.what());
|
||
SPOT_UNREACHABLE();
|
||
}
|
||
}
|
||
|
||
int
|
||
process_formula(spot::formula f,
|
||
const char* filename = nullptr, int linenum = 0) override
|
||
{
|
||
static unsigned order = 0;
|
||
++order;
|
||
spot::process_timer timer;
|
||
timer.start();
|
||
|
||
|
||
if (opt_max_count >= 0 && match_count >= opt_max_count)
|
||
{
|
||
abort_run = true;
|
||
return 0;
|
||
}
|
||
|
||
if (negate)
|
||
f = spot::formula::Not(f);
|
||
|
||
bool matched = opt_nth.contains(order);
|
||
|
||
if (from_ltlf)
|
||
{
|
||
matched &= !ltl || f.is_ltl_formula();
|
||
if (matched)
|
||
f = spot::from_ltlf(f, from_ltlf);
|
||
}
|
||
|
||
if (remove_x)
|
||
{
|
||
// If simplification are enabled, we do them before and after.
|
||
if (simplification_level)
|
||
f = simpl.simplify(f);
|
||
f = spot::remove_x(f);
|
||
}
|
||
|
||
if (simplification_level || boolean_to_isop)
|
||
f = simpl.simplify(f);
|
||
|
||
if (nnf)
|
||
f = simpl.negative_normal_form(f);
|
||
|
||
if (sonf != nullptr)
|
||
{
|
||
std::vector<std::string> new_aps;
|
||
std::tie(f, new_aps) = suffix_operator_normal_form(f, sonf);
|
||
|
||
if (opt->output_sonf
|
||
&& output_format != count_output
|
||
&& output_format != quiet_output)
|
||
{
|
||
for (size_t i = 0; i < new_aps.size(); ++i)
|
||
{
|
||
if (i > 0)
|
||
opt->output_sonf->ostream() << ' ';
|
||
opt->output_sonf->ostream() << new_aps[i];
|
||
}
|
||
opt->output_sonf->ostream() << '\n';
|
||
}
|
||
}
|
||
|
||
switch (relabeling)
|
||
{
|
||
case ApRelabeling:
|
||
{
|
||
relmap.clear();
|
||
f = spot::relabel(f, style, &relmap);
|
||
break;
|
||
}
|
||
case BseRelabeling:
|
||
{
|
||
relmap.clear();
|
||
f = spot::relabel_bse(f, style, &relmap);
|
||
break;
|
||
}
|
||
case OverlappingRelabeling:
|
||
{
|
||
relmap.clear();
|
||
f = spot::relabel_overlapping_bse(f, style, &relmap);
|
||
break;
|
||
}
|
||
case NoRelabeling:
|
||
break;
|
||
}
|
||
|
||
if (!unabbreviate.empty())
|
||
f = spot::unabbreviate(f, unabbreviate.c_str());
|
||
|
||
if (!opt->excl_ap.empty())
|
||
f = opt->excl_ap.constrain(f);
|
||
|
||
matched &= !ltl || f.is_ltl_formula();
|
||
matched &= !psl || f.is_psl_formula();
|
||
matched &= !boolean || f.is_boolean();
|
||
matched &= !universal || f.is_universal();
|
||
matched &= !eventual || f.is_eventual();
|
||
matched &= !syntactic_safety || f.is_syntactic_safety();
|
||
matched &= !syntactic_guarantee || f.is_syntactic_guarantee();
|
||
matched &= !syntactic_obligation || f.is_syntactic_obligation();
|
||
matched &= !syntactic_recurrence || f.is_syntactic_recurrence();
|
||
matched &= !syntactic_persistence || f.is_syntactic_persistence();
|
||
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
|
||
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
|
||
{
|
||
spot::atomic_prop_set* s = atomic_prop_collect(f);
|
||
int n = s->size();
|
||
delete s;
|
||
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
|
||
matched &= (ap_n.max < 0) || (n <= ap_n.max);
|
||
}
|
||
|
||
if (matched && (size.min > 0 || size.max >= 0))
|
||
{
|
||
int l = spot::length(f);
|
||
matched &= (size.min <= 0) || (l >= size.min);
|
||
matched &= (size.max < 0) || (l <= size.max);
|
||
}
|
||
|
||
if (matched && (bsize.min > 0 || bsize.max >= 0))
|
||
{
|
||
int l = spot::length_boolone(f);
|
||
matched &= (bsize.min <= 0) || (l >= bsize.min);
|
||
matched &= (bsize.max < 0) || (l <= bsize.max);
|
||
}
|
||
|
||
matched &= !opt->implied_by || simpl.implication(opt->implied_by, f);
|
||
matched &= !opt->imply || simpl.implication(f, opt->imply);
|
||
matched &= !opt->equivalent_to
|
||
|| simpl.are_equivalent(f, opt->equivalent_to);
|
||
matched &= !stutter_insensitive || spot::is_stutter_invariant(f);
|
||
|
||
if (matched && (obligation || recurrence || persistence
|
||
|| !opt->acc_words.empty()
|
||
|| !opt->rej_words.empty()
|
||
|| liveness))
|
||
{
|
||
spot::twa_graph_ptr aut = nullptr;
|
||
|
||
if (!opt->acc_words.empty() || !opt->rej_words.empty() || liveness)
|
||
{
|
||
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
|
||
|
||
if (matched && !opt->acc_words.empty())
|
||
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
|
||
if (spot::product(aut, word_aut)->is_empty())
|
||
{
|
||
matched = false;
|
||
break;
|
||
}
|
||
|
||
if (matched && !opt->rej_words.empty())
|
||
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
|
||
if (!spot::product(aut, word_aut)->is_empty())
|
||
{
|
||
matched = false;
|
||
break;
|
||
}
|
||
|
||
matched &= !liveness || is_liveness_automaton(aut);
|
||
}
|
||
|
||
// Some combinations of options can be simplified.
|
||
if (recurrence && persistence)
|
||
obligation = true;
|
||
if (obligation && recurrence)
|
||
recurrence = false;
|
||
if (obligation && persistence)
|
||
persistence = false;
|
||
|
||
// Try a syntactic match before looking at the automata.
|
||
if (matched &&
|
||
!((!persistence || f.is_syntactic_persistence())
|
||
&& (!recurrence || f.is_syntactic_recurrence())
|
||
&& (!guarantee || f.is_syntactic_guarantee())
|
||
&& (!safety || f.is_syntactic_safety())
|
||
&& (!obligation || f.is_syntactic_obligation())))
|
||
{
|
||
// Match obligations and subclasses using WDBA minimization.
|
||
// Because this is costly, we compute it later, so that we don't
|
||
// have to compute it on formulas that have been discarded for
|
||
// other reasons.
|
||
if (obligation && (safety || guarantee))
|
||
{
|
||
if (!aut)
|
||
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
|
||
|
||
auto min = minimize_obligation(aut, f);
|
||
assert(min);
|
||
if (aut == min)
|
||
{
|
||
// Not an obligation
|
||
matched = false;
|
||
}
|
||
else
|
||
{
|
||
spot::scc_info si(min);
|
||
matched &= !guarantee
|
||
|| is_terminal_automaton(min, &si, true);
|
||
matched &= !safety || is_safety_automaton(min, &si);
|
||
}
|
||
}
|
||
else if (obligation) // just obligation, not safety or guarantee
|
||
matched &= is_obligation(f, aut);
|
||
else if (persistence)
|
||
matched &= spot::is_persistence(f);
|
||
else if (recurrence)
|
||
matched &= spot::is_recurrence(f, aut);
|
||
}
|
||
}
|
||
|
||
matched ^= invert;
|
||
|
||
if (unique && !unique_set.insert(f).second)
|
||
matched = false;
|
||
|
||
timer.stop();
|
||
|
||
if (matched)
|
||
{
|
||
if (opt->output_define
|
||
&& output_format != count_output
|
||
&& output_format != quiet_output)
|
||
{
|
||
// Sort the formulas alphabetically.
|
||
std::map<std::string, spot::formula> m;
|
||
for (const auto& [newformula, oldname]: relmap)
|
||
m.emplace(str_psl(newformula), oldname);
|
||
for (const auto& [newname, oldname]: m)
|
||
stream_formula(opt->output_define->ostream()
|
||
<< "#define " << newname << " (",
|
||
oldname, filename,
|
||
std::to_string(linenum).c_str()) << ")\n";
|
||
}
|
||
one_match = true;
|
||
output_formula_checked(f, &timer, filename, linenum,
|
||
match_count, prefix, suffix);
|
||
++match_count;
|
||
}
|
||
return 0;
|
||
}
|
||
};
|
||
}
|
||
|
||
int
|
||
main(int argc, char** argv)
|
||
{
|
||
return protected_main(argv, [&] {
|
||
const argp ap = { options, parse_opt, "[FILENAME[/COL]...]",
|
||
argp_program_doc, children, nullptr, nullptr };
|
||
|
||
// This will ensure that all objects stored in this struct are
|
||
// destroyed before global variables.
|
||
opt_t o;
|
||
opt = &o;
|
||
|
||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||
exit(err);
|
||
|
||
if (jobs.empty())
|
||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
||
|
||
if (boolean_to_isop && simplification_level == 0)
|
||
simplification_level = 1;
|
||
spot::tl_simplifier_options tlopt(simplification_level);
|
||
tlopt.boolean_to_isop = boolean_to_isop;
|
||
spot::tl_simplifier simpl(tlopt, opt->dict);
|
||
|
||
ltl_processor processor(simpl);
|
||
if (processor.run())
|
||
return 2;
|
||
|
||
if (output_format == count_output)
|
||
std::cout << match_count << '\n';
|
||
flush_cout();
|
||
return one_match ? 0 : 1;
|
||
});
|
||
}
|