Compare commits

...
Sign in to create a new pull request.

342 commits

Author SHA1 Message Date
b04c4d7fd9 expansions: expose easy expansion in python 2023-10-12 15:04:40 +02:00
49f3c18ae3 expansions: store as vector of pairs 2023-10-12 15:04:06 +02:00
0199ebd592 expansions: US order in pipeline configurable 2023-10-12 04:13:47 +02:00
de2025298e expansions: UniquePrefixSeenOpt 2023-09-21 08:51:58 +02:00
46aee256eb expansions: fixes + BDD encode changes + printer 2023-07-04 07:21:20 +02:00
094fa85b02 expansions: simple determinization 2023-06-01 22:27:44 +02:00
189dde38d3 expansions: signature merge impl 2023-06-01 22:27:44 +02:00
81a635c831 expansions: optimize sigma star encoding 2023-06-01 22:27:44 +02:00
aeba9ff674 expansions: remove multiple old implementations 2023-06-01 22:27:44 +02:00
564e3af5dd expansions: fix first_match case 2023-06-01 22:27:44 +02:00
2c4f85f687 twaalgos: ltl2tgba_fm: allow disabling SCC trim 2023-06-01 22:27:44 +02:00
d410435adc expansions: allow toggling merge_edges off 2023-06-01 22:27:44 +02:00
0168efea60 expansions: latest implementation 2023-06-01 22:27:44 +02:00
22f76b7e1c expansions: multimap version 2023-06-01 22:27:44 +02:00
66761b3980 expansions: determinize only once per state 2023-06-01 22:27:44 +02:00
b62945b5de expansions: fix bdd method 2023-06-01 22:27:44 +02:00
f4b2637c04 expansions: add BDD method 2023-06-01 22:27:44 +02:00
806b7319b9 expansions: multiple implementations 2023-06-01 22:27:44 +02:00
2e40892fd6 expansions: split-off OrRat case 2023-06-01 22:27:44 +02:00
bd8b5b4b51 expansions: first_match deterministic 2023-06-01 22:27:44 +02:00
16fd28d29b expansions: draft 2023-06-01 22:27:44 +02:00
4ce9c483c1 derive: add options to control distribution 2023-06-01 22:27:44 +02:00
b2b80831ca derive: option for some optimisations 2023-06-01 22:27:44 +02:00
2ef0ea00f4 sere_to_tgba: produce state-names 2023-06-01 22:27:44 +02:00
8abad2b4f7 ltl2aa: handle edge case in UConcat
If SERE recognizes false, then combined with UConcat the property is
always true.
2023-06-01 22:27:44 +02:00
2d11d907ef alternation: fix bug introduced in oe_combiner
turns out sometimes we want to account for bddfalse
2023-06-01 22:27:44 +02:00
66f0ab85d0 ltl2aa: implement EConcat 2023-06-01 22:27:44 +02:00
3744d0cbed ltl2aa: comment 2023-06-01 22:27:44 +02:00
36b09fa1f6 ltl2aa: finalize UConcat 2023-06-01 22:27:44 +02:00
88914c58c7 ltl2aa: finish SERE aut merging with rhs outedges 2023-06-01 22:27:44 +02:00
87c99cb38f ltl2aa: fix two bugs in SERE aut merge 2023-06-01 22:27:44 +02:00
2af19a485b ltl2aa: place new state in var_to_state map 2023-06-01 22:27:44 +02:00
44568b5622 ltl2aa: implem closure 2023-06-01 22:27:44 +02:00
85b8717c05 ltl2aa: share dict between sere and final aut 2023-06-01 22:27:44 +02:00
c1a0b5aa46 ltl2aa: fix bdd manipulation in UConcat 2023-06-01 22:27:44 +02:00
7eacf99f76 ltl2aa: fix R & M operators handling 2023-06-01 22:27:44 +02:00
11c469648f Add ltl2aa binary to tests/core 2023-06-01 22:27:44 +02:00
8f4ba3ec1a psl not working 2023-06-01 22:27:44 +02:00
be45ccd46d ltl2aa: factorize self-loop creation 2023-06-01 22:27:44 +02:00
06f21899b1 twaalgos: add LTL to AA translation 2023-06-01 22:27:44 +02:00
382acca320 twaalgos: filter accepting sinks in oe combiner 2023-06-01 22:27:44 +02:00
abe3da54fb graph: filter accepting sinks in univ_dest_mapper 2023-06-01 22:27:44 +02:00
f2063b7fc3 derive: use first 2023-06-01 22:27:44 +02:00
0d6c3cd6e9 derive: handle AndNLM 2023-06-01 22:27:44 +02:00
6882611d25 derive: extract AndNLM rewriting 2023-06-01 22:27:44 +02:00
2c89e09a47 derive: no nullptr handling 2023-06-01 22:27:44 +02:00
90be62be3d derive: use from_finite 2023-06-01 22:27:44 +02:00
d2667d48f6 twaalgos: add from_finite
* spot/twaalgos/remprop.cc, spot/twaalgos/remprop.hh: add a from_finite
  function to perform the opposite operation to to_finite
2023-06-01 22:27:44 +02:00
04112b26cc twaalgos: extract internal sere2dfa 2023-06-01 22:27:44 +02:00
1092e6c0c2 tl: implement SERE derivation 2023-06-01 22:27:44 +02:00
f0e4efa238 twagraph: merge_edges supports finite automata
* spot/twa/twagraph.cc: don't remove false-labeled edges if the
  automaton uses state-based acceptance and the edge is a self loop
2023-06-01 22:27:44 +02:00
d2bc100656 nix: provide package in release tarballs 2023-06-01 22:20:11 +02:00
4535b4a915 nix: setup Nix Flake file
* flake.nix, flake.lock: here
2023-06-01 22:20:11 +02:00
Florian Renkin
7868115a8b parity_type_to_parity: Add missing cases
* spot/twaalgos/toparity.cc: Correct some cases where the solution was
not detected.
* tests/python/toparity.py: Update tests.
2023-05-24 20:05:43 +02:00
Alexandre Duret-Lutz
abe7222973 bitvect: work around incorrect warning from gcc
* spot/misc/bitvect.hh: Don't free the old ptr if realloc() returns
NULL, as this confuse GCC who warns that we are freeing something that
has already been freed.   Instead, let the ~bitvect() destructor
handle this.
2023-05-15 09:43:46 +02:00
Alexandre Duret-Lutz
134da9209c genem: Add yet another version of the algorithm
* spot/twa/acc.hh, spot/twa/acc.cc (fin_unit_one_split_improved): New
function.
* python/spot/impl.i: Add bindings for fin_unit_one_split_improved.
* spot/twaalgos/genem.cc: Add the spot212 version.
* tests/python/genem.py: Test it.
2023-05-15 09:43:46 +02:00
Alexandre Duret-Lutz
747ec8b1c5 debian: add missing build dependencies
* debian/control: Add Build-Depends on graphviz, jupyter-nbconvert,
doxygen.
2023-05-15 09:43:43 +02:00
Alexandre Duret-Lutz
b487ff4190 Merge branch 'master' into next 2023-04-20 09:50:23 +02:00
Alexandre Duret-Lutz
d0ae0dfc38 * NEWS, configure.ac: Bump version to 2.11.5.dev. 2023-04-20 09:48:22 +02:00
Alexandre Duret-Lutz
b6c076ce19 release Spot 2.11.5
* NEWS, configure.ac, doc/org/setup.org: Update version.
2023-04-20 09:45:41 +02:00
Alexandre Duret-Lutz
184aa9931e org: replace version references with org-babel blocks
This way we have fewer lines to edit multiple when making releases.

* doc/org/index.org, doc/org/init.el.in, doc/org/install.org,
doc/org/setup.org, doc/org/tools.org: Use org-babel instead of macros
for release version and links.
2023-04-19 09:07:02 +02:00
Alexandre Duret-Lutz
eb80f5d5af powerset: fix segfault when the initial state is a sink
Reported by Raven Beutner.

* spot/twaalgos/minimize.cc: Improve comment.
* spot/twaalgos/powerset.cc: Fix handling of an initial state that
is also a sink.
* tests/core/wdba2.test: Add test case.
* NEWS: Mention the bug.
2023-04-19 09:06:58 +02:00
Alexandre Duret-Lutz
eb0f40b9d6 twa_run: let as_twa work on the result of intersecting_run
Reported by Philipp Schlehuber-Caissier.

* spot/twaalgos/emptiness.cc (as_twa): Simplify considerably.  Don't
try to replay the run, and don't merge identical states.
* spot/twaalgos/word.hh, spot/twaalgos/emptiness.hh: Improve
documentation.
* tests/python/intrun.py: Add a test case.
* NEWS: Mention the bug.
2023-04-19 09:06:55 +02:00
Philipp Schlehuber-Caissier
993695a2c4 Fix parity solver if edgevector is not contiguous
Validity of strategies was tested relying on
num_edges() which might be smaller than the edge_number

* spot/twaalgos/game.cc: Fix here
* tests/python/game.py: Test here
2023-04-19 09:06:25 +02:00
Alexandre Duret-Lutz
0c8093eded correctly fails if emacs needed and missing
Fixes #528.

* configure.ac: Define EMACS using tools/missing.
* NEWS: Mention the bug.
2023-04-19 09:06:01 +02:00
Alexandre Duret-Lutz
646b6e546f fix spurious test-case failure when Python is not installed
Fixes #530.

* tests/core/ltlsynt2.test: Skip when PYTHON is empty.
* NEWS: Mention the fix.
2023-04-19 09:05:42 +02:00
Alexandre Duret-Lutz
1a0b1f235d * doc/tl/tl.tex: Typo in firstmatch semantics. 2023-04-19 09:04:16 +02:00
Philipp Schlehuber
5714ecce32 Ignore ltargz.m4
* .gitignore: Ignore it
* m4/ltargz.m4: Remove it
2023-04-19 09:04:11 +02:00
Alexandre Duret-Lutz
dcd4759896 org: fix rendering of R examples for recent ESS/Org
* doc/org/.dir-locals.el.in, doc/org/init.el.in: Newer ESS version
need to be taught to use default-directory instead of the project
directory.
* doc/org/ltlcross.org: Use "result file" to render the output.
2023-04-19 09:04:07 +02:00
Alexandre Duret-Lutz
a146457ea1 * doc/org/tut03.org: Typos. 2023-04-19 09:04:02 +02:00
Alexandre Duret-Lutz
d3013b072d org: do not require org-install
org-install has been obsolete for a long time, and has been removed
from Org 9.6.

* doc/org/init.el.in: Remove org-install.
2023-04-19 09:03:53 +02:00
Alexandre Duret-Lutz
c12b0622b4 org: replace version references with org-babel blocks
This way we have fewer lines to edit multiple when making releases.

* doc/org/index.org, doc/org/init.el.in, doc/org/install.org,
doc/org/setup.org, doc/org/tools.org: Use org-babel instead of macros
for release version and links.
2023-04-18 22:18:16 +02:00
Alexandre Duret-Lutz
0e54a85310 powerset: fix segfault when the initial state is a sink
Reported by Raven Beutner.

* spot/twaalgos/minimize.cc: Improve comment.
* spot/twaalgos/powerset.cc: Fix handling of an initial state that
is also a sink.
* tests/core/wdba2.test: Add test case.
* NEWS: Mention the bug.
2023-04-18 22:18:16 +02:00
Alexandre Duret-Lutz
ae10361bdd twa_run: let as_twa work on the result of intersecting_run
Reported by Philipp Schlehuber-Caissier.

* spot/twaalgos/emptiness.cc (as_twa): Simplify considerably.  Don't
try to replay the run, and don't merge identical states.
* spot/twaalgos/word.hh, spot/twaalgos/emptiness.hh: Improve
documentation.
* tests/python/intrun.py: Add a test case.
* NEWS: Mention the bug.
2023-04-18 22:18:16 +02:00
Philipp Schlehuber-Caissier
d152b3a316 Fix parity solver if edgevector is not contiguous
Validity of strategies was tested relying on
num_edges() which might be smaller than the edge_number

* spot/twaalgos/game.cc: Fix here
* tests/python/game.py: Test here
2023-03-31 15:17:57 +02:00
Alexandre Duret-Lutz
0c34152a33 correctly fails if emacs needed and missing
Fixes #528.

* configure.ac: Define EMACS using tools/missing.
* NEWS: Mention the bug.
2023-03-29 17:01:13 +02:00
Alexandre Duret-Lutz
039cd756d5 fix spurious test-case failure when Python is not installed
Fixes #530.

* tests/core/ltlsynt2.test: Skip when PYTHON is empty.
* NEWS: Mention the fix.
2023-03-29 16:20:51 +02:00
Alexandre Duret-Lutz
7a97a6080c * doc/tl/tl.tex: Typo in firstmatch semantics. 2023-03-29 16:16:06 +02:00
Philipp Schlehuber
7a91cf78ec Ignore ltargz.m4
* .gitignore: Ignore it
* m4/ltargz.m4: Remove it
2023-03-23 09:02:32 +01:00
Philipp Schlehuber
e7e23d5ffc Adding option to solve parity games globally
Parity games have been solved semi-locally so far.
We deduced a strategy for the reachable part of the arena
This lead to some inconsistencies when not all state were
rachable.
Now you can chose to solve parity games truely globally.

* spot/twaalgos/game.cc, spot/twaalgos/game.hh: Here
* tests/python/games.ipynb: Test
2023-03-23 09:02:09 +01:00
Alexandre Duret-Lutz
146942953a org: fix rendering of R examples for recent ESS/Org
* doc/org/.dir-locals.el.in, doc/org/init.el.in: Newer ESS version
need to be taught to use default-directory instead of the project
directory.
* doc/org/ltlcross.org: Use "result file" to render the output.
2023-03-03 15:36:31 +01:00
Alexandre Duret-Lutz
f117159ec4 * doc/org/tut03.org: Typos. 2023-02-24 11:26:12 +01:00
Alexandre Duret-Lutz
66839b1a29 bdd_to_formula: add CNF variant
* spot/twa/formula2bdd.hh,
spot/twa/formula2bdd.cc (bdd_to_cnf_formula): New function.
* python/spot/__init__.py: Add a default dictionary for convenience.
* tests/python/bdditer.py: Add test cases.
* NEWS: Mention it.
2023-02-24 11:26:12 +01:00
Alexandre Duret-Lutz
8a5b86521c * NEWS: Remove duplicate entries. 2023-02-16 17:48:49 +01:00
Alexandre Duret-Lutz
4bd023e515 org: do not require org-install
org-install has been obsolete for a long time, and has been removed
from Org 9.6.

* doc/org/init.el.in: Remove org-install.
2023-02-16 17:46:51 +01:00
Alexandre Duret-Lutz
e16d82d5bd Merge branch 'master' into next 2023-02-10 08:53:17 +01:00
Alexandre Duret-Lutz
e44cb5152a Bump version to 2.11.4.dev
* NEWS, configure.ac: Here.
2023-02-10 08:51:29 +01:00
Alexandre Duret-Lutz
50a58254a7 Release spot 2.11.4
* NEWS, configure.ac, doc/org/setup.org: Update version.
2023-02-10 08:49:26 +01:00
Alexandre Duret-Lutz
6fd0eebad4 to_finit: fix issue #526
* spot/twaalgos/remprop.cc: Use bdd_restrict instead of bdd_exists.
* tests/core/ltlf.test: Add test case.
* NEWS: Mention the bug.
2023-02-07 23:13:25 +01:00
Alexandre Duret-Lutz
a117fe1a22 to_finit: fix issue #526
* spot/twaalgos/remprop.cc: Use bdd_restrict instead of bdd_exists.
* tests/core/ltlf.test: Add test case.
* NEWS: Mention the bug.
2023-02-07 14:40:20 +01:00
Alexandre Duret-Lutz
058975c167 dbranch: fix handling of state-based acceptance
Fixes issue #525.

* spot/twaalgos/dbranch.hh, NEWS: Document.
* spot/twaalgos/dbranch.cc: Detect cases where the acceptance should
be changed from state-based to transition-based.
* tests/python/dbranch.py: Add a test case.
2023-02-05 14:59:50 +01:00
Alexandre Duret-Lutz
43b4d80da1 dbranch: fix handling of state-based acceptance
Fixes issue #525.

* spot/twaalgos/dbranch.hh, NEWS: Document.
* spot/twaalgos/dbranch.cc: Detect cases where the acceptance should
be changed from state-based to transition-based.
* tests/python/dbranch.py: Add a test case.
2023-02-03 09:35:46 +01:00
Alexandre Duret-Lutz
5969aa4925 work around gcc-snapshot warnings about dangling references
* spot/twaalgos/game.hh, spot/twaalgos/game.cc (get_state_players,
get_strategy, get_state_winners): Take argument by reference, not
copy.
* spot/twaalgos/synthesis.cc, spot/twaalgos/mealy_machine.cc: Replace
auto by actual type for readability.
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
2666072867 * .gitlab-ci.yml: Use pipeline id to name volumes. 2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
126d9bc103 bin: fix number conversion routines on 32bit
On 32bit archetectures, long int = int the current check for detecting
values that overflow int will fail.  Conversion routings should check
errno.

* bin/common_conv.cc, bin/common_range.cc: Here.
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
a1c02856ac autfilt: allow --highlight-word to work on Fin acceptance
Fixes #523.

* bin/autfilt.cc: Remove the restriction.
* tests/core/acc_word.test: Add test case.
* NEWS: Mention the fix.
2023-01-31 17:55:51 +01:00
Florian Renkin
315872a54b ltlsynt: typo in doc
* bin/ltlsynt.cc: here
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
9ca2927291 bin: update copyright year and laboratory name
* bin/common_setup.cc: Here.
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
eae91e97cd robin_hood: update to version version 3.11.5
* spot/priv/robin_hood.hh: Update.
* spot/priv/Makefile.am: Patch ROBIN_HOOD_IS_TRIVIALLY_COPYABLE to
work around an issue with clang on Arch linux.
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
7e1d684797 dbranch: fix handling of states without successors
Fixes #524, reported by Rüdiger Ehlers.

* spot/twaalgos/dbranch.cc: When merging an edge going to state
without successors simply delete it.
* bin/spot-x.cc: Typo in documentation.
* tests/core/ltlcross.test: Add a test case.
* NEWS: Mention the bug.
2023-01-31 17:55:51 +01:00
Alexandre Duret-Lutz
39212bbcd2 more code smells
* bin/common_file.cc, bin/common_file.hh, bin/common_finput.cc,
bin/common_finput.hh, bin/common_output.cc, bin/common_setup.cc,
bin/common_setup.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/ltlsynt.cc, bin/randltl.cc: Fix minor code issues reported by
sonarcloud.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
7b0507a950 bin: detect overflows in conversion functions
* bin/common_conv.cc (to_int, to_unsigned): Here.
* bin/common_range.cc (parse_range): And there.
* tests/core/ltlgrind.test, tests/core/genaut.test,
tests/core/randaut.test: Add test cases.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
4a78d1bff4 fix some code smells reported by sonarcloud
* bench/dtgbasat/gen.py, bin/autcross.cc, bin/autfilt.cc,
bin/common_aoutput.cc, bin/common_aoutput.hh: Various cleanups.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
36e79ecca6 * spot/twaalgos/game.cc: Fix incorrect std::forward. 2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
344d82f2b4 simplify several comparison operators
* spot/twaalgos/dtbasat.cc, spot/twaalgos/dtwasat.cc,
spot/twaalgos/simulation.cc: Simplify, as reported by sonarcloud.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
403e55d555 * doc/org/spot.css: Do not define background twice. 2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
104e98aca6 fix merging of initial states in state-based automata
Fixes #522 reported by Raven Beutner.

* spot/parseaut/parseaut.yy: Make sure all edges leaving
the initial state have the same color.
* THANKS: Add Raven.
* NEWS: Mention the bug.
* tests/core/522.test: New file.
* tests/Makefile.am: Add it.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
cab3ea7faf acd: rewrite Python wrapper without jQuery
* python/spot/__init__.py (acd): Rewrite javascript so that it does
not use jQuery, to make it easier to use in jupyterlab, or with
nbconvert.
* tests/python/zlktree.ipynb: Adjust.
* NEWS: Mention this.
2023-01-31 17:51:18 +01:00
Alexandre Duret-Lutz
bdaa31ef21 work around gcc-snapshot warnings about dangling references
* spot/twaalgos/game.hh, spot/twaalgos/game.cc (get_state_players,
get_strategy, get_state_winners): Take argument by reference, not
copy.
* spot/twaalgos/synthesis.cc, spot/twaalgos/mealy_machine.cc: Replace
auto by actual type for readability.
2023-01-31 14:29:40 +01:00
Alexandre Duret-Lutz
d16183c053 * .gitlab-ci.yml: Use pipeline id to name volumes. 2023-01-25 08:36:40 +01:00
Alexandre Duret-Lutz
121d5e5524 bin: fix number conversion routines on 32bit
On 32bit archetectures, long int = int the current check for detecting
values that overflow int will fail.  Conversion routings should check
errno.

* bin/common_conv.cc, bin/common_range.cc: Here.
2023-01-25 08:36:27 +01:00
Alexandre Duret-Lutz
e5150d0314 autfilt: allow --highlight-word to work on Fin acceptance
Fixes #523.

* bin/autfilt.cc: Remove the restriction.
* tests/core/acc_word.test: Add test case.
* NEWS: Mention the fix.
2023-01-24 17:55:17 +01:00
Florian Renkin
5b0143eba6 ltlsynt: typo in doc
* bin/ltlsynt.cc: here
2023-01-23 16:35:16 +01:00
Alexandre Duret-Lutz
60abfeb31f bin: update copyright year and laboratory name
* bin/common_setup.cc: Here.
2023-01-23 16:07:49 +01:00
Alexandre Duret-Lutz
3aba452b5b robin_hood: update to version version 3.11.5
* spot/priv/robin_hood.hh: Update.
* spot/priv/Makefile.am: Patch ROBIN_HOOD_IS_TRIVIALLY_COPYABLE to
work around an issue with clang on Arch linux.
2023-01-23 15:25:06 +01:00
Alexandre Duret-Lutz
a9c457f93f dbranch: fix handling of states without successors
Fixes #524, reported by Rüdiger Ehlers.

* spot/twaalgos/dbranch.cc: When merging an edge going to state
without successors simply delete it.
* bin/spot-x.cc: Typo in documentation.
* tests/core/ltlcross.test: Add a test case.
* NEWS: Mention the bug.
2023-01-23 11:59:49 +01:00
Alexandre Duret-Lutz
09bbaa1e41 more code smells
* bin/common_file.cc, bin/common_file.hh, bin/common_finput.cc,
bin/common_finput.hh, bin/common_output.cc, bin/common_setup.cc,
bin/common_setup.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/ltlsynt.cc, bin/randltl.cc: Fix minor code issues reported by
sonarcloud.
2023-01-10 21:53:40 +01:00
Alexandre Duret-Lutz
96c3972c5c bin: detect overflows in conversion functions
* bin/common_conv.cc (to_int, to_unsigned): Here.
* bin/common_range.cc (parse_range): And there.
* tests/core/ltlgrind.test, tests/core/genaut.test,
tests/core/randaut.test: Add test cases.
2023-01-09 11:34:21 +01:00
Alexandre Duret-Lutz
05edab3f5a fix some code smells reported by sonarcloud
* bench/dtgbasat/gen.py, bin/autcross.cc, bin/autfilt.cc,
bin/common_aoutput.cc, bin/common_aoutput.hh: Various cleanups.
2023-01-06 10:12:50 +01:00
Alexandre Duret-Lutz
716bb781eb * spot/twaalgos/game.cc: Fix incorrect std::forward. 2023-01-05 17:51:01 +01:00
Alexandre Duret-Lutz
2ba6fba29f simplify several comparison operators
* spot/twaalgos/dtbasat.cc, spot/twaalgos/dtwasat.cc,
spot/twaalgos/simulation.cc: Simplify, as reported by sonarcloud.
2023-01-05 17:50:37 +01:00
Alexandre Duret-Lutz
16ad7bdf77 * doc/org/spot.css: Do not define background twice. 2023-01-05 17:47:46 +01:00
Alexandre Duret-Lutz
396009c014 parseaut: better merge of multiple initial states
If an initial states without incoming transition has to be merged into
another one, its outgoing edges can be reused by just changing their
source.

* spot/parseaut/parseaut.yy (fix_initial_state): Implement this here.
* tests/core/522.test: Add more tests.
* tests/core/readsave.test: Adjust one expected output.
* doc/org/hoa.org: Mention the completeness change.
* NEWS: Mention the new feature.
2023-01-05 16:15:08 +01:00
Alexandre Duret-Lutz
daf797b9d4 fix merging of initial states in state-based automata
Fixes #522 reported by Raven Beutner.

* spot/parseaut/parseaut.yy: Make sure all edges leaving
the initial state have the same color.
* THANKS: Add Raven.
* NEWS: Mention the bug.
* tests/core/522.test: New file.
* tests/Makefile.am: Add it.
2023-01-04 15:12:59 +01:00
Alexandre Duret-Lutz
c9ba998200 avoid a g++-12 warning about potential null pointer dereference
* spot/twaalgos/determinize.cc (sorted_nodes): Rewrite to
avoid reallocation of temporary vector.
2022-12-10 22:18:18 +00:00
Alexandre Duret-Lutz
ba695194cd priv: remove unused allocator.hh
* spot/priv/allocator.hh: Delete.
* spot/priv/Makefile.am, tests/core/mempool.cc: Adjust.
2022-12-10 22:18:18 +00:00
Alexandre Duret-Lutz
d0b1508831 acd: rewrite Python wrapper without jQuery
* python/spot/__init__.py (acd): Rewrite javascript so that it does
not use jQuery, to make it easier to use in jupyterlab, or with
nbconvert.
* tests/python/zlktree.ipynb: Adjust.
* NEWS: Mention this.
2022-12-10 22:18:18 +00:00
Philipp Schlehuber-Caissier
427f667f9f lazy eval for sat mealy minimization
Evaluate incomp of player conditions only if necessary

* spot/twaalgos/mealy_machine.cc: Here
2022-12-09 17:00:52 +01:00
Philipp Schlehuber-Caissier
6e2e7c942e Using partitioned_relabel_here
Put the new function to use in order to speed up
mealy machine minimization

* spot/twaalgos/mealy_machine.cc: Here
* spot/twaalgos/synthesis.cc
, spot/twaalgos/synthesis.hh: Helper function to relabel games
* tests/python/_mealy.ipynb
, tests/python/except.py
, tests/python/_partitioned_relabel.ipynb: Adapt/expand tests
2022-12-09 17:00:52 +01:00
Philipp Schlehuber-Caissier
fb63dfc309 introduce partitioned_relabel_here
Function taking an automaton and trying to relabel
it by partitioning the old conditions and encode the
different subsets of the partition with new variables

* spot/priv/Makefile.am: Add
* spot/priv/partitioned_relabel.hh
, spot/priv/partitioned_relabel.cc: try_partition_me,
computes the partition of a given vector of bdds
* spot/twaalgos/relabel.hh
, spot/twaalgos/relabel.cc: Here. Adapt also relabel()
to cope with the different type of relabeling_maps
* tests/python/_partitioned_relabel.ipynb
, tests/python/except.py: Test and Usage
* tests/Makefile.am: Add test
2022-12-09 17:00:51 +01:00
Alexandre Duret-Lutz
b02d8328ee Merge branch 'master' into next 2022-12-09 09:45:01 +01:00
Alexandre Duret-Lutz
09e147ee4b * NEWS, configure.ac: Bump version to 2.11.3.dev. 2022-12-09 09:43:18 +01:00
Alexandre Duret-Lutz
d7feeca13e Release Spot 2.11.3
* NEWS, configure.ac, doc/org/setup.org: Bump version to 2.11.3.
2022-12-09 09:40:27 +01:00
Alexandre Duret-Lutz
1248d326aa Work around spurious g++-12 warnings
* spot/twaalgos/ltl2tgba_fm.cc, spot/tl/formula.hh,
spot/twaalgos/translate.cc: Add SPOT_ASSUME in various places to help
g++.
2022-12-09 09:30:10 +01:00
Alexandre Duret-Lutz
720c380412 formula: new trivial simplifications
Add the following rules:
  - f|[+] = [+] if f rejects [*0]
  - f|[*] = [*] if f accepts [*0]
  - f&&[+] = f if f rejects [*0]
  - b:b[*i..j] = b[*max(i,1)..j]
  - b[*i..j]:b[*k..l] = b[*max(i,1)+max(k,1)-1,1), j+l-1]

* spot/tl/formula.cc: Implement the new rules.
* doc/tl/tl.tex: Document them.
* tests/core/equals.test: Test them.
* NEWS: Add them
2022-12-09 09:30:10 +01:00
Alexandre Duret-Lutz
8ed9e3381f formula: introduce one_plus(), and saturate predefined formulas
* spot/tl/formula.hh, spot/tl/formula.cc (one_plus): New.
(fnode): Add a saturated argument.
(tt_, ff_, eword_, one_plus, one_star): Create saturated node.
(destroy): Do not check for id() < 3.
2022-12-09 09:29:46 +01:00
Alexandre Duret-Lutz
4629d074ab Fix semantics of [*i..j] and [:*i..j]
* doc/tl/tl.tex: After a discussion with Antoin, it appears that the
semantics previously given for f[*0..j] was not considering that f[*0]
should accept any sequence of one letter.
2022-12-07 11:26:51 +01:00
Alexandre Duret-Lutz
5dbf601afb * NEWS: Typos. 2022-12-06 16:07:21 +01:00
Philipp Schlehuber-Caissier
37d4e513d9 game: fix appending strategies bug
When calling solve_parity_game() multiple times on the same
automaton the strategies are appended one after the other.
Reported by Dávid Smolka.

* NEWS: Mention the bug.
* spot/twaalgos/game.cc: Fix it.
* tests/python/game.py: Test it.
* THANKS: Add Dávid.
2022-12-06 16:06:04 +01:00
Philipp Schlehuber-Caissier
86c433cf80 mealy: fix incorrect assertion
* spot/twaalgos/mealy_machine.cc (minimize_mealy): Do not compare
result to the original unsplit machine without splitting it first.
* tests/python/mealy.py: Add a test case.
2022-12-06 16:04:40 +01:00
Alexandre Duret-Lutz
6b70edabf0 getopt: do not include sys/cdefs.h to please Alpine Linux
* m4/getopt.m4: Pretend sys/cdefs.h is missing, so that Alpine linux
does not output a warning which we would turn into an error.
2022-12-02 17:30:29 +01:00
Alexandre Duret-Lutz
29037c1f55 autfilt: print match count even on parse errors
* bin/autfilt.cc: If -c is used, print the match_count even
in present of parse errors.
* tests/core/readsave.test: Adjust.
* NEWS: Mention the bug.
2022-12-02 15:24:31 +01:00
Alexandre Duret-Lutz
a032abf0c5 parseaut: diagnose states that are unused and undefined
Reported by Pierre Ganty.

* spot/parseaut/parseaut.yy: Add diagnostics.
* tests/core/parseaut.test: Adjust expected output, and add a test
case.
* NEWS: Mention the bug.
2022-12-02 15:24:25 +01:00
Alexandre Duret-Lutz
cfe1b0b70d configure: --with-pythondir should also override pyexecdir
Fixes #512.

* configure.ac: Here.
* NEWS: Mention the bug.
2022-11-17 11:14:32 +01:00
Alexandre Duret-Lutz
c2a3f2941d ltl_to_tgba_fm: fix a memory leak on abort
This issue surfaced in twacube.test after the previous patches.

* spot/twaalgos/ltl2tgba_fm.cc: Release the formula namer on abort.
* NEWS: Mention the bug.
2022-11-15 17:50:45 +01:00
Alexandre Duret-Lutz
843c4cdb91 translate, simplify: limit containment checks of n-ary operators
Fixes #521.

* spot/tl/simplify.cc, spot/tl/simplify.hh,
spot/twaalgos/translate.cc, spot/twaalgos/translate.hh: Add an option
to limit automata-based implication checks of n-ary operators when too
many operands are used.  Defaults to 16.
* bin/spot-x.cc, NEWS, doc/tl/tl.tex: Document it.
* tests/core/bdd.test: Disable the limit for this test.
2022-11-15 17:49:21 +01:00
Alexandre Duret-Lutz
f2c65ea557 simplify: set exprop=false during containment checks
For issue #521, reported by Jacopo Binchi.

* spot/tl/simplify.cc: Here.
* tests/core/521.test: New test case.
* tests/Makefile.am: Add it.
* NEWS: Mention it.
* THANKS: Add Jacopo Binchi.
2022-11-15 17:22:13 +01:00
Alexandre Duret-Lutz
a6c65dff8d misc Doxygen fixes
* spot/misc/satsolver.hh, spot/tl/formula.hh, spot/twaalgos/hoa.hh,
spot/twaalgos/synthesis.hh, spot/twaalgos/zlktree.hh,
spot/twacube_algos/convert.hh: Typos in Doxygen comments.
2022-11-10 17:08:30 +01:00
Alexandre Duret-Lutz
0f4f7ec287 * debian/copyright: Fix download URL. 2022-11-10 17:08:30 +01:00
Alexandre Duret-Lutz
b36cee06a1 adjust to Swig 4.1.0
* python/spot/__init__.py: Add flatnested versions of some static
methods.
* spot/twa/acc.hh: Hide && version of & and |, causing trouble
to swig.
* tests/python/_synthesis.ipynb, tests/python/synthesis.ipynb:
Upgrade expected type names.
* tests/python/ipnbdoctest.py: Adjust for difference between 4.0 and
4.1.
2022-11-10 17:08:30 +01:00
Alexandre Duret-Lutz
6dc740184c * tests/sanity/style.test: Fix recent grep warnings. 2022-11-07 09:37:40 +01:00
Alexandre Duret-Lutz
5c5133348e mealy: improve error reporting
* spot/twaalgos/mealy_machine.cc: Add more exceptions.
* tests/python/except.py: Test them.
2022-11-07 09:07:31 +01:00
Alexandre Duret-Lutz
fafe40c530 fix namespace for exception errors
* spot/priv/satcommon.cc, spot/twaalgos/dtbasat.cc,
spot/twaalgos/dtwasat.cc: When setting exception on std::ofstream, use
ofstream::failbit and ofstream::badbit instead of ifstream::failbit
and ifstream::badbit.
2022-11-04 18:21:13 +01:00
Alexandre Duret-Lutz
17a959aa29 Bump version to 2.11.2.dev
* NEWS, configure.ac: Here.
2022-10-26 11:24:20 +02:00
Alexandre Duret-Lutz
66aaa11580 Release Spot 2.11.2
* NEWS, configure.ac, doc/org/setup.org: Bump version to 2.11.2.
2022-10-26 11:15:39 +02:00
Alexandre Duret-Lutz
c312a05bbd do not use id for animating the logo
because we remove ids using svgo...

* doc/org/spot2.svg, doc/org/spot.css: Animate the verison using a
class.
2022-10-26 10:04:48 +02:00
Alexandre Duret-Lutz
0a710eb995 declare all argp_program_doc as static
* bench/stutter/stutter_invariance_formulas.cc, bin/autcross.cc,
bin/autfilt.cc, 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/ltlsynt.cc, bin/randaut.cc, bin/randltl.cc,
bin/spot-x.cc, bin/spot.cc, tests/ltsmin/modelcheck.cc: Here.
2022-10-25 16:31:35 +02:00
Alexandre Duret-Lutz
65bc67f300 relabel_here: make sure free_bddpair is called
* spot/twaalgos/relabel.cc (relabel_here): This function has multiple
exit paths, and none of them were calling bdd_freepair.  Use a
unique_ptr to ensure that.
2022-10-25 11:53:05 +02:00
Alexandre Duret-Lutz
0ecc870a0e [buddy] Add a default_deleter for bddPair
* src/bddx.h (std::default_deleter<bddPair>): Here.
2022-10-25 11:52:03 +02:00
Alexandre Duret-Lutz
0ba6949f7d use bdd_restrict more
Doing so reduced the number of GC passes tested in bdd.test, which is
good.

* spot/twaalgos/ltl2tgba_fm.cc: Simplify minato loops with
bdd_restrict.
* spot/twaalgos/synthesis.cc (split_2step): Use bdd_restrict instead
of bdd_appex.
* tests/core/bdd.test, tests/core/ltlf.test: Adjust test cases.
2022-10-25 10:16:20 +02:00
Alexandre Duret-Lutz
de29ba9e4c stats: add options to count unreachable states and transitions
Based on a request from Pierre Ganty.

* spot/twaalgos/stats.cc, spot/twaalgos/stats.hh,
bin/common_aoutput.cc, bin/common_aoutput.hh: Implement those
options.
* tests/core/format.test: Add test case.
* doc/org/autfilt.org: Update doc.
* NEWS: Mention them.
2022-10-19 17:10:37 +02:00
Alexandre Duret-Lutz
52ed3d1e8f * bin/common_aoutput.cc: Missing space in doc string. 2022-10-19 14:54:34 +02:00
Alexandre Duret-Lutz
c4a33d3457 add a .mailmap for git
* .mailmap: New file, to fix email inconsistencies.
2022-10-18 17:34:13 +02:00
Alexandre Duret-Lutz
67722db78f reduce_parity: expose the internal vectors of colors
* spot/twaalgos/parity.cc, spot/twaalgos/parity.hh: Add a
reduce_parity_data class for access to the vectors of colors
computed by reduce_parity.
* python/spot/impl.i: Add bindings for std::vector<int>.
2022-10-17 15:42:45 +02:00
Alexandre Duret-Lutz
b0c299b9e9 reduce_parity: add layered option
* spot/twaalgos/parity.cc: Implement it.
* spot/twaalgos/parity.hh, NEWS: Document it.
* tests/python/parity.ipynb: Demonstrate it.  This is the only test so
far, but more uses are coming.
2022-10-17 15:42:45 +02:00
Alexandre Duret-Lutz
eb2616efaa * .gitlab-ci.yml (debian-unstable-gcc-coverage): Disable devel mode. 2022-10-14 09:45:23 +02:00
Alexandre Duret-Lutz
179672fe3b relabel: fix handling of concat and fusion
* spot/tl/relabel.cc (formula_to_fgraph): Do not assume that n-ary
operators are Boolean operators.
* tests/python/relabel.py: Add a test case found while discussing
some expression with Antoine Martin.
* NEWS: Mention it.
2022-10-13 11:39:10 +02:00
Alexandre Duret-Lutz
666d78d499 * doc/org/init.el.in: Typo in comment. 2022-10-13 11:22:14 +02:00
Alexandre Duret-Lutz
7f6e3c2bf8 * NEWS: Add news entry for previous fix. 2022-10-13 11:21:50 +02:00
Alexandre Duret-Lutz
da356f1142 substitute @LIBSPOT_PTHREAD@ in spot/libspot.pc
Fixes #520, reported by Fangyi Zhou.

* spot/Makefile.am (libspot.pc): Substitute @LIBSPOT_PTHREAD@.
* THANKS: Add Fangyi Zhou.
2022-10-11 15:37:34 +02:00
Alexandre Duret-Lutz
bfb8f0a078 * .gitlab-ci.yml: Fail if coverage goes below 90.7%. 2022-10-11 15:06:54 +02:00
Alexandre Duret-Lutz
dae46567e7 org: work around newer org-mode not displaying SVG as <object>
* doc/org/init.el.in (spot-svg-output-as-object): New function.
2022-10-11 14:54:24 +02:00
Alexandre Duret-Lutz
9de5455552 fix some typos
* spot/graph/graph.hh, spot/ltsmin/spins_kripke.hxx,
spot/mc/bloemen.hh, spot/mc/lpar13.hh, spot/twaalgos/determinize.cc:
Here.
2022-10-11 13:28:15 +02:00
Alexandre Duret-Lutz
583ca38d91 replace bdd_relprod by bdd_restrict
* spot/twaalgos/alternation.cc, spot/twaalgos/dualize.cc,
spot/twaalgos/simulation.cc, spot/twaalgos/toweak.cc: Here.
2022-10-11 10:43:27 +02:00
Alexandre Duret-Lutz
548f3d7663 * NEWS, configure.ac: Bump version to 2.11.1.dev. 2022-10-10 14:15:23 +02:00
Alexandre Duret-Lutz
c2bbb3fd00 Release Spot 2.11.1
* NEWS, configure.ac, doc/org/setup.org: Update.
2022-10-10 14:13:42 +02:00
Alexandre Duret-Lutz
55e4d340fe CI: fix upload of stable Debian packages for amd64
This prevented the Spot website to regenerate.
Should fix #516 once we release 2.11.1.

* .gitlab-ci.yml (publish-stable): Upload changes for amd64 and i386,
not just the later.
2022-10-10 10:42:40 +02:00
Alexandre Duret-Lutz
d0c296e1cf org: mention "make check" and the new GPG key
Fixes #515.

* doc/org/install.org: Here.
2022-10-10 10:06:25 +02:00
Alexandre Duret-Lutz
2c13b299b8 hoa: add missing include
Fixes #515, reported by Yuri Victorovich.

* spot/twaalgos/hoa.hh: Include <unordered_map>.
2022-10-10 10:00:38 +02:00
Alexandre Duret-Lutz
db79d5a79e * NEWS, configure.ac: Bump version to 2.11.0.dev. 2022-10-08 21:05:04 +02:00
Alexandre Duret-Lutz
8131fae1a6 Release Spot 2.11
* NEWS, configure.ac, doc/org/setup.org: Update version.
2022-10-08 20:59:27 +02:00
Alexandre Duret-Lutz
1a5b5602db * .gitlab-ci.yml (publish-unstable): Publish both amd64 and i386. 2022-10-08 15:28:15 +02:00
Alexandre Duret-Lutz
9fc48daf28 CI: work around GIT_STRATEGY=none not cleaning the build dir
* .gitlab-ci.yml (publish-rpm, publish-stable, publish-unstable):
Use the latest files and clean things up after publication.
2022-10-08 10:35:35 +02:00
Alexandre Duret-Lutz
1a4121c6c2 * tests/Makefile.am (.ipynb.html): Use classic template. 2022-10-07 19:26:54 +02:00
Alexandre Duret-Lutz
05b8fa8dbf fix previous patch
this patch failed on i386 and on Raspberry.

* spot/twaalgos/translate.cc: Clear.
* spot/twaalgos/postproc.cc: Call reduce_parity_here
in more cases.
2022-10-05 16:29:47 +02:00
Alexandre Duret-Lutz
344e01d4e2 translate, postproc: improve parity output
* spot/twaalgos/translate.cc: When producing Parity output, split LTL
as we do in the Generic case.
* spot/twaalgos/postproc.hh, spot/twaalgos/postproc.cc: Use
acd_transform() and add an "acd" option to disable this.
* bin/spot-x.cc, NEWS: Document this.
* tests/core/genltl.test, tests/core/minusx.test,
tests/core/parity2.test: Adjust test cases for improved outputs.
2022-10-05 11:08:19 +02:00
Alexandre Duret-Lutz
e867242cf6 Update troubleshouting instruction for Python bindings
For issue #512

* README: Update instructions.
* configure.ac: Add some code to warn if Python files will be
installed in a place that is not searched up by default.  Add
--with-pythondir support.
* NEWS: Mention --with-pythondir.
2022-10-04 13:11:14 +02:00
Alexandre Duret-Lutz
4ab51e1c88 toparity: cover more options
* tests/python/toparity.py: Augment test cases.
2022-10-04 09:24:03 +02:00
Alexandre Duret-Lutz
e907f11488 emptinesscheck: improve coverage of CVWY90 and SE05
* tests/core/randtgba.cc: Test the ar:form_stack variants.
2022-10-03 17:00:15 +02:00
Alexandre Duret-Lutz
ce006cbbaa * .dir-locals.el (bug-reference-bug-regexp): Fix first group. 2022-10-03 16:48:03 +02:00
Alexandre Duret-Lutz
35b4cb89fc add test for previous decomposition patch
* tests/core/ltlsynt.test: Here.
2022-10-03 16:27:38 +02:00
Alexandre Duret-Lutz
fa4500a8d3 * tests/python/ipnbdoctest.py: Also retry if Kernel does not respond. 2022-10-03 16:27:38 +02:00
Alexandre Duret-Lutz
74b752eb79 * .gitlab-ci.yml (debian-gcc-snapshot): Build from tarball. 2022-10-03 16:27:38 +02:00
Florian Renkin
4d2c096ec0 dot: fix 'g' with a Mealy machine
* spot/twaalgos/dot.cc: here
* tests/python/mealy.py: add test
2022-10-03 10:35:38 +02:00
Florian Renkin
27816ea438 synthesis: Fix for implication decomposition
* spot/twaalgos/synthesis.cc: here
2022-10-03 10:35:38 +02:00
Alexandre Duret-Lutz
3cd43f618c test: fix running on python test in OpenBSD
* tests/run.in: Add LD_LIBRARY_PATH.
2022-10-02 14:37:21 +02:00
Alexandre Duret-Lutz
0521901e9d revert c45ff0c94 and add test case showing why
* bin/ltlsynt.cc: Revert c45ff0c94.  Also fix documentation of exit
status.
* tests/core/ltlsynt2.test: New file.
* tests/Makefile.am: Add it.
2022-09-26 14:15:33 +02:00
Alexandre Duret-Lutz
51caa5588e update gitlab references
As LRDE is being renamed LRE, gitlab is one of the first URL to
migrate.  The old URL is still supported, but we want to only use the
new one eventually.

* .dir-locals.el, .gitlab-ci.yml, HACKING, NEWS, doc/org/concepts.org,
doc/org/install.org, doc/org/setup.org, elisp/Makefile.am,
elisp/hoa-mode.el, tests/ltsmin/README: Update to the new gitlab URL.
2022-09-23 08:57:57 +02:00
Alexandre Duret-Lutz
383128d983 * doc/tl/tl.tex: Fix a couple of typos detected by ispell. 2022-09-23 08:57:57 +02:00
Alexandre Duret-Lutz
3729dfad90 translate: add a branch-post option
* spot/twaalgos/translate.cc, spot/twaalgos/translate.hh: Here.
* NEWS, bin/spot-x.cc: Mention it.
* tests/core/genltl.test: Test it.
2022-09-23 08:57:57 +02:00
Alexandre Duret-Lutz
7ed62f7eed genltl: introduce --eil-gsi
Based on a mail from Edmond Irani Liu.  The test case also serves for
the previous patch.

* bin/genltl.cc, spot/gen/formulas.cc, spot/gen/formulas.hh: Add it.
* NEWS: Mention it.
* tests/core/genltl.test: Test it.
2022-09-23 08:57:57 +02:00
Alexandre Duret-Lutz
3efab05cf2 introduce delay_branching_here
This is motivated by an example sent by Edmond Irani Liu,
that will be tested in next patch.

* spot/twaalgos/dbranch.cc, spot/twaalgos/dbranch.hh: New files.
* python/spot/impl.i, spot/twaalgos/Makefile.am: Add them.
* spot/twaalgos/translate.cc: Call delay_branching_here
unconditionally.
* spot/twa/twagraph.cc (defrag_states): Do not assume
that games are alternating.
* tests/core/genltl.test: Adjust expected numbers.
* tests/python/dbranch.py: New file.
* tests/Makefile.am: Add it.
2022-09-23 08:57:57 +02:00
Alexandre Duret-Lutz
aa7992c65f simplify some uses of minato_isop
Typically intead of doing

    minato_isop isop(rel & letter);
    while (bdd cube = isop.next()) {
       bdd res = bdd_exists(cube, ap)
       ...
    }

do

    minato_isop isop(bdd_relprod(rel, letter, ap);
    while (bdd res = isop.next()) {
       ...
    }

this way the existential quantification is done once at the same time
of the conjunction, and isop has fewer variable to work with.

* spot/twaalgos/alternation.cc, spot/twaalgos/dualize.cc,
spot/twaalgos/simulation.cc, spot/twaalgos/toweak.cc: Here.
2022-09-23 08:57:57 +02:00
Philipp Schlehuber-Caissier
c45ff0c94c fix: ltlsynt --tlsf does not propagate name to csv
* bin/ltlsynt.cc: Here
2022-09-21 21:03:06 +02:00
Philipp Schlehuber-Caissier
4a24739c3f Improving minimize_mealy benchmarking
* python/spot/__init__.py: Adding helper function for
inline plot of csv
*spot/twaalgos/mealy_machine.cc, spot/twaalgos/mealy_machine.hh:
Main changes
* tests/python/_mealy.ipynb: Update
* tests/python/ipnbdoctest.py: Ignore timing table
* tests/python/synthesis.ipynb: Update
2022-09-21 21:03:06 +02:00
Philipp Schlehuber-Caissier
c63c1796b9 Improve aiger INF encoding
the encoding cna be simplified to produce less gates
when high or low is True.

* spot/twaalgos/aiger.cc: Here
* tests/python/_synthesis.ipynb: Test
2022-09-21 17:28:04 +02:00
Alexandre Duret-Lutz
c1c874b1a5 ltlsynt: add options --dot and --hide-status
* bin/ltlsynt.cc: Implement these options.
* bin/common_aoutput.hh, bin/common_aoutput.cc (automaton_format_opt):
Make extern.
* NEWS: Mention the new options.
* doc/org/ltlsynt.org: Use dot output in documentation.
* tests/core/ltlsynt.test: Quick test of the new options.
2022-09-14 15:33:46 +02:00
Alexandre Duret-Lutz
ef0aeed228 ltlsynt: fix documentation of --aiger option
* bin/ltlsynt.cc: Here.
2022-09-14 11:29:18 +02:00
Alexandre Duret-Lutz
b3b22388c9 postproc: introduce -x merge-states-min
* spot/twaalgos/postproc.cc, spot/twaalgos/postproc.hh: Introduce a
merge-states-min option.
* bin/spot-x.cc: Document it.
* spot/gen/automata.cc, spot/gen/automata.hh, bin/genaut.cc: Add
option to generate cyclist test cases.
* NEWS: Document the above.
* tests/core/included.test: Add test cases that used to be too slow.
2022-09-13 15:19:55 +02:00
Alexandre Duret-Lutz
d9248e2e97 * doc/org/concepts.org (T-based vs. S-based acceptance): Adjust example. 2022-09-12 14:15:05 +02:00
Alexandre Duret-Lutz
bdac53511a degen: learn to work on generalized-Co-Büchi as well
* spot/twaalgos/degen.hh, spot/twaalgos/degen.cc: Adjust
degeneralize() and degeneralize_tba() to work on generalized-co-Büchi.
* NEWS: Mention this.
* spot/twaalgos/cobuchi.hh, spot/twaalgos/cobuchi.cc (to_nca): Use
degeneralization on generalized-co-Büchi.
* spot/twaalgos/postproc.cc: Use degeneralization for generalized
co-Büchi as well.
* bin/autfilt.cc: Improve chain products of co-Büchi automata by using
generalization if too many colors are needed.
* tests/core/prodchain.test, tests/python/pdegen.py: Add test cases.
2022-09-12 14:14:43 +02:00
Alexandre Duret-Lutz
fe3ebd370b add the TACAS'22 reference
* doc/org/citing.org, doc/spot.bib: There.
2022-09-07 09:59:31 +02:00
Alexandre Duret-Lutz
0f131f2eee product: Büchi|Büchi=Büchi, CoBüchi&CoBüchi=CoBüchi
Improve the construction of the above constructions, saving colors.

* spot/twaalgos/product.cc: Here.
* spot/twaalgos/product.hh, NEWS: Mention it.
* tests/core/prodchain.test, tests/core/prodor.test,
tests/python/_product_weak.ipynb: Adjust.
2022-09-06 18:05:52 +02:00
Alexandre Duret-Lutz
7cf580a9c5 we want the tarball we distribute to be built on Debian unstable
See issue #512.

* .gitlab-ci.yml (make-dist): New build.
(debian-unstable-gcc-pypy, arch-gcc-glibcxxdebug, mingw-shared,
mingw-static, publish-stable): Depend upon make-dist.
2022-09-02 20:50:04 +02:00
Alexandre Duret-Lutz
2e32793ed1 * .gitlab-ci.yml (debian-unstable-gcc-coverage): Export coverage.css. 2022-09-02 20:49:58 +02:00
Alexandre Duret-Lutz
925ac6bbe4 * .gitlab-ci.yml: Use gcovr and produce an XML report for gitlab. 2022-09-01 10:40:40 +02:00
Alexandre Duret-Lutz
cd21521bfe * spot/twa/twagraph.cc (merge_states): Some cleanup and simplifications. 2022-08-14 23:09:56 +02:00
Alexandre Duret-Lutz
d1b8495510 do not use a global variable to define the number of available threads
* python/spot/impl.i: Make parallel_policy implicitly contractible.
* spot/graph/graph.hh (sort_edges_srcfirst_): Pass a parallel_policy
explicitly.
* spot/twa/twagraph.hh, spot/twa/twagraph.cc (merge_states): Likewise.
* spot/misc/common.cc: Remove file.
* spot/misc/common.hh (set_nthreads, get_nthreads): Remove, and
replace with...
(parallel_policy): ... this.
* spot/misc/Makefile.am, tests/python/mergedge.py, NEWS: Adjust.
2022-08-14 23:09:56 +02:00
Alexandre Duret-Lutz
2848951965 * doc/spot.bib: Add entries for last two tool papers. 2022-08-10 10:28:44 +02:00
Alexandre Duret-Lutz
a7e87a1fc7 Mention the CAV'22 paper
* doc/org/citing.org: Here.
* doc/org/spot.css: Add support for "begin_note...end_note".
2022-08-10 10:28:41 +02:00
Alexandre Duret-Lutz
faa8fe8873 mealy: cleanup the doxygen documentation
* spot/twaalgos/mealy_machine.hh: Create a new "Mealy" section for
all these function, and fix some doc strings.
2022-08-06 15:08:11 +02:00
Alexandre Duret-Lutz
de9041bb31 mealy: make output_assignment the default for reduce_mealy
* spot/twaalgos/mealy_machine.hh: Here. Also cite the FORTE paper.
* doc/spot.bib (renkin.22.forte): New entry.
2022-08-06 14:08:23 +02:00
Alexandre Duret-Lutz
b0165cf39c * doc/org/tut10.org: Use the same formula in C++ as in Python and sh. 2022-08-05 18:55:44 +02:00
Alexandre Duret-Lutz
8b93b6967d rename pg_print() as print_pg() and add it to to_str()
* NEWS: Mention those change.
* spot/twaalgos/game.hh (print_pg): New function.
(pg_print): Mark as deprecated.
* spot/twaalgos/game.cc (pg_print): Redirect to print_pg().
(print_pg): Update to output state names.
* python/spot/__init__.py: Teach to_str() about print_pg().
* bin/ltlsynt.cc: Adjust to call print_pg().
* tests/python/games.ipynb: Add an example.
* tests/core/ltlsynt.test: Adjust to remove the "INIT" note.
2022-07-23 21:38:23 +02:00
Alexandre Duret-Lutz
b3e994c249 * spot/twaalgos/hoa.cc: Typo in error message. 2022-07-22 10:54:15 +02:00
Alexandre Duret-Lutz
444e2b5b89 parseaut: Add support for PGSolver's format
* spot/parseaut/parseaut.yy, spot/parseaut/scanaut.ll: Add rules for
PGSolver's format.
* spot/parseaut/public.hh: PGAME is a new type of output.
* tests/core/pgsolver.test: New file.
* tests/Makefile.am: Add it.
* tests/python/games.ipynb: More exemples.
* NEWS: Mention the new feature.
2022-07-22 10:54:08 +02:00
Alexandre Duret-Lutz
d6b3c757d0 test: ignore OpenBSD's "Terminated" messages
For #501.

* tests/core/autcross4.test: Here.
2022-07-12 15:43:39 +02:00
Alexandre Duret-Lutz
3e2201bd80 tests: add figures from CAV'22 paper
* tests/python/cav22-figs.ipynb: New file.
* doc/org/tut.org, tests/Makefile.am: Add it.
2022-07-12 15:05:09 +02:00
12920c44e3 Trigger archival services on new release
* .gitlab-ci.yml: curl Software Heritage and Internet Archive endpoints
to trigger archival on push to stable
2022-07-07 23:23:41 +02:00
Florian Renkin
6dd99e049b to_parity: Rewrite the function and add new transformations
* spot/twaalgos/synthesis.cc: Now needs to call reduce_parity.
* spot/twaalgos/toparity.cc, spot/twaalgos/toparity.hh: here.
* spot/twaalgos/zlktree.hh: make zielonka_node public
* tests/core/ltlsynt.test, tests/python/games.ipynb,
  tests/python/synthesis.ipynb, tests/python/toparity.py:
  update tests
2022-07-07 20:43:21 +02:00
Florian Renkin
3f333792ff Add a procedure that detects if an automaton is parity-type
* spot/twaalgos/genem.cc, spot/twaalgos/genem.hh: add detection
  of edges that are in at least one accepting cycle.
* spot/twaalgos/toparity.cc,
  spot/twaalgos/toparity.hh: add parity_type_to_parity and
  buchi_type_to_buchi.
2022-07-07 20:43:21 +02:00
Alexandre Duret-Lutz
5b8350bc9b rpm: omit *.la files
* spot.spec.in: It seems RedHat does not distribute *.la files anymore.
2022-07-07 15:51:11 +02:00
Alexandre Duret-Lutz
1cfb4a14ec bloemen: simplify style
Fixes #510.

* spot/mc/bloemen_ec.hh: Here.
2022-07-06 17:11:55 +02:00
Alexandre Duret-Lutz
69eba6fd9a bloemen: fix a unused variable warning
As discussed in #510.

* spot/mc/bloemen_ec.hh: Here.
2022-07-06 16:34:01 +02:00
Alexandre Duret-Lutz
ee55dabfaa * spot/mc/cndfs.hh: Fix a unused variable warning in NDEBUG. 2022-07-05 23:56:36 +02:00
Alexandre Duret-Lutz
a66c305609 gen: work around a warning on red hat
When n is an int, doing "new formula[n];" gives us "warning: argument 1
value '18446744073709551615' exceeds maximum object size
9223372036854775807" on Red Hat.

* spot/gen/formulas.cc (pps_arbiter): Pass n as unsigned.  Also
fix some determinism in the strict variant.
2022-07-05 11:10:43 +02:00
Alexandre Duret-Lutz
ff89601306 utf8: Update to match current version
* utf8/LICENSE, utf8/utf8/cpp11.h, utf8/utf8/cpp17.h: New files.
* Makefile.am: Distribute them.
* utf8/README.md, utf8/utf8/checked.h, utf8/utf8/core.h,
utf8/utf8/unchecked.h: Update to the current version of utfcpp.
* README: Add a link to the upstream github.
2022-07-05 10:56:57 +02:00
Alexandre Duret-Lutz
efee1c4130 * spot/twaalgos/mealy_machine.cc (is_complete_): Define in debug only. 2022-07-05 10:41:24 +02:00
Alexandre Duret-Lutz
833fcdebc1 work around GCC bug 106159
* m4/gccwarn.m4: Add an example of multiple inheritance of virtual
classes to trigger to new -Woverloaded-virtual warning on the
destructor.
2022-07-05 10:38:51 +02:00
Alexandre Duret-Lutz
1fc94ee6f2 gnulib: install the environ module
This should fix compilation on OSX, as reported by Yann Thierry-Mieg.

* m4/environ.m4: New file.
* m4/gnulib-cache.m4, m4/gnulib-comp.m4: Update.
* bin/common_trans.cc [HAVE_SPAWN_H]: Do not define environ.
2022-06-30 09:50:13 +02:00
Alexandre Duret-Lutz
db725ffaf8 * spot/twaalgos/degen.cc (propagate_marks_here): Cleanup previous patch. 2022-06-30 09:18:03 +02:00
Philipp Schlehuber-Caissier
99bf152673 propagate_marks_here can break state-acc prop
* spot/twaalgos/degen.cc: Fix
* tests/python/pdegen.py: Test
2022-06-29 14:02:36 +02:00
Philipp Schlehuber-Caissier
ddbdcd39cb Adept ltlsynt pgame to new solver
* bin/ltlsynt.cc: Remove change/colorize_parity, check alternating
2022-06-29 13:19:57 +02:00
Philipp Schlehuber-Caissier
6bc1dd0467 Use new zielonka for synthesis
Remove all now unnecessary colorize_parity and
change_parity calls.

* spot/twaalgos/synthesis.cc: Change here
* spot/twaalgos/game.cc: Adjust pg-print
* tests/core/ltlsynt.test,
  tests/python/_mealy.ipynb,
  tests/python/games.ipynb,
  tests/python/synthesis.ipynb,
  tests/python/synthesis.py: Adjust tests
2022-06-27 09:29:46 +02:00
philipp
9124484719 Modifying Zielonka
* spot/twaalgos/game.cc: solve_parity_game now works for any of
the four parity types and partially colored graphs.
 Also removing unnescessary steps from Zielonka.
h: Update
* tests/python/game.py: Update and additional tests
* tests/python/except.py: Remove outdated exception
2022-06-27 09:29:36 +02:00
Alexandre Duret-Lutz
9222e9713b parseaut: fix handling of [ outside HOA
Fixes #509.

* spot/parseaut/scanaut.ll: Reset ->str whenever a [ is read,
so that we do not attempt to clear ->str while reading garbage.
* NEWS: Mention the bug.
* tests/core/parseaut.test: Test it.
2022-06-23 17:19:09 +02:00
Alexandre Duret-Lutz
b4279d3a12 dot: quote identifiers containing a minus
* spot/twaalgos/dot.cc: Quote identifiers containing a minus.
* tests/core/alternating.test: Add test case.
* NEWS: Mention the bug.
2022-06-23 16:19:50 +02:00
Alexandre Duret-Lutz
166a26417c graph: fix creation of universal edge
* spot/graph/graph.hh: Use a temporary array to store the destination
vector if the passed range belong to the dests_ vector.  Otherwise the
passed begin/end risk being invalidated when dests_ is reallocated.
* NEWS: Mention the bug.
2022-06-23 15:52:24 +02:00
Alexandre Duret-Lutz
288b1c7958 contains: generalize second argument to a twa
This was triggered by a question from Pierre Ganty on the mailing
list.

* spot/twaalgos/contains.hh, spot/twaalgos/contains.cc (contains):
Generalize second argument to const_twa_ptr instead of
const_twa_graph_ptr.
* NEWS: Mention this.
* tests/python/ltsmin-pml.ipynb: Show that it work.
* THANKS: Mention Pierre.
2022-06-22 23:43:07 +02:00
Alexandre Duret-Lutz
be28365db4 ltlsynt: add --from-pgame option to read parity games
* bin/common_file.cc, bin/common_file.hh (output_file): Add a
force_append option.
* bin/ltlsynt.cc: Implement the --from-pgame option, and
fix suppot for --csv when multiple inputs are processed.
* NEWS: Mention the new option.
* tests/core/syfco.test: Add a test case.
* tests/core/ltlsynt-pgame.test: New file.
* tests/Makefile.am: Add it.
2022-06-22 23:20:20 +02:00
Alexandre Duret-Lutz
04d718ab9c ltlsynt: support multiple --tlsf options
* bin/common_finput.cc, bin/common_finput.hh: Add support for
process_tlsf_file.
* bin/ltlsynt.cc: Implement it.
* tests/core/syfco.test: Adjust test case.
2022-06-22 19:37:41 +02:00
Alexandre Duret-Lutz
df685433f4 bin: separate process_file() for aut and ltl
* bin/common_finput.cc, bin/common_finput.hh,
bin/common_hoaread.hh (process_file): Split into...
(process_ltl_file, process_aut_filt): ... these, as we will need both
in ltlsynt.
2022-06-22 19:37:41 +02:00
Alexandre Duret-Lutz
8161a8c531 tests: workaround test not failing if the Spot support more colors
* configure.ac (MAX_ACCSETS): Add AC_SUBST.
* tests/run.in: Define MAX_ACCSETS.
* tests/core/prodchain.test: Test MAX_ACCSETS.
2022-06-21 14:24:08 +02:00
Alexandre Duret-Lutz
23908f3d2f Add a --enable-pthread option to activate experimental threading code
* NEWS, README, doc/org/compile.org: Mention the option and
its effect on compilation requirements.
* configure.ac: Add the --enable-pthread option, and ENABLE_PTHREAD
macro.
* doc/org/g++wrap.in, spot/Makefile.am, spot/libspot.pc.in: Compile
with -pthread conditionally.
* spot/graph/graph.hh, spot/twa/twagraph.cc: Adjust the code to not
use thread-local variables, and let the pthread code be optional.
* .gitlab-ci.yml: Activate --enable-pthread in two configurations.
2022-06-21 09:56:13 +02:00
Alexandre Duret-Lutz
721d5695ec add a newer version of the generic emptiness check
As discussed with Jan Strejček.

* spot/twa/acc.cc, spot/twa/acc.hh (fin_unit_one_split): New function.
(fin_one_extract): Return the simplified acceptance condition as an
optimization.
* python/spot/impl.i: Bind this new function.
* tests/python/acc.py: New file, to test it.
* tests/Makefile.am: Add acc.py.
* spot/twaalgos/genem.cc, spot/twaalgos/genem.hh: Implement the
spot211 variant of the emptiness check.
* tests/python/genem.py: Test it.
* tests/python/acc_cond.ipynb: Adjust test for fin_one_extract.
2022-06-17 09:54:42 +02:00
Florian Renkin
aca6bd9042 synthesis: Deletion of an incorrect case in the bypass
With a formula like G(b1) & (GFi <-> GF(b1)), a direct strategy was
created while it is unrealizable.

* spot/twaalgos/synthesis.cc: here.
* tests/core/ltlsynt.test: add tests
2022-05-31 13:56:20 +02:00
Philipp Schlehuber-Caissier
d8cc0c5acb Introduce a faster merge_states
merge_states is now hash-based, uses the new edge-sorting with
src first and can be executed in parallel.

* spot/twa/twagraph.cc: Here
* tests/python/mergedge.py: Test
2022-05-24 16:58:07 +02:00
Philipp Schlehuber-Caissier
71c2a7b1a6 Add a new function to sort edges
sort_edge_srcfirst_ will sort the edge with respect
to the src state, then sort each sub list with respect
to the given predicate, possibly in parallel.

* spot/graph/graph.hh: Here
2022-05-24 16:58:07 +02:00
Philipp Schlehuber-Caissier
e064726b64 Introducing a global variable to define the number of threads
* NEWS: Announce
* spot/Makefile.am: Add pthread to use threads
* spot/misc/common.cc,
  spot/misc/common.hh: Add variable + getter/setter
* spot/misc/Makefile.am: Add common.cc
2022-05-24 16:58:07 +02:00
Alexandre Duret-Lutz
b11208440b zlktree: use a cache in the construction of zielonka_tree
This largely speeds up the computation for conditions
like "Rabin n" sharing a lot of subtrees.

Also implement options to stop the construction if the shape is wrong.

* spot/twaalgos/zlktree.cc, spot/twaalgos/zlktree.hh: Implement the
cache and the options.
* tests/python/zlktree.ipynb, tests/python/zlktree.py: New tests.
2022-05-20 17:07:26 +02:00
Alexandre Duret-Lutz
f784e40548 complete: do not force Büchi on universal automata
* spot/twaalgos/complete.hh: Adjust documentation.
* spot/twaalgos/complete.cc: If the acceptance condition is a
tautology, delay the forcing of Büchi acceptance until we are sure it
is needed.
* NEWS: Mention the change.
2022-05-20 14:51:48 +02:00
Alexandre Duret-Lutz
3b8e11322b Merge branch 'master' into next 2022-05-18 09:03:40 +02:00
Alexandre Duret-Lutz
457839df36 * NEWS, configure.ac: Bump version to 2.10.6. 2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
e0de77d8a4 Release Spot 2.10.6
* NEWS, configure.ac, doc/org/setup.org: Set version to 2.10.6.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
a6639e56cb more noexcept to pleace GCC
* spot/bricks/brick-hashset (Row): Add noexcept.
* bin/autcross.cc (out_statistics): Likewise.
* bin/ltlcross.cc (statistics): Likewise.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
99d030f5e1 GCC 12 warns too much about <regex>
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562

* m4/gccwarn.m4: Compile a small regex and add
-Wno-maybe-uninitialized if needed.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
10bc253dd8 work around spurious gcc 12 "potentially null dereference"
The issue seems to be inside std::vector's copy constructor, but it
highlighted places in Spot were we could avoid this copy.

* spot/twaalgos/ltl2taa.cc: Avoid some copies of std::vector<formula>.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
eecb9af21e Fix a clang++15 warning
* spot/parseaut/parseaut.yy: Move the try-block inside the code of the
constructors, so that they can refer to non-static members.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
8a628d96bc fix warnings from clang-15
* spot/twa/acc.cc (acc_cond::acc_code::symmetries): Fix weird loop.
* spot/twaalgos/aiger.cc (aig::circ_step): Replace & by &&.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
b5f8e3c75d [buddy] remove some unused variables
* src/reorder.c (reorder_win2ite): Do not set c=1.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
c609f4cb4b * spot/twa/bdddict.hh (bdd_info): Add noexcept, suggested by gcc 12. 2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
cb5bc38f35 bin: reset column specification between files
* bin/common_finput.cc (job_processor::process_file): Reset
col_to_read.
* tests/core/ltlfilt.test: Test it.
* NEWS: Mention the bug.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
f14b0bb4bd Fix compilation on MacOS X
Patch by Shachar Itzhaky.

* spot/parseaut/scanaut.ll, spot/parsetl/scantl.ll: Include
libc-config.h instead of config.h.
* NEWS: Mention the fix.
* THANKS: Add Shachar.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
78d7224026 twagraph: improve copy of kripke_graph
Fix #505, Reported by Edmond Irani Liu.

* spot/twa/twagraph.cc (copy): Deal with kripke_graph in a better way.
* spot/twaalgos/hoa.cc: Do not force the use of named-states since
when the input is a kripke_graph.
* tests/python/kripke.py: Adjust test cases.
* NEWS: Mention the change.
* THANKS: Add Edmund.
2022-05-18 08:52:33 +02:00
Alexandre Duret-Lutz
506442450e parsetl: remove a superfluous diagnostic on some erroneous input
* tests/core/neverclaimread.test: Adjust and remove FIXME.
* spot/parsetl/parsetl.yy (try_recursive_parse): Return false
on empty string.
2022-05-18 07:07:52 +02:00
Alexandre Duret-Lutz
9ae2e9c03d Fix link to parity game example
Reported by Florian Renkin.

* doc/org/index.org: Here.
2022-05-18 07:07:26 +02:00
Alexandre Duret-Lutz
2a4e68bfae more noexcept to pleace GCC
* spot/bricks/brick-hashset (Row): Add noexcept.
* bin/autcross.cc (out_statistics): Likewise.
* bin/ltlcross.cc (statistics): Likewise.
2022-05-17 22:06:59 +02:00
Alexandre Duret-Lutz
a23b30abdc GCC 12 warns too much about <regex>
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562

* m4/gccwarn.m4: Compile a small regex and add
-Wno-maybe-uninitialized if needed.
2022-05-17 17:01:48 +02:00
Alexandre Duret-Lutz
e4f8226c62 work around spurious gcc 12 "potentially null dereference"
The issue seems to be inside std::vector's copy constructor, but it
highlighted places in Spot were we could avoid this copy.

* spot/twaalgos/ltl2taa.cc: Avoid some copies of std::vector<formula>.
2022-05-17 15:25:17 +02:00
Alexandre Duret-Lutz
e8f496bb6c Fix a clang++15 warning
* spot/parseaut/parseaut.yy: Move the try-block inside the code of the
constructors, so that they can refer to non-static members.
2022-05-17 12:01:11 +02:00
Alexandre Duret-Lutz
3a234e24ae fix warnings from clang-15
* spot/twa/acc.cc (acc_cond::acc_code::symmetries): Fix weird loop.
* spot/twaalgos/aiger.cc (aig::circ_step): Replace & by &&.
2022-05-17 11:43:55 +02:00
Alexandre Duret-Lutz
5dab2ede41 [buddy] remove some unused variables
* src/reorder.c (reorder_win2ite): Do not set c=1.
2022-05-17 11:37:52 +02:00
Alexandre Duret-Lutz
4bb58f457b * spot/twa/bdddict.hh (bdd_info): Add noexcept, suggested by gcc 12. 2022-05-17 11:17:37 +02:00
Alexandre Duret-Lutz
d35f7bd37c bin: reset column specification between files
* bin/common_finput.cc (job_processor::process_file): Reset
col_to_read.
* tests/core/ltlfilt.test: Test it.
* NEWS: Mention the bug.
2022-05-17 11:11:23 +02:00
Alexandre Duret-Lutz
d697f57a97 bin: introduce a non-binary job_type
This will later help improve the handling of different input types of
ltlsynt.

* bin/common_finput.hh (job_type): New enum.
(job::type): Use it.
* bin/autcross.cc, bin/autfilt.cc, bin/common_finput.cc,
bin/dstar2tgba.cc, bin/ltl2tgba.cc, bin/ltl2tgta.cc, bin/ltlcross.cc,
bin/ltldo.cc, bin/ltlfilt.cc, bin/ltlgrind.cc, bin/ltlsynt.cc: Adjust
to use the job_type enum instead of a boolean.
2022-05-17 10:49:06 +02:00
Alexandre Duret-Lutz
3b809c0a14 Fix compilation on MacOS X
Patch by Shachar Itzhaky.

* spot/parseaut/scanaut.ll, spot/parsetl/scantl.ll: Include
libc-config.h instead of config.h.
* NEWS: Mention the fix.
* THANKS: Add Shachar.
2022-05-17 09:35:09 +02:00
Alexandre Duret-Lutz
013c879b41 twagraph: improve copy of kripke_graph
Fix #505, Reported by Edmond Irani Liu.

* spot/twa/twagraph.cc (copy): Deal with kripke_graph in a better way.
* spot/twaalgos/hoa.cc: Do not force the use of named-states since
when the input is a kripke_graph.
* tests/python/kripke.py: Adjust test cases.
* NEWS: Mention the change.
* THANKS: Add Edmund.
2022-05-09 13:42:20 +02:00
Alexandre Duret-Lutz
ef9267a58e parsetl: remove a superfluous diagnostic on some erroneous input
* tests/core/neverclaimread.test: Adjust and remove FIXME.
* spot/parsetl/parsetl.yy (try_recursive_parse): Return false
on empty string.
2022-05-06 13:58:52 +02:00
Alexandre Duret-Lutz
4a2bdd6e86 Fix link to parity game example
Reported by Florian Renkin.

* doc/org/index.org: Here.
2022-05-04 17:40:17 +02:00
Alexandre Duret-Lutz
73e148446c Merge branch 'master' into next 2022-05-03 09:05:26 +02:00
Alexandre Duret-Lutz
56666e0db5 * NEWS, configure.ac: Bump version to 2.10.5.dev. 2022-05-03 09:01:03 +02:00
Alexandre Duret-Lutz
c70a06ae0a Release Spot 2.10.5
* NEWS, configure.ac, doc/org/setup.org: Update.
2022-05-03 08:59:17 +02:00
Alexandre Duret-Lutz
385da8ebd0 update NEWS for upcoming release
* NEWS: Here.
2022-05-02 17:47:53 +02:00
Florian Renkin
0f3ffd59ce ltlsynt: don't solve games when we want to display them
* bin/ltlsynt.cc: here
2022-05-02 17:24:23 +02:00
Alexandre Duret-Lutz
fa6912a574 debian: simplify LTO configuration to work around newer libtool
Libtool 2.4.7 breaks if AR_FLAGS contains a space. See
https://lists.gnu.org/archive/html/bug-libtool/2022-03/msg00009.html

* debian/rules: Use gcc-{nm,ar,ranlib} so we do not have to pass
the plugin explicitly.
2022-05-02 17:24:23 +02:00
Philipp Schlehuber-Caissier
add2fced44 Correct bug in zielonka
Optimization in Zielonka failed
under certain circumstances
todo: Devise a specialized test
for direct attr computation

* spot/twaalgos/game.cc: Correction
* tests/python/game.py: Test
2022-05-02 17:24:23 +02:00
Alexandre Duret-Lutz
58f39ec287 * doc/org/tut40.org: Clarify, as suggested by a CAV'22 reviewer. 2022-05-02 17:24:23 +02:00
Florian Renkin
d1f49c721a ltlsynt: don't fail if --outs or --ins is set to empty
* bin/ltlsynt.cc: here
* tests/core/ltlsynt.test: add tests
2022-05-02 17:24:23 +02:00
Alexandre Duret-Lutz
53118d9314 * spot/twaalgos/gfguarantee.hh: Typos in comments. 2022-05-02 17:24:23 +02:00
Alexandre Duret-Lutz
96e051d2bb graph: fix invalid read
Reported by Florian Renkin.

* spot/graph/graph.hh (sort_edges_of): Fix invalid read when sorting a
state without successor.  Seen on core/tgbagraph.test.
2022-05-02 17:24:23 +02:00
Florian Renkin
968ef0f7b8 ltlsynt: typo in help
* bin/ltlsynt.cc: here
2022-05-02 17:24:23 +02:00
Alexandre Duret-Lutz
2aecf9a79e fix typos and make formula_from_bdd more usable in Python
* python/spot/impl.i (formula_from_bdd): Instantiate for twa_graph.
* spot/twa/twa.hh (register_aps_from_dict): Typo in exception.
* tests/python/except.py: More tests for the above.
* tests/python/bdddict.py: Typo in comment.
2022-05-02 17:24:23 +02:00
734de00bfd tests: don't wipe python environment
* tests/run.in: keep original PYTHONPATH contents
* NEWS: mention the bug
2022-05-02 15:36:27 +02:00
Alexandre Duret-Lutz
d61d6e5e2f tests: avoid seq
Partial fix for #501.

* tests/core/prodchain.test: Hardcode the seq output.
* tests/core/bricks.test: Use $AWK instead of seq.
* tests/core/defs.in: Define $AWK.
* NEWS: Mention the bug.
2022-05-02 15:36:11 +02:00
Alexandre Duret-Lutz
7149e5a34d * .gitlab-ci.yml (alpine-gcc): Fix path for logs. 2022-05-02 15:35:51 +02:00
Alexandre Duret-Lutz
7d9fddadce work around an issue in Flex 2.6.4
The fallback definition of SIZE_MAX supplied by flex was not
preprocessor friendly and prevented robin_hood.hh from doing "#if
SIZE_MAX == UINT64_MAX", as observed by Marc Espie on OpenBSD.

* spot/parseaut/scanaut.ll, spot/parsetl/scantl.ll: Define
__STDC_VERSION__ just so that the code generated by Flex
include <inttypes.h>.
* NEWS: Mention the bug.
* THANKS: Add Marc.
2022-05-02 15:35:09 +02:00
Alexandre Duret-Lutz
64020279cb reduce_parity: fix to work on automata with deleted edges
* spot/twaalgos/parity.cc (reduce_parity): Use the
size of the edge vector to initialize piprime1 and piprime2,
not the number of edges.
* tests/python/parity.py: Add test case, based on a report
by Yann Thierry-Mieg.
2022-05-02 15:34:57 +02:00
Alexandre Duret-Lutz
b7825552f8 remove uses of unary_function and binary_function
These were deprecated in C++11, and are supposed to be removed from
C++17, however gcc-snapshot just started warning about those.

* spot/misc/bddlt.hh, spot/misc/hash.hh, spot/misc/ltstr.hh,
spot/twa/taatgba.hh, spot/twaalgos/ltl2tgba_fm.cc: Here.
2022-05-02 15:34:14 +02:00
Florian Renkin
355c5ffeb1 ltlsynt: display the number of subformulas
* bin/ltlsynt.cc: here
* tests/core/ltlsynt.test: ajust tests
2022-04-25 11:25:29 +02:00
Florian Renkin
62725fb507 ltlsynt: don't solve games when we want to display them
* bin/ltlsynt.cc: here
2022-04-25 11:25:29 +02:00
Florian Renkin
55aac8e107 ltlsynt: display ACD instead of LAR when needed
* spot/twaalgos/synthesis.cc: here
* tests/core/ltlsynt.test: add test
2022-04-25 11:25:25 +02:00
Alexandre Duret-Lutz
5f43c9bfce ltlsynt: implement --tlsf to call syfco automatically
Fixes #473.

* NEWS, doc/org/ltlsynt.org: Mention it.
* bin/common_trans.cc, bin/common_trans.hh (read_stdout_of_command):
New function.
* bin/ltlsynt.cc: Implement the --tlsf option.
* tests/core/syfco.test: New file.
* tests/Makefile.am: Add it.
2022-04-13 09:08:40 +02:00
Philipp Schlehuber-Caissier
06b73c39fa +ud option of mealy_machine_to_aig received wrong value
Also aiger received a tracing option for
debugging

* spot/twaalgos/aiger.cc: Here
* tests/core/ltlsynt.test: Test
2022-04-07 21:21:52 +02:00
Philipp Schlehuber-Caissier
524edea8da Propagate colors in split_2step
Reduce the amount of uncolored transitions
after split_2step by trying to color the env transitions.
This is currently only supported for parity like
acceptance conditions.

* spot/twaalgos/game.cc: Determinizatio of "colored"
game can created trivial self-loops. Fix them
* spot/twaalgos/synthesis.cc: Here
* tests/core/ltlsynt.test,
tests/python/_synthesis.ipynb,
tests/python/games.ipynb,
tests/python/synthesis.ipynb,
tests/python/synthesis.py: New and adjusted tests
2022-04-07 21:21:06 +02:00
Philipp Schlehuber-Caissier
dfb75632ba Update merge_states
Current implementation of merge_states fails
on certain self-loops.
Updated implementation to take them into
account and use a hashbased implementation
to speed up calculations.
Moreover, merge_states() is now aware
of "state-player", just like defrag_states_

* spot/twa/twagraph.cc: Here
* spot/twaalgos/game.cc: Fix odd cycle for sink
* spot/twaalgos/synthesis.cc: Adapt split_det pipeline
* tests/python/_synthesis.ipynb: Tests
2022-04-07 17:42:14 +02:00
Alexandre Duret-Lutz
a211bace68 autcross: implement --language-complemented
Suggested by Ondřej Lengál.  Fixes #504.

* bin/autcross.cc: Implement the --language-complemented option.
* NEWS, doc/org/autcross.org: Document it.
* tests/core/autcross.test: Test it.
* THANKS: Add Ondřej.
2022-04-06 15:38:23 +02:00
Alexandre Duret-Lutz
5e1b751971 debian: simplify LTO configuration to work around newer libtool
Libtool 2.4.7 breaks if AR_FLAGS contains a space. See
https://lists.gnu.org/archive/html/bug-libtool/2022-03/msg00009.html

* debian/rules: Use gcc-{nm,ar,ranlib} so we do not have to pass
the plugin explicitly.
2022-03-30 11:20:25 +02:00
Philipp Schlehuber-Caissier
27d455389e Correct bug in zielonka
Optimization in Zielonka failed
under certain circumstances
todo: Devise a specialized test
for direct attr computation

* spot/twaalgos/game.cc: Correction
* tests/python/game.py: Test
2022-03-29 22:36:35 +02:00
Alexandre Duret-Lutz
9c6a09890e parsetl: speedup parsing of n-ary operators with many operands
Issue #500, reported by Yann Thierry-Mieg.

* spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll: Use variant
to store a new pnode objects that delays the construction of n-ary
operators.
* spot/parsetl/Makefile.am: Do not distribute stack.hh anymore.
* spot/tl/formula.cc: Fix detection of overflow in Star and FStar.
* HACKING: Update Bison requirements to 3.3.
* tests/core/500.test: New test case.
* tests/Makefile.am: Add it.
* tests/core/ltl2tgba2.test, tests/core/ltlsynt.test,
tests/core/tostring.test: Adjust to new expected order.
* NEWS: Mention the change.
2022-03-28 09:00:18 +02:00
Alexandre Duret-Lutz
46f3f5aaf4 * doc/org/tut40.org: Clarify, as suggested by a CAV'22 reviewer. 2022-03-25 22:56:37 +01:00
Florian Renkin
7abcf4e38b ltlsynt: create a "bypass" option
* bin/ltlsynt.cc: here.
* tests/core/ltlsynt.test: add tests
2022-03-22 19:05:31 +01:00
Florian Renkin
328cf95816 ltlsynt: generalization of the bypass
* spot/twaalgos/synthesis.cc, spot/twaalgos/synthesis.hh: generalize the
  bypass and avoid to construct a strategy when we want realizability.
* bin/ltlsynt.cc: adapt for realizability
* tests/core/ltlsynt.test: update tests
2022-03-22 19:05:28 +01:00
Florian Renkin
0a6b627914 option_map: Don't report unused options if option_map is not used
* spot/misc/optionmap.cc, spot/misc/optionmap.hh: here.
2022-03-22 16:08:51 +01:00
Florian Renkin
8d9597d80d ltlsynt: add --algo=acd
* bin/ltlsynt.cc: Add "acd" to the list of possible paritization
		  algorithms used by ltlsynt
* spot/twaalgos/synthesis.cc, spot/twaalgos/synthesis.hh: Add
	ACD as paritisation algorithm
* tests/core/ltlsynt.test: add tests
2022-03-22 16:08:51 +01:00
Florian Renkin
dd58747659 synthesis.ipynb: remove useless import
* tests/python/synthesis.ipynb: here.
2022-03-22 16:08:51 +01:00
Florian Renkin
0dd36e9a53 ltlsynt: don't fail if --outs or --ins is set to empty
* bin/ltlsynt.cc: here
* tests/core/ltlsynt.test: add tests
2022-03-22 16:08:51 +01:00
Alexandre Duret-Lutz
e9c1aeaa54 * spot/twaalgos/gfguarantee.hh: Typos in comments. 2022-03-22 15:50:36 +01:00
Alexandre Duret-Lutz
3ed337ec46 graph: fix invalid read
Reported by Florian Renkin.

* spot/graph/graph.hh (sort_edges_of): Fix invalid read when sorting a
state without successor.  Seen on core/tgbagraph.test.
2022-03-22 15:50:36 +01:00
Philipp Schlehuber-Caissier
bb7072402a Removing eeroneaus test
* tests/python/except.py: Here
2022-03-21 10:51:38 +01:00
Philipp Schlehuber-Caissier
97fc3f6c0b Introduce simplify_mealy
Convenience function dispatching to
minimize_mealy and reduce_mealy.
Change tests accordingly

* spot/twaalgos/mealy_machine.cc,
  spot/twaalgos/mealy_machine.hh: Here
* bin/ltlsynt.cc: Use simplify
* spot/twaalgos/synthesis.cc,
  spot/twaalgos/synthesis.hh: Remove
 minimization, Update options
* tests/core/ltlsynt.test,
  tests/python/synthesis.ipynb,
  tests/python/_synthesis.ipynb: Adapt
2022-03-18 15:35:54 +01:00
Philipp Schlehuber-Caissier
86de4d4052 Introduce mealy_prod
Product between mealy machines
with propagation of synthesis outputs
and additional assertions.
Currently it only supports input complete machines

* spot/twaalgos/mealy_machine.cc,
  spot/twaalgos/mealy_machine.hh: Here
* bin/ltlsynt.cc: Use
* tests/python/except.py,
  tests/python/synthesis.ipynb: Test
2022-03-18 15:33:15 +01:00
Alexandre Duret-Lutz
5cd0ce14b0 fix mempool test to use __has_include
This follows 6b88d6f35b.

* tests/core/mempool.cc: Use __has_include too.
2022-03-17 16:50:01 +01:00
Alexandre Duret-Lutz
75818fde13 synthesis: fix suboptimal colorization after LAR
* spot/twaalgos/synthesis.cc (ltl_to_game): In LAR and LAR_OLD mode,
for max odd and colorize the game after the split, not before.  The
previous code used to colorize twice, and could waste up to 4 colors
in the process.
* tests/core/ltlsynt.test, tests/python/_mealy.ipynb,
tests/python/games.ipynb, tests/python/synthesis.ipynb,
tests/python/synthesis.py: Adjust all test cases to reflect the fact
that the game uses fewer colors.
2022-03-17 16:44:48 +01:00
Alexandre Duret-Lutz
c1e6340228 optionmap: set_if_unset and simplifications
* spot/misc/optionmap.hh (set_if_unset): New method.
* spot/misc/optionmap.cc (set_if_unset, set, set_str): Implement
set_if_unset, and simplify set and set_str to not perform two lookups.
* spot/twaalgos/synthesis.cc (create_translator): Use set_if_unset
to simplify the code.
2022-03-17 16:42:01 +01:00
Florian Renkin
4f69e99c45 synthesis.ipynb: correct typos
* tests/python/synthesis.ipynb: here
2022-03-17 11:53:51 +01:00
Florian Renkin
e248f4500d ltlsynt: typo in help
* bin/ltlsynt.cc: here
2022-03-15 14:04:16 +01:00
Alexandre Duret-Lutz
0745e735bb fix typos and make formula_from_bdd more usable in Python
* python/spot/impl.i (formula_from_bdd): Instantiate for twa_graph.
* spot/twa/twa.hh (register_aps_from_dict): Typo in exception.
* tests/python/except.py: More tests for the above.
* tests/python/bdddict.py: Typo in comment.
2022-03-11 09:53:04 +01:00
187bacc254 tests: don't wipe python environment
* tests/run.in: keep original PYTHONPATH contents
* NEWS: mention the bug
2022-03-10 15:57:19 +01:00
Alexandre Duret-Lutz
530cf7ca47 tests: replace all "assert" by unittest assertions
If the assert fails because of a comparison, it is useful that the
test suite log contains a comparison of these values.
unittest.assertEqual() and friends do that for us.

* HACKING: Add a section about Python tests.
* tests/sanity/style.test: Forbid the use of "assert" in
Python tests.
* tests/python/298.py, tests/python/341.py, tests/python/471.py,
tests/python/accparse2.py, tests/python/aiger.py,
tests/python/aliases.py, tests/python/alternating.py,
tests/python/bdddict.py, tests/python/bdditer.py,
tests/python/bugdet.py, tests/python/complement_semidet.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/game.py, tests/python/gen.py,
tests/python/genem.py, tests/python/implies.py,
tests/python/intrun.py, tests/python/kripke.py,
tests/python/langmap.py, tests/python/ltl2tgba.py,
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/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/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/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: Replace all occurrences of "assert" by calls
to unittest.TestCase methods.
2022-03-07 09:03:21 +01:00
Alexandre Duret-Lutz
7b7e1b254b tests: avoid seq
Partial fix for #501.

* tests/core/prodchain.test: Hardcode the seq output.
* tests/core/bricks.test: Use $AWK instead of seq.
* tests/core/defs.in: Define $AWK.
* NEWS: Mention the bug.
2022-03-04 17:25:37 +01:00
93fb11017b ltlfilt: add --sonf and --sonf-aps flags
* bin/ltlfilt.cc: Here.
* NEWS: Mention new ltlfilt flags.
* tests/Makefile.am, tests/core/sonf.test: Test these flags.
2022-03-04 17:24:26 +01:00
c71691659b tl: implement suffix operator normal form
* spot/tl/Makefile.am: New sonf files
* spot/tl/sonf.cc, spot/tl/sonf.hh: Here.
* python/spot/impl.i: include sonf.hh header
* doc/spot.bib: add entry for the SONF paper
* tests/Makefile.am: new python tests
* tests/python/formulas.ipynb: show sample usage
* tests/python/sonf.py: test automata equivalence before/after SONF
* NEWS: mention the change
2022-03-04 17:23:58 +01:00
331 changed files with 41766 additions and 11808 deletions

View file

@ -3,9 +3,9 @@
(require-final-newline . t)
(mode . global-whitespace)
(bug-reference-bug-regexp
. "\\(?:[Ff]ix\\(es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)")
. "\\(?1:\\(?:[Ff]ix\\(?:es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)\\)")
(bug-reference-url-format
. "https://gitlab.lrde.epita.fr/spot/spot/issues/%s")
. "https://gitlab.lre.epita.fr/spot/spot/issues/%s")
(mode . bug-reference)
(magit-branch-adjust-remote-upstream-alist ("origin/next" . "/"))))
(c++-mode . ((c-default-style . "gnu")

2
.gitignore vendored
View file

@ -4,6 +4,7 @@ configure
config.log
config.status
aclocal.m4
ltargz.m4
autom4te.cache
libtool
auto
@ -81,3 +82,4 @@ GTAGS
*.dsc
*.gcov
spot.spec
default.nix

View file

@ -19,12 +19,12 @@ debian-stable-gcc:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
script:
- autoreconf -vfi
- ./configure --enable-max-accsets=256
- ./configure --enable-max-accsets=256 --enable-pthread
- make
- make distcheck
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-max-accsets=256 --enable-pthread'
artifacts:
when: always
paths:
@ -32,22 +32,47 @@ debian-stable-gcc:
- ./*.log
- ./*.tar.gz
# We build on Debian unstable because we want an up-to-date Automake.
# (See issue #512.) We do not run distcheck here to speedup this build
# that several other builds depend upon. Other builds will run distcheck.
make-dist:
stage: build
only:
- branches
except:
- /wip/
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- autoreconf -vfi
- ./configure --disable-static --enable-doxygen
- make
- make dist
- autoconf --trace='AC_INIT:$2' > VERSION
artifacts:
when: always
paths:
- spot-*/_build/sub/tests/*/*.log
- ./*.log
- ./*.tar.gz
- VERSION
# We --disable-devel for coverage, because debug mode replaces
# SPOT_UNREACHABLE by an assertion wich is never reachable, lowering
# our coverage.
debian-unstable-gcc-coverage:
stage: build
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- autoreconf -vfi
- ./configure CXX='g++ --coverage' --enable-devel --disable-static --enable-doxygen
- ./configure CXX='g++ --coverage' --disable-devel --enable-warnings --disable-static --enable-doxygen
- make
- make check
- lcov --capture --directory . --no-external --output spot.info
- lcov --remove spot.info '*/bin/spot.cc' '*/bin/spot-x.cc' '*/spot/parse*/scan*.cc' '*/spot/parse*/parse*.cc' '*/utf8/*' '*/python/*' '*/buddy/*' '*/doc/org/tmp/*' --output spot2.info
- lcov --summary spot2.info
- genhtml --legend --demangle-cpp --output-directory coverage spot2.info
- gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root $PWD -e 'bin/spot.cc' -e 'bin/spot-x.cc' -e 'spot/bricks/.*' -e 'spot/parse.*/scan.*.cc' -e 'spot/parse.*/parse.*.cc' -e 'utf8/.*' -e 'python/.*' -e 'buddy/.*' -e 'doc/org/tmp/.*' --html-details coverage.html --html-tab-size 8 --fail-under-line 90.7
coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts:
when: always
paths:
@ -55,50 +80,66 @@ debian-unstable-gcc-coverage:
- ./*.log
- doc/spot.html/
- doc/userdoc/
- coverage/
- coverage*.html
- coverage*.css
- ./*.tar.gz
- spot2.info
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
debian-unstable-gcc-pypy:
stage: build
stage: build2
needs:
- job: make-dist
artifacts: true
variables:
GIT_STRATEGY: none
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- autoreconf -vfi
- VERSION=`cat VERSION`
- tar xvf spot-$VERSION.tar.gz
- cd spot-$VERSION
- ./configure PYTHON=/usr/bin/pypy3 --disable-static
- make
- make check TESTS='$(TESTS_python) $(TESTS_ipython)'
artifacts:
when: always
paths:
- tests/*/*.log
- ./*.log
- spot-*/tests/*/*.log
- spot-*/*.log
# With emacs now using gcc for on-the-fly compilation,
# we cannot rebuild the documentation using gcc-snapshot. So we start
# from the tarball instead.
debian-gcc-snapshot:
stage: build
stage: build2
needs:
- job: make-dist
artifacts: true
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- export PATH="/usr/lib/gcc-snapshot/bin:$PATH" LD_LIBRARY_PATH="/usr/lib/gcc-snapshot/lib:$LD_LIBRARY_PATH"
- autoreconf -vfi
- VERSION=`cat VERSION`
- tar xvf spot-$VERSION.tar.gz
- cd spot-$VERSION
- ./configure --with-included-ltdl CXX='g++'
- make
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
allow_failure: true
artifacts:
when: always
paths:
- ./spot-*/_build/sub/tests/*/*.log
- ./*.log
- doc/spot.html/
- doc/userdoc/
- ./*.tar.gz
- spot-*/tests/*/*.log
- spot-*/*.log
alpine-gcc:
stage: build
@ -106,12 +147,12 @@ alpine-gcc:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/alpine
image: gitlab-registry.lre.epita.fr/spot/buildenv/alpine
script:
- autoreconf -vfi
- ./configure
- make
- make distcheck || { chmod -R u+w ./spot-*; false; }
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-pthread' || { chmod -R u+w ./spot-*; false; }
artifacts:
when: always
paths:
@ -125,7 +166,7 @@ arch-clang:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
script:
- autoreconf -vfi
- ./configure --prefix ~/install_dir CC='clang -Qunused-arguments' CXX='clang++ -Qunused-arguments' --enable-devel --enable-c++20 --enable-doxygen
@ -138,22 +179,30 @@ arch-clang:
- ./*.log
arch-gcc-glibcxxdebug:
stage: build
stage: build2
needs:
- job: make-dist
artifacts: true
variables:
GIT_STRATEGY: none
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
script:
- autoreconf -vfi
- ./configure --enable-devel --enable-c++20 --enable-glibcxx-debug
- VERSION=`cat VERSION`
- tar xvf spot-$VERSION.tar.gz
- mkdir build-$VERSION
- cd build-$VERSION
- ../spot-$VERSION/configure --enable-devel --enable-c++20 --enable-glibcxx-debug
- make
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-devel --enable-c++20 --enable-glibcxx-debug'
artifacts:
when: on_failure
paths:
- ./spot-*/_build/sub/tests/*/*.log
- ./*.log
- build-*/spot-*/_build/sub/tests/*/*.log
- build-*/*.log
mingw-shared:
stage: build2
@ -161,15 +210,17 @@ mingw-shared:
# We start from the tarball generated from a non-cross-compiling
# job, so that all generated files are included, especially those
# built from the executables.
- job: debian-stable-gcc
- job: make-dist
artifacts: true
variables:
GIT_STRATEGY: none
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- VERSION=`autoconf --trace='AC_INIT:$2'`
- VERSION=`cat VERSION`
- tar xvf spot-$VERSION.tar.gz
- cd spot-$VERSION
- ./configure CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++-posix --host i686-w64-mingw32 --disable-python
@ -186,15 +237,17 @@ mingw-static:
# We start from the tarball generated from a non-cross-compiling
# job, so that all generated files are included, especially those
# built from the executables.
- job: debian-stable-gcc
- job: make-dist
artifacts: true
variables:
GIT_STRATEGY: none
only:
- branches
except:
- /wip/
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
script:
- VERSION=`autoconf --trace='AC_INIT:$2'`
- VERSION=`cat VERSION`
- tar xvf spot-$VERSION.tar.gz
- cd spot-$VERSION
- mkdir install_dir
@ -214,17 +267,19 @@ mingw-static:
debpkg-stable:
stage: build
variables:
GIT_STRATEGY: none
only:
- /-deb$/
- master
- next
- stable
script:
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
- vol=spot-stable-$CI_COMMIT_SHA
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
- docker volume create $vol
- exitcode=0
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
- docker cp helper-$vol:/build/result _build_stable || exitcode=$?
- docker rm helper-$vol || exitcode=$?
- docker volume rm $vol || exitcode=$?
@ -238,6 +293,8 @@ debpkg-stable:
debpkg-stable-i386:
stage: build2
variables:
GIT_STRATEGY: none
only:
- /-deb$/
- master
@ -246,11 +303,11 @@ debpkg-stable-i386:
tags: ["x86"]
needs: ["debpkg-stable"]
script:
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386:stable
- vol=spot-stable-$CI_COMMIT_SHA
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386:stable
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
- docker volume create $vol
- exitcode=0
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386:stable ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386:stable ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
- docker cp _build_stable/. helper-$vol:/build/result || exitcode=$?
- rm -rf _build_stable
- docker start -a helper-$vol || exitcode=$?
@ -267,15 +324,17 @@ debpkg-stable-i386:
debpkg-unstable:
stage: build
variables:
GIT_STRATEGY: none
only:
- /-deb$/
- next
script:
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian
- vol=spot-unstable-$CI_COMMIT_SHA
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
- docker volume create $vol
- exitcode=0
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
- docker cp helper-$vol:/build/result _build_unstable || exitcode=$?
- docker rm helper-$vol || exitcode=$?
- docker volume rm $vol || exitcode=$?
@ -289,17 +348,19 @@ debpkg-unstable:
debpkg-unstable-i386:
stage: build2
variables:
GIT_STRATEGY: none
only:
- /-deb$/
- next
tags: ["x86"]
needs: ["debpkg-unstable"]
script:
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386
- vol=spot-unstable-$CI_COMMIT_SHA
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
- docker volume create $vol
- exitcode=0
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386 ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386 ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
- docker cp _build_unstable/. helper-$vol:/build/result || exitcode=$?
- rm -rf _build_unstable
- docker start -a helper-$vol || exitcode=$?
@ -321,7 +382,7 @@ rpm-pkg:
- master
- next
- stable
image: gitlab-registry.lrde.epita.fr/spot/buildenv/fedora
image: gitlab-registry.lre.epita.fr/spot/buildenv/fedora
script:
- autoreconf -vfi
- ./configure
@ -340,6 +401,8 @@ rpm-pkg:
publish-rpm:
stage: publish
variables:
GIT_STRATEGY: none
only:
- /-rpm$/
- next
@ -350,6 +413,7 @@ publish-rpm:
- rpm-pkg
script:
- case $CI_COMMIT_REF_NAME in stable) rput fedora stable *.rpm;; next) rput fedora unstable *.rpm;; esac
- rm -rf ./*
publish-stable:
only:
@ -357,15 +421,23 @@ publish-stable:
tags:
- dput
stage: publish
variables:
GIT_STRATEGY: none
dependencies:
- debpkg-stable-i386
- make-dist
script:
- cd _build_stable
- ls -l
- dput lrde *.changes
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
- cd ..
- ls -l
- tgz=`ls spot-*.tar.* | head -n 1`
- case $tgz in *[0-9].tar.*) scp $tgz doc@perso:/var/www/dload/spot/;; esac
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=stable" https://gitlab.lrde.epita.fr/api/v4/projects/131/trigger/pipeline
- rm -rf ./*
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=stable" https://gitlab.lre.epita.fr/api/v4/projects/131/trigger/pipeline
- curl -X POST "https://archive.softwareheritage.org/api/1/origin/save/git/url/https://gitlab.lre.epita.fr/spot/spot/"
- curl "https://web.archive.org/save/https://www.lrde.epita.fr/dload/spot/$tgz"
publish-unstable:
only:
@ -373,14 +445,18 @@ publish-unstable:
tags:
- dput
stage: publish
variables:
GIT_STRATEGY: none
dependencies:
- debpkg-unstable-i386
script:
- cd _build_unstable
- ls -l
- dput lrde *.changes
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=next" https://gitlab.lrde.epita.fr/api/v4/projects/131/trigger/pipeline
- curl -X POST -F ref=master -F token=$TRIGGER_SANDBOX https://gitlab.lrde.epita.fr/api/v4/projects/181/trigger/pipeline
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
- cd ..
- rm -rf _build_unstable
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=next" https://gitlab.lre.epita.fr/api/v4/projects/131/trigger/pipeline
- curl -X POST -F ref=master -F token=$TRIGGER_SANDBOX https://gitlab.lre.epita.fr/api/v4/projects/181/trigger/pipeline
raspbian:
stage: build

20
.mailmap Normal file
View file

@ -0,0 +1,20 @@
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@gaborone.lrde.epita.fr>
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@pret-move.rsr.lip6.fr>
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@gaborone.lrde.epita.fr>
Antoine Martin <amartin@lrde.epita.fr> <antoine97.martin@gmail.com>
Arthur Remaud <aremaud@lrde.epita.fr> <aremaud@avignon.lrde.epita.fr>
Arthur Remaud <aremaud@lrde.epita.fr> <aremaud@node7.lrde.epita.fr>
Damien Lefortier <dam@lrde.epita.fr> <eg@feather.vurt>
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@bosc-guerard.lrde.epita.fr>
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@scalea.lrde.epita.fr>
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@lrde.epita.fr>
Guillaume Sadegh <sadegh@lrde.epita.fr>
Guillaume Sadegh <sadegh@lrde.epita.fr> <guillaume.sadegh@lrde.epita.fr>
Henrich Lauko <xlauko@mail.muni.cz>
Henrich Lauko <xlauko@mail.muni.cz> <henrich.lau@gmail.com>
Jerome Dubois <jdubois@lrde.epita.fr> Jérôme Dubois <jdubois@lrde.epita.fr>
Philipp Schlehuber-Caissier <philipp@lrde.epita.fr>
Thibaud Michaud <thibaud.michaud@epita.fr> <michau_n@epita.fr>
Thomas Badie <badie@lrde.epita.fr> <badie@champoteux.lrde.epita.fr>
Rachid Rebiha <rebiha>
Thomas Martinez <martinez>

50
HACKING
View file

@ -5,11 +5,11 @@ Bootstraping from the GIT repository
Spot's gitlab page is at
https://gitlab.lrde.epita.fr/spot/spot
https://gitlab.lre.epita.fr/spot/spot
The GIT repository can be cloned with
git clone https://gitlab.lrde.epita.fr/spot/spot.git
git clone https://gitlab.lre.epita.fr/spot/spot.git
Some files in SPOT's source tree are generated. They are distributed
so that users do not need to install tools to rebuild them, but we
@ -25,7 +25,7 @@ since the generated files they produce are distributed.)
GNU Automake >= 1.11
GNU Libtool >= 2.4
GNU Flex >= 2.6
GNU Bison >= 3.0
GNU Bison >= 3.3
GNU Emacs (preferably >= 24 but it may work with older versions)
org-mode >= 9.1 (the version that comes bundled with your emacs
version is likely out-of-date; but distribution often have
@ -290,8 +290,8 @@ would understand with:
make check LOG_DRIVER=$PWD/tools/test-driver-teamcity
Coding conventions
==================
C++ Coding conventions
======================
Here some of the conventions we follow in Spot, so that the code looks
homogeneous. Please follow these strictly. Since this is free
@ -682,3 +682,43 @@ Other style recommandations
* Always code as if the person who ends up maintaining your code is
a violent psychopath who knows where you live.
Coding conventions for Python Tests
===================================
Unless you have some specific reason to write test cases in C++ (for
instance do test some specific C++ constructions, or to use valgrind),
prefer writing test cases in Python. Writing test cases in C++
requires some compilation, which slows down the test suite. Doing the
same test in Python is therefore faster, and it has the added benefit
of ensuring that the Python bindings works.
We have two types of Python tests: Python scripts or jupyter
notebooks. Jupyter notebooks are usually used for a sequence of
examples and comments that can also serve as part of the
documentation. Such jupyter notebooks should be added to the list of
code examples in doc/org/tut.org. Testing a notebook is done by the
tests/python/ipnbdoctest.py scripts, which evaluate each cells, and
checks that the obtainted result is equivalent to the result saved in
the notebook. The process is a bit slow, so plain Python scripts
should be prefered for most tests.
If you do need a notebook to tests Jupyter-specific code but this
notebook should not be shown in the documentation, use a filename
starting with '_'.
Tests written as Python scripts should follow the same convention as
shell scripts: exit 0 for PASS, exit 77 for SKIP, and any other exit
code for FAIL.
Do not use assert() in those scripts, as (1) asserts can be disabled,
and (2) they provide poor insights in case of failures. Instead do
from unittest import TestCase
tc = TestCase()
and then use tc.assertTrue(...), tc.assertEqual(..., ...),
tc.assertIn(..., ...), etc. In case of failures, those will print
useful messages in the trace of the tests. For instance multiline
strings that should have been equal will be presented with a diff.

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2011-2017, 2020 Laboratoire de Recherche et Développement
## Copyright (C) 2011-2017, 2020, 2022 Laboratoire de Recherche et Développement
## de l'Epita (LRDE).
## Copyright (C) 2003, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -36,8 +36,9 @@ DOC_SUBDIR = doc
SUBDIRS = picosat buddy lib ltdl spot bin tests $(PYTHON_SUBDIR) $(DOC_SUBDIR) \
$(NEVER_SUBDIRS)
UTF8 = utf8/README.md utf8/utf8.h \
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
UTF8 = utf8/README.md utf8/LICENSE utf8/utf8.h \
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h \
utf8/utf8/cpp11.h utf8/utf8/cpp17.h
DEBIAN = \
debian/changelog \
@ -68,7 +69,8 @@ EXTRA_DIST = HACKING ChangeLog.1 tools/gitlog-to-changelog \
tools/help2man tools/man2html.pl \
tools/test-driver-teamcity $(UTF8) $(DEBIAN) \
m4/gnulib-cache.m4 .dir-locals.el \
spot.spec spot.spec.in
spot.spec spot.spec.in \
default.nix default.nix.in
dist-hook: gen-ChangeLog
@ -114,3 +116,6 @@ deb: dist
spot.spec: configure.ac spot.spec.in
sed 's/[@]VERSION[@]/$(VERSION)/;s/[@]GITPATCH[@]/@@@$(GITPATCH)/;s/@@@\.//' spot.spec.in > $@.tmp && mv $@.tmp $@
default.nix: configure.ac default.nix.in
sed 's/[@]VERSION[@]/$(VERSION)/' default.nix.in > $@.tmp && mv $@.tmp $@

338
NEWS
View file

@ -1,16 +1,203 @@
New in spot 2.10.4.dev (net yet released)
New in spot 2.11.5.dev (not yet released)
Library:
- The following new trivial simplifications have been implemented for SEREs:
- f|[+] = [+] if f rejects [*0]
- f|[*] = [*] if f accepts [*0]
- f&&[+] = f if f rejects [*0]
- b:b[*i..j] = b[*max(i,1)..j]
- b[*i..j]:b[*k..l] = b[*max(i,1)+max(k,1)-1, j+l-1]
- The HOA parser is a bit smarter when merging multiple initial
states into a single initial state (Spot's automaton class
supports only one): it now reuse the edges leaving initial states
without incoming transitions.
- spot::bdd_to_cnf_formula() is a new variant of spot::bdd_to_formula()
that converts a BDD into a CNF instead of a DNF.
New in spot 2.11.5 (2023-04-20)
Bug fixes:
- Fix spurious failure of ltlsynt2.test when Python is not installed
(issue #530).
- Building from the git repository would fail to report a missing
emacs (issue #528).
- Fix exception raised by aut1.intersecting_run(aut2).as_twa()
because the run did not match transitions present in aut1
verbatim. We also changed the behavior of as_twa() to not merge
identical states.
- Fix segfaults occuring in determinization of 1-state terminal
automata.
- Fix incorrect assertion in game solver when the edge vector
contains deleted transitions.
New in spot 2.11.4 (2023-02-10)
Python:
- spot.acd() no longer depends on jQuery for interactivity.
Bug fixes:
- When merging initial states from state-based automata with
multiple initial states (because Spot supports only one), the HOA
parser could break state-based acceptance. (Issue #522.)
- autfilt --highlight-word refused to work on automata with Fin
acceptance for historical reasons, however the code has been
perfectly able to handle this for a while. (Issue #523.)
- delay_branching_here(), a new optimization of Spot 2.11 had an
incorrect handling of states without successors, causing some
segfaults. (Issue #524.)
- Running delay_branching_here() on state-based automata (this was not
done in Spot so far) may require the output to use transition-based
acceptance. (Issue #525.)
- to_finite(), introduce in 2.11, had a bug that could break the
completeness of automata and trigger an exception from the HOA
printer. (Issue #526.)
New in spot 2.11.3 (2022-12-09)
Bug fixes:
- Automata-based implication checks, used to simplify formulas were
slower than necessary because the translator was configured to
favor determinism unnecessarily. (Issue #521.)
- Automata-based implication checks for f&g and f|g could be
very slow when those n-ary operator had two many arguments.
They have been limited to 16 operands, but this value can be changed
with option -x tls-max-ops=N. (Issue #521 too.)
- Running ltl_to_tgba_fm() with an output_aborter (which is done
during automata-based implication checks) would leak memory on
abort.
- configure --with-pythondir should also redefine pyexecdir,
otherwise, libraries get installed in the wrong place on Debian.
(Issue #512.)
- The HOA parser used to silently declare unused and undefined states
(e.g., when the State: header declare many more states than the body
of the file). It now warns about those.
- 'autfilt -c ...' should display a match count even in presence of
parse errors.
- Calling solve_parity_game() multiple times on the same automaton
used to append the new strategy to the existing one instead of
overwriting it.
New in spot 2.11.2 (2022-10-26)
Command-line tools:
- The --stats specifications %s, %e, %t for printing the number of
(reachable) states, edges, and transitions, learned to support
options [r], [u], [a] to indicate if only reachable, unreachable,
or all elements should be counted.
Library:
- spot::reduce_parity() now has a "layered" option to force all
transition in the same parity layer to receive the same color;
like acd_transform() would do.
Bugs fixed:
- Fix pkg-config files containing @LIBSPOT_PTHREAD@ (issue #520)
- spot::relabel_bse() was incorrectly relabeling some dependent
Boolean subexpressions in SERE. (Note that this had no
consequence on automata translated from those SERE.)
New in spot 2.11.1 (2022-10-10)
Bugs fixed:
- Fix a build issue preventing the update of website (issue #516).
- Fix a compilation error with clang-14 on FreeBSD (issue #515).
New in spot 2.11 (2022-10-08)
Build:
- configure will now diagnose situations where Python bindings will
be installed in a directory that is not part of Python's search
path. A new configure option --with-pythondir can be used to
modify this installation path.
- A new configure option --enable-pthread enables the compilation of
Spot with -pthread, and render available the parallel version of
some algorithms. If Spot is compiled with -pthread enabled, any
user linking with Spot should also link with the pthread library.
In order to not break existing build setups using Spot, this
option is currently disabled by default in this release. We plan
to turn it on by default in some future release. Third-party
project using Spot may want to start linking with -pthread in
prevision for this change.
Command-line tools:
- autfilt has a new options --aliases=drop|keep to specify
if the output code should attempt to preserve aliases
if the HOA printer should attempt to preserve aliases
present in the HOA input. This defaults to "keep".
- autfilt has a new --to-finite option, illustrated on
https://spot.lrde.epita.fr/tut12.html
- ltlfilt has a new --sonf option to produce a formula's Suffix
Operator Normal Form, described in [cimatti.06.fmcad]. The
associated option --sonf-aps allows listing the newly introduced
atomic propositions.
- autcross learned a --language-complemented option to assist in the
case one is testing tools that complement automata. (issue #504).
- ltlsynt has a new option --tlsf that takes the filename of a TLSF
specification and calls syfco (which must be installed) to convert
it into an LTL formula.
- ltlsynt has a new option --from-pgame that takes a parity game in
extended HOA format, as used in the Synthesis Competition.
- ltlsynt has a new option --hide-status to hide the REALIZABLE or
UNREALIZABLE output expected by SYNTCOMP. (This line is
superfluous, because the exit status of ltlsynt already indicate
whether the formula is realizable or not.)
- ltlsynt has a new option --dot to request GraphViz output instead
of most output. This works for displaying Mealy machines, games,
or AIG circuits. See https://spot.lrde.epita.fr/ltlsynt.html for
examples.
- genaut learned the --cyclist-trace-nba and --cyclist-proof-dba
options. Those are used to generate pairs of automata that should
include each other, and are used to show a regression (in speed)
present in Spot 2.10.x and fixed in 2.11.
- genltl learned --eil-gsi to generate a familly a function whose
translation and simplification used to be very slow. In particular
genltl --eil-gsi=23 | ltlfilt --from-ltlf | ltl2tgba
was reported as taking 9 days. This is now instantaneous.
Library:
- The new function suffix_operator_normal_form() implements
transformation of formulas to Suffix Operator Normal Form,
described in [cimatti.06.fmcad].
- "original-classes" is a new named property similar to
"original-states". It maps an each state to an unsigned integer
such that if two classes are in the same class, they are expected
@ -21,16 +208,20 @@ New in spot 2.10.4.dev (net yet released)
- tgba_determinize() learned to fill the "original-classes" property.
States of the determinized automaton that correspond to the same
subset of states of the original automaton belong to the same
class. Filling this property is only done on demand has it inccurs
on small overhead.
class. Filling this property is only done on demand as it inccurs
a small overhead.
- sbacc() learned to take the "original-classes" property into
account and preserve it.
account and to preserve it.
- The HOA parser and printer learned to map the synthesis-outputs
property of Spot to the controllable-AP header for the Extended
HOA format used in SyntComp. https://arxiv.org/abs/1912.05793
- The automaton parser learned to parse games in the PGSolver format.
See the bottom of https://spot.lrde.epita.fr/ipynb/games.html for
an example.
- "aliases" is a new named property that is filled by the HOA parser
using the list of aliases declared in the HOA file, and then used
by the HOA printer on a best-effort basis. Aliases can be used to
@ -57,14 +248,147 @@ New in spot 2.10.4.dev (net yet released)
- purge_dead_states() will now also remove edges labeled by false
(except self-loops).
- When parsing formulas with a huge number of operands for an n-ary
operator (for instance 'p1 | p2 | ... | p1000') the LTL parser
would construct that formula two operand at a time, and the
formula constructor for that operator would be responsible for
inlining, sorting, deduplicating, ... all operands at each step.
This resulted in a worst-than-quadratic slowdown. This is now
averted in the parser by delaying the construction of such n-ary
nodes until all children are known.
- complement() used to always turn tautological acceptance conditions
into Büchi. It now only does that if the automaton is modified.
- The zielonka_tree construction was optimized using the same
memoization trick that is used in ACD. Additionally it can now be
run with additional options to abort when the tree as an unwanted
shape, or to turn the tree into a DAG.
- contains() can now take a twa as a second argument, not just a
twa_graph. This allows for instance to do contains(ltl, kripke)
to obtain a simple model checker (that returns true or false,
without counterexample).
- degeneralize() and degeneralize_tba() learned to work on
generalized-co-Büchi as well.
- product() learned that the product of two co-Büchi automata
is a co-Büchi automaton. And product_or() learned that the
"or"-product of two Büchi automata is a Büchi automaton.
- spot::postprocessor has a new extra option "merge-states-min" that
indicates above how many states twa_graph::merge_states() (which
perform a very cheap pass to fuse states with identicall
succesors) should be called before running simulation-based
reductions.
- A new function delay_branching_here(aut) can be used to simplify
some non-deterministic branching. If two transitions (q₁,,M,q₂)
and (q₁,,M,q₃) differ only by their destination state, and are
the only incoming transitions of their destination states, then q₂
and q₃ can be merged (taking the union of their outgoing
transitions). This is cheap function is automatically called by
spot::translate() after translation of a formula to GBA, before
further simplification. This was introduced to help with automata
produced from formulas output by "genltl --eil-gsi" (see above).
- spot::postprocessor has new configuration variable branch-post
that can be used to control the use of branching-postponement
(disabled by default) or delayed-branching (see above, enabled by
default). See the spot-x(7) man page for details.
- spot::postprocessor is now using acd_transform() by default when
building parity automata. Setting option "acd=0" will revert
to using "to_parity()" instead.
- to_parity() has been almost entirely rewritten and is a bit
faster.
- When asked to build parity automata, spot::translator is now more
aggressively using LTL decomposition, as done in the Generic
acceptance case before paritizing the result. This results in
much smaller automata in many cases.
- spot::parallel_policy is an object that can be passed to some
algorithm to specify how many threads can be used if Spot has been
compiled with --enable-pthread. Currently, only
twa_graph::merge_states() supports it.
Python bindings:
- The to_str() method of automata can now export a parity game into
the PG-Solver format by passing option 'pg'. See
https://spot.lrde.epita.fr/ipynb/games.html for an example.
Deprectation notice:
- spot::pg_print() has been deprecated in favor of spot::print_pg()
for consistency with the rest of the API.
Bugs fixed:
- calling twa_graph::new_univ_edge(src, begin, end, cond, acc) could
produce unexpected result if begin and end where already pointing
into the universal edge vector, since the later can be
reallocated during that process.
- Printing an alternating automaton with print_dot() using 'u' to
hide true state could produce some incorrect GraphViz output if
the automaton as a true state as part of a universal group.
- Due to an optimization introduces in 2.10 to parse HOA label more
efficiently, the automaton parser could crash when parsing random
input (not HOA) containing '[' (issue #509).
New in spot 2.10.6 (2022-05-18)
Bugs fixed:
- Fix compilation error on MacOS X.
- Using -Ffile/N to read column N of a CSV file would not reset the
/N specification for the next file.
- make_twa_graph() will now preserve state number when copying a
kripke_graph object. As a consequence, print_dot() and
print_hoa() will now use state numbers matching those of the
kripke_graph (issue #505).
- Fix several compilation warning introduced by newer versions
of GCC and Clang.
New in spot 2.10.5 (2022-05-03)
Bugs fixed:
- reduce_parity() produced incorrect results when applied to
automata with deleted edges.
- work around a portability issue in Flex 2.6.4 preventing
- An optimization of Zielonka could result in incorrect results
in some cases.
- ltlsynt --print-pg incorrectly solved the game in addition to
printing it.
- ltlsynt would fail if only one of --ins or --outs was set, and
if it was set empty.
- Work around a portability issue in Flex 2.6.4 preventing
compilation on OpenBSD.
- Do not use the seq command in test cases, it is not available
everywhere.
- Do not erase the previous contents of the PYTHONPATH environment
variable when running tests, prepend to it instead.
- Simplify Debian instructions for LTO build to work around newer
libtool version.
- Fix invalid read in digraph::sort_edges_of_(), currently unused in
Spot.
New in spot 2.10.4 (2022-02-01)
Bug fixed:
@ -1424,7 +1748,7 @@ New in spot 2.6.2 (2018-09-28)
- We no longer distribute the Python-based CGI script + javascript
code for the online translator. Its replacement has its own
repository: https://gitlab.lrde.epita.fr/spot/spot-web-app/
repository: https://gitlab.lre.epita.fr/spot/spot-web-app/
Library:

50
README
View file

@ -110,16 +110,16 @@ Spot follows the traditional `./configure && make && make check &&
make install' process. People unfamiliar with the GNU Build System
should read the file INSTALL for generic instructions.
If you plan to use the Python binding, we recommend you use one
of the following --prefix options when calling configure:
If you plan to use the Python bindings, we recommend you use the
following --prefix options when calling configure:
--prefix /usr
--prefix /usr/local (the default)
--prefix ~/.local (if you do not have root permissions)
--prefix ~/.local
The reason is that all these locations are usually automatically
searched by Python. If you use a different prefix directory, you may
have to tune the PYTHONPATH environment variable.
The reason is that ~/.local/lib/python3.X/site-packages, where Spot's
Python bindings will be installed, is automatically searched by
Python. If you use a different prefix directory, you may have to tune
the PYTHONPATH environment variable, or use the --with-pythondir
option to specify different installation paths.
In addition to its usual options, ./configure will accept some
flags specific to Spot:
@ -173,6 +173,12 @@ flags specific to Spot:
client code should be compiled with -D_GLIBCXX_DEBUG as well. This
options should normally only be useful to run Spot's test-suite.
--enable-pthread
Build and link with the -pthread option, and activate a few
parallel variants of the algorithms. This is currently disabled
by default, as it require all third-party tools using Spot to
build with -pthread as well.
--enable-c++20
Build everything in C++20 mode. We use that in our build farm to
ensure that Spot can be used in C++20 projects as well.
@ -244,17 +250,31 @@ To test the Python bindings, try running
>>> import spot
>>> print(spot.version())
If you installed Spot with a prefix that is not one of those suggested
in the "Building and installing" section, it is likely that the above
import statement will fail to locate the spot package. You can show
the list of directories that are searched by Python using:
If you installed Spot with a prefix that is not searched by Python by
default it is likely that the above import statement will fail to
locate the spot package. You can show the list of directories that
are searched by Python using:
% python3
>>> import sys
>>> print(sys.path)
And you can modify that list of searched directories using the
PYTHONPATH environment variable.
PYTHONPATH environment variable. Alternatively, you can instruct Spot
to install its Python files in one of those directory using the
--with-pythondir configure option. As an example, an issue in
distributions derived from Debian is that if you run
./configure && make && make install
Python files get installed in /usr/local/lib/python3.X/site-packages
while Debian's version of Python only looks for them into
/usr/local/lib/python3.X/dist-packages instead. You can fix that by
instructing configure that you want packages installed into the right
directory instead:
./configure --with-pythondir=/usr/local/lib/python3.X/dist-packages \
&& make && make install
To test if man pages can be found, simply try:
@ -319,13 +339,13 @@ bench/ Benchmarks for ...
wdba/ ... WDBA minimization (for obligation properties).
python/ Python bindings for Spot and BuDDy
Third party software
Third-party software
--------------------
buddy/ A customized version of BuDDy 2.3 (a BDD library).
ltdl/ Libtool's portable dlopen() wrapper library.
lib/ Gnulib's portability modules.
utf8/ Nemanja Trifunovic's utf-8 routines.
utf8/ Trifunovic's utf-8 routines. https://github.com/nemtrif/utfcpp
elisp/ Related emacs modes, used for building the documentation.
picosat/ A distribution of PicoSAT 965 (a satsolver library).
spot/bricks/ A collection of useful C++ code provided by DiVinE

12
THANKS
View file

@ -11,9 +11,12 @@ Christian Dax
Christopher Ziegler
Clément Tamines
David Müller
Dávid Smolka
Edmond Irani Liu
Ernesto Posse
Étienne Renault
Fabrice Kordon
Fangyi Zhou
Felix Klaedtke
Florian Perlié-Long
František Blahoudek
@ -21,6 +24,7 @@ Gerard J. Holzmann
Hashim Ali
Heikki Tauriainen
Henrich Lauko
Jacopo Binchi
Jan Strejček
Jean-Michel Couvreur
Jean-Michel Ilié
@ -41,14 +45,18 @@ Michael Weber
Mikuláš Klokočka
Ming-Hsien Tsai
Nikos Gorogiannis
Ondřej Lengál
Paul Guénézan
Pierre Ganty
Raven Beutner
Reuben Rowe
Roei Nahum
Rüdiger Ehlers
Silien Hong
Simon Jantsch
Shachar Itzhaky
Shengping Shaw
Shufang Zhu
Silien Hong
Simon Jantsch
Sonali Dutta
Tereza Šťastná
Tobias Meggendorfer.

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (C) 2016-2018 Laboratoire de Recherche et Développement de
# Copyright (C) 2016-2018, 2023 Laboratoire de Recherche et Développement de
# l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
@ -55,12 +55,12 @@ class BenchConfig(object):
if line[0] == '#' or line.isspace():
continue
elif line[0:2] == "sh":
sh = re.search('sh (.+?)$', line).group(1)
sh = re.search('sh (.+)$', line).group(1)
continue
else:
name = re.search('(.+?):', line).group(1)
code = re.search(':(.+?)>', line).group(1)
xoptions = re.search('>(.+?)$', line).group(1)
xoptions = re.search('>(.+)$', line).group(1)
b = Bench(name=name, code=code, xoptions=xoptions)
self.l.append(b)
self.sh.append(sh)

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015, 2016, 2017 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2014, 2015, 2016, 2017, 2022 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -28,7 +28,7 @@
#include <spot/misc/timer.hh>
#include <argp.h>
const char argp_program_doc[] ="";
static const char argp_program_doc[] = "";
const struct argp_child children[] =
{

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017-2020 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2017-2020, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -51,7 +51,7 @@
#include <spot/misc/escape.hh>
#include <spot/misc/timer.hh>
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Call several tools that process automata and cross-compare their output \
to detect bugs, or to gather statistics. The list of automata to use \
should be supplied on standard input, or using the -F option.\v\
@ -64,6 +64,7 @@ Exit status:\n\
enum {
OPT_BOGUS = 256,
OPT_COMPLEMENTED,
OPT_CSV,
OPT_HIGH,
OPT_FAIL_ON_TIMEOUT,
@ -94,6 +95,8 @@ static const argp_option options[] =
"consider timeouts as errors", 0 },
{ "language-preserved", OPT_LANG, nullptr, 0,
"expect that each tool preserves the input language", 0 },
{ "language-complemented", OPT_COMPLEMENTED, nullptr, 0,
"expect that each tool complements the input language", 0 },
{ "no-checks", OPT_NOCHECKS, nullptr, 0,
"do not perform any sanity checks", 0 },
/**************************************************/
@ -144,6 +147,7 @@ static bool fail_on_timeout = false;
static bool stop_on_error = false;
static bool no_checks = false;
static bool opt_language_preserved = false;
static bool opt_language_complemented = false;
static bool opt_omit = false;
static const char* csv_output = nullptr;
static unsigned round_num = 0;
@ -158,7 +162,7 @@ parse_opt(int key, char* arg, struct argp_state*)
switch (key)
{
case 'F':
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
case 'q':
quiet = true;
@ -170,6 +174,9 @@ parse_opt(int key, char* arg, struct argp_state*)
bogus_output_filename = arg;
break;
}
case OPT_COMPLEMENTED:
opt_language_complemented = true;
break;
case OPT_CSV:
csv_output = arg ? arg : "-";
break;
@ -209,7 +216,7 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
if (arg[0] == '-' && !arg[1])
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
else
tools_push_autproc(arg);
break;
@ -338,7 +345,6 @@ struct in_statistics
struct out_statistics
{
// If OK is false, output statistics are not available.
bool ok;
const char* status_str;
@ -346,7 +352,7 @@ struct out_statistics
double time;
aut_statistics output;
out_statistics()
out_statistics() noexcept
: ok(false),
status_str(nullptr),
status_code(0),
@ -533,25 +539,32 @@ namespace
const spot::const_twa_graph_ptr& aut_j,
size_t i, size_t j)
{
auto is_really_comp = [lc = opt_language_complemented,
ts = tools.size()](unsigned i) {
return lc && i == ts;
};
if (aut_i->num_sets() + aut_j->num_sets() >
spot::acc_cond::mark_t::max_accsets())
{
if (!quiet)
std::cerr << "info: building " << autname(i)
<< '*' << autname(j, true)
std::cerr << "info: building " << autname(i, is_really_comp(i))
<< '*' << autname(j, !is_really_comp(j))
<< " requires more acceptance sets than supported\n";
return false;
}
if (verbose)
std::cerr << "info: check_empty "
<< autname(i) << '*' << autname(j, true) << '\n';
<< autname(i, is_really_comp(i))
<< '*' << autname(j, !is_really_comp(j)) << '\n';
auto w = aut_i->intersecting_word(aut_j);
if (w)
{
std::ostream& err = global_error();
err << "error: " << autname(i) << '*' << autname(j, true)
err << "error: " << autname(i, is_really_comp(i))
<< '*' << autname(j, !is_really_comp(j))
<< (" is nonempty; both automata accept the infinite word:\n"
" ");
example() << *w << '\n';
@ -600,7 +613,7 @@ namespace
return src.str();
}();
input_statistics.push_back(in_statistics());
input_statistics.emplace_back(in_statistics());
input_statistics[round_num].input_source = std::move(source);
if (auto name = input->get_named_prop<std::string>("automaton-name"))
@ -621,12 +634,15 @@ namespace
int problems = 0;
size_t m = tools.size();
size_t mi = m + opt_language_preserved;
size_t mi = m + opt_language_preserved + opt_language_complemented;
std::vector<spot::twa_graph_ptr> pos(mi);
std::vector<spot::twa_graph_ptr> neg(mi);
vector_tool_statistics stats(m);
if (opt_language_preserved)
// For --language-complemented, we store the input automata in
// pos and will compute its complement in neg. Before running
// checks we will swap both automata.
if (opt_language_preserved || opt_language_complemented)
pos[mi - 1] = input;
if (verbose)
@ -642,7 +658,7 @@ namespace
problems += prob;
}
spot::cleanup_tmpfiles();
output_statistics.push_back(std::move(stats));
output_statistics.emplace_back(std::move(stats));
if (verbose)
{
@ -718,6 +734,9 @@ namespace
};
}
if (opt_language_complemented)
std::swap(pos[mi - 1], neg[mi - 1]);
// Just make a circular implication check
// A0 <= A1, A1 <= A2, ..., AN <= A0
unsigned ok = 0;
@ -824,10 +843,15 @@ main(int argc, char** argv)
check_no_automaton();
if (s == 1 && !opt_language_preserved && !no_checks)
error(2, 0, "Since --language-preserved is not used, you need "
"at least two tools to compare.");
if (s == 1 && !no_checks
&& !opt_language_preserved
&& !opt_language_complemented)
error(2, 0, "Since --language-preserved and --language-complemented "
"are not used, you need at least two tools to compare.");
if (opt_language_preserved && opt_language_complemented)
error(2, 0, "Options --language-preserved and --language-complemented "
"are incompatible.");
setup_color();
setup_sig_handler();

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -75,7 +75,7 @@
#include <spot/twaalgos/sum.hh>
#include <spot/twaalgos/totgba.hh>
static const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Convert, transform, and filter omega-automata.\v\
Exit status:\n\
0 if some automata were output\n\
@ -448,7 +448,7 @@ struct canon_aut
std::vector<tr_t> edges;
std::string acc;
canon_aut(const spot::const_twa_graph_ptr& aut)
explicit canon_aut(const spot::const_twa_graph_ptr& aut)
: num_states(aut->num_states())
, edges(aut->edge_vector().begin() + 1,
aut->edge_vector().end())
@ -713,10 +713,12 @@ ensure_deterministic(const spot::twa_graph_ptr& aut, bool nonalt = false)
return p.run(aut);
}
static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
static spot::twa_graph_ptr
ensure_tba(spot::twa_graph_ptr aut,
spot::postprocessor::output_type type = spot::postprocessor::Buchi)
{
spot::postprocessor p;
p.set_type(spot::postprocessor::Buchi);
p.set_type(type);
p.set_pref(spot::postprocessor::Any);
p.set_level(spot::postprocessor::Low);
return p.run(aut);
@ -726,12 +728,14 @@ static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
static spot::twa_graph_ptr
product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
{
if ((type == spot::postprocessor::Buchi)
&& (left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets()))
// Are we likely to fail because of too many colors?
if ((left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets())
&& (type == spot::postprocessor::Buchi
|| type == spot::postprocessor::CoBuchi))
{
left = ensure_tba(left);
right = ensure_tba(right);
left = ensure_tba(left, type);
right = ensure_tba(right, type);
}
return spot::product(left, right);
}
@ -739,16 +743,34 @@ product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
static spot::twa_graph_ptr
product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
{
if ((type == spot::postprocessor::Buchi)
&& (left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets()))
// Are we likely to fail because of too many colors?
if ((left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets())
&& (type == spot::postprocessor::Buchi
|| type == spot::postprocessor::CoBuchi))
{
left = ensure_tba(left);
right = ensure_tba(right);
left = ensure_tba(left, type);
right = ensure_tba(right, type);
}
return spot::product_or(left, right);
}
static spot::twa_graph_ptr
word_to_aut(const char* word, const char *argname)
{
try
{
return spot::parse_word(word, opt->dict)->as_automaton();
}
catch (const spot::parse_error& e)
{
error(2, 0, "failed to parse the argument of --%s:\n%s",
argname, e.what());
}
SPOT_UNREACHABLE();
return nullptr;
}
static int
parse_opt(int key, char* arg, struct argp_state*)
{
@ -761,7 +783,7 @@ parse_opt(int key, char* arg, struct argp_state*)
automaton_format = Count;
break;
case 'F':
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
case 'n':
opt_max_count = to_pos_int(arg, "-n/--max-count");
@ -770,17 +792,14 @@ parse_opt(int key, char* arg, struct argp_state*)
opt_nth = parse_range(arg, 0, std::numeric_limits<int>::max());
break;
case 'u':
opt->uniq = std::unique_ptr<unique_aut_t>(new std::set<canon_aut>());
opt->uniq = std::make_unique<unique_aut_t>();
break;
case 'v':
opt_invert = true;
break;
case 'x':
{
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
}
if (const char* opt = extra_options.parse_options(arg))
error(2, 0, "failed to parse --options near '%s'", opt);
break;
case OPT_ALIASES:
opt_aliases = XARGMATCH("--aliases", arg, aliases_args, aliases_types);
@ -796,16 +815,7 @@ parse_opt(int key, char* arg, struct argp_state*)
opt_art_sccs_set = true;
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());
}
opt->acc_words.emplace_back(word_to_aut(arg, "accept-word"));
break;
case OPT_ACCEPTANCE_IS:
{
@ -958,16 +968,7 @@ parse_opt(int key, char* arg, struct argp_state*)
"%d should be followed by a comma and WORD", res);
arg = endptr + 1;
}
try
{
opt->hl_words.emplace_back(spot::parse_word(arg, opt->dict)
->as_automaton(), res);
}
catch (const spot::parse_error& e)
{
error(2, 0, "failed to parse the argument of --highlight-word:\n%s",
e.what());
}
opt->hl_words.emplace_back(word_to_aut(arg, "highlight-word"), res);
}
break;
case OPT_HIGHLIGHT_LANGUAGES:
@ -988,7 +989,7 @@ parse_opt(int key, char* arg, struct argp_state*)
if (!opt->included_in)
opt->included_in = aut;
else
opt->included_in = spot::product_or(opt->included_in, aut);
opt->included_in = ::product_or(opt->included_in, aut);
}
break;
case OPT_INHERENTLY_WEAK_SCCS:
@ -1151,16 +1152,7 @@ parse_opt(int key, char* arg, struct argp_state*)
opt_art_sccs_set = 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());
}
opt->rej_words.emplace_back(word_to_aut(arg, "reject-word"));
break;
case OPT_REM_AP:
opt->rem_ap.add_ap(arg);
@ -1252,7 +1244,7 @@ parse_opt(int key, char* arg, struct argp_state*)
opt_art_sccs_set = true;
break;
case ARGP_KEY_ARG:
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
default:
@ -1285,7 +1277,7 @@ namespace
static
bool match_acceptance(spot::twa_graph_ptr aut)
{
auto& acc = aut->acc();
const spot::acc_cond& acc = aut->acc();
switch (opt_acceptance_is)
{
case ACC_Any:
@ -1340,8 +1332,7 @@ namespace
{
bool max;
bool odd;
bool is_p = acc.is_parity(max, odd, true);
if (!is_p)
if (!acc.is_parity(max, odd, true))
return false;
switch (opt_acceptance_is)
{
@ -1454,7 +1445,7 @@ namespace
if (matched && opt_acceptance_is)
matched = match_acceptance(aut);
if (matched && (opt_sccs_set | opt_art_sccs_set))
if (matched && (opt_sccs_set || opt_art_sccs_set))
{
spot::scc_info si(aut);
unsigned n = si.scc_count();
@ -1534,14 +1525,14 @@ namespace
&& spot::contains(aut, opt->equivalent_pos);
if (matched && !opt->acc_words.empty())
for (auto& word_aut: opt->acc_words)
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 (auto& word_aut: opt->rej_words)
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
if (!spot::product(aut, word_aut)->is_empty())
{
matched = false;
@ -1675,14 +1666,9 @@ namespace
aut->accepting_run()->highlight(opt_highlight_accepting_run);
if (!opt->hl_words.empty())
for (auto& word_aut: opt->hl_words)
{
if (aut->acc().uses_fin_acceptance())
error(2, 0,
"--highlight-word does not yet work with Fin acceptance");
if (auto run = spot::product(aut, word_aut.first)->accepting_run())
run->project(aut)->highlight(word_aut.second);
}
for (auto& [word_aut, color]: opt->hl_words)
if (auto run = spot::product(aut, word_aut)->accepting_run())
run->project(aut)->highlight(color);
timer.stop();
if (opt->uniq)
@ -1757,15 +1743,17 @@ main(int argc, char** argv)
post.set_level(level);
autfilt_processor processor(post, o.dict);
if (processor.run())
return 2;
// Diagnose unused -x options
extra_options.report_unused_options();
int err = processor.run();
if (automaton_format == Count)
std::cout << match_count << std::endl;
// Diagnose unused -x options
if (!err)
extra_options.report_unused_options();
else
return 2;
check_cout();
return match_count ? 0 : 1;
});

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -41,7 +41,7 @@
#include <spot/twaalgos/isdet.hh>
automaton_format_t automaton_format = Hoa;
static const char* automaton_format_opt = nullptr;
const char* automaton_format_opt = nullptr;
const char* opt_name = nullptr;
static const char* opt_output = nullptr;
static const char* stats = "";
@ -203,12 +203,18 @@ static const argp_option io_options[] =
"to specify additional options as in --hoa=opt)", 0 },
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"name of the automaton", 0 },
{ "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable states", 0 },
{ "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable edges", 0 },
{ "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable transitions", 0 },
{ "%S, %s, %[LETTER]S, %[LETTER]s",
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of states (add one LETTER to select (r) reachable [default], "
"(u) unreachable, (a) all).", 0 },
{ "%E, %e, %[LETTER]E, %[LETTER]e",
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of edges (add one LETTER to select (r) reachable [default], "
"(u) unreachable, (a) all).", 0 },
{ "%T, %t, %[LETTER]E, %[LETTER]e",
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of transitions (add one LETTER to select (r) reachable "
"[default], (u) unreachable, (a) all).", 0 },
{ "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of acceptance sets", 0 },
{ "%G, %g, %[LETTERS]G, %[LETTERS]g", 0, nullptr,
@ -221,7 +227,7 @@ static const argp_option io_options[] =
"(iw) inherently weak. Use uppercase letters to negate them.", 0 },
{ "%R, %[LETTERS]R", 0, nullptr,
OPTION_DOC | OPTION_NO_USAGE,
"CPU time (excluding parsing), in seconds; Add LETTERS to restrict to"
"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 },
{ "%N, %n", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
@ -268,12 +274,15 @@ static const argp_option o_options[] =
"to specify additional options as in --hoa=opt)", 0 },
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"name of the automaton", 0 },
{ "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable states", 0 },
{ "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable edges", 0 },
{ "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of reachable transitions", 0 },
{ "%s, %[LETTER]s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of states (add one LETTER to select (r) reachable [default], "
"(u) unreachable, (a) all).", 0 },
{ "%e, %[LETTER]e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of edges (add one LETTER to select (r) reachable [default], "
"(u) unreachable, (a) all).", 0 },
{ "%t, %[LETTER]t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of transitions (add one LETTER to select (r) reachable "
"[default], (u) unreachable, (a) all).", 0 },
{ "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of acceptance sets", 0 },
{ "%g, %[LETTERS]g", 0, nullptr,
@ -444,7 +453,7 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
const spot::const_twa_graph_ptr& aut,
spot::formula f,
const char* filename, int loc,
spot::process_timer& ptimer,
const spot::process_timer& ptimer,
const char* csv_prefix, const char* csv_suffix)
{
timer_ = ptimer;
@ -472,15 +481,15 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
if (has('T'))
{
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
haut_trans_ = s.transitions;
haut_states_.set(s.states, haut->aut->num_states());
haut_edges_.set(s.edges, haut->aut->num_edges());
haut_trans_.set(s.transitions, count_all_transitions(haut->aut));
}
else if (has('E') || has('S'))
{
spot::twa_statistics s = stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
haut_states_.set(s.states, haut->aut->num_states());
haut_edges_.set(s.edges, haut->aut->num_edges());
}
if (has('M'))
{
@ -624,10 +633,10 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
outputnamer.print(haut, aut, f, filename, loc, ptimer,
csv_prefix, csv_suffix);
std::string fname = outputname.str();
auto p = outputfiles.emplace(fname, nullptr);
if (p.second)
p.first->second.reset(new output_file(fname.c_str()));
out = &p.first->second->ostream();
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
if (b)
it->second.reset(new output_file(fname.c_str()));
out = &it->second->ostream();
}
// Output it.

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014-2018, 2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2014-2018, 2020, 2022, 2023 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -47,6 +47,7 @@ enum automaton_format_t {
// The format to use in output_automaton()
extern automaton_format_t automaton_format;
extern const char* automaton_format_opt;
// Set to the argument of --name, else nullptr.
extern const char* opt_name;
// Output options
@ -154,7 +155,7 @@ public:
print(const spot::const_parsed_aut_ptr& haut,
const spot::const_twa_graph_ptr& aut,
spot::formula f,
const char* filename, int loc, spot::process_timer& ptimer,
const char* filename, int loc, const spot::process_timer& ptimer,
const char* csv_prefix, const char* csv_suffix);
private:
@ -165,9 +166,9 @@ private:
spot::printable_value<std::string> aut_word_;
spot::printable_value<std::string> haut_word_;
spot::printable_acc_cond haut_gen_acc_;
spot::printable_value<unsigned> haut_states_;
spot::printable_value<unsigned> haut_edges_;
spot::printable_value<unsigned long long> haut_trans_;
spot::printable_size haut_states_;
spot::printable_size haut_edges_;
spot::printable_long_size haut_trans_;
spot::printable_value<unsigned> haut_acc_;
printable_varset haut_ap_;
printable_varset aut_ap_;
@ -195,7 +196,7 @@ class automaton_printer
std::map<std::string, std::unique_ptr<output_file>> outputfiles;
public:
automaton_printer(stat_style input = no_input);
explicit automaton_printer(stat_style input = no_input);
~automaton_printer();
void

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
// Copyright (C) 2015, 2018, 2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -25,10 +25,15 @@ int
to_int(const char* s, const char* where)
{
char* endptr;
int res = strtol(s, &endptr, 10);
errno = 0;
long int lres = strtol(s, &endptr, 10);
if (*endptr)
error(2, 0, "failed to parse '%s' as an integer (in argument of %s).",
s, where);
int res = lres;
if (res != lres || errno == ERANGE)
error(2, 0, "value '%s' is too large for an int (in argument of %s).",
s, where);
return res;
}
@ -45,11 +50,17 @@ unsigned
to_unsigned (const char *s, const char* where)
{
char* endptr;
unsigned res = strtoul(s, &endptr, 10);
errno = 0;
unsigned long lres = strtoul(s, &endptr, 10);
if (*endptr)
error(2, 0,
"failed to parse '%s' as an unsigned integer (in argument of %s).",
s, where);
unsigned res = lres;
if (res != lres || errno == ERANGE)
error(2, 0,
"value '%s' is too large for a unsigned int (in argument of %s).",
s, where);
return res;
}
@ -57,8 +68,9 @@ float
to_float(const char* s, const char* where)
{
char* endptr;
errno = 0;
float res = strtof(s, &endptr);
if (*endptr)
if (*endptr || errno == ERANGE)
error(2, 0, "failed to parse '%s' as a float (in argument of %s)",
s, where);
return res;
@ -80,8 +92,9 @@ to_longs(const char* arg)
while (*arg)
{
char* endptr;
errno = 0;
long value = strtol(arg, &endptr, 10);
if (endptr == arg)
if (endptr == arg || errno)
error(2, 0, "failed to parse '%s' as an integer.", arg);
res.push_back(value);
while (*endptr == ' ' || *endptr == ',')

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2015, 2016, 2022, 2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -21,25 +21,27 @@
#include <error.h>
#include <iostream>
output_file::output_file(const char* name)
output_file::output_file(const char* name, bool force_append)
{
std::ios_base::openmode mode = std::ios_base::trunc;
if (name[0] == '>' && name[1] == '>')
{
mode = std::ios_base::app;
append_ = true;
name += 2;
}
if (force_append)
append_ = true;
if (append_)
mode = std::ios_base::app;
if (name[0] == '-' && name[1] == 0)
{
os_ = &std::cout;
return;
}
of_ = new std::ofstream(name, mode);
of_ = std::make_unique<std::ofstream>(name, mode);
if (!*of_)
error(2, errno, "cannot open '%s'", name);
os_ = of_;
os_ = of_.get();
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2015-2016, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -21,27 +21,22 @@
#include "common_sys.hh"
#include <iosfwd>
#include <memory>
#include <fstream>
#include <error.h>
class output_file
{
std::ostream* os_;
std::ofstream* of_ = nullptr;
std::unique_ptr<std::ofstream> of_;
bool append_ = false;
public:
// Open a file for output. "-" is interpreted as stdout.
// Names that start with ">>" are opened for append.
// The function calls error() on... error.
output_file(const char* name);
output_file(const char* name, bool force_append = false);
void close(const std::string& name);
~output_file()
{
delete of_;
}
bool append() const
{
return append_;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2017, 2019, 2021 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2012-2017, 2019, 2021-2023 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -68,10 +68,10 @@ parse_opt_finput(int key, char* arg, struct argp_state*)
switch (key)
{
case 'f':
jobs.emplace_back(arg, false);
jobs.emplace_back(arg, job_type::LTL_STRING);
break;
case 'F':
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::LTL_FILENAME);
break;
case OPT_LBT:
lbt_input = true;
@ -96,12 +96,6 @@ parse_formula(const std::string& s)
(s, spot::default_environment::instance(), false, lenient);
}
job_processor::job_processor()
: abort_run(false), real_filename(nullptr),
col_to_read(0), prefix(nullptr), suffix(nullptr)
{
}
job_processor::~job_processor()
{
if (real_filename)
@ -303,8 +297,22 @@ job_processor::process_stream(std::istream& is,
}
int
job_processor::process_file(const char* filename)
job_processor::process_aut_file(const char*)
{
throw std::runtime_error("process_aut_file not defined for this tool");
}
int
job_processor::process_tlsf_file(const char*)
{
throw std::runtime_error("process_tlsf_file not defined for this tool");
}
int
job_processor::process_ltl_file(const char* filename)
{
col_to_read = 0;
// Special case for stdin.
if (filename[0] == '-' && filename[1] == 0)
return process_stream(std::cin, filename);
@ -356,12 +364,25 @@ int
job_processor::run()
{
int error = 0;
for (auto& j: jobs)
for (const auto& j: jobs)
{
if (!j.file_p)
error |= process_string(j.str);
else
error |= process_file(j.str);
switch (j.type)
{
case job_type::LTL_STRING:
error |= process_string(j.str);
break;
case job_type::LTL_FILENAME:
error |= process_ltl_file(j.str);
break;
case job_type::AUT_FILENAME:
error |= process_aut_file(j.str);
break;
case job_type::TLSF_FILENAME:
error |= process_tlsf_file(j.str);
break;
default:
throw std::runtime_error("unexpected job type");
}
if (abort_run)
break;
}
@ -376,7 +397,7 @@ void check_no_formula()
error(2, 0, "No formula to translate? Run '%s --help' for help.\n"
"Use '%s -' to force reading formulas from the standard "
"input.", program_name, program_name);
jobs.emplace_back("-", true);
jobs.emplace_back("-", job_type::LTL_FILENAME);
}
void check_no_automaton()
@ -387,5 +408,5 @@ void check_no_automaton()
error(2, 0, "No automaton to process? Run '%s --help' for help.\n"
"Use '%s -' to force reading automata from the standard "
"input.", program_name, program_name);
jobs.emplace_back("-", true);
jobs.emplace_back("-", job_type::AUT_FILENAME);
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2017 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2012-2017, 2022, 2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -25,13 +25,18 @@
#include <vector>
#include <spot/tl/parse.hh>
enum class job_type : char { LTL_STRING,
LTL_FILENAME,
AUT_FILENAME,
TLSF_FILENAME };
struct job
{
const char* str;
bool file_p; // true if str is a filename, false if it is a formula
job_type type;
job(const char* str, bool file_p) noexcept
: str(str), file_p(file_p)
job(const char* str, job_type type) noexcept
: str(str), type(type)
{
}
};
@ -51,9 +56,11 @@ spot::parsed_formula parse_formula(const std::string& s);
class job_processor
{
protected:
bool abort_run; // Set to true in process_formula() to abort run().
bool abort_run = false; // Set to true in process_formula() to abort run().
public:
job_processor();
job_processor() = default;
job_processor(const job_processor&) = delete;
job_processor& operator=(const job_processor&) = delete;
virtual ~job_processor();
@ -68,15 +75,21 @@ public:
process_stream(std::istream& is, const char* filename);
virtual int
process_file(const char* filename);
process_ltl_file(const char* filename);
virtual int
process_aut_file(const char* filename);
virtual int
process_tlsf_file(const char* filename);
virtual int
run();
char* real_filename;
long int col_to_read;
char* prefix;
char* suffix;
char* real_filename = nullptr;
long int col_to_read = 0;
char* prefix = nullptr;
char* suffix = nullptr;
};
// Report and error message or add a default job depending on whether

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2017, 2018 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2015, 2017, 2018, 2022 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -80,8 +80,10 @@ public:
}
int
process_file(const char* filename) override
process_aut_file(const char* filename) override
{
col_to_read = 0;
// If we have a filename like "foo/NN" such
// that:
// ① foo/NN is not a file,

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
// Copyright (C) 2012-2019, 2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -23,6 +23,7 @@
#include "common_setup.hh"
#include <iostream>
#include <sstream>
#include <memory>
#include <spot/tl/print.hh>
#include <spot/tl/length.hh>
#include <spot/tl/apcollect.hh>
@ -297,9 +298,9 @@ namespace
};
}
static formula_printer* format = nullptr;
static std::unique_ptr<formula_printer> format;
static std::ostringstream outputname;
static formula_printer* outputnamer = nullptr;
static std::unique_ptr<formula_printer> outputnamer;
static std::map<std::string, std::unique_ptr<output_file>> outputfiles;
int
@ -320,7 +321,7 @@ parse_opt_output(int key, char* arg, struct argp_state*)
output_format = lbt_output;
break;
case 'o':
outputnamer = new formula_printer(outputname, arg);
outputnamer = std::make_unique<formula_printer>(outputname, arg);
break;
case 'p':
full_parenth = true;
@ -341,8 +342,7 @@ parse_opt_output(int key, char* arg, struct argp_state*)
output_format = wring_output;
break;
case OPT_FORMAT:
delete format;
format = new formula_printer(std::cout, arg);
format = std::make_unique<formula_printer>(std::cout, arg);
break;
default:
return ARGP_ERR_UNKNOWN;
@ -417,10 +417,10 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
formula_with_location fl = { f, filename, linenum, prefix, suffix };
outputnamer->print(fl, ptimer);
std::string fname = outputname.str();
auto p = outputfiles.emplace(fname, nullptr);
if (p.second)
p.first->second.reset(new output_file(fname.c_str()));
out = &p.first->second->ostream();
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
if (b)
it->second.reset(new output_file(fname.c_str()));
out = &it->second->ostream();
}
output_formula(*out, f, ptimer, filename, linenum, prefix, suffix);
*out << output_terminator;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2014, 2016 Laboratoire de Recherche et
// Copyright (C) 2012, 2014, 2016, 2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -36,13 +36,17 @@ parse_range(const char* str, int missing_left, int missing_right)
{
range res;
char* end;
res.min = strtol(str, &end, 10);
errno = 0;
long lres = strtol(str, &end, 10);
res.min = lres;
if (res.min != lres || errno == ERANGE)
error(2, 0, "start of range '%s' is too large for an int.", str);
if (end == str)
{
// No leading number. It's OK as long as the string is not
// empty.
if (!*end)
error(1, 0, "invalid empty range");
error(2, 0, "invalid empty range");
res.min = missing_left;
}
if (!*end)
@ -66,19 +70,23 @@ parse_range(const char* str, int missing_left, int missing_right)
{
// Parse the next integer.
char* end2;
res.max = strtol(end, &end2, 10);
errno = 0;
lres = strtol(end, &end2, 10);
res.max = lres;
if (res.max != lres || errno == ERANGE)
error(2, 0, "end of range '%s' is too large for an int.", str);
if (str == end2)
error(1, 0, "invalid range '%s' "
error(2, 0, "invalid range '%s' "
"(should start with digits, dots, or colon)", str);
if (end == end2)
error(1, 0, "invalid range '%s' (missing end?)", str);
error(2, 0, "invalid range '%s' (missing end?)", str);
if (*end2)
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
error(2, 0, "invalid range '%s' (trailing garbage?)", str);
}
}
if (res.min < 0 || res.max < 0)
error(1, 0, "invalid range '%s': values must be positive", str);
error(2, 0, "invalid range '%s': values must be positive", str);
return res;
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2022 Laboratoire de Recherche et Développement
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -20,13 +20,14 @@
#include "common_setup.hh"
#include "common_aoutput.hh"
#include "argp.h"
#include "closeout.h"
#include <argp.h>
#include <closeout.h>
#include <cstdlib>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <sys/wait.h>
#include <error.h>
#include <spot/misc/tmpfile.hh>
static void
@ -35,7 +36,7 @@ display_version(FILE *stream, struct argp_state*)
fputs(program_name, stream);
fputs(" (" PACKAGE_NAME ") " PACKAGE_VERSION "\n\
\n\
Copyright (C) 2022 Laboratoire de Recherche et Développement de l'Epita.\n\
Copyright (C) 2023 Laboratoire de Recherche de l'Epita (LRE)\n\
License GPLv3+: \
GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
This is free software: you are free to change and redistribute it.\n\

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2018, 2019 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2012-2013, 2018-2019, 2023 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -34,5 +34,5 @@ int protected_main(char** progname, std::function<int()> mainfun);
// Diagnose exceptions.
[[noreturn]] void handle_any_exception();
#define BEGIN_EXCEPTION_PROTECT try { (void)0;
#define BEGIN_EXCEPTION_PROTECT try { (void)0
#define END_EXCEPTION_PROTECT } catch (...) { handle_any_exception(); }

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015-2022 Laboratoire de Recherche et Développement
// Copyright (C) 2015-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -27,6 +27,7 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <iomanip>
#include <fstream>
#if __has_include(<spawn.h>)
#define HAVE_SPAWN_H 1
#include <spawn.h>
@ -52,7 +53,7 @@ struct shorthands_t
};
#define SHORTHAND(PRE, POST) { PRE, std::regex("^" PRE), POST }
static shorthands_t shorthands_ltl[] = {
static const shorthands_t shorthands_ltl[] = {
SHORTHAND("delag", " %f>%O"),
SHORTHAND("lbt", " <%L>%O"),
SHORTHAND("ltl2ba", " -f %s>%O"),
@ -72,7 +73,7 @@ static shorthands_t shorthands_ltl[] = {
SHORTHAND("owl.* ltl-utilities\\b", " -f %f"),
};
static shorthands_t shorthands_autproc[] = {
static const shorthands_t shorthands_autproc[] = {
SHORTHAND("autfilt", " %H>%O"),
SHORTHAND("dra2dpa", " <%H>%O"),
SHORTHAND("dstar2tgba", " %H>%O"),
@ -84,7 +85,7 @@ static shorthands_t shorthands_autproc[] = {
" <%H>%O"),
};
static void show_shorthands(shorthands_t* begin, shorthands_t* end)
static void show_shorthands(const shorthands_t* begin, const shorthands_t* end)
{
std::cout
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
@ -99,7 +100,8 @@ static void show_shorthands(shorthands_t* begin, shorthands_t* end)
}
tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
tool_spec::tool_spec(const char* spec,
const shorthands_t* begin, const shorthands_t* end,
bool is_ref) noexcept
: spec(spec), cmd(spec), name(spec), reference(is_ref)
{
@ -112,15 +114,15 @@ tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
{
if (*pos == '{')
++count;
else if (*pos == '}')
if (!--count)
{
name = strndup(cmd + 1, pos - cmd - 1);
cmd = pos + 1;
while (*cmd == ' ' || *cmd == '\t')
++cmd;
break;
}
else if (*pos == '}' && --count == 0)
{
name = strndup(cmd + 1, pos - cmd - 1);
cmd = pos + 1;
// skip leading whitespace
while (*cmd == ' ' || *cmd == '\t')
++cmd;
break;
}
}
}
// If there is no % in the string, look for a known
@ -146,11 +148,11 @@ tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
auto& p = *begin++;
if (std::regex_search(basename, p.rprefix))
{
int m = strlen(p.suffix);
int q = strlen(cmd);
size_t m = strlen(p.suffix);
size_t q = strlen(cmd);
char* tmp = static_cast<char*>(malloc(q + m + 1));
strcpy(tmp, cmd);
strcpy(tmp + q, p.suffix);
memcpy(tmp, cmd, q);
memcpy(tmp + q, p.suffix, m + 1);
cmd = tmp;
allocated = true;
break;
@ -461,6 +463,92 @@ autproc_runner::round_automaton(spot::const_twa_graph_ptr aut, unsigned serial)
filename_automaton.new_round(aut, serial);
}
std::string
read_stdout_of_command(char* const* args)
{
#if HAVE_SPAWN_H
int cout_pipe[2];
if (int err = pipe(cout_pipe))
error(2, err, "pipe() failed");
posix_spawn_file_actions_t actions;
if (int err = posix_spawn_file_actions_init(&actions))
error(2, err, "posix_spawn_file_actions_init() failed");
posix_spawn_file_actions_addclose(&actions, STDIN_FILENO);
posix_spawn_file_actions_addclose(&actions, cout_pipe[0]);
posix_spawn_file_actions_adddup2(&actions, cout_pipe[1], STDOUT_FILENO);
posix_spawn_file_actions_addclose(&actions, cout_pipe[1]);
pid_t pid;
if (int err = posix_spawnp(&pid, args[0], &actions, nullptr, args, environ))
error(2, err, "failed to run '%s'", args[0]);
if (int err = posix_spawn_file_actions_destroy(&actions))
error(2, err, "posix_spawn_file_actions_destroy() failed");
if (close(cout_pipe[1]) < 0)
error(2, errno, "closing write-side of pipe failed");
std::string results;
ssize_t bytes_read;
for (;;)
{
static char buffer[512];
bytes_read = read(cout_pipe[0], buffer, sizeof(buffer));
if (bytes_read > 0)
results.insert(results.end(), buffer, buffer + bytes_read);
else
break;
}
if (bytes_read < 0)
error(2, bytes_read, "failed to read from pipe");
if (cout_pipe[0] < 0)
error(2, errno, "closing read-side of pipe failed");
int exit_code = 0;
if (waitpid(pid, &exit_code, 0) == -1)
error(2, errno, "waitpid() failed");
if (exit_code)
error(2, 0, "'%s' exited with status %d", args[0], exit_code);
return results;
#else
// We could provide a pipe+fork+exec alternative implementation, but
// systems without posix_spawn() might also not have fork and exec.
// For instance MinGW does not. So let's fallback to system+tmpfile
// instead for maximum portability.
char prefix[30];
snprintf(prefix, sizeof prefix, "spot-tmp");
spot::temporary_file* tmpfile = spot::create_tmpfile(prefix);
std::string tmpname = tmpfile->name();
std::ostringstream cmd;
for (auto t = args; *t != nullptr; ++t)
spot::quote_shell_string(cmd, *t) << ' ';
cmd << '>';
spot::quote_shell_string(cmd, tmpfile->name());
std::string cmdstr = cmd.str();
int exit_code = system(cmdstr.c_str());
if (exit_code < 0)
error(2, errno, "failed to execute %s", cmdstr.c_str());
if (exit_code > 0)
error(2, 0, "'%s' exited with status %d", args[0], exit_code);
std::ifstream ifs(tmpname, std::ifstream::in);
if (!ifs)
error(2, 0, "failed to open %s (output of %s)", tmpname.c_str(), args[0]);
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::stringstream buffer;
buffer << ifs.rdbuf();
delete tmpfile;
return buffer.str();
#endif
}
std::atomic<bool> timed_out{false};
unsigned timeout_count = 0;
@ -524,7 +612,7 @@ get_arg(const char*& cmd)
{
const char* start = cmd;
std::string arg;
while (int c = *cmd)
while (char c = *cmd)
{
switch (c)
{
@ -554,14 +642,14 @@ get_arg(const char*& cmd)
goto end_loop;
case '\'':
{
int d = 0;
char d = '\0';
while ((d = *++cmd))
{
if (d == '\'')
break;
arg.push_back(d);
}
if (d == 0)
if (d == '\0')
return nullptr;
}
break;
@ -706,6 +794,7 @@ parse_simple_command(const char* cmd)
return res;
}
#ifndef HAVE_SPAWN_H
static void
exec_command(const char* cmd)
@ -751,8 +840,6 @@ exec_command(const char* cmd)
SPOT_UNREACHABLE();
return;
}
#else
extern char **environ;
#endif
int

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015-2018, 2020 Laboratoire de Recherche et
// Copyright (C) 2015-2018, 2020, 2022 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -51,7 +51,8 @@ struct tool_spec
// Whether the tool is a reference.
bool reference;
tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
tool_spec(const char* spec,
const shorthands_t* begin, const shorthands_t* end,
bool is_ref) noexcept;
tool_spec(const tool_spec& other) noexcept;
tool_spec& operator=(const tool_spec& other);
@ -71,7 +72,7 @@ struct quoted_formula final: public spot::printable_value<spot::formula>
struct filed_formula final: public spot::printable
{
filed_formula(const quoted_formula& ltl) : f_(ltl)
explicit filed_formula(const quoted_formula& ltl) : f_(ltl)
{
}
@ -89,9 +90,7 @@ struct filed_formula final: public spot::printable
struct filed_automaton final: public spot::printable
{
filed_automaton()
{
}
filed_automaton() = default;
void print(std::ostream& os, const char* pos) const override;
@ -112,7 +111,7 @@ struct printable_result_filename final:
unsigned translator_num;
printable_result_filename();
~printable_result_filename();
~printable_result_filename() override;
void reset(unsigned n);
void cleanup();
@ -126,7 +125,7 @@ protected:
spot::bdd_dict_ptr dict;
// Round-specific variables
quoted_formula ltl_formula;
filed_formula filename_formula = ltl_formula;
filed_formula filename_formula{ltl_formula};
// Run-specific variables
printable_result_filename output;
public:
@ -151,9 +150,9 @@ protected:
public:
using spot::formater::has;
autproc_runner(// whether we accept the absence of output
// specifier
bool no_output_allowed = false);
explicit autproc_runner(// whether we accept the absence of output
// specifier
bool no_output_allowed = false);
void round_automaton(spot::const_twa_graph_ptr aut, unsigned serial);
};
@ -175,3 +174,9 @@ int exec_with_timeout(const char* cmd);
#define exec_with_timeout(cmd) system(cmd)
#define setup_sig_handler() while (0);
#endif // !ENABLE_TIMEOUT
// Run a command (whose args[0], args[1], etc. are given by args), and
// return its captured stdout. Stderr is not captured. Will abort
// with an error message if the command is not found, or if it exit
// with a non-zero status code.
std::string read_stdout_of_command(char* const* args);

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2019 Laboratoire de Recherche et Développement
// Copyright (C) 2013-2019, 2022, 2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -48,7 +48,7 @@
#include <spot/parseaut/public.hh>
#include <spot/twaalgos/sccinfo.hh>
static const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Convert automata with any acceptance condition into variants of \
Büchi automata.\n\nThis reads automata into any supported format \
(HOA, LBTT, ltl2dstar, never claim) and outputs a \
@ -89,7 +89,7 @@ parse_opt(int key, char* arg, struct argp_state*)
switch (key)
{
case 'F':
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
case 'x':
{
@ -99,7 +99,7 @@ parse_opt(int key, char* arg, struct argp_state*)
}
break;
case ARGP_KEY_ARG:
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
default:
return ARGP_ERR_UNKNOWN;
@ -117,7 +117,7 @@ namespace
spot::postprocessor& post;
automaton_printer printer;
dstar_processor(spot::postprocessor& post)
explicit dstar_processor(spot::postprocessor& post)
: hoa_processor(spot::make_bdd_dict()), post(post), printer(aut_input)
{
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017-2019 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2017-2019, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -43,7 +43,8 @@
using namespace spot;
const char argp_program_doc[] ="Generate ω-automata from predefined patterns.";
static const char argp_program_doc[] =
"Generate ω-automata from predefined patterns.";
static const argp_option options[] =
{
@ -62,6 +63,11 @@ static const argp_option options[] =
{ "m-nba", gen::AUT_M_NBA, "RANGE", 0,
"An NBA with N+1 states whose determinization needs at least "
"N! states", 0},
{ "cyclist-trace-nba", gen::AUT_CYCLIST_TRACE_NBA, "RANGE", 0,
"An NBA with N+2 states that should include cyclist-proof-dba=B.", 0},
{ "cyclist-proof-dba", gen::AUT_CYCLIST_PROOF_DBA, "RANGE", 0,
"A DBA with N+2 states that should be included "
"in cyclist-trace-nba=B.", 0},
RANGE_DOC,
/**************************************************/
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
@ -122,7 +128,7 @@ output_pattern(gen::aut_pattern_id pattern, int n)
static void
run_jobs()
{
for (auto& j: jobs)
for (const auto& j: jobs)
{
int inc = (j.range.max < j.range.min) ? -1 : 1;
int n = j.range.min;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2015-2019 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2012, 2013, 2015-2019, 2022-2023 Laboratoire de
// Recherche et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -45,7 +45,7 @@
using namespace spot;
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Generate temporal logic formulas from predefined patterns.";
// We reuse the values from gen::ltl_pattern_id as option keys.
@ -84,6 +84,8 @@ static const argp_option options[] =
{ "eh-patterns", gen::LTL_EH_PATTERNS, "RANGE", OPTION_ARG_OPTIONAL,
"Etessami and Holzmann [Concur'00] patterns "
"(range should be included in 1..12)", 0 },
{ "eil-gsi", gen::LTL_EIL_GSI, "RANGE", 0,
"G[0..n]((a S b) -> c) rewritten using future operators", 0 },
{ "fxg-or", gen::LTL_FXG_OR, "RANGE", 0,
"F(p0 | XG(p1 | XG(p2 | ... XG(pn))))", 0},
{ "gf-equiv", gen::LTL_GF_EQUIV, "RANGE", 0,
@ -315,7 +317,7 @@ output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
static void
run_jobs()
{
for (auto& j: jobs)
for (const auto& j: jobs)
{
int inc = (j.range.max < j.range.min) ? -1 : 1;
int n = j.range.min;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2012-2019, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -39,7 +39,7 @@
#include <spot/misc/optionmap.hh>
#include <spot/misc/timer.hh>
static const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Translate linear-time formulas (LTL/PSL) into various types of automata.\n\n\
By default it will apply all available optimizations to output \
the smallest Transition-based Generalized Büchi Automata, \
@ -105,10 +105,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
// FIXME: use stat() to distinguish filename from string?
if (*arg == '-' && !arg[1])
jobs.emplace_back(arg, true);
else
jobs.emplace_back(arg, false);
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
? job_type::LTL_FILENAME
: job_type::LTL_STRING));
break;
default:
@ -125,10 +124,10 @@ namespace
{
public:
spot::translator& trans;
automaton_printer printer;
automaton_printer printer{ltl_input};
trans_processor(spot::translator& trans)
: trans(trans), printer(ltl_input)
explicit trans_processor(spot::translator& trans)
: trans(trans)
{
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2012-2020, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -46,7 +46,7 @@
#include <spot/taalgos/minimize.hh>
#include <spot/misc/optionmap.hh>
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Translate linear-time formulas (LTL/PSL) into Testing Automata.\n\n\
By default it outputs a transition-based generalized Testing Automaton \
the smallest Transition-based Generalized Büchi Automata, \
@ -148,10 +148,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
// FIXME: use stat() to distinguish filename from string?
if (*arg == '-' && !arg[1])
jobs.emplace_back(arg, true);
else
jobs.emplace_back(arg, false);
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
? job_type::LTL_FILENAME
: job_type::LTL_STRING));
break;
default:
@ -169,7 +168,7 @@ namespace
public:
spot::translator& trans;
trans_processor(spot::translator& trans)
explicit trans_processor(spot::translator& trans)
: trans(trans)
{
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2012-2020, 2022, 2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -69,7 +69,7 @@
#include <spot/misc/tmpfile.hh>
#include <spot/misc/timer.hh>
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Call several LTL/PSL translators and cross-compare their output to detect \
bugs, or to gather statistics. The list of formulas to use should be \
supplied on standard input, or using the -f or -F options.\v\
@ -264,55 +264,32 @@ end_error()
struct statistics
{
statistics()
: ok(false),
alternating(false),
status_str(nullptr),
status_code(0),
time(0),
states(0),
edges(0),
transitions(0),
acc(0),
scc(0),
nonacc_scc(0),
terminal_scc(0),
weak_scc(0),
strong_scc(0),
nondetstates(0),
nondeterministic(false),
terminal_aut(false),
weak_aut(false),
strong_aut(false)
{
}
// If OK is false, only the status_str, status_code, and time fields
// should be valid.
bool ok;
bool alternating;
const char* status_str;
int status_code;
double time;
unsigned states;
unsigned edges;
unsigned long long transitions;
unsigned acc;
unsigned scc;
unsigned nonacc_scc;
unsigned terminal_scc;
unsigned weak_scc;
unsigned strong_scc;
unsigned nondetstates;
bool nondeterministic;
bool terminal_aut;
bool weak_aut;
bool strong_aut;
bool ok = false;
bool alternating = false;
const char* status_str = nullptr;
int status_code = 0;
double time = 0.0;
unsigned states = 0;
unsigned edges = 0;
unsigned long long transitions = 0;
unsigned acc = 0;
unsigned scc = 0;
unsigned nonacc_scc = 0;
unsigned terminal_scc = 0;
unsigned weak_scc = 0;
unsigned strong_scc = 0;
unsigned nondetstates = 0;
bool nondeterministic = false;
bool terminal_aut = false;
bool weak_aut = false;
bool strong_aut = false;
std::vector<double> product_states;
std::vector<double> product_transitions;
std::vector<double> product_scc;
bool ambiguous;
bool complete;
bool ambiguous = false;
bool complete = false;
std::string hoa_str;
static void
@ -484,7 +461,7 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
if (arg[0] == '-' && !arg[1])
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::LTL_FILENAME);
else
tools_push_trans(arg);
break;
@ -581,7 +558,7 @@ namespace
class xtranslator_runner final: public translator_runner
{
public:
xtranslator_runner(spot::bdd_dict_ptr dict)
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
: translator_runner(dict)
{
}
@ -1095,17 +1072,14 @@ namespace
}
// Make sure we do not translate the same formula twice.
if (!allow_dups)
if (!allow_dups && !unique_set.insert(f).second)
{
if (!unique_set.insert(f).second)
{
if (!quiet)
std::cerr
<< ("warning: This formula or its negation has already"
" been checked.\n Use --allow-dups if it "
"should not be ignored.\n\n");
return 0;
}
if (!quiet)
std::cerr
<< ("warning: This formula or its negation has already"
" been checked.\n Use --allow-dups if it "
"should not be ignored.\n\n");
return 0;
}
int problems = 0;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015-2020 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2015-2020, 2022-2023 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -47,7 +47,7 @@
#include <spot/twaalgos/totgba.hh>
#include <spot/parseaut/public.hh>
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Run LTL/PSL formulas through another program, performing conversion\n\
of input and output as required.";
@ -193,7 +193,7 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
if (arg[0] == '-' && !arg[1])
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::LTL_FILENAME);
else
tools_push_trans(arg);
break;
@ -209,7 +209,7 @@ namespace
class xtranslator_runner final: public translator_runner
{
public:
xtranslator_runner(spot::bdd_dict_ptr dict)
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
: translator_runner(dict, true)
{
}
@ -224,8 +224,6 @@ namespace
format(command, tools[translator_num].cmd);
std::string cmd = command.str();
//std::cerr << "Running [" << l << translator_num << "]: "
// << cmd << std::endl;
timer.start();
int es = exec_with_timeout(cmd.c_str());
timer.stop();
@ -312,7 +310,7 @@ namespace
spot::printable_value<std::string> inputf;
public:
processor(spot::postprocessor& post)
explicit processor(spot::postprocessor& post)
: runner(dict), best_printer(best_stream, best_format), post(post)
{
printer.add_stat('T', &cmdname);
@ -323,9 +321,7 @@ namespace
best_printer.declare('f', &inputf);
}
~processor()
{
}
~processor() override = default;
int
process_string(const std::string& input,

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -38,6 +38,7 @@
#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>
@ -58,7 +59,7 @@
#include <spot/twaalgos/totgba.hh>
#include <spot/twaalgos/word.hh>
const char argp_program_doc[] ="\
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\
@ -100,6 +101,8 @@ enum {
OPT_SIZE_MAX,
OPT_SIZE_MIN,
OPT_SKIP_ERRORS,
OPT_SONF,
OPT_SONF_APS,
OPT_STUTTER_INSENSITIVE,
OPT_SUSPENDABLE,
OPT_SYNTACTIC_GUARANTEE,
@ -127,6 +130,11 @@ static const argp_option options[] =
{ "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 },
@ -316,6 +324,7 @@ 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
@ -327,6 +336,7 @@ 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;
@ -377,7 +387,7 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
// FIXME: use stat() to distinguish filename from string?
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::LTL_FILENAME);
break;
case OPT_ACCEPT_WORD:
try
@ -460,6 +470,12 @@ parse_opt(int key, char* arg, struct argp_state*)
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;
@ -570,7 +586,7 @@ namespace
fset_t unique_set;
spot::relabeling_map relmap;
ltl_processor(spot::tl_simplifier& simpl)
explicit ltl_processor(spot::tl_simplifier& simpl)
: simpl(simpl)
{
}
@ -650,6 +666,25 @@ namespace
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:
@ -687,7 +722,7 @@ namespace
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
{
auto s = atomic_prop_collect(f);
spot::atomic_prop_set* s = atomic_prop_collect(f);
int n = s->size();
delete s;
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
@ -726,7 +761,7 @@ namespace
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
if (matched && !opt->acc_words.empty())
for (auto& word_aut: opt->acc_words)
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
if (spot::product(aut, word_aut)->is_empty())
{
matched = false;
@ -734,7 +769,7 @@ namespace
}
if (matched && !opt->rej_words.empty())
for (auto& word_aut: opt->rej_words)
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
if (!spot::product(aut, word_aut)->is_empty())
{
matched = false;
@ -808,12 +843,12 @@ namespace
{
// Sort the formulas alphabetically.
std::map<std::string, spot::formula> m;
for (auto& p: relmap)
m.emplace(str_psl(p.first), p.second);
for (auto& p: 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 " << p.first << " (",
p.second, filename,
<< "#define " << newname << " (",
oldname, filename,
std::to_string(linenum).c_str()) << ")\n";
}
one_match = true;
@ -841,7 +876,7 @@ main(int argc, char** argv)
exit(err);
if (jobs.empty())
jobs.emplace_back("-", 1);
jobs.emplace_back("-", job_type::LTL_FILENAME);
if (boolean_to_isop && simplification_level == 0)
simplification_level = 1;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et
// Copyright (C) 2014-2019, 2022 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -143,7 +143,7 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case ARGP_KEY_ARG:
// FIXME: use stat() to distinguish filename from string?
jobs.emplace_back(arg, true);
jobs.emplace_back(arg, job_type::LTL_FILENAME);
break;
case OPT_AP2CONST:
opt_all = 0;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2017-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -23,8 +23,10 @@
#include "common_aoutput.hh"
#include "common_finput.hh"
#include "common_hoaread.hh"
#include "common_setup.hh"
#include "common_sys.hh"
#include "common_trans.hh"
#include <spot/misc/bddlt.hh>
#include <spot/misc/escape.hh>
@ -35,6 +37,7 @@
#include <spot/twaalgos/aiger.hh>
#include <spot/twaalgos/game.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/dot.hh>
#include <spot/twaalgos/minimize.hh>
#include <spot/twaalgos/mealy_machine.hh>
#include <spot/twaalgos/product.hh>
@ -44,8 +47,12 @@
enum
{
OPT_ALGO = 256,
OPT_BYPASS,
OPT_CSV,
OPT_DECOMPOSE,
OPT_DOT,
OPT_FROM_PGAME,
OPT_HIDE,
OPT_INPUT,
OPT_OUTPUT,
OPT_PRINT,
@ -53,6 +60,7 @@ enum
OPT_PRINT_HOA,
OPT_REAL,
OPT_SIMPLIFY,
OPT_TLSF,
OPT_VERBOSE,
OPT_VERIFY
};
@ -63,13 +71,19 @@ static const argp_option options[] =
{ nullptr, 0, nullptr, 0, "Input options:", 1 },
{ "outs", OPT_OUTPUT, "PROPS", 0,
"comma-separated list of controllable (a.k.a. output) atomic"
" propositions", 0},
" propositions", 0 },
{ "ins", OPT_INPUT, "PROPS", 0,
"comma-separated list of controllable (a.k.a. output) atomic"
" propositions", 0},
"comma-separated list of uncontrollable (a.k.a. input) atomic"
" propositions", 0 },
{ "tlsf", OPT_TLSF, "FILENAME", 0,
"Read a TLSF specification from FILENAME, and call syfco to "
"convert it into LTL", 0 },
{ "from-pgame", OPT_FROM_PGAME, "FILENAME", 0,
"Read a parity game in Extended HOA format instead of building it.",
0 },
/**************************************************/
{ nullptr, 0, nullptr, 0, "Fine tuning:", 10 },
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old", 0,
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old|acd", 0,
"choose the algorithm for synthesis:"
" \"sd\": translate to tgba, split, then determinize;"
" \"ds\": translate to tgba, determinize, then split;"
@ -77,45 +91,60 @@ static const argp_option options[] =
" \"lar\": translate to a deterministic automaton with arbitrary"
" acceptance condition, then use LAR to turn to parity,"
" then split (default);"
" \"lar.old\": old version of LAR, for benchmarking.\n", 0 },
" \"lar.old\": old version of LAR, for benchmarking;"
" \"acd\": translate to a deterministic automaton with arbitrary"
" acceptance condition, then use ACD to turn to parity,"
" then split.\n", 0 },
{ "bypass", OPT_BYPASS, "yes|no", 0,
"whether to try to avoid to construct a parity game "
"(enabled by default)", 0},
{ "decompose", OPT_DECOMPOSE, "yes|no", 0,
"whether to decompose the specification as multiple output-disjoint "
"problems to solve independently (enabled by default)", 0 },
{ "simplify", OPT_SIMPLIFY, "no|bisim|bwoa|sat|bisim-sat|bwoa-sat", 0,
"simplification to apply to the controler (no) nothing, "
"(bisim) bisimulation-based reduction, (bwoa) bissimulation-based "
"simplification to apply to the controller (no) nothing, "
"(bisim) bisimulation-based reduction, (bwoa) bisimulation-based "
"reduction with output assignment, (sat) SAT-based minimization, "
"(bisim-sat) SAT after bisim, (bwoa-sat) SAT after bwoa. Defaults "
"to 'bwoa'.", 0 },
/**************************************************/
{ nullptr, 0, nullptr, 0, "Output options:", 20 },
{ "print-pg", OPT_PRINT, nullptr, 0,
"print the parity game in the pgsolver format, do not solve it", 0},
"print the parity game in the pgsolver format, do not solve it", 0 },
{ "print-game-hoa", OPT_PRINT_HOA, "options", OPTION_ARG_OPTIONAL,
"print the parity game in the HOA format, do not solve it", 0},
"print the parity game in the HOA format, do not solve it", 0 },
{ "realizability", OPT_REAL, nullptr, 0,
"realizability only, do not compute a winning strategy", 0},
"realizability only, do not compute a winning strategy", 0 },
{ "aiger", OPT_PRINT_AIGER, "ite|isop|both[+ud][+dc]"
"[+sub0|sub1|sub2]", OPTION_ARG_OPTIONAL,
"prints a winning strategy as an AIGER circuit. The first, and only "
"mandatory option defines the method to be used. \"ite\" for "
"If-then-else normal form; "
"\"isop\" for irreducible sum of producs; "
"\"both\" tries both encodings and keeps the smaller one. "
"The other options further "
"refine the encoding, see aiger::encode_bdd.", 0},
{ "verbose", OPT_VERBOSE, nullptr, 0,
"verbose mode", -1 },
{ "verify", OPT_VERIFY, nullptr, 0,
"verifies the strategy or (if demanded) aiger against the spec.", -1 },
"encode the winning strategy as an AIG circuit and print it in AIGER"
" format. The first word indicates the encoding to used: \"ite\" for "
"If-Then-Else normal form; "
"\"isop\" for irreducible sum of products; "
"\"both\" tries both and keeps the smaller one. "
"Other options further "
"refine the encoding, see aiger::encode_bdd. Defaults to \"ite\".", 0 },
{ "dot", OPT_DOT, "options", OPTION_ARG_OPTIONAL,
"Use dot format when printing the result (game, strategy, or "
"AIG circuit, depending on other options). The options that "
"may be passed to --dot depend on the nature of what is printed. "
"For games and strategies, standard automata rendering "
"options are supported (e.g., see ltl2tgba --dot). For AIG circuit, "
"use (h) for horizontal and (v) for vertical layouts.", 0 },
{ "csv", OPT_CSV, "[>>]FILENAME", OPTION_ARG_OPTIONAL,
"output statistics as CSV in FILENAME or on standard output "
"(if '>>' is used to request append mode, the header line is "
"not output)", 0 },
{ "hide-status", OPT_HIDE, nullptr, 0,
"Hide the REALIZABLE or UNREALIZABLE line. (Hint: exit status "
"is enough of an indication.)", 0 },
/**************************************************/
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
{ "extra-options", 'x', "OPTS", 0,
"fine-tuning options (see spot-x (7))", 0 },
{ "verbose", OPT_VERBOSE, nullptr, 0, "verbose mode", 0 },
{ "verify", OPT_VERIFY, nullptr, 0,
"verify the strategy or (if demanded) AIG against the formula", 0 },
{ nullptr, 0, nullptr, 0, nullptr, 0 },
};
@ -123,20 +152,19 @@ static const struct argp_child children[] =
{
{ &finput_argp_headless, 0, nullptr, 0 },
{ &aoutput_argp, 0, nullptr, 0 },
//{ &aoutput_o_format_argp, 0, nullptr, 0 },
{ &misc_argp, 0, nullptr, 0 },
{ nullptr, 0, nullptr, 0 }
};
const char argp_program_doc[] = "\
static const char argp_program_doc[] = "\
Synthesize a controller from its LTL specification.\v\
Exit status:\n\
0 if the input problem is realizable\n\
1 if the input problem is not realizable\n\
0 if all input problems were realizable\n\
1 if at least one input problem was not realizable\n\
2 if any error has been reported";
static std::vector<std::string> all_output_aps;
static std::vector<std::string> all_input_aps;
static std::optional<std::vector<std::string>> all_output_aps;
static std::optional<std::vector<std::string>> all_input_aps;
static const char* opt_csv = nullptr;
static bool opt_print_pg = false;
@ -145,8 +173,10 @@ static const char* opt_print_hoa_args = nullptr;
static bool opt_real = false;
static bool opt_do_verify = false;
static const char* opt_print_aiger = nullptr;
static const char* opt_dot_arg = nullptr;
static bool opt_dot = false;
static spot::synthesis_info* gi;
static bool show_status = true;
static char const *const algo_names[] =
{
@ -154,7 +184,8 @@ static char const *const algo_names[] =
"sd",
"ps",
"lar",
"lar.old"
"lar.old",
"acd",
};
static char const *const algo_args[] =
@ -164,6 +195,7 @@ static char const *const algo_args[] =
"dpasplit", "ps",
"lar",
"lar.old",
"acd",
nullptr
};
static spot::synthesis_info::algo const algo_types[] =
@ -173,9 +205,24 @@ static spot::synthesis_info::algo const algo_types[] =
spot::synthesis_info::algo::DPA_SPLIT, spot::synthesis_info::algo::DPA_SPLIT,
spot::synthesis_info::algo::LAR,
spot::synthesis_info::algo::LAR_OLD,
spot::synthesis_info::algo::ACD,
};
ARGMATCH_VERIFY(algo_args, algo_types);
static const char* const bypass_args[] =
{
"yes", "true", "enabled", "1",
"no", "false", "disabled", "0",
nullptr
};
static bool bypass_values[] =
{
true, true, true, true,
false, false, false, false,
};
ARGMATCH_VERIFY(bypass_args, bypass_values);
bool opt_bypass = true;
static const char* const decompose_args[] =
{
"yes", "true", "enabled", "1",
@ -221,7 +268,22 @@ namespace
};
static void
print_csv(const spot::formula& f)
dispatch_print_hoa(const spot::const_twa_graph_ptr& game)
{
if (opt_dot)
spot::print_dot(std::cout, game, opt_print_hoa_args);
else if (opt_print_pg)
spot::print_pg(std::cout, game);
else
spot::print_hoa(std::cout, game, opt_print_hoa_args) << '\n';
}
// If filename is passed, it is printed instead of the formula. We
// use that when processing games since we have no formula to print.
// It would be cleaner to have two columns: one for location (that's
// filename + line number if known), and one for formula (if known).
static void
print_csv(const spot::formula& f, const char* filename = nullptr)
{
auto& vs = gi->verbose_stream;
auto& bv = gi->bv;
@ -230,7 +292,9 @@ namespace
if (vs)
*vs << "writing CSV to " << opt_csv << '\n';
output_file outf(opt_csv);
static bool not_first_time = false;
output_file outf(opt_csv, not_first_time);
not_first_time = true; // force append on next print.
std::ostream& out = outf.ostream();
// Do not output the header line if we append to a file.
@ -255,10 +319,15 @@ namespace
out << '\n';
}
std::ostringstream os;
os << f;
spot::escape_rfc4180(out << '"', os.str());
out << "\",\"" << algo_names[(int) gi->s]
<< "\"," << bv->total_time
if (filename)
os << filename;
else
os << f;
spot::escape_rfc4180(out << '"', os.str()) << "\",";
// if a filename was given, assume the game has been read directly
if (!filename)
out << '"' << algo_names[(int) gi->s] << '"';
out << ',' << bv->total_time
<< ',' << bv->trans_time
<< ',' << bv->split_time
<< ',' << bv->paritize_time;
@ -285,11 +354,13 @@ namespace
outf.close(opt_csv);
}
int
static int
solve_formula(const spot::formula& f,
const std::vector<std::string>& input_aps,
const std::vector<std::string>& output_aps)
{
if (opt_csv) // reset benchmark data
gi->bv = spot::synthesis_info::bench_var();
spot::stopwatch sw;
if (gi->bv)
sw.start();
@ -305,6 +376,12 @@ namespace
if (opt_decompose_ltl)
{
auto subs = split_independant_formulas(f, output_aps);
if (gi->verbose_stream)
{
*gi->verbose_stream << "there are "
<< subs.first.size()
<< " subformulas\n";
}
if (subs.first.size() > 1)
{
sub_form = subs.first;
@ -347,17 +424,6 @@ namespace
auto sub_o = sub_outs_str.begin();
std::vector<spot::mealy_like> mealy_machines;
auto print_game = want_game ?
[](const spot::twa_graph_ptr& game)->void
{
if (opt_print_pg)
pg_print(std::cout, game);
else
spot::print_hoa(std::cout, game, opt_print_hoa_args) << '\n';
}
:
[](const spot::twa_graph_ptr&)->void{};
for (; sub_f != sub_form.end(); ++sub_f, ++sub_o)
{
spot::mealy_like m_like
@ -368,15 +434,16 @@ namespace
};
// If we want to print a game,
// we never use the direct approach
if (!want_game)
if (!want_game && opt_bypass)
m_like =
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi);
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi, !opt_real);
switch (m_like.success)
{
case spot::mealy_like::realizability_code::UNREALIZABLE:
{
std::cout << "UNREALIZABLE" << std::endl;
if (show_status)
std::cout << "UNREALIZABLE" << std::endl;
safe_tot_time();
return 1;
}
@ -394,13 +461,20 @@ namespace
assert((spptr->at(arena->get_init_state_number()) == false)
&& "Env needs first turn");
}
print_game(arena);
if (want_game)
{
dispatch_print_hoa(arena);
continue;
}
if (!spot::solve_game(arena, *gi))
{
std::cout << "UNREALIZABLE" << std::endl;
if (show_status)
std::cout << "UNREALIZABLE" << std::endl;
safe_tot_time();
return 1;
}
if (gi->bv)
gi->bv->realizable = true;
// Create the (partial) strategy
// only if we need it
if (!opt_real)
@ -408,14 +482,13 @@ namespace
spot::mealy_like ml;
ml.success =
spot::mealy_like::realizability_code::REALIZABLE_REGULAR;
if (opt_print_aiger)
// we do not care about the type,
// machine to aiger can handle it
ml.mealy_like =
spot::solved_game_to_mealy(arena, *gi);
else
ml.mealy_like =
spot::solved_game_to_separated_mealy(arena, *gi);
// By default this produces a split machine
ml.mealy_like =
spot::solved_game_to_mealy(arena, *gi);
// Keep the machine split for aiger
// else -> separated
spot::simplify_mealy_here(ml.mealy_like, *gi,
opt_print_aiger);
ml.glob_cond = bddfalse;
mealy_machines.push_back(ml);
}
@ -426,54 +499,14 @@ namespace
// the direct approach yielded a strategy
// which can now be minimized
// We minimize only if we need it
assert(m_like.mealy_like && "Expected success but found no mealy!");
assert(opt_real ||
(m_like.mealy_like && "Expected success but found no mealy!"));
if (!opt_real)
{
spot::stopwatch sw_direct;
sw_direct.start();
if ((0 < gi->minimize_lvl) && (gi->minimize_lvl < 3))
// Uses reduction or not,
// both work with mealy machines (non-separated)
reduce_mealy_here(m_like.mealy_like, gi->minimize_lvl == 2);
auto delta = sw_direct.stop();
sw_direct.start();
// todo better algo here?
m_like.mealy_like =
split_2step(m_like.mealy_like,
spot::get_synthesis_outputs(m_like.mealy_like),
false);
if (gi->bv)
gi->bv->split_time += sw_direct.stop();
sw_direct.start();
if (gi->minimize_lvl >= 3)
{
sw_direct.start();
// actual minimization, works on split mealy
m_like.mealy_like = minimize_mealy(m_like.mealy_like,
gi->minimize_lvl - 4);
delta = sw_direct.stop();
}
// If our goal is to have an aiger,
// we can use split or separated machines
if (!opt_print_aiger)
// Unsplit to have separated mealy
m_like.mealy_like = unsplit_mealy(m_like.mealy_like);
if (gi->bv)
gi->bv->strat2aut_time += delta;
if (gi->verbose_stream)
*gi->verbose_stream << "final strategy has "
<< m_like.mealy_like->num_states()
<< " states and "
<< m_like.mealy_like->num_edges()
<< " edges\n"
<< "minimization took " << delta
<< " seconds\n";
// Keep the machine split for aiger
// else -> separated
spot::simplify_mealy_here(m_like.mealy_like, *gi,
opt_print_aiger);
}
SPOT_FALLTHROUGH;
}
@ -494,7 +527,8 @@ namespace
return 0;
}
std::cout << "REALIZABLE" << std::endl;
if (show_status)
std::cout << "REALIZABLE" << std::endl;
if (opt_real)
{
safe_tot_time();
@ -503,8 +537,8 @@ namespace
// If we reach this line
// a strategy was found for each subformula
assert(mealy_machines.size() == sub_form.size()
&& "There are subformula for which no mealy like object"
"has been created.");
&& ("There are subformula for which no mealy like object"
" has been created."));
spot::aig_ptr saig = nullptr;
spot::twa_graph_ptr tot_strat = nullptr;
@ -533,7 +567,10 @@ namespace
<< " latches and "
<< saig->num_gates() << " gates\n";
}
spot::print_aiger(std::cout, saig) << '\n';
if (opt_dot)
spot::print_dot(std::cout, saig, opt_dot_arg);
else
spot::print_aiger(std::cout, saig) << '\n';
}
else
{
@ -545,7 +582,8 @@ namespace
&& "ltlsynt: Cannot handle TGBA as strategy.");
tot_strat = mealy_machines.front().mealy_like;
for (size_t i = 1; i < mealy_machines.size(); ++i)
tot_strat = spot::product(tot_strat, mealy_machines[i].mealy_like);
tot_strat = spot::mealy_product(tot_strat,
mealy_machines[i].mealy_like);
printer.print(tot_strat, timer_printer_dummy);
}
@ -583,15 +621,27 @@ namespace
return 0;
}
static void
split_aps(const std::string& arg, std::vector<std::string>& where)
{
std::istringstream aps(arg);
std::string ap;
while (std::getline(aps, ap, ','))
{
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
where.push_back(str_tolower(ap));
}
}
class ltl_processor final : public job_processor
{
private:
std::vector<std::string> input_aps_;
std::vector<std::string> output_aps_;
std::optional<std::vector<std::string>> input_aps_;
std::optional<std::vector<std::string>> output_aps_;
public:
ltl_processor(std::vector<std::string> input_aps_,
std::vector<std::string> output_aps_)
ltl_processor(std::optional<std::vector<std::string>> input_aps_,
std::optional<std::vector<std::string>> output_aps_)
: input_aps_(std::move(input_aps_)),
output_aps_(std::move(output_aps_))
{
@ -601,11 +651,13 @@ namespace
const char* filename, int linenum) override
{
auto unknown_aps = [](spot::formula f,
const std::vector<std::string>& known,
const std::vector<std::string>* known2 = nullptr)
const std::optional<std::vector<std::string>>& known,
const std::optional<std::vector<std::string>>& known2 = {})
{
std::vector<std::string> unknown;
std::set<spot::formula> seen;
// If we don't have --ins and --outs, we must not find an AP.
bool can_have_ap = known.has_value();
f.traverse([&](const spot::formula& s)
{
if (s.is(spot::op::ap))
@ -613,10 +665,11 @@ namespace
if (!seen.insert(s).second)
return false;
const std::string& a = s.ap_name();
if (std::find(known.begin(), known.end(), a) == known.end()
&& (!known2
if (!can_have_ap
|| (std::find(known->begin(), known->end(), a) == known->end()
&& (!known2.has_value()
|| std::find(known2->begin(),
known2->end(), a) == known2->end()))
known2->end(), a) == known2->end())))
unknown.push_back(a);
}
return false;
@ -626,36 +679,233 @@ namespace
// Decide which atomic propositions are input or output.
int res;
if (input_aps_.empty() && !output_aps_.empty())
if (!input_aps_.has_value() && output_aps_.has_value())
{
res = solve_formula(f, unknown_aps(f, output_aps_), output_aps_);
res = solve_formula(f, unknown_aps(f, output_aps_), *output_aps_);
}
else if (output_aps_.empty() && !input_aps_.empty())
else if (!output_aps_.has_value() && input_aps_.has_value())
{
res = solve_formula(f, input_aps_, unknown_aps(f, input_aps_));
res = solve_formula(f, *input_aps_, unknown_aps(f, input_aps_));
}
else if (output_aps_.empty() && input_aps_.empty())
else if (!output_aps_.has_value() && !input_aps_.has_value())
{
for (const std::string& ap: unknown_aps(f, input_aps_, &output_aps_))
for (const std::string& ap: unknown_aps(f, input_aps_, output_aps_))
error_at_line(2, 0, filename, linenum,
"one of --ins or --outs should list '%s'",
ap.c_str());
res = solve_formula(f, input_aps_, output_aps_);
res = solve_formula(f, *input_aps_, *output_aps_);
}
else
{
for (const std::string& ap: unknown_aps(f, input_aps_, &output_aps_))
for (const std::string& ap: unknown_aps(f, input_aps_, output_aps_))
error_at_line(2, 0, filename, linenum,
"both --ins and --outs are specified, "
"but '%s' is unlisted",
ap.c_str());
res = solve_formula(f, input_aps_, output_aps_);
res = solve_formula(f, *input_aps_, *output_aps_);
}
if (opt_csv)
print_csv(f);
return res;
}
int
process_tlsf_file(const char* filename) override
{
static char arg0[] = "syfco";
static char arg1[] = "-f";
static char arg2[] = "ltlxba";
static char arg3[] = "-m";
static char arg4[] = "fully";
char* command[] = { arg0, arg1, arg2, arg3, arg4,
const_cast<char*>(filename), nullptr };
std::string tlsf_string = read_stdout_of_command(command);
// The set of atomic proposition will be temporary set to those
// given by syfco, unless they were forced from the command-line.
bool reset_aps = false;
if (!input_aps_.has_value() && !output_aps_.has_value())
{
reset_aps = true;
static char arg5[] = "--print-output-signals";
char* command[] = { arg0, arg5,
const_cast<char*>(filename), nullptr };
std::string res = read_stdout_of_command(command);
output_aps_.emplace(std::vector<std::string>{});
split_aps(res, *output_aps_);
}
int res = process_string(tlsf_string, filename);
if (reset_aps)
output_aps_.reset();
return res;
}
int process_pgame(spot::twa_graph_ptr arena,
const std::string& location)
{
if (opt_csv) // reset benchmark data
gi->bv = spot::synthesis_info::bench_var();
spot::stopwatch sw_global;
spot::stopwatch sw_local;
if (gi->bv)
{
sw_global.start();
sw_local.start();
}
if (!arena->get_named_prop<bdd>("synthesis-outputs"))
{
std::cerr << location << ": controllable-AP is not specified\n";
return 2;
}
if (!arena->get_named_prop<std::vector<bool>>("state-player"))
arena = spot::split_2step(arena, true);
else
{
// Check if the game is alternating and fix trivial cases
const unsigned N = arena->num_states();
// Can not use get_state_players because we need a non-const version
auto spptr =
arena->get_named_prop<std::vector<bool>>("state-player");
assert(spptr);
const bdd& outs = get_synthesis_outputs(arena);
for (unsigned n = 0; n < N; ++n)
{
const bool p = (*spptr)[n];
for (auto& e : arena->out(n))
{
if (p != (*spptr)[e.dst])
continue; // All good
// Check if the condition is a simply conjunction of input and
// output. If so insert an intermediate state
// This also covers trivial self-loops
bdd cond = e.cond;
bdd i_cond = bdd_exist(cond, outs);
bdd o_cond = bdd_existcomp(cond, outs);
if ((i_cond & o_cond) == cond)
{
unsigned inter = arena->new_state();
spptr->push_back(!p);
e.cond = p ? o_cond : i_cond;
e.dst = inter;
arena->new_edge(inter, e.dst, !p ? o_cond : i_cond);
}
else
throw std::runtime_error("ltlsynt: given parity game is not"
"alternating and not trivially fixable!");
}
}
}
if (gi->bv)
{
gi->bv->split_time += sw_local.stop();
gi->bv->nb_states_arena += arena->num_states();
auto spptr =
arena->get_named_prop<std::vector<bool>>("state-player");
assert(spptr);
gi->bv->nb_states_arena_env +=
std::count(spptr->cbegin(), spptr->cend(), false);
}
if (opt_print_pg || opt_print_hoa)
{
dispatch_print_hoa(arena);
return 0;
}
auto safe_tot_time = [&]() {
if (gi->bv)
gi->bv->total_time = sw_global.stop();
};
if (!spot::solve_game(arena, *gi))
{
if (show_status)
std::cout << "UNREALIZABLE" << std::endl;
safe_tot_time();
return 1;
}
if (gi->bv)
gi->bv->realizable = true;
if (show_status)
std::cout << "REALIZABLE" << std::endl;
if (opt_real)
{
safe_tot_time();
return 0;
}
sw_local.start();
spot::twa_graph_ptr mealy_like =
spot::solved_game_to_mealy(arena, *gi);
// Keep the machine split for aiger otherwise, separate it.
spot::simplify_mealy_here(mealy_like, *gi, opt_print_aiger);
automaton_printer printer;
spot::process_timer timer_printer_dummy;
if (opt_print_aiger)
{
if (gi->bv)
sw_local.start();
spot::aig_ptr saig =
spot::mealy_machine_to_aig(mealy_like, opt_print_aiger);
if (gi->bv)
{
gi->bv->aig_time = sw_local.stop();
gi->bv->nb_latches = saig->num_latches();
gi->bv->nb_gates = saig->num_gates();
}
if (gi->verbose_stream)
{
*gi->verbose_stream << "AIG circuit was created in "
<< gi->bv->aig_time
<< " seconds and has " << saig->num_latches()
<< " latches and "
<< saig->num_gates() << " gates\n";
}
spot::print_aiger(std::cout, saig) << '\n';
}
else
{
printer.print(mealy_like, timer_printer_dummy);
}
safe_tot_time();
return 0;
}
int
process_aut_file(const char* filename) override
{
spot::automaton_stream_parser hp(filename);
int err = 0;
while (!abort_run)
{
spot::parsed_aut_ptr haut = hp.parse(spot::make_bdd_dict());
if (!haut->aut && haut->errors.empty())
break;
if (haut->format_errors(std::cerr))
err = 2;
if (!haut->aut /*|| (err && abort_on_error_)*/)
{
error(2, 0, "failed to read automaton from %s",
haut->filename.c_str());
}
else if (haut->aborted)
{
std::cerr << haut->filename << ':' << haut->loc
<< ": aborted input automaton\n";
err = std::max(err, 2);
}
else
{
std::ostringstream os;
os << haut->filename << ':' << haut->loc;
std::string loc = os.str();
int res = process_pgame(haut->aut, loc);
if (res < 2 && opt_csv)
print_csv(nullptr, loc.c_str());
err = std::max(err, res);
}
}
return err;
}
};
}
@ -669,35 +919,37 @@ parse_opt(int key, char *arg, struct argp_state *)
case OPT_ALGO:
gi->s = XARGMATCH("--algo", arg, algo_args, algo_types);
break;
case OPT_BYPASS:
opt_bypass = XARGMATCH("--bypass", arg, bypass_args, bypass_values);
break;
case OPT_CSV:
opt_csv = arg ? arg : "-";
if (not gi->bv)
gi->bv = spot::synthesis_info::bench_var();
break;
case OPT_DECOMPOSE:
opt_decompose_ltl = XARGMATCH("--decompose", arg,
decompose_args, decompose_values);
break;
case OPT_DOT:
opt_dot = true;
automaton_format_opt = opt_dot_arg = arg;
automaton_format = Dot;
break;
case OPT_FROM_PGAME:
jobs.emplace_back(arg, job_type::AUT_FILENAME);
break;
case OPT_HIDE:
show_status = false;
break;
case OPT_INPUT:
{
std::istringstream aps(arg);
std::string ap;
while (std::getline(aps, ap, ','))
{
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
all_input_aps.push_back(str_tolower(ap));
}
all_input_aps.emplace(std::vector<std::string>{});
split_aps(arg, *all_input_aps);
break;
}
case OPT_OUTPUT:
{
std::istringstream aps(arg);
std::string ap;
while (std::getline(aps, ap, ','))
{
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
all_output_aps.push_back(str_tolower(ap));
}
all_output_aps.emplace(std::vector<std::string>{});
split_aps(arg, *all_output_aps);
break;
}
case OPT_PRINT:
@ -718,6 +970,9 @@ parse_opt(int key, char *arg, struct argp_state *)
gi->minimize_lvl = XARGMATCH("--simplify", arg,
simplify_args, simplify_values);
break;
case OPT_TLSF:
jobs.emplace_back(arg, job_type::TLSF_FILENAME);
break;
case OPT_VERBOSE:
gi->verbose_stream = &std::cerr;
if (not gi->bv)
@ -754,13 +1009,15 @@ main(int argc, char **argv)
argp_program_doc, children, nullptr, nullptr };
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
check_no_formula();
// Check if inputs and outputs are distinct
for (const std::string& ai : all_input_aps)
if (std::find(all_output_aps.begin(), all_output_aps.end(), ai)
!= all_output_aps.end())
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
if (all_input_aps.has_value() && all_output_aps.has_value())
for (const std::string& ai : *all_input_aps)
if (std::find(all_output_aps->begin(), all_output_aps->end(), ai)
!= all_output_aps->end())
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
ltl_processor processor(all_input_aps, all_output_aps);
if (int res = processor.run(); res == 0 || res == 1)

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2016, 2018-2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2012-2016, 2018-2020, 2022 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -42,7 +42,7 @@
#include <spot/twaalgos/canonicalize.hh>
const char argp_program_doc[] = "\
static const char argp_program_doc[] = "\
Generate random connected automata.\n\n\
The automata are built over the atomic propositions named by PROPS...\n\
or, if N is a nonnegative number, using N arbitrary names.\n\

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
// Copyright (C) 2012-2016, 2018-2019, 2022, 2023 Laboratoire de
// Recherche et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -40,7 +40,7 @@
#include <spot/misc/random.hh>
#include <spot/misc/optionmap.hh>
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Generate random temporal logic formulas.\n\n\
The formulas are built over the atomic propositions named by PROPS...\n\
or, if N is a nonnegative number, using N arbitrary names.\v\
@ -65,7 +65,6 @@ enum {
OPT_DUMP_PRIORITIES,
OPT_DUPS,
OPT_LTL_PRIORITIES,
OPT_PSL_PRIORITIES,
OPT_SEED,
OPT_SERE_PRIORITIES,
OPT_TREE_SIZE,
@ -194,7 +193,6 @@ parse_opt(int key, char* arg, struct argp_state* as)
case OPT_DUMP_PRIORITIES:
opt_dump_priorities = true;
break;
// case OPT_PSL_PRIORITIES: break;
case OPT_SERE_PRIORITIES:
opt_pS = arg;
break;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -24,7 +24,7 @@
#include <argp.h>
#include "common_setup.hh"
const char argp_program_doc[] ="\
static const char argp_program_doc[] = "\
Common fine-tuning options for programs installed with Spot.\n\
\n\
The argument of -x or --extra-options is a comma-separated list of KEY=INT \
@ -47,9 +47,17 @@ depends on the --low, --medium, or --high settings.") },
{ DOC("tls-max-states",
"Maximum number of states of automata involved in automata-based \
implication checks for formula simplifications. Defaults to 64.") },
{ DOC("tls-max-ops",
"Maximum number of operands in n-ary opertors (or, and) on which \
implication-based simplifications are attempted. Defaults to 16.") },
{ nullptr, 0, nullptr, 0, "Translation options:", 0 },
{ DOC("ltl-split", "Set to 0 to disable the translation of automata \
as product or sum of subformulas.") },
{ DOC("branch-post", "Set to 0 to disable branching-postponement \
(done during translation, may create more states) and delayed-branching \
(almost similar, but done after translation to only remove states). \
Set to 1 to force branching-postponement, and to 2 \
to force delayed-branching. By default delayed-branching is used.") },
{ DOC("comp-susp", "Set to 1 to enable compositional suspension, \
as described in our SPIN'13 paper (see Bibliography below). Set to 2, \
to build only the skeleton TGBA without composing it. Set to 0 (the \
@ -75,6 +83,9 @@ only if it is smaller than the original skeleton. This option is only \
used when comp-susp=1 and default to 1 or 2 depending on whether --small \
or --deterministic is specified.") },
{ nullptr, 0, nullptr, 0, "Postprocessing options:", 0 },
{ DOC("acd", "Set to 1 (the default) to use paritize automata using \
the alternatinc cycle decomposition. Set to 0 to use paritization based \
on latest appearance record variants.") },
{ DOC("scc-filter", "Set to 1 (the default) to enable \
SCC-pruning and acceptance simplification at the beginning of \
post-processing. Transitions that are outside of accepting SCC are \
@ -164,6 +175,10 @@ Set to 1 to use only direct simulation. Set to 2 to use only reverse \
simulation. Set to 3 to iterate both direct and reverse simulations. \
The default is the value of parameter \"simul\" in --high mode, and 0 \
therwise.") },
{ DOC("merge-states-min", "Number of states above which states are \
merged using a cheap approximation of a bisimulation quotient before \
attempting simulation-based reductions. Defaults to 128. Set to 0 to \
never merge states.") },
{ DOC("simul-max", "Number of states above which simulation-based \
reductions are skipped. Defaults to 4096. Set to 0 to disable. This \
applies to all simulation-based optimization, including thoses of the \

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2018 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2013-2018, 2022 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -24,7 +24,8 @@
#include <argp.h>
#include "common_setup.hh"
const char argp_program_doc[] ="Command-line tools installed by Spot.";
static const char argp_program_doc[] =
"Command-line tools installed by Spot.";
#define DOC(NAME, TXT) NAME, 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, TXT, 0

View file

@ -501,6 +501,7 @@ BUDDY_API_VAR const BDD bddtrue;
*************************************************************************/
#ifdef CPLUSPLUS
#include <iostream>
#include <memory>
/*=== User BDD class ===================================================*/
@ -1092,6 +1093,11 @@ inline bddxfalse bdd_false(void)
{ return bddxfalse(); }
template<>
struct std::default_delete<bddPair> {
void operator()(bddPair *p) const { bdd_freepair(p); };
};
/*=== Iostream printing ================================================*/
class BUDDY_API bdd_ioformat

View file

@ -210,7 +210,6 @@ static BddTree *reorder_win2ite(BddTree *t)
{
BddTree *this, *first=t;
int lastsize;
int c=1;
if (t == NULL)
return t;
@ -246,7 +245,6 @@ static BddTree *reorder_win2ite(BddTree *t)
if (verbose > 1)
printf(" %d nodes\n", reorder_nodenum());
c++;
}
while (reorder_nodenum() != lastsize);

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2022, Laboratoire de Recherche et Développement
# Copyright (C) 2008-2023, Laboratoire de Recherche et Développement
# de l'Epita (LRDE).
# Copyright (C) 2003-2007 Laboratoire d'Informatique de Paris 6
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
@ -21,7 +21,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ([2.69])
AC_INIT([spot], [2.10.4.dev], [spot@lrde.epita.fr])
AC_INIT([spot], [2.11.5.dev], [spot@lrde.epita.fr])
AC_CONFIG_AUX_DIR([tools])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests])
@ -53,6 +53,15 @@ AC_ARG_ENABLE([c++20],
[Compile in C++20 mode.])],
[enable_20=$enableval], [enable_20=no])
AC_ARG_ENABLE([pthread],
[AS_HELP_STRING([--enable-pthread],
[Allow libspot to use POSIX threads.])],
[enable_pthread=$enableval], [enable_pthread=no])
if test "$enable_pthread" = yes; then
AC_DEFINE([ENABLE_PTHREAD], [1], [Whether Spot is compiled with -pthread.])
AC_SUBST([LIBSPOT_PTHREAD], [-pthread])
fi
AC_ARG_ENABLE([doxygen],
[AS_HELP_STRING([--enable-doxygen],
[enable generation of Doxygen documentation (requires Doxygen)])],
@ -70,6 +79,7 @@ if test 0 -eq `expr $enable_max_accsets % $default_max_accsets`
then
AC_DEFINE_UNQUOTED([MAX_ACCSETS], [$enable_max_accsets],
[The maximal number of acceptance sets supported (also known as acceptance marks)])
AC_SUBST([MAX_ACCSETS], [$enable_max_accsets])
else
AC_MSG_ERROR([The argument of --enable-max-accsets must be a multiple of $default_max_accsets])
fi
@ -150,7 +160,7 @@ AX_CHECK_BUDDY
AC_CHECK_FUNCS([times kill alarm sigaction sched_getcpu])
oLIBS=$LIBS
LIBS="$LIBS -lpthread"
LIBS="$LIBS -pthread"
AC_CHECK_FUNCS([pthread_setaffinity_np])
LIBS=$oLIBS
@ -179,9 +189,14 @@ if test "x${enable_python:-yes}" = xyes; then
AC_MSG_NOTICE([You may configure with --disable-python ]dnl
[if you do not need Python bindings.])
adl_CHECK_PYTHON
AC_ARG_WITH([pythondir],
[AS_HELP_STRING([--with-pythondir], [override the computed pythondir])],
[pythondir=$withval pyexecdir=$withval], [])
fi
adl_ENABLE_DEBUG
ad_GCC_OPTIM
adl_NDEBUG
@ -202,7 +217,7 @@ AC_CHECK_PROG([LTL3BA], [ltl3ba], [ltl3ba])
AC_CHECK_PROG([PERL], [perl], [perl])
AC_CHECK_PROG([SPIN], [spin], [spin])
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
AC_CHECK_PROG([EMACS], [emacs], [emacs])
AM_MISSING_PROG([EMACS], [emacs])
AC_CHECK_PROGS([IPYTHON], [ipython3 ipython], [ipython])
AC_CHECK_PROGS([JUPYTER], [jupyter], [jupyter])
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
@ -280,3 +295,23 @@ case $VERSION:$enable_devel in
echo '==================================================================='
;;
esac
case $enable_python in
yes)
pd=$pythondir
eval pd=$pd
eval pd=$pd
$PYTHON -c "
import sys
if '$pd' in sys.path:
exit()
else:
print('\nWARNING: Python bindings will be installed in $pd')
print(' however this path is not searched by default by $PYTHON.')
print('\n$PYTHON\'s sys.path contains the following paths:\n',
'\n'.join(sys.path))
print('\nUse --with-pythondir=... if you wish '
'to change this installation path.')
"
;;
esac

2
debian/control vendored
View file

@ -2,7 +2,7 @@ Source: spot
Section: science
Priority: optional
Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
Build-Depends: debhelper (>= 12), python3-all-dev, ipython3-notebook | python3-ipykernel, ipython3-notebook | python3-nbconvert, libltdl-dev, dh-python
Build-Depends: debhelper (>= 12), python3-all-dev, ipython3-notebook | python3-ipykernel, ipython3-notebook | python3-nbconvert, libltdl-dev, dh-python, graphviz, jupyter-nbconvert, doxygen
Standards-Version: 4.5.1
Homepage: http://spot.lrde.epita.fr/

2
debian/copyright vendored
View file

@ -1,6 +1,6 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: spot
Source: http://spot.lrde.epita.fr/dload/spot/
Source: http://www.lrde.epita.fr/dload/spot/
Files: *
Copyright: 2003-2007 Laboratoire d'Informatique de Paris 6 (LIP6)

22
debian/rules vendored
View file

@ -20,20 +20,16 @@ include /usr/share/dpkg/default.mk
%:
dh $@ --with=python3
# Find the LTO plugin, which we need to pass to ar, nm, and ranlib.
LTOPLUG := $(shell gcc -v 2>&1 | \
sed -n 's:COLLECT_LTO_WRAPPER=\(/.*/\)[^/]*:\1:p')liblto_plugin.so
# ARFLAGS is for Automake
# AR_FLAGS is for Libtool
# These activate the LTO pluggin, but also remove the 'u' option
# from ar, since its now ignored with Debian's default to 'D'.
LTOSETUP = \
LDFLAGS='-fuse-linker-plugin' \
NM='nm --plugin $(LTOPLUG)' \
ARFLAGS='cr --plugin $(LTOPLUG)' \
AR_FLAGS='cr --plugin $(LTOPLUG)' \
RANLIB='ranlib --plugin $(LTOPLUG)' \
# AR_FLAGS is for Libtool, (but libtool 2.4.7 will now use ARFLAGS as well)
# The gcc-tools activate the LTO plugin.
LTOSETUP = \
LDFLAGS='-fuse-linker-plugin' \
NM='gcc-nm' \
AR='gcc-ar' \
ARFLAGS='cr' \
AR_FLAGS='cr' \
RANLIB='gcc-ranlib' \
VALGRIND=false
GCDADIR := $(shell pwd)/gcda

35
default.nix.in Normal file
View file

@ -0,0 +1,35 @@
# -*- mode: nix; coding: utf-8 -*-
# Copyright (C) 2022 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/>.
{ pkgs ? import <nixpkgs> {} }:
let
version = "@VERSION@";
in
pkgs.stdenv.mkDerivation {
inherit version;
pname = "spot";
buildInputs = [
pkgs.python3
];
src = ./.;
enableParallelBuilding = true;
}

View file

@ -27,6 +27,9 @@
(setenv "SPOT_DOTEXTRA" "node[fontsize=12] fontsize=12 stylesheet=\"spot.css\" edge[arrowhead=vee, arrowsize=.7, fontsize=12]")
(setq org-babel-temporary-directory "@abs_top_builddir@/doc/org/tmp")
(make-directory org-babel-temporary-directory t)
; has to be set globally, not buffer-local
(setq ess-ask-for-ess-directory nil)
(setq ess-startup-directory 'default-directory)
(org-babel-do-load-languages 'org-babel-load-languages
`((,(if (version< org-version "8.3") 'sh 'shell) . t)
(python . t)
@ -39,7 +42,6 @@
(org-babel-python-command . "@PYTHON@")
(org-babel-C++-compiler . "./g++wrap")
(shell-file-name . "@SHELL@")
(ess-ask-for-ess-directory . nil)
(org-export-html-postamble . nil)
(org-html-table-header-tags
"<th scope=\"%s\"%s><div><span>" . "</span></div></th>")

View file

@ -249,7 +249,7 @@ EOF
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | AF | ok | 0 | 0.0211636 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 |
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | L2D | ok | 0 | 0.0028508 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 |
* Language preserving transformation
* Transformation that preserve or complement languages
By default =autcross= assumes that for a given input the automata
produced by all tools should be equivalent. However it does not
@ -261,6 +261,13 @@ automaton, it is worth to pass the =--language-preserved= option to
=autfilt=. Doing so a bit like adding =cat %H>%O= as another tool: it
will also ensure that the output is equivalent to the input.
Similarly, if the tools being tested implement complementation
algorithm, adding the =--language-complemented= will additionally
compare the outputs using this own complementation algorithm. Using
this option is more efficient than passing =autfilt --complement= as a
tool, since =autcross= can save on complementation by using the input
automaton.
* Detecting problems
:PROPERTIES:
:CUSTOM_ID: checks

View file

@ -145,7 +145,8 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
(iw) inherently weak. Use uppercase letters to
negate them.
%d 1 if the output is deterministic, 0 otherwise
%e number of reachable edges
%e, %[LETTER]e number of edges (add one LETTER to select (r)
reachable [default], (u) unreachable, (a) all).
%f the formula, in Spot's syntax
%F name of the input file
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
@ -170,8 +171,11 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
LETTERS to restrict to(u) user time, (s) system
time, (p) parent process, or (c) children
processes.
%s number of reachable states
%t number of reachable transitions
%s, %[LETTER]s number of states (add one LETTER to select (r)
reachable [default], (u) unreachable, (a) all).
%t, %[LETTER]t number of transitions (add one LETTER to select
(r) reachable [default], (u) unreachable, (a)
all).
%u, %[e]u number of states (or [e]dges) with universal
branching
%u, %[LETTER]u 1 if the automaton contains some universal

View file

@ -6,18 +6,22 @@
* Generic reference
If you need to cite the Spot project in some academic paper, please
use the following reference:
If you need to cite the Spot project, the latest tool paper about
it is the following reference:
- *Spot 2.0 — a framework for LTL and ω-automata manipulation*,
/Alexandre Duret-Lutz/, /Alexandre Lewkowicz/, /Amaury Fauchille/,
/Thibaud Michaud/, /Etienne Renault/, and /Laurent Xu/. In Proc.
of ATVA'16, LNCS 9938, pp. 122--129. Chiba, Japan, Oct. 2016.
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.16.atva2][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][pdf]])
- *From Spot 2.0 to Spot 2.10: What's new?*, /Alexandre Duret-Lutz/,
/Etienne Renault/, /Maximilien Colange/, /Florian Renkin/,
/Alexandre Gbaguidi Aisse/, /Philipp Schlehuber-Caissier/, /Thomas
Medioni/, /Antoine Martin/, /Jérôme Dubois/, /Clément Gillard/, and
Henrich Lauko/. In Proc. of CAV'22, LNCS 13372, pp. 174--187.
Haifa, Israel, Aug. 2022.
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.22.cav][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.22.cav.pdf][pdf]])
This provides a quick overview of the entire project (the features
of the library, [[file:tools.org][the tools]], the Python bindings), and provides many
references detailing more specific aspects.
#+begin_note
Tools evolve while published papers don't. Please always specify
the version of Spot (or any other tool) you are using when citing it
in a paper. Future versions might have different behaviors.
#+end_note
* Other, more specific, references
@ -76,12 +80,28 @@ be more specific about a particular aspect of Spot.
- *Generic Emptiness Check for Fun and Profit*,
/Christel Baier/, /František Blahoudek/, /Alexandre Duret-Lutz/,
/Joachim Klein/, /David Müller/, and /Jan Strejček/.
In. Proc. of ATVA'19, LNCS 11781, pp. 11781, Oct 2019. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#baier.19.atva][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.pdf][pdf]] |
In. Proc. of ATVA'19, LNCS 11781, pp. 445--461, Oct 2019. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#baier.19.atva][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.pdf][pdf]] |
[[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.slides.mefosyloma.pdf][slides1]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.slides.pdf][slides2]])
Presents the generic emptiness-check implemented in Spot.
* Obsolete reference
- *Practical Applications of the Alternating Cycle Decomposition*,
/Antonio Casares/, /Alexandre Duret-Lutz/, /Klara J. Meyer/, /Florian Renkin/,
and /Salomon Sickert/.
In. Proc. of TACAS'22, LNCS 13244, pp. 99--117, Apr 2022. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#casares.22.tacas][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.pdf][pdf]] |
[[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.slides.pdf][slides1]] | [[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.slides2.pdf][slides2]])
* Obsolete references
- *Spot 2.0 — a framework for LTL and ω-automata manipulation*,
/Alexandre Duret-Lutz/, /Alexandre Lewkowicz/, /Amaury Fauchille/,
/Thibaud Michaud/, /Etienne Renault/, and /Laurent Xu/. In Proc.
of ATVA'16, LNCS 9938, pp. 122--129. Chiba, Japan, Oct. 2016.
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.16.atva2][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][pdf]])
This provides a quick overview of the entire project (the features
of the library, [[file:tools.org][the tools]], the Python bindings), and provides many
references detailing more specific aspects.
- *Spot: an extensible model checking library using transition-based
generalized Büchi automata*, /Alexandre Duret-Lutz/ and /Denis

View file

@ -210,11 +210,14 @@ one library requiring another, you will need to link with the =bddx=
library. This should be as simple as adding =-lbddx= after =-lspot=
in the first three cases.
Similarly, if Spot has been configured with =--enable-pthread=, you
will need to add =-pthread= to the compiler flags.
In the fourth case where =libtool= is used to link against
=libspot.la= linking against =libbddx.la= should not be necessary because
Libtool already handles such dependencies. However the version of =libtool=
distributed with Debian is patched to ignore those dependencies, so in this
case you 2
case you have to list all dependencies.
* Additional suggestions

View file

@ -381,13 +381,14 @@ When /transition-based acceptance/ is used, acceptance sets are now
sets of /edges/ (or set of /transitions/ if you prefer), and runs are
accepting if the edges they visit satisfy the acceptance condition.
Here is an example of Transition-based Generalized Büchi Automaton
(TGBA).
Here is an example of Transition-based Büchi Automaton
(TBA).
#+NAME: tgba-example1
#+BEGIN_SRC sh
ltl2tgba 'GF(a & X(a U b))' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results
$txt
#+END_SRC
@ -399,27 +400,13 @@ This automaton accept all ω-words that infinitely often match the
pattern $a^+;b$ (that is: a positive number of letters where $a$ is
true are followed by one letter where $b$ is true).
Using transition-based acceptance allows for more compact automata.
The typical example is the LTL formula =GFa= (infinitely often $a$)
that can be represented using a one-state transition-based Büchi
automaton:
#+NAME: tgba-example2
#+BEGIN_SRC sh
ltl2tgba 'GFa' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tgba2.svg :var txt=tgba-example2 :exports results
$txt
#+END_SRC
#+RESULTS:
[[file:concept-tgba2.svg]]
While the same property require a 2-state Büchi automaton using
Using transition-based acceptance often allows for more compact automata.
For instance the above automaton would need at least 3 states with
state-based acceptance:
#+NAME: tgba-example3
#+BEGIN_SRC sh
ltl2tgba 'GFa' -B -d
ltl2tgba 'GF(a & X(a U b))' -B -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results
$txt
@ -1035,7 +1022,7 @@ layers.
dynamic libraries that [[http://fmt.cs.utwente.nl/tools/ltsmin/][LTSmin]] uses to represent state-spaces. It
currently supports libraries generated from Promela models using
SpinS or a patched version of DiVinE, but you have to install
those third-party tools first. See [[https://gitlab.lrde.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
those third-party tools first. See [[https://gitlab.lre.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
for details.
- In addition to the C++17 API, we also provide Python bindings for
=libspotgen=, =libspotltsmin=, =libbddx=, and most of =libspot=.
@ -1047,8 +1034,8 @@ layers.
distributed with the rest of Spot, their source-code is publicly
available (in case you want to contribute or run a local version).
The [[https://spot-sandbox.lrde.epita.fr/][=spot-sandbox=]] website runs from a Docker container whose
configuration can be found in [[https://gitlab.lrde.epita.fr/spot/sandbox/tree/master=][this repository]]. The client and
server parts of the [[https://spot.lrde.epita.fr/app/][online LTL translator]] can be found in [[https://gitlab.lrde.epita.fr/spot/spot-web-app/][this
configuration can be found in [[https://gitlab.lre.epita.fr/spot/sandbox/tree/master=][this repository]]. The client and
server parts of the [[https://spot.lrde.epita.fr/app/][online LTL translator]] can be found in [[https://gitlab.lre.epita.fr/spot/spot-web-app/][this
repository]].
* Automaton property flags

View file

@ -1,6 +1,6 @@
#!/bin/sh
# This is a wrapper around the compiler, to ensure that the code
# example run from the org-mode file are all linked with Spot.
# examples run from org-mode files are all linked with Spot.
#
# Also we save errors to org.errors, so that we can detect issues
# after org-mode has exported everything. Otherwise these errors
@ -8,7 +8,7 @@
@top_builddir@/libtool link @CXX@ @CXXFLAGS@ @CPPFLAGS@ -Wall -Werror \
-I@abs_top_builddir@ -I@abs_top_srcdir@ -I@abs_top_srcdir@/buddy/src \
"$@" @abs_top_builddir@/spot/libspot.la \
@abs_top_builddir@/buddy/src/libbddx.la 2> errors.$$
@abs_top_builddir@/buddy/src/libbddx.la @LIBSPOT_PTHREAD@ 2> errors.$$
code=$?
if test $code -ne 0 && test -s errors.$$; then
cat errors.$$ >>org.errors

View file

@ -66,7 +66,7 @@ the HOA format, the output may not be exactly the same as the input.
sets.
This hard-coded limit can be augmented at configure time
using option `--enable-max-accsets=N`, but doing so will consume
using option =--enable-max-accsets=N=, but doing so will consume
more memory and time.
- Multiple (or missing) initial states are emulated.
@ -76,7 +76,8 @@ the HOA format, the output may not be exactly the same as the input.
is transformed into an equivalent TωA by merging the initial states
into a single one. The merged state can either be one of the
original initial states (if one of those has no incoming edge) or a
new state introduced for that purpose.
new state introduced for that purpose. This "conversion" may change
the completeness property of the automaton.
Similarly, when an automaton with no initial state is loaded (this
includes the case where the automaton has no state), a disconnected

View file

@ -25,7 +25,7 @@ checking. It has the following notable features:
weak-DBA, removal of useless SCCs, acceptance-condition
transformations, determinization, [[file:satmin.org][SAT-based minimization of
deterministic automata]], [[https://spot.lrde.epita.fr/ipynb/zlktree.html][Alternating Cycle Decomposition]], etc.
- Support for [[file:tut40.org][Safety]] and [[https://spot-dev.lrde.epita.fr/ipynb/games.html][parity games]].
- Support for [[file:tut40.org][Safety]] and [[https://spot.lrde.epita.fr/ipynb/games.html][parity games]].
- Applications to [[file:ltlsynt.org][reactive synthesis]] and [[https://spot.lrde.epita.fr/ipynb/atva16-fig2b.html][model checking]].
- In addition to the C++ interface, most of its algorithms are usable
via [[file:tools.org][command-line tools]], and via [[file:tut.org][Python bindings]].
@ -37,7 +37,7 @@ checking. It has the following notable features:
* Latest version
The latest version is *{{{LASTRELEASE}}}* and was released on
The latest version is *call_SPOT_VERSION()* and was released on
*{{{LASTDATE}}}*. Please see the [[file:install.org][download and installation instructions]].
* Documentation

View file

@ -51,7 +51,6 @@
(package-install ess)))))
(require 'ox-publish)
(require 'org-install)
(require 'hoa-mode)
; See https://github.com/emacs-ess/ESS/issues/1052
@ -89,7 +88,9 @@
(setq org-babel-C++-compiler "./g++wrap")
(setq shell-file-name "@SHELL@")
(setq ess-ask-for-ess-directory nil)
; setting ess-startup-directory to 'default-directory is enough with
; newer ESS version (after Fev 2022) but does not work with older ones.
(setq ess-startup-directory "@abs_top_builddir@/doc/org")
(setq org-babel-default-header-args:plantuml
'((:results . "file")
(:exports . "results")
@ -159,7 +160,7 @@ up.html points to index.html, then the result is:
(setq body res)
(not cmp)))
(concat "#+TITLE: " title
"\n#+SETUPFILE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
"\n#+INCLUDE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
body)))
(setq org-publish-project-alist
@ -184,6 +185,49 @@ up.html points to index.html, then the result is:
:publishing-function org-publish-attachment)
("spot-all" :components ("spot-html" "spot-static"))))
;;; Org-mode 9.5 is now using <img> to render SVG images.
;;; Unfortunately, this breaks SVG images that use external style
;;; sheets as <img> are expected to be self-contained.
;;;
;;; Since we do use such external style-sheets and never had
;;; any issue with <object type="image/svg+xml"...>, we revert
;;; to the previous behavior.
;;;
;;; The following function is based on org-html--svg-image from
;;; Org-mode 9.4.5, with the addition of the SVG extension test.
(defun spot-svg-output-as-object (source attributes info)
"If source is an SVG file, return an \"object\" embedding svg file
SOURCE with given ATTRIBUTES.
INFO is a plist used as a communication channel. Otherwise return nil.
The special attribute \"fallback\" can be used to specify a
fallback image file to use if the object embedding is not
supported. CSS class \"org-svg\" is assigned as the class of the
object unless a different class is specified with an attribute."
(when (string= "svg" (file-name-extension source))
(let ((fallback (plist-get attributes :fallback))
(attrs (org-html--make-attribute-string
(org-combine-plists
;; Remove fallback attribute, which is not meant to
;; appear directly in the attributes string, and
;; provide a default class if none is set.
'(:class "org-svg") attributes '(:fallback nil)))))
(format "<object type=\"image/svg+xml\" data=\"%s\" %s>\n%s</object>"
source
attrs
(if fallback
(org-html-close-tag
"img" (format "src=\"%s\" %s" fallback attrs) info)
"Sorry, your browser does not support SVG.")))))
;;; Hack org-html--format-image to call the above first.
;;; (The org-html--svg-image function was removed when the formater code
;;; switched to <img> for SVG.)
(unless (fboundp 'org-html--svg-image)
(advice-add 'org-html--format-image :before-until 'spot-svg-output-as-object))
(org-publish-all t)
;;; org-babel-remove-temporary-directory does not correctly remove
;;; nested directories and we have some files in tmp/.libs/ because of

View file

@ -9,12 +9,12 @@
:CUSTOM_ID: tar
:END:
The latest release of Spot is version {{{LASTRELEASE}}}:
The latest release of Spot is version call_SPOT_VERSION() and was released on {{{LASTDATE}}}:
- {{{LASTTARBALL}}} (see also the {{{LASTNEWS}}})
- call_TARBALL_LINK() (see also the call_NEWS_LINK())
Past releases can be found [[https://www.lrde.epita.fr/dload/spot/][in the same directory]]. If you are
interested in /future/ releases, you can always peek at the [[https://gitlab.lrde.epita.fr/spot/spot/-/jobs/artifacts/next/browse?job=debian-stable-gcc][last
interested in /future/ releases, you can always peek at the [[https://gitlab.lre.epita.fr/spot/spot/-/jobs/artifacts/next/browse?job=make-dist][last
successful development build]].
** Requirements
@ -52,10 +52,13 @@ make
make install
#+END_SRC
Before running =make install=, you might want to run =make check= to
run our test-suite.
Files =INSTALL= and =README= included in the tarball contains more
explanations about the various options you can use during this
process. Also note that =README= has a section about troubleshooting
installations.
explanations about the various options you can use during the
compilation process. Also note that =README= has a section about
troubleshooting installations.
* Installing the Debian packages
:PROPERTIES:
@ -88,7 +91,9 @@ apt-get install spot libspot-dev spot-doc python3-spot # Or a subset of those
Note that our Debian repository is signed since that is the new Debian
policy, and both of the above command blocks start with a download of
our [[https://www.lrde.epita.fr/repo/debian.gpg][GPG key]]. Its fingerprint is =209B 7362 CFD6 FECF B41D 717F 03D9
9E74 44F2 A84A=, if you want to verify it.
9E74 44F2 A84A=, if you want to verify it. If you have an old copy of
the GPG key that expired, please download it again: the current
version should be valid until 2032.
The package =spot= contains the [[file:tools.org][command-line tools]]. =libspot-dev=
contains the header files if you plan to use Spot in a C++17
@ -162,11 +167,11 @@ the (working) code that should be part of the next major release.
To clone the git repository, use
#+BEGIN_SRC sh
git clone https://gitlab.lrde.epita.fr/spot/spot.git
git clone https://gitlab.lre.epita.fr/spot/spot.git
#+END_SRC
This should put you on the =next= branch by default. From there, read
the [[https://gitlab.lrde.epita.fr/spot/spot/blob/next/HACKING][HACKING]] file that should be at the top of your cloned repository:
the [[https://gitlab.lre.epita.fr/spot/spot/blob/next/HACKING][HACKING]] file that should be at the top of your cloned repository:
it lists all the tools you should install before attempting to compile
the source tree.

View file

@ -924,7 +924,7 @@ compare the number of states produced by the two configurations of
=ltl2tgba= for each formula, we just need to plot column
=dt2$state.small= against =dt2$state.deter=.
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r.svg
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r.svg
library(ggplot2)
ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point()
@ -937,7 +937,7 @@ ggplot(dt2, aes(x=states.small, y=states.deter)) +
We should probably print the formulas for the cases where the two
sizes differ.
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r2.svg
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r2.svg
ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point() +
geom_text(data=subset(dt2, states.small != states.deter),

View file

@ -7,19 +7,19 @@
* Basic usage
This tool synthesizes controllers from LTL/PSL formulas.
This tool synthesizes reactive controllers from LTL/PSL formulas.
Consider a set $I$ of /input/ atomic propositions, a set $O$ of output atomic
propositions, and a PSL formula \phi over the propositions in $I \cup O$. A
=controller= realizing \phi is a function $c: (2^{I})^\star \times 2^I \mapsto
*reactive controller* realizing \phi is a function $c: (2^{I})^\star \times 2^I \mapsto
2^O$ such that, for every \omega-word $(u_i)_{i \in N} \in (2^I)^\omega$ over
the input propositions, the word $(u_i \cup c(u_0 \dots u_{i-1}, u_i))_{i \in
N}$ satisfies \phi.
If a controller exists, then one with finite memory exists. Such controllers
are easily represented as automata (or more specifically as I/O automata or
transducers). In the automaton representing the controller, the acceptance
condition is irrelevant and trivially true.
If a reactive controller exists, then one with finite memory
exists. Such controllers are easily represented as automata (or more
specifically as Mealy machines). In the automaton representing the
controller, the acceptance condition is irrelevant and trivially true.
=ltlsynt= has three mandatory options:
- =--ins=: a comma-separated list of input atomic propositions;
@ -27,45 +27,52 @@ condition is irrelevant and trivially true.
- =--formula= or =--file=: a specification in LTL or PSL.
One of =--ins= or =--outs= may be omitted, as any atomic proposition not listed
as input can be assumed to be an output and vice-versa.
as input can be assumed to be output and vice-versa.
The following example illustrates the synthesis of a controller acting as an
=AND= gate. We have two inputs =a= and =b= and one output =c=, and we want =c=
to always be the =AND= of the two inputs:
The following example illustrates the synthesis of a controller
ensuring that input =i1= and =i2= are both true initially if and only
if eventually output =o1= will go from true to false at some point.
Note that this is an equivalence, not an implication.
#+NAME: example
#+BEGIN_SRC sh :exports both
ltlsynt --ins=a,b -f 'G (a & b <=> c)'
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))'
#+END_SRC
#+RESULTS: example
#+begin_example
REALIZABLE
HOA: v1
States: 1
States: 3
Start: 0
AP: 3 "a" "b" "c"
AP: 3 "i1" "i2" "o1"
acc-name: all
Acceptance: 0 t
properties: trans-labels explicit-labels state-acc deterministic
controllable-AP: 2
--BODY--
State: 0
[!0&!2 | !1&!2] 0
[0&1&2] 0
[0&1&2] 1
[!0&2 | !1&2] 2
State: 1
[!2] 0
State: 2
[2] 2
--END--
#+end_example
The output is composed of two parts:
- the first one is a single line =REALIZABLE= or =UNREALIZABLE;=
- the second one, only present in the =REALIZABLE= case is an automaton describing the controller.
In this example, the controller has a single
state, with two loops labeled by =a & b & c= and =(!a | !b) & !c=.
- The first one is a single line =REALIZABLE= or =UNREALIZABLE=; the presence of this
line, required by the [[http://http://www.syntcomp.org/][SyntComp competition]], can be disabled with option =--hide-status=.
- The second one, only present in the =REALIZABLE= case, is an automaton describing the controller.
The controller contains the line =controllable-AP: 2=, which means that this automaton
should be interpreted as a Mealy machine where =o0= is part of the output.
Using the =--dot= option, makes it easier to visualize this machine.
#+NAME: exampledot
#+BEGIN_SRC sh :exports none :noweb yes
sed 1d <<EOF | autfilt --dot=.A
<<example()>>
EOF
#+BEGIN_SRC sh :exports code
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --dot
#+END_SRC
#+BEGIN_SRC dot :file ltlsyntex.svg :var txt=exampledot :exports results
@ -75,9 +82,6 @@ EOF
#+RESULTS:
[[file:ltlsyntex.svg]]
The label =a & b & c= should be understood as: "if the input is =a&b=,
the output should be =c=".
The following example illustrates the case of an unrealizable specification. As
=a= is an input proposition, there is no way to guarantee that it will
eventually hold.
@ -90,11 +94,68 @@ ltlsynt --ins=a -f 'F a'
: UNREALIZABLE
By default, the controller is output in HOA format, but it can be
output as an [[http://fmv.jku.at/aiger/][AIGER]] circuit thanks to the =--aiger= flag. This is the
output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
output as an And-Inverter-Graph in [[http://fmv.jku.at/aiger/][AIGER format]] using the =--aiger=
flag. This is the output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
The generation of a controller can be disabled with the flag =--realizability=.
In this case, =ltlsynt= output is limited to =REALIZABLE= or =UNREALIZABLE=.
#+NAME: exampleaig
#+BEGIN_SRC sh :exports both
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --aiger
#+END_SRC
#+RESULTS: exampleaig
#+begin_example
REALIZABLE
aag 14 2 2 1 10
2
4
6 14
8 29
7
10 7 9
12 4 10
14 2 12
16 7 8
18 4 16
20 5 7
22 21 19
24 2 23
26 3 7
28 27 25
i0 i1
i1 i2
o0 o1
#+end_example
The above format is not very human friendly. Again, by passing both
=--aiger= and =--dot=, one can display the And-Inverter-Graph representing
the controller:
#+NAME: exampleaigdot
#+BEGIN_SRC sh :exports code
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --aiger --dot
#+END_SRC
#+BEGIN_SRC dot :file ltlsyntexaig.svg :var txt=exampleaigdot :exports results
$txt
#+END_SRC
#+RESULTS:
[[file:ltlsyntexaig.svg]]
In the above diagram, round nodes represent AND gates. Small black
circles represent inversions (or negations), colored triangles are
used to represent input signals (at the bottom) and output signals (at
the top), and finally rectangles represent latches. A latch is a one
bit register that delays the signal by one step. Initially, all
latches are assumed to contain =false=, and them emit their value from
the =L0_out= and =L1_out= rectangles at the bottom. Their input value,
to be emitted at the next step, is received via the =L0_in= and =L1_in=
boxes at the top. In =ltlsynt='s encoding, the set of latches is used
to keep track of the current state of the Mealy machine.
The generation of a controller can be disabled with the flag
=--realizability=. In this case, =ltlsynt='s output is limited to
=REALIZABLE= or =UNREALIZABLE=.
* TLSF
@ -104,14 +165,20 @@ specification language created for the purpose of this competition.
Fortunately, the SYNTCOMP organizers also provide a tool called
[[https://github.com/reactive-systems/syfco][=syfco=]] which can translate a TLSF specification to an LTL formula.
The following four steps show you how a TLSF specification called =FILE= can
The following line shows how a TLSF specification called =FILE= can
be synthesized using =syfco= and =ltlsynt=:
#+BEGIN_SRC sh :export code
LTL=$(syfco FILE -f ltlxba -m fully)
IN=$(syfco FILE --print-input-signals)
OUT=$(syfco FILE --print-output-signals)
ltlsynt --formula="$LTL" --ins="$IN" --outs="$OUT"
ltlsynt --tlsf FILE
#+END_SRC
The above =--tlsf= option will call =syfco= to perform the conversion
and extract output signals, as if you had used:
#+BEGIN_SRC sh :export code
LTL=$(syfco -f ltlxba -m fully FILE)
OUT=$(syfco --print-output-signals FILE)
ltlsynt --formula="$LTL" --outs="$OUT"
#+END_SRC
* Internal details
@ -171,7 +238,18 @@ be tried by separating them using commas. For instance
You can also ask =ltlsynt= to print to obtained parity game into
[[https://github.com/tcsprojects/pgsolver][PGSolver]] format, with the flag =--print-pg=, or in the HOA format,
using =--print-game-hoa=. These flag deactivate the resolution of the
parity game.
parity game. Note that if any of those flag is used with =--dot=, the game
will be printed in the Dot format instead:
#+NAME: examplegamedot
#+BEGIN_SRC sh :exports code
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --print-game-hoa --dot
#+END_SRC
#+BEGIN_SRC dot :file ltlsyntexgame.svg :var txt=examplegamedot :exports results
$txt
#+END_SRC
#+RESULTS:
[[file:ltlsyntexgame.svg]]
For benchmarking purpose, the =--csv= option can be used to record
intermediate statistics about the resolution.
@ -194,6 +272,11 @@ Further improvements are described in the following paper:
/Alexandre Duret-Lutz/, and /Adrien Pommellet/. Presented at the
SYNT'21 workshop. ([[https://www.lrde.epita.fr/~adl/dl/adl/renkin.21.synt.pdf][pdf]] | [[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#renkin.21.synt][bib]])
Simplification of Mealy machines is discussed in:
- *Effective reductions of Mealy machines*, /Florian Renkin/,
/Philipp Schlehuber-Caissier/, /Alexandre Duret-Lutz/, and /Adrien Pommellet/.
Presented at FORTE'22. ([[https://www.lrde.epita.fr/~adl/dl/adl/renkin.22.forte.pdf][pdf]] | [[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#renkin.22.forte][bib]])
# LocalWords: utf ltlsynt AIGER html args mapsto SRC acc aiger TLSF
# LocalWords: UNREALIZABLE unrealizable SYNTCOMP realizability Proc

View file

@ -1,11 +1,23 @@
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil
#+EMAIL: spot@lrde.epita.fr
#+HTML_LINK_HOME: index.html
#+MACRO: SPOTVERSION 2.10.4
#+MACRO: LASTRELEASE 2.10.4
#+MACRO: LASTTARBALL [[http://www.lrde.epita.fr/dload/spot/spot-2.10.4.tar.gz][=spot-2.10.4.tar.gz=]]
#+MACRO: LASTNEWS [[https://gitlab.lrde.epita.fr/spot/spot/blob/spot-2-10-4/NEWS][summary of the changes]]
#+MACRO: LASTDATE 2022-02-01
#+MACRO: LASTDATE 2023-04-20
#+NAME: SPOT_VERSION
#+BEGIN_SRC python :exports none :results value :wrap org
return "2.11.5"
#+END_SRC
#+NAME: TARBALL_LINK
#+BEGIN_SRC python :exports none :var version=SPOT_VERSION :results output :wrap org
print(f"[[http://www.lrde.epita.fr/dload/spot/spot-{version}.tar.gz][=spot-{version}.tar.gz=]]")
#+END_SRC
#+NAME: NEWS_LINK
#+BEGIN_SRC python :exports none :var version=SPOT_VERSION :results output :wrap org
version = version.replace('.', '-')
print(f"[[https://gitlab.lre.epita.fr/spot/spot/blob/spot-{version}/NEWS][summary of the changes]]")
#+END_SRC
#+ATTR_HTML: :id spotlogo
[[file:spot2.svg]]

View file

@ -16,9 +16,9 @@ h1::before{content:"";position:absolute;z-index:-1;background-color:#ffe35e;left
#table-of-contents #text-table-of-contents{text-align:left}
#org-div-home-and-up{text-align:center;font-size:100%}
.outline-2 h2{display:block;width:100%;position:relative}
.outline-2 h2::before{content:"";height:100%;width:calc(100% + 2em);position:absolute;z-index:-1;bottom:0em;left:-1em;background-color:#ffe35e;background:linear-gradient(45deg,#ffe35e 50%,transparent 75%);transform:skew(10deg);border-radius:5px;}
.outline-2 h2::before{content:"";height:100%;width:calc(100% + 2em);position:absolute;z-index:-1;bottom:0em;left:-1em;background:linear-gradient(45deg,#ffe35e 50%,transparent 75%);transform:skew(10deg);border-radius:5px;}
.outline-3 h3{display:block;width:auto;position:relative}
.outline-3 h3::before{content:"";position:absolute;z-index:-1;width:calc(100% + 2em);height:100%;left:-1em;bottom:0em;;background-color:#ffe35e;background:linear-gradient(45deg,#ffe35e 25%,transparent 50%);transform:skew(10deg);border-radius:3px}
.outline-3 h3::before{content:"";position:absolute;z-index:-1;width:calc(100% + 2em);height:100%;left:-1em;bottom:0em;background:linear-gradient(45deg,#ffe35e 25%,transparent 50%);transform:skew(10deg);border-radius:3px}
.outline-2 h2:hover::before,.outline-3 h3:hover::before{background-color:#ffe35e}
pre{margin:1.2ex}
pre.src{padding-top:8px;border-left-style:solid;border-color:#00adad;overflow:auto;margin-top:0;margin-bottom:0}
@ -77,11 +77,13 @@ thead tr{background:#ffe35e}
.org-hoa-ap-number{color:#d70079}
.implem{background:#fff0a6;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#ffe35e;border-style:solid none}
.implem::before{background:#ffe35e;content:"Implementation detail";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
.note{background:#fff0a6;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#ffe35e;border-style:solid none}
.note::before{background:#ffe35e;content:"Note";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
.caveat{background:#ef99c9;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#d70079;border-style:solid none}
.caveat::before{background:#d70079;content:"Caveat";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
.spotlogo{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogo}
g.spotlogobg{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogobg}
g#version{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
g.spotlogover{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
@keyframes animspotlogo{
0%{transform:rotateY(90deg)}
80%{transform:rotateY(0deg)}

View file

@ -14,7 +14,7 @@
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.83905%,93.728638%);fill-opacity:1;" d="M 29.054688 0.707031 L 0.707031 29.054688 L 29.054688 57.402344 L 43.226562 43.226562 L 43.226562 14.882812 Z M 29.054688 0.707031 "/>
<path style="fill:none;stroke-width:1.41731;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(30.000305%,77.487183%,95.610046%);stroke-opacity:1;stroke-miterlimit:10;" d="M -0.0003125 28.347969 L -28.347969 0.0003125 L -0.0003125 -28.347344 L 14.171563 -14.171563 L 14.171563 14.172187 Z M -0.0003125 28.347969 " transform="matrix(1,0,0,-1,29.055,29.055)"/>
</g>
<g id="version">
<g class="spotlogover">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,94.898987%,0%);fill-opacity:1;" d="M 34.84375 29.054688 C 34.84375 25.855469 32.253906 23.265625 29.054688 23.265625 C 25.855469 23.265625 23.265625 25.855469 23.265625 29.054688 C 23.265625 32.253906 25.855469 34.84375 29.054688 34.84375 C 32.253906 34.84375 34.84375 32.253906 34.84375 29.054688 Z M 34.84375 29.054688 "/>
<path style="fill:none;stroke-width:2.83466;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.78875 0.0003125 C 5.78875 3.199531 3.198906 5.789375 -0.0003125 5.789375 C -3.199531 5.789375 -5.789375 3.199531 -5.789375 0.0003125 C -5.789375 -3.198906 -3.199531 -5.78875 -0.0003125 -5.78875 C 3.198906 -5.78875 5.78875 -3.198906 5.78875 0.0003125 Z M 5.78875 0.0003125 " transform="matrix(1,0,0,-1,29.055,29.055)"/>
<path style="fill:none;stroke-width:5.66934;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 10.499688 15.965156 C 9.312188 18.754219 7.015313 21.062812 3.945 22.18 C -1.941719 24.320625 -8.445625 21.289375 -10.590156 15.402656 C -11.972969 11.597969 -11.222969 7.340156 -8.621406 4.234687 C -6.465156 1.668281 -3.285469 0.187812 0.0660938 0.187812 C 6.327813 0.187812 11.405938 -4.890313 11.405938 -11.152031 C 11.405938 -17.41375 6.327813 -22.491875 0.0660938 -22.491875 C -6.195625 -22.491875 -11.27375 -17.41375 -11.27375 -11.152031 " transform="matrix(1,0,0,-1,29.055,29.055)"/>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before After
Before After

View file

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
#+TITLE: Command-line tools installed by Spot {{{SPOTVERSION}}}
#+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}}
#+INCLUDE: setup.org
#+TITLE: Command-line tools installed by Spot
#+DESCRIPTION: List of all the command-line tools installed by Spot
#+HTML_LINK_UP: index.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This document introduces command-line tools that are installed with
the Spot library. We give some examples to highlight possible
Spot call_SPOT_VERSION(). We give some examples to highlight possible
use-cases but shall not attempt to cover all features exhaustively
(please check the man pages for further inspiration).

View file

@ -89,6 +89,7 @@ real notebooks instead.
automata.
- [[https://spot.lrde.epita.fr/ipynb/atva16-fig2a.html][=atva16-fig2a.ipynb=]] first example from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][ATVA'16 tool paper]].
- [[https://spot.lrde.epita.fr/ipynb/atva16-fig2b.html][=atva16-fig2b.ipynb=]] second example from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][ATVA'16 tool paper]].
- [[https://spot.lrde.epita.fr/ipynb/cav22-figs.html][=cav22-figs.ipynb=]] figures from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.22.cav.pdf][CAV'22 tool paper]].
- [[https://spot.lrde.epita.fr/ipynb/alternation.html][=alternation.ipynb=]] examples of alternating automata.
- [[https://spot.lrde.epita.fr/ipynb/stutter-inv.html][=stutter-inv.ipynb=]] working with stutter-invariant formulas properties.
- [[https://spot.lrde.epita.fr/ipynb/satmin.html][=satmin.ipynb=]] Python interface for [[file:satmin.org][SAT-based minimization of deterministic ω-automata]].

View file

@ -81,7 +81,7 @@ simplifications called /trivial identities/. For instance
=formula::F(formula::X(formula::tt()))= will return the same formula
as =formula::tt()=. These simplifications are those that involve the
true and false constants, impotence (=F(F(e))=F(e)=), involutions
(=Not(Not(e)=e=), associativity
(=Not(Not(e))=e=), associativity
(=And({And({e1,e2},e3})=And({e1,e2,e3})=). See [[https://spot.lrde.epita.fr/tl.pdf][tl.pdf]] for a list of
these /trivial identities/.
@ -113,7 +113,7 @@ detail of the top-level operator in the formula.
std::cout << f << '\n';
// kindstar() prints the name of the operator
// kindstr() prints the name of the operator
// size() return the number of operands of the operators
std::cout << f.kindstr() << ", " << f.size() << " children\n";
// operator[] accesses each operand
@ -157,7 +157,7 @@ The Python equivalent is similar:
print(f)
# kindstar() prints the name of the operator
# kindstr() prints the name of the operator
# size() return the number of operands of the operators
print("{}, {} children".format(f.kindstr(), f.size()))
# [] accesses each operand

View file

@ -139,7 +139,7 @@ automaton. Finally, the output as a never claim is done via the
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("[]<>a || <>[]b");
spot::parsed_formula pf = spot::parse_infix_psl("GFa -> GFb");
if (pf.format_errors(std::cerr))
return 1;
spot::translator trans;
@ -158,22 +158,22 @@ never {
T0_init:
if
:: (true) -> goto T0_init
:: (a) -> goto accept_S1
:: (b) -> goto accept_S2
:: (b) -> goto accept_S1
:: (!(a)) -> goto accept_S2
fi;
accept_S1:
if
:: (a) -> goto accept_S1
:: (!(a)) -> goto T0_S3
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
accept_S2:
if
:: (b) -> goto accept_S2
:: (!(a)) -> goto accept_S2
fi;
T0_S3:
if
:: (a) -> goto accept_S1
:: (!(a)) -> goto T0_S3
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
}

View file

@ -144,9 +144,11 @@ states.
We now look at how to create such a game in Python.
Essentially, a game in Spot is just an automaton equiped with a
special property to indicate the owner of each states. So it can be
created using the usual interface:
Essentially, a game in Spot is just an automaton equiped with a [[file:concepts.org::#named-properties][named
property "state-player"]] that hold a Boolean vector indicating the
owner of each state. The game can be created using the usual
automaton interface, and the owners are set by calling
=game.set_state_players()= with a vector of Boolean at the very end.
#+NAME: build_game
#+BEGIN_SRC python :exports code
@ -173,7 +175,7 @@ created using the usual interface:
todo = []
# Create the state (i, j) for a player if it does not exist yet and
# returns the state's number in the game.
# return the state's number in the game.
def get_game_state(player, i, j):
orig_state = s_orig_states if player else d_orig_states
if (i, j) in orig_state:

View file

@ -1,4 +1,3 @@
@InProceedings{ babiak.12.tacas,
author = {Tom{\'a}{\v{s}} Babiak and Mojm{\'i}r
K{\v{r}}et{\'i}nsk{\'y} and Vojt{\v{e}}ch {\v{R}}eh{\'a}k
@ -173,6 +172,22 @@
doi = {10.4230/LIPIcs.ICALP.2021.123}
}
@InProceedings{ casares.22.tacas,
author = {Antonio Casares and Alexandre Duret-Lutz and Klara J.
Meyer and Florian Renkin and Salomon Sickert},
title = {Practical Applications of the {A}lternating {C}ycle
{D}ecomposition},
booktitle = {Proceedings of the 28th International Conference on Tools
and Algorithms for the Construction and Analysis of
Systems},
year = {2022},
series = {Lecture Notes in Computer Science},
month = apr,
volume = {13244},
pages = {99--117},
doi = {10.1007/978-3-030-99527-0_6},
}
@InProceedings{ cerna.03.mfcs,
author = {Ivana {\v{C}}ern{\'a} and Radek Pel{\'a}nek},
title = {Relating Hierarchy of Temporal Properties to Model
@ -214,6 +229,18 @@
doi = {10.1109/DepCoS-RELCOMEX.2009.31}
}
@InProceedings{ cimatti.06.fmcad,
author = {Cimatti, Alessandro and Roveri, Marco and Semprini, Simone
and Tonetta, Stefano},
title = {From {PSL} to {NBA}: a Modular Symbolic Encoding},
booktitle = {Proceedings of the 6th conference on Formal Methods in
Computer Aided Design (FMCAD'06)},
pages = {125--133},
year = {2006},
publisher = {IEEE Computer Society},
doi = {10.1109/FMCAD.2006.19}
}
@Article{ cimatti.08.tcad,
author = {Alessandro Cimatti and Marco Roveri and Stefano Tonetta},
journal = {IEEE Transactions on Computer Aided Design of Integrated
@ -341,6 +368,41 @@
doi = {10.1504/IJCCBS.2014.059594}
}
@InProceedings{ duret.16.atva,
author = {Alexandre Duret-Lutz and Fabrice Kordon and Denis
Poitrenaud and Etienne Renault},
title = {Heuristics for Checking Liveness Properties with Partial
Order Reductions},
booktitle = {Proceedings of the 14th International Symposium on
Automated Technology for Verification and Analysis
(ATVA'16)},
series = {Lecture Notes in Computer Science},
publisher = {Springer},
volume = {9938},
pages = {340--356},
year = {2016},
month = oct,
doi = {10.1007/978-3-319-46520-3_22}
}
@InProceedings{ duret.22.cav,
author = {Alexandre~Duret-Lutz and Etienne Renault and Maximilien
Colange and Florian Renkin and Alexandre Gbaguidi~Aisse and
Philipp Schlehuber-Caissier and Thomas Medioni and Antoine
Martin and J{\'e}r{\^o}me Dubois and Cl{\'e}ment Gillard
and Henrich Lauko},
title = {From {S}pot 2.0 to {S}pot 2.10: What's New?},
booktitle = {Proceedings of the 34th International Conference on
Computer Aided Verification (CAV'22)},
year = 2022,
volume = {13372},
series = {Lecture Notes in Computer Science},
pages = {174--187},
month = aug,
publisher = {Springer},
doi = {10.1007/978-3-031-13188-2_9}
}
@InProceedings{ dwyer.98.fmsp,
author = {Matthew B. Dwyer and George S. Avrunin and James C.
Corbett},
@ -846,6 +908,22 @@
doi = {10.1007/978-3-030-59152-6_7}
}
@InProceedings{ renkin.22.forte,
author = {Florian Renkin and Philipp Schlehuber-Caissier and
Alexandre Duret-Lutz and Adrien Pommellet},
title = {Effective Reductions of {M}ealy Machines},
year = 2022,
booktitle = {Proceedings of the 42nd International Conference on Formal
Techniques for Distributed Objects, Components, and Systems
(FORTE'22)},
series = {Lecture Notes in Computer Science},
volume = 13273,
pages = {170--187},
month = jun,
publisher = {Springer},
doi = {10.1007/978-3-031-08679-3_8}
}
@InProceedings{ rozier.07.spin,
author = {Kristin Y. Rozier and Moshe Y. Vardi},
title = {LTL Satisfiability Checking},
@ -1008,7 +1086,19 @@
publisher = {Elsevier},
editor = {Rance Cleaveland and Hubert Garavel},
year = {2002},
month = jul,
month = jul, pdf = {adl/duret.16.atva.pdf},
abstract = {Checking liveness properties with partial-order reductions
requires a cycle proviso to ensure that an action cannot be
postponed forever. The proviso forces each cycle to contain
at least one fully expanded state. We present new
heuristics to select which state to expand, hoping to
reduce the size of the resulting graph. The choice of the
state to expand is done when encountering a
\emph{dangerous} edge. Almost all existing provisos expand
the source of this edge, while this paper also explores the
expansion of the destination and the use of SCC-based
information.},
address = {M{\'a}laga, Spain},
doi = {10.1016/S1571-0661(04)80409-2}
}

View file

@ -395,7 +395,7 @@ following Boolean operators:
(allowing better compatibility with Wring and VIS) may only used in
temporal formulas. Boolean expressions that occur inside SERE (see
Section~\ref{sec:sere}) may not use this form because the $\STARALT$
symbol is used as the Kleen star.}
symbol is used as the Kleene star.}
Additionally, an atomic proposition $a$ can be negated using the
syntax \samp{$a$=0}, which is equivalent to \samp{$\NOT a$}. Also
@ -600,7 +600,7 @@ the source. It can mean either ``\textit{Sequential Extended Regular
``\textit{Semi-Extended Regular Expression}''~\citep{eisner.08.hvc}.
In any case, the intent is the same: regular expressions with
traditional operations (union `$\OR$', concatenation `$\CONCAT$',
Kleen star `$\STAR{}$') are extended with operators such as
Kleene star `$\STAR{}$') are extended with operators such as
intersection `$\ANDALT$', and fusion `$\FUSION$'.
Any Boolean formula (section~\ref{def:boolform}) is a SERE. SERE can
@ -638,7 +638,7 @@ denote arbitrary SERE.
\end{tabular}
\end{center}
\footnotetext{\emph{Non-Length-Matching} interesction.}
\footnotetext{\emph{Non-Length-Matching} intersection.}
The character \samp{\$} or the string \samp{inf} can also be used as
value for $\mvar{j}$ in the above operators to denote an unbounded
@ -668,20 +668,17 @@ $a$ is an atomic proposition.
\sigma\VDash f\FUSION g&\iff \exists k\in\N,\,(\sigma^{0..k} \VDash f)\land(\sigma^{k..} \VDash g)\\
\sigma\VDash f\STAR{\mvar{i}..\mvar{j}}& \iff
\begin{cases}
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
\VDash f\STAR{\mvar{0}..\mvar{j-1}}))\\
\text{either} & \mvar{i}=0 \land\mvar{j}=0\land \sigma=\varepsilon \\
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma = \varepsilon) \lor (\sigma
\VDash f\STAR{\mvar{1}..\mvar{j}})\bigr)\\
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
\VDash f\STAR{\mvar{i-1}..\mvar{j-1}}))\\
\end{cases}\\
\sigma\VDash f\STAR{\mvar{i}..} & \iff
\begin{cases}
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
\text{or} & \mvar{i}=0 \land (\exists k\in\N,\,
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
\VDash f\STAR{\mvar{0}..}))\\
\text{either} & \mvar{i}=0 \land \bigl((\sigma=\varepsilon)\lor(\sigma
\VDash f\STAR{\mvar{1}..})\bigr)\\
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
\VDash f\STAR{\mvar{i-1}..}))\\
@ -689,25 +686,22 @@ $a$ is an atomic proposition.
\sigma\VDash f\FSTAR{\mvar{i}..\mvar{j}}& \iff
\begin{cases}
\text{either} & \mvar{i}=0 \land \mvar{j}=0 \land \sigma\VDash\1 \\
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
\VDash f\FSTAR{\mvar{0}..\mvar{j-1}}))\\
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma\VDash\1)\lor(\sigma
\VDash f\FSTAR{\mvar{1}..\mvar{j}})\bigr)\\
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
\VDash f\FSTAR{\mvar{i-1}..\mvar{j-1}}))\\
\end{cases}\\
\sigma\VDash f\FSTAR{\mvar{i}..} & \iff
\begin{cases}
\text{either} & \mvar{i}=0 \land \sigma\VDash\1 \\
\text{or} & \mvar{i}=0 \land (\exists k\in\N,\,
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
\VDash f\FSTAR{\mvar{0}..}))\\
\text{either} & \mvar{i}=0 \land \bigl((\sigma\VDash\1)
\lor(\sigma \VDash f\FSTAR{\mvar{1}..})\bigr)\\
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
\VDash f\FSTAR{\mvar{i-1}..}))\\
\end{cases}\\
\sigma\VDash \FIRSTMATCH\code(f\code) & \iff
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k}\nVDash f)
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k-1}\nVDash f)
\end{align*}}
Notes:
@ -859,10 +853,18 @@ The following rules are all valid with the two arguments swapped.
\1\OR b &\equiv \1 &
\1 \FUSION f & \equiv f\mathrlap{\text{~if~}\varepsilon\nVDash f}\\
&&
\STAR{} \AND f &\equiv f &
\STAR{} \OR f &\equiv \1\mathrlap{\STAR{}} &
\STAR{} \ANDALT f &\equiv f &
\STAR{} \OR f &\equiv \mathrlap{\STAR{}} &
&&
\STAR{} \CONCAT f &\equiv \STAR{}\mathrlap{\text{~if~}\varepsilon\VDash f}& \\
\STAR{} \CONCAT f &\equiv \STAR{}\text{~if~}\varepsilon\VDash f& \\
&&
\PLUS{} \ANDALT f &\equiv f \text{~if~}\varepsilon\nVDash f&
\PLUS{} \OR f &\equiv \begin{cases}
\mathrlap{\STAR{}\text{~if~} \varepsilon\VDash f} \\
\mathrlap{\PLUS{}\text{~if~} \varepsilon\nVDash f} \\
\end{cases} &
&&
&& \\
\eword\AND f &\equiv f &
\eword\ANDALT f &\equiv
\begin{cases}
@ -886,7 +888,9 @@ The following rules are all valid with the two arguments swapped.
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f&\equiv f\STAR{\mvar{i+1}..\mvar{j+1}} &
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f\STAR{\mvar{k}..\mvar{l}}&\equiv f\STAR{\mvar{i+k}..\mvar{j+l}}\\
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f&\equiv f\FSTAR{\mvar{i+1}..\mvar{j+1}} &
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f\FSTAR{\mvar{k}..\mvar{l}}&\equiv f\FSTAR{\mvar{i+k}..\mvar{j+l}}
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f\FSTAR{\mvar{k}..\mvar{l}}&\equiv f\FSTAR{\mvar{i+k}..\mvar{j+l}}\\
b\STAR{\mvar{i}..\mvar{j}}\FUSION b &\equiv b\STAR{\mvar{\max(i,1)}..\mvar{j}} &
b\STAR{\mvar{i}..\mvar{j}}\FUSION b\STAR{\mvar{k}..\mvar{l}} &\equiv b\mathrlap{\STAR{\mvar{\max(i,1)+\max(k,1)-1}..\mvar{j+l-1}}}
\end{align*}
\section{SERE-LTL Binding Operators}
@ -1069,7 +1073,7 @@ psl2ba, Modella, and NuSMV all have $\U$ and $\R$ as left-associative,
while Goal (hence Büchi store), LTL2AUT, and LTL2Büchi (from
JavaPathFinder) have $\U$ and $\R$ as right-associative. Vis and LBTT
have these two operators as non-associative (parentheses required).
Similarly the tools do not aggree on the associativity of $\IMPLIES$
Similarly the tools do not agree on the associativity of $\IMPLIES$
and $\EQUIV$: some tools handle both operators as left-associative, or
both right-associative, other have only $\IMPLIES$ as right-associative.
@ -1429,7 +1433,7 @@ $\NOT$ operator.
\end{align*}
Note that the above rules include the ``unabbreviation'' of operators
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', correspondings to the
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', corresponding to the
rules \texttt{"ei\^"} of function `\verb=unabbreviate()= as described
in Section~\ref{sec:unabbrev}. Therefore it is never necessary to
apply these abbreviations before or after
@ -1926,6 +1930,12 @@ Many of the above rules were collected from the
literature~\cite{somenzi.00.cav,tauriainen.03.tr,babiak.12.tacas} and
sometimes generalized to support operators such as $\M$ and $\W$.
The first six rules, about n-ary operators $\AND$ and $\OR$, are
implemented for $n$ operands by testing each operand against all
other. To prevent the complexity to escalate, this is only performed
with up to 16 operands. That value can be changed in
``\verb|tl_simplifier_options::containment_max_ops|''.
The following rules mix implication-based checks with formulas that
are pure eventualities ($e$) or that are purely universal ($u$).
@ -2097,3 +2107,14 @@ $f_1\AND f_2$ & \bor{f_1}{g}{f_2}{g} & & &
%%% TeX-master: t
%%% coding: utf-8
%%% End:
% LocalWords: tabu Alexandre Duret Lutz toc subsequence Kripke unary
% LocalWords: LTL GFa INISHED ZX FX cccccrl UTF syntaxes disjunction
% LocalWords: VIS Kleene overline overbar ary cccrl EF sep FB LTLf
% LocalWords: rewritings TSLF NLM iter un SVA PSL SEREs DFA ccccc ba
% LocalWords: SystemVerilog clc ltl psl Modella NuSMV Büchi AUT Vis
% LocalWords: JavaPathFinder LBTT AST subtrees boolean nenoform lbt
% LocalWords: eword nn LBT's automata subformulas ottom unabbreviate
% LocalWords: Unabbreviations ei GRW RW WR unabbreviator simplifier
% LocalWords: tl unabbreviation indeterminism dnf cnf SNF rl iff BDD
% LocalWords: subformula

View file

@ -1,6 +1,6 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2015, 2016, 2017, 2018 Laboratoire de Recherche et Développement
## de l'Epita (LRDE).
## Copyright (C) 2015-2018, 2022 Laboratoire de Recherche et
## Développement de l'Epita (LRDE).
##
## This file is part of Spot, a model checking library.
##
@ -19,7 +19,7 @@
EXTRA_DIST = hoa-mode.el
GIT = https://gitlab.lrde.epita.fr/spot/emacs-modes/raw/master/
GIT = https://gitlab.lre.epita.fr/spot/emacs-modes/raw/master/
.PHONY: update-el
update-el:

View file

@ -1,10 +1,10 @@
;;; hoa-mode.el --- Major mode for the HOA format -*- lexical-binding: t -*-
;; Copyright (C) 2015, 2017, 2019 Alexandre Duret-Lutz
;; Copyright (C) 2015, 2017, 2019, 2022 Alexandre Duret-Lutz
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
;; URL: https://gitlab.lrde.epita.fr/spot/emacs-modes
;; URL: https://gitlab.lre.epita.fr/spot/emacs-modes
;; Keywords: major-mode, automata, convenience
;; Created: 2015-11-13

43
flake.lock generated Normal file
View file

@ -0,0 +1,43 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1673800717,
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-22.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

211
flake.nix Normal file
View file

@ -0,0 +1,211 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachSystem
[
"x86_64-linux"
]
(system:
let
pkgs = import nixpkgs { inherit system; };
lib = pkgs.lib;
mkSpotApps = appNames:
pkgs.lib.genAttrs appNames
(name: flake-utils.lib.mkApp {
drv = self.packages.${system}.spot;
name = name;
});
spotPackage =
let
inherit (builtins)
filter
head
isString
match
readFile
split
;
# NOTE: Maintaining the version separately would be a pain, and we
# can't have a flake.nix.in with a @VERSION@ because it would make
# the flake unusable without running autoconf first, defeating some
# of its purpose.
#
# So let's get it the hard way instead :)
extractVersionRegex = ''^AC_INIT\(\[spot], \[([^]]+)], \[spot@lrde\.epita\.fr]\)$'';
getLines = (fileContent:
filter isString (split "\n" fileContent)
);
findVersionLine = (lines:
lib.lists.findFirst
(l: lib.strings.hasPrefix "AC_INIT(" l)
null
lines
);
getVersion = (file:
let
lines = getLines (readFile file);
versionLine = findVersionLine lines;
version = head (match extractVersionRegex versionLine);
in
version
);
in
{
lib,
pkgs,
stdenv,
# FIXME: do we want this flag?
buildOrgDoc ? false,
# Whether to enable Spot's Python 3 bindings
enablePython ? false
}:
stdenv.mkDerivation {
pname = "spot";
version = getVersion ./configure.ac;
src = self;
enableParallelBuilding = true;
# NOTE: Nix enables a lot of hardening flags by default, some of
# these probably harm performance so I've disabled everything
# (haven't benchmarked with vs without these, though).
hardeningDisable = [ "all" ];
# NOTE: mktexpk fails without a HOME set
preBuild = ''
export HOME=$TMPDIR
patchShebangs tools
'' + (if buildOrgDoc then ''
ln -s ${pkgs.plantuml}/lib/plantuml.jar doc/org/plantuml.jar
'' else ''
touch doc/org-stamp
'');
configureFlags = [
"--disable-devel"
"--enable-optimizations"
] ++ lib.optional (!enablePython) [
"--disable-python"
];
nativeBuildInputs = with pkgs; [
autoreconfHook
autoconf
automake
bison
flex
libtool
perl
] ++ lib.optional buildOrgDoc [
graphviz
groff
plantuml
pdf2svg
R
] ++ lib.optional enablePython [
python3
swig4
];
buildInputs = with pkgs; [
# should provide the minimum amount of packages necessary for
# building tl.pdf
(texlive.combine {
inherit (texlive)
scheme-basic
latexmk
booktabs
cm-super
doi
doublestroke
etoolbox
koma-script
mathabx-type1
mathpazo
metafont
microtype
nag
pgf
standalone
stmaryrd
tabulary
todonotes
wasy-type1
wasysym
;
})
];
};
in
{
defaultPackage = self.packages.${system}.spot;
packages = {
# binaries + library only
spot = pkgs.callPackage spotPackage {};
# NOTE: clang build is broken on Nix when linking to stdlib++, using
# libcxx instead. See:
# https://github.com/NixOS/nixpkgs/issues/91285
spotClang = pkgs.callPackage spotPackage {
stdenv = pkgs.llvmPackages.libcxxStdenv;
};
spotWithOrgDoc = pkgs.callPackage spotPackage {
buildOrgDoc = true;
};
spotWithPython = pkgs.python3Packages.toPythonModule (
pkgs.callPackage spotPackage {
enablePython = true;
}
);
spotFull = pkgs.python3Packages.toPythonModule (
pkgs.callPackage spotPackage {
buildOrgDoc = true; enablePython = true;
}
);
};
apps = mkSpotApps [
"autcross"
"autfilt"
"dstar2tgba"
"genaut"
"genltl"
"ltl2tgba"
"ltl2tgta"
"ltlcross"
"ltldo"
"ltlfilt"
"ltlgrind"
"ltlsynt"
"randaut"
"randltl"
];
devShell = pkgs.mkShell {
name = "spot-dev";
inputsFrom = [ self.packages.${system}.spotFull ];
buildInputs = [
pkgs.gdb
(pkgs.python3.withPackages (p: [
p.jupyter
p.ipython # otherwise ipython module isn't found when running ipynb tests
]))
];
};
});
}

46
m4/environ.m4 Normal file
View file

@ -0,0 +1,46 @@
# environ.m4 serial 8
dnl Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN_ONCE([gl_ENVIRON],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
dnl Persuade glibc <unistd.h> to declare environ.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_HEADERS_ONCE([unistd.h])
gt_CHECK_VAR_DECL(
[#if HAVE_UNISTD_H
#include <unistd.h>
#endif
/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
#include <stdlib.h>
],
[environ])
if test $gt_cv_var_environ_declaration != yes; then
HAVE_DECL_ENVIRON=0
fi
])
# Check if a variable is properly declared.
# gt_CHECK_VAR_DECL(includes,variable)
AC_DEFUN([gt_CHECK_VAR_DECL],
[
define([gt_cv_var], [gt_cv_var_]$2[_declaration])
AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[$1
typedef struct { int foo; } foo_t;
extern foo_t $2;]],
[[$2.foo = 1;]])],
[gt_cv_var=no],
[gt_cv_var=yes])])
if test $gt_cv_var = yes; then
AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1,
[Define if you have the declaration of $2.])
fi
undefine([gt_cv_var])
])

View file

@ -21,6 +21,14 @@ AC_DEFUN([CF_GXX_WARNINGS],
cat > conftest.$ac_ext <<EOF
#line __oline__ "configure"
#include <string>
#include <regex>
// From GCC bug 106159
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106159
struct left { virtual ~left() {} };
struct right { virtual ~right() {} };
struct both: public left, public right {};
int main(int argc, char *argv[[]])
{
// This string comparison is here to detect superfluous
@ -33,19 +41,26 @@ int main(int argc, char *argv[[]])
std::string a{"foo"}, b{"bar"};
if (b < a)
return 1;
// GCC 12 has spurious warnings about ininialized values in regex.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
// We need -Wno-maybe-uninitialized in this case.
std::regex r{"a"};
(void)r;
return argv[[argc-1]] == nullptr;
}
EOF
cf_save_CXXFLAGS="$CXXFLAGS"
ac_cv_prog_gxx_warn_flags="-W -Wall"
ac_cv_prog_gxx_warn_flags="-W -Werror"
dnl The following list has options of the form OPT:BAD:GOOD
dnl if -OPT fails we try -OPT -BAD. If -OPT succeeds we add -GOOD.
for cf_opt in \
Werror \
Wall:Wno-maybe-uninitialized:\
Wint-to-void-pointer-cast \
Wzero-as-null-pointer-constant \
Wcast-align \
Wpointer-arith \
Wwrite-strings \
Wcast-qual \
Wcast-qual::DXTSTRINGDEFINES \
Wdocumentation \
Wmissing-declarations \
Wnoexcept \
@ -58,11 +73,26 @@ EOF
Wsuggest-override \
Wpedantic
do
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$cf_opt"
if AC_TRY_EVAL(ac_compile); then
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$cf_opt"
test "$cf_opt" = Wcast-qual && ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -DXTSTRINGDEFINES"
fi
fopt=${cf_opt%%:*}
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$fopt"
if AC_TRY_EVAL(ac_compile); then
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$fopt"
case $cf_opt in
*:*:);;
*:*:*)ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -${cf_opt##*:}";;
esac
else
case $cf_opt in
*::*);;
*:*:*)
sopt=${cf_opt%:*}
sopt=${sopt#*:}
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$fopt -$sopt"
if AC_TRY_EVAL(ac_compile); then
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$fopt -$sopt"
fi;;
esac
fi
done
rm -f conftest*
CXXFLAGS="$cf_save_CXXFLAGS"])

View file

@ -1,5 +1,5 @@
# getopt.m4 serial 47
dnl Copyright (C) 2002-2006, 2008-2020 Free Software Foundation, Inc.
dnl Copyright (C) 2002-2006, 2008-2020, 2022 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@ -363,13 +363,9 @@ dnl is ambiguous with environment values that contain newlines.
AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
[
AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
if test $ac_cv_header_sys_cdefs_h = yes; then
HAVE_SYS_CDEFS_H=1
else
HAVE_SYS_CDEFS_H=0
fi
AC_SUBST([HAVE_SYS_CDEFS_H])
# pretend HAVE_SYS_CDEFS_H is always 0 including <sys/defs.h> isn't
# really necessary and causes warning on Alpine Linux.
AC_SUBST([HAVE_SYS_CDEFS_H], [0])
AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
[Define to rpl_ if the getopt replacement functions and variables

View file

@ -1,4 +1,4 @@
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -57,6 +57,7 @@ gl_MODULES([
argmatch
argp
closeout
environ
error
isatty
mkstemp

View file

@ -1,5 +1,5 @@
# DO NOT EDIT! GENERATED AUTOMATICALLY!
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -246,6 +246,8 @@ AC_SUBST([LTALLOCA])
AC_LIBOBJ([lstat])
gl_PREREQ_LSTAT
fi
gl_ENVIRON
gl_UNISTD_MODULE_INDICATOR([environ])
gl_SYS_STAT_MODULE_INDICATOR([lstat])
gl_FUNC_MALLOC_GNU
if test $REPLACE_MALLOC = 1; then

View file

@ -1,74 +0,0 @@
# Portability macros for glibc argz. -*- Autoconf -*-
#
# Copyright (C) 2004-2007, 2011-2015 Free Software Foundation, Inc.
# Written by Gary V. Vaughan <gary@gnu.org>
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 1 ltargz.m4
AC_DEFUN([LT_FUNC_ARGZ], [
AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_TYPES([error_t],
[],
[AC_DEFINE([error_t], [int],
[Define to a type to use for 'error_t' if it is not otherwise available.])
AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h
does not typedef error_t.])],
[#if defined(HAVE_ARGZ_H)
# include <argz.h>
#endif])
LT_ARGZ_H=
AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \
argz_next argz_stringify], [], [LT_ARGZ_H=lt__argz.h; AC_LIBOBJ([lt__argz])])
dnl if have system argz functions, allow forced use of
dnl libltdl-supplied implementation (and default to do so
dnl on "known bad" systems). Could use a runtime check, but
dnl (a) detecting malloc issues is notoriously unreliable
dnl (b) only known system that declares argz functions,
dnl provides them, yet they are broken, is cygwin
dnl releases prior to 16-Mar-2007 (1.5.24 and earlier)
dnl So, it's more straightforward simply to special case
dnl this for known bad systems.
AS_IF([test -z "$LT_ARGZ_H"],
[AC_CACHE_CHECK(
[if argz actually works],
[lt_cv_sys_argz_works],
[[case $host_os in #(
*cygwin*)
lt_cv_sys_argz_works=no
if test no != "$cross_compiling"; then
lt_cv_sys_argz_works="guessing no"
else
lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/'
save_IFS=$IFS
IFS=-.
set x `uname -r | sed -e "$lt_sed_extract_leading_digits"`
IFS=$save_IFS
lt_os_major=${2-0}
lt_os_minor=${3-0}
lt_os_micro=${4-0}
if test 1 -lt "$lt_os_major" \
|| { test 1 -eq "$lt_os_major" \
&& { test 5 -lt "$lt_os_minor" \
|| { test 5 -eq "$lt_os_minor" \
&& test 24 -lt "$lt_os_micro"; }; }; }; then
lt_cv_sys_argz_works=yes
fi
fi
;; #(
*) lt_cv_sys_argz_works=yes ;;
esac]])
AS_IF([test yes = "$lt_cv_sys_argz_works"],
[AC_DEFINE([HAVE_WORKING_ARGZ], 1,
[This value is set to 1 to indicate that the system argz facility works])],
[LT_ARGZ_H=lt__argz.h
AC_LIBOBJ([lt__argz])])])
AC_SUBST([LT_ARGZ_H])
])

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2021 Laboratoire de
# Recherche et Développement de l'Epita (LRDE).
# Copyright (C) 2014-2023 Laboratoire de Recherche et Développement de
# l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
#
@ -104,19 +104,22 @@ def setup(**kwargs):
os.environ['SPOT_DOTDEFAULT'] = d
# In version 3.0.2, Swig puts strongly typed enum in the main
# namespace without prefixing them. Latter versions fix this. So we
# can remove for following hack once 3.0.2 is no longer used in our
# build farm.
if 'op_ff' not in globals():
# Swig versions prior to 4.1.0 export formula.X as formula_X as well,
# for all operators. Swig 4.1.0 stops doing this, breaking some
# existing code.
if 'formula_ff' not in globals():
for i in ('ff', 'tt', 'eword', 'ap', 'Not', 'X', 'F', 'G',
'Closure', 'NegClosure', 'NegClosureMarked',
'Xor', 'Implies', 'Equiv', 'U', 'R', 'W', 'M',
'EConcat', 'EConcatMarked', 'UConcat', 'Or',
'OrRat', 'And', 'AndRat', 'AndNLM', 'Concat',
'Fusion', 'Star', 'FStar'):
globals()['op_' + i] = globals()[i]
del globals()[i]
'Fusion', 'Star', 'FStar', 'nested_unop_range',
'sugar_goto', 'sugar_equal', 'sugar_delay', 'unop',
'binop', 'bunop', 'multop', 'first_match', 'unbounded'):
globals()['formula_' + i] = formula.__dict__[i].__func__
if 'trival_maybe' not in globals():
for i in ('maybe',):
globals()['trival_' + i] = trival.__dict__[i].__func__
# Global BDD dict so that we do not have to create one in user code.
@ -261,6 +264,12 @@ class twa:
ostr = ostringstream()
print_lbtt(ostr, a, opt)
return ostr.str()
if format == 'pg':
if opt is not None:
raise ValueError("print_pg() has no option")
ostr = ostringstream()
print_pg(ostr, a)
return ostr.str()
raise ValueError("unknown string format: " + format)
def save(a, filename, format='hoa', opt=None, append=False):
@ -493,51 +502,57 @@ class acd:
.acdacc polygon{fill:green;}
'''
js = '''
function acd{num}_clear(){{
$("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge")
.removeClass("acdhigh acdbold acdacc acdrej");
function acdremclasses(sel, classes) {{
document.querySelectorAll(sel).forEach(n=>{{n.classList.remove(...classes)}});}}
function acdaddclasses(sel, classes) {{
document.querySelectorAll(sel).forEach(n=>{{n.classList.add(...classes)}});}}
function acdonclick(sel, fn) {{
document.querySelectorAll(sel).forEach(n=>
{{n.addEventListener("click", fn)}});
}}
function acd{num}_clear() {{
acdremclasses("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge",
["acdhigh", "acdbold", "acdacc", "acdrej"]);
}};
function acd{num}_state(state){{
acd{num}_clear();
$("#acd{num} .acdS" + state).addClass("acdhigh acdbold");
$("#acdaut{num} #S" + state).addClass("acdbold");
acd{num}_clear();
acdaddclasses("#acd{num} .acdS" + state, ["acdhigh", "acdbold"]);
acdaddclasses("#acdaut{num} #S" + state, ["acdbold"]);
}};
function acd{num}_edge(edge){{
acd{num}_clear();
var theedge = $('#acdaut{num} #E' + edge)
var classList = theedge.attr('class').split(/\s+/);
$.each(classList, function(index, item) {{
if (item.startsWith('acdN')) {{
$("#acd{num} #" + item.substring(3)).addClass("acdhigh acdbold");
}}
}});
theedge.addClass("acdbold");
acd{num}_clear();
var theedge = document.querySelector('#acdaut{num} #E' + edge);
theedge.classList.forEach(function(item, index) {{
if (item.startsWith('acdN')) {{
acdaddclasses("#acd{num} #" + item.substring(3), ["acdhigh", "acdbold"]);
}}
}});
theedge.classList.add("acdbold");
}};
function acd{num}_node(node, acc){{
acd{num}_clear();
$("#acdaut{num} .acdN" + node).addClass(acc
? "acdacc acdbold"
: "acdrej acdbold");
$("#acd{num} #N" + node).addClass("acdbold acdhigh");
acdaddclasses("#acdaut{num} .acdN" + node,
[acc ? "acdacc" : "acdrej", "acdbold"]);
acdaddclasses("#acd{num} #N" + node, ["acdbold", "acdhigh"]);
}};'''.format(num=num)
me = 0
for n in range(self.node_count()):
for e in self.edges_of_node(n):
me = max(e, me)
js += '$("#acdaut{num} #E{e}").addClass("acdN{n}");'\
js += 'acdaddclasses("#acdaut{num} #E{e}", ["acdN{n}"]);\n'\
.format(num=num, e=e, n=n)
for e in range(1, me + 1):
js += '$("#acdaut{num} #E{e}")'\
'.click(function(){{acd{num}_edge({e});}});'\
js += 'acdonclick("#acdaut{num} #E{e}",'\
'function(){{acd{num}_edge({e});}});\n'\
.format(num=num, e=e)
for s in range(self.get_aut().num_states()):
js += '$("#acdaut{num} #S{s}")'\
'.click(function(){{acd{num}_state({s});}});'\
js += 'acdonclick("#acdaut{num} #S{s}",'\
'function(){{acd{num}_state({s});}});\n'\
.format(num=num, s=s)
for n in range(self.node_count()):
v = int(self.node_acceptance(n))
js += '$("#acd{num} #N{n}")'\
'.click(function(){{acd{num}_node({n}, {v});}});'\
js += 'acdonclick("#acd{num} #N{n}",'\
'function(){{acd{num}_node({n}, {v});}});\n'\
.format(num=num, n=n, v=v)
html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\
.format(style,
@ -1292,6 +1307,36 @@ def sat_minimize(aut, acc=None, colored=False,
else:
return sm(aut, args, state_based)
# Adding the inline csv-display option
def minimize_mealy(mm, opt = -1, display_log = False, return_log = False):
from spot.impl import minimize_mealy as minmealy
try:
lvl = int(opt)
opt = synthesis_info()
opt.minimize_lvl = lvl + 4
except (ValueError, TypeError) as _:
pass
if display_log or return_log:
import pandas as pd
with tempfile.NamedTemporaryFile(dir='.', suffix='.minlog') as t:
opt.opt.set_str("satlogcsv", t.name)
resmm = minmealy(mm, opt)
dfrm = pd.read_csv(t.name, dtype=object)
if display_log:
from IPython.display import display
del dfrm['instance']
display(dfrm)
if return_log:
return resmm, dfrm
else:
return resmm
else:
return minmealy(mm, opt)
def parse_word(word, dic=_bdd_dict):
from spot.impl import parse_word as pw
@ -1302,6 +1347,10 @@ def bdd_to_formula(b, dic=_bdd_dict):
from spot.impl import bdd_to_formula as bf
return bf(b, dic)
def bdd_to_cnf_formula(b, dic=_bdd_dict):
from spot.impl import bdd_to_cnf_formula as bf
return bf(b, dic)
def language_containment_checker(dic=_bdd_dict):
from spot.impl import language_containment_checker as c

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2009-2022 Laboratoire de Recherche et Développement
// Copyright (C) 2009-2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
@ -90,10 +90,13 @@
#include <spot/tl/apcollect.hh>
#include <spot/tl/contain.hh>
#include <spot/tl/derive.hh>
#include <spot/tl/dot.hh>
#include <spot/tl/expansions.hh>
#include <spot/tl/nenoform.hh>
#include <spot/tl/print.hh>
#include <spot/tl/simplify.hh>
#include <spot/tl/sonf.hh>
#include <spot/tl/unabbrev.hh>
#include <spot/tl/randomltl.hh>
#include <spot/tl/length.hh>
@ -113,13 +116,14 @@
#include <spot/twaalgos/aiger.hh>
#include <spot/twaalgos/alternation.hh>
#include <spot/twaalgos/cleanacc.hh>
#include <spot/twaalgos/degen.hh>
#include <spot/twaalgos/dot.hh>
#include <spot/twaalgos/dualize.hh>
#include <spot/twaalgos/cobuchi.hh>
#include <spot/twaalgos/copy.hh>
#include <spot/twaalgos/complete.hh>
#include <spot/twaalgos/complement.hh>
#include <spot/twaalgos/dbranch.hh>
#include <spot/twaalgos/degen.hh>
#include <spot/twaalgos/dot.hh>
#include <spot/twaalgos/dualize.hh>
#include <spot/twaalgos/emptiness.hh>
#include <spot/twaalgos/gtec/gtec.hh>
#include <spot/twaalgos/genem.hh>
@ -159,6 +163,7 @@
#include <spot/twaalgos/stutter.hh>
#include <spot/twaalgos/synthesis.hh>
#include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/translate_aa.hh>
#include <spot/twaalgos/toweak.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/dtwasat.hh>
@ -485,6 +490,7 @@ static void handle_any_exception()
}
}
%implicitconv spot::parallel_policy;
%include <spot/misc/common.hh>
%include <spot/misc/version.hh>
%include <spot/misc/minato.hh>
@ -517,8 +523,12 @@ namespace std {
%template(vectorbdd) vector<bdd>;
%template(aliasvector) vector<pair<string, bdd>>;
%template(vectorstring) vector<string>;
%template(vectorint) vector<int>;
%template(pair_formula_vectorstring) pair<spot::formula, vector<string>>;
%template(atomic_prop_set) set<spot::formula>;
%template(relabeling_map) map<spot::formula, spot::formula>;
%template(pair_formula) pair<spot::formula, spot::formula>;
%template(vector_pair_formula) vector<pair<spot::formula, spot::formula>>;
}
%include <spot/tl/environment.hh>
@ -531,6 +541,8 @@ namespace std {
%include <spot/twa/bdddict.hh>
%include <spot/twa/bddprint.hh>
%include <spot/twa/formula2bdd.hh>
%template(formula_to_bdd) spot::formula_to_bdd<spot::twa_graph>;
%include <spot/twa/fwd.hh>
/* These operators may raise exceptions, and we do not
want Swig4 to convert those exceptions to NotImplemented. */
@ -547,6 +559,27 @@ namespace std {
}
%apply std::vector<unsigned> &OUTPUT {std::vector<unsigned>& pairs}
%apply std::vector<spot::acc_cond::rs_pair> &OUTPUT {std::vector<spot::acc_cond::rs_pair>& pairs}
// Must occur before the twa declaration
%typemap(out) SWIGTYPE spot::acc_cond::fin_unit_one_split %{
{
auto& v = static_cast<const std::tuple<int, spot::acc_cond, spot::acc_cond>>($1);
$result = PyTuple_Pack(3,
swig::from(std::get<0>(v)),
swig::from(std::get<1>(v)),
swig::from(std::get<2>(v)));
}
%}
// Must occur before the twa declaration
%typemap(out) SWIGTYPE spot::acc_cond::fin_unit_one_split_improved %{
{
auto& v = static_cast<const std::tuple<int, spot::acc_cond, spot::acc_cond>>($1);
$result = PyTuple_Pack(3,
swig::from(std::get<0>(v)),
swig::from(std::get<1>(v)),
swig::from(std::get<2>(v)));
}
%}
%include <spot/twa/acc.hh>
%template(pair_bool_mark) std::pair<bool, spot::acc_cond::mark_t>;
@ -575,8 +608,11 @@ namespace std {
%include <spot/tl/apcollect.hh>
%include <spot/tl/contain.hh>
%include <spot/tl/derive.hh>
%include <spot/tl/expansions.hh>
%include <spot/tl/dot.hh>
%include <spot/tl/nenoform.hh>
%include <spot/tl/sonf.hh>
%include <spot/tl/print.hh>
%include <spot/tl/simplify.hh>
%include <spot/tl/unabbrev.hh>
@ -661,11 +697,14 @@ def state_is_accepting(self, src) -> "bool":
%include <spot/twaalgos/aiger.hh>
%include <spot/twaalgos/alternation.hh>
%include <spot/twaalgos/cleanacc.hh>
%include <spot/twaalgos/degen.hh>
%include <spot/twaalgos/dot.hh>
%include <spot/twaalgos/cobuchi.hh>
%include <spot/twaalgos/copy.hh>
%include <spot/twaalgos/complete.hh>
%include <spot/twaalgos/dbranch.hh>
%include <spot/twaalgos/degen.hh>
%include <spot/twaalgos/determinize.hh>
%include <spot/twaalgos/dot.hh>
%include <spot/twaalgos/dualize.hh>
%feature("flatnested") spot::twa_run::step;
%include <spot/twaalgos/emptiness.hh>
%template(list_step) std::list<spot::twa_run::step>;
@ -677,8 +716,6 @@ def state_is_accepting(self, src) -> "bool":
%include <spot/twaalgos/gfguarantee.hh>
%include <spot/twaalgos/compsusp.hh>
%include <spot/twaalgos/contains.hh>
%include <spot/twaalgos/determinize.hh>
%include <spot/twaalgos/dualize.hh>
%include <spot/twaalgos/langmap.hh>
%include <spot/twaalgos/magic.hh>
%include <spot/twaalgos/minimize.hh>
@ -725,6 +762,7 @@ def state_is_accepting(self, src) -> "bool":
%include <spot/twaalgos/stutter.hh>
%include <spot/twaalgos/synthesis.hh>
%include <spot/twaalgos/translate.hh>
%include <spot/twaalgos/translate_aa.hh>
%include <spot/twaalgos/toweak.hh>
%include <spot/twaalgos/hoa.hh>
%include <spot/twaalgos/dtwasat.hh>

View file

@ -71,16 +71,16 @@ logic (LTL & PSL).
%files -n libspot
%{_libdir}/libbddx.a
%{_libdir}/libbddx.la
%exclude %{_libdir}/libbddx.la
%{_libdir}/libbddx.so*
%{_libdir}/libspot.a
%{_libdir}/libspot.la
%exclude %{_libdir}/libspot.la
%{_libdir}/libspot.so*
%{_libdir}/libspotgen.a
%{_libdir}/libspotgen.la
%exclude %{_libdir}/libspotgen.la
%{_libdir}/libspotgen.so*
%{_libdir}/libspotltsmin.a
%{_libdir}/libspotltsmin.la
%exclude %{_libdir}/libspotltsmin.la
%{_libdir}/libspotltsmin.so*
%license COPYING
%doc AUTHORS COPYING NEWS README THANKS
@ -121,7 +121,7 @@ temporal logic (LTL & PSL).
%dir %{python3_sitearch}/spot
%{python3_sitearch}/spot/*
%{python3_sitearch}/_buddy.*.a
%{python3_sitearch}/_buddy.*.la
%exclude %{python3_sitearch}/_buddy.*.la
%{python3_sitearch}/_buddy.*.so
%license COPYING
%doc AUTHORS COPYING NEWS README THANKS

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020, 2022
## Laboratoire de Recherche et Développement de l'Epita (LRDE).
## Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -35,7 +35,7 @@ SUBDIRS = misc priv tl graph twa twacube twaalgos ta taalgos kripke \
lib_LTLIBRARIES = libspot.la
libspot_la_SOURCES =
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined $(SYMBOLIC_LDFLAGS)
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined @LIBSPOT_PTHREAD@ $(SYMBOLIC_LDFLAGS)
libspot_la_LIBADD = \
kripke/libkripke.la \
misc/libmisc.la \
@ -68,6 +68,7 @@ libspot.pc: $(srcdir)/libspot.pc.in Makefile
-e 's![@]includedir[@]!$(includedir)!g' \
-e 's![@]libdir[@]!$(libdir)!g' \
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
-e 's![@]LIBSPOT_PTHREAD[@]!$(LIBSPOT_PTHREAD)!g' \
$(srcdir)/libspot.pc.in > $@.tmp && mv $@.tmp $@
CLEANFILES = libspot.pc

View file

@ -583,7 +583,7 @@ struct _ConcurrentHashSet : HashSetBase< Cell >
return begin() + size();
}
Row() : _data( nullptr ), _size( 0 ) {}
Row() noexcept : _data( nullptr ), _size( 0 ) {}
~Row() { free(); }
};

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017-2019, 2021 Laboratoire de Recherche et
// Copyright (C) 2017-2019, 2021-2022 Laboratoire de Recherche et
// Developpement de l'EPITA (LRDE).
//
// This file is part of Spot, a model checking library.
@ -220,13 +220,48 @@ namespace spot
return aut;
}
static twa_graph_ptr
cyclist_trace_or_proof(unsigned n, bool trace, bdd_dict_ptr dict)
{
auto aut = make_twa_graph(dict);
acc_cond::mark_t m = aut->set_buchi();
aut->new_states(n + 2);
aut->set_init_state(0);
if (trace)
m = {};
aut->prop_state_acc(true);
// How many AP to we need to represent n letters
unsigned nap = ulog2(n + 1);
std::vector<int> apvars(nap);
for (unsigned a = 0; a < nap; ++a)
apvars[a] = aut->register_ap("p" + std::to_string(a));
if (trace)
aut->new_edge(0, 0, bddtrue); // the only non-deterministic edge
else
aut->prop_universal(true);
bdd zero = bdd_ibuildcube(0, nap, apvars.data());
aut->new_edge(0, 1, zero, m);
for (unsigned letter = 1; letter <= n; ++letter)
{
bdd cond = bdd_ibuildcube(letter, nap, apvars.data());
aut->new_acc_edge(1, letter + 1, cond);
aut->new_edge(letter + 1, 1, zero, m);
}
return aut;
}
twa_graph_ptr aut_pattern(aut_pattern_id pattern, int n, bdd_dict_ptr dict)
{
if (n < 0)
{
std::ostringstream err;
err << "pattern argument for " << aut_pattern_name(pattern)
<< " should be positive";
<< " should be non-negative";
throw std::runtime_error(err.str());
}
@ -241,6 +276,10 @@ namespace spot
return l_dsa(n, dict);
case AUT_M_NBA:
return m_nba(n, dict);
case AUT_CYCLIST_TRACE_NBA:
return cyclist_trace_or_proof(n, true, dict);
case AUT_CYCLIST_PROOF_DBA:
return cyclist_trace_or_proof(n, false, dict);
case AUT_END:
break;
}
@ -255,6 +294,8 @@ namespace spot
"l-nba",
"l-dsa",
"m-nba",
"cyclist-trace-nba",
"cyclist-proof-dba",
};
// Make sure we do not forget to update the above table every
// time a new pattern is added.

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017, 2019 Laboratoire de Recherche et Developpement de
// Copyright (C) 2017, 2019, 2022 Laboratoire de Recherche et Developpement de
// l'EPITA (LRDE).
//
// This file is part of Spot, a model checking library.
@ -79,6 +79,24 @@ namespace spot
/// propositions to encode the $n+1$ letters used in the
/// original alphabet.
AUT_M_NBA,
/// \brief An NBA with (n+2) states derived from a Cyclic test
/// case.
///
/// This familly of automata is derived from a couple of
/// examples supplied by Reuben Rowe. The task is to
/// check that the automaton generated with AUT_CYCLIST_TRACE_NBA
/// for a given n contain the automaton generated with
/// AUT_CYCLIST_PROOF_DBA for the same n.
AUT_CYCLIST_TRACE_NBA,
/// \brief A DBA with (n+2) states derived from a Cyclic test
/// case.
///
/// This familly of automata is derived from a couple of
/// examples supplied by Reuben Rowe. The task is to
/// check that the automaton generated with AUT_CYCLIST_TRACE_NBA
/// for a given n contain the automaton generated with
/// AUT_CYCLIST_PROOF_DBA for the same n.
AUT_CYCLIST_PROOF_DBA,
AUT_END
};

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2019 Laboratoire de Recherche et Developpement
// Copyright (C) 2012-2019, 2022 Laboratoire de Recherche et Developpement
// de l'EPITA (LRDE).
//
// This file is part of Spot, a model checking library.
@ -1198,13 +1198,13 @@ namespace spot
}
static formula
pps_arbiter(std::string r_, std::string g_, int n, bool strict_)
pps_arbiter(std::string r_, std::string g_, unsigned n, bool strict_)
{
formula* r = new formula[n];
formula* g = new formula[n];
std::vector<formula> res;
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
{
r[i] = formula::ap(r_ + std::to_string(i + 1));
g[i] = formula::ap(g_ + std::to_string(i + 1));
@ -1218,17 +1218,17 @@ namespace spot
formula phi_s;
{
std::vector<formula> res;
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
res.push_back(formula::Not(r[i]));
theta_e = formula::And(res);
res.clear();
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
res.push_back(formula::Not(g[i]));
theta_s = formula::And(res);
res.clear();
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
{
formula left = formula::Xor(r[i], g[i]);
formula right = formula::Equiv(r[i], formula::X(r[i]));
@ -1237,9 +1237,9 @@ namespace spot
psi_e = formula::And(res);
res.clear();
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
{
for (int j = 0; j < i; ++j)
for (unsigned j = 0; j < i; ++j)
res.push_back(formula::Not(formula::And({g[i], g[j]})));
formula left = formula::Equiv(r[i], g[i]);
formula right = formula::Equiv(g[i], formula::X(g[i]));
@ -1248,7 +1248,7 @@ namespace spot
psi_s = formula::And(res);
res.clear();
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
{
formula f = formula::Not(formula::And({r[i], g[i]}));
res.push_back(formula::G(formula::F(f)));
@ -1256,7 +1256,7 @@ namespace spot
phi_e = formula::And(res);
res.clear();
for (int i = 0; i < n; ++i)
for (unsigned i = 0; i < n; ++i)
{
res.push_back(formula::G(formula::F(formula::Equiv(r[i], g[i]))));
}
@ -1267,9 +1267,9 @@ namespace spot
if (!strict_)
{
formula left = formula::And({formula::G(psi_e), phi_e});
formula imp =
formula::Implies(formula::And({formula::G(psi_e), phi_e}),
formula::And({formula::G(psi_s), phi_s}));
formula::Implies(left, formula::And({formula::G(psi_s), phi_s}));
return formula::Implies(theta_e, formula::And({theta_s, imp}));
}
else
@ -1281,6 +1281,21 @@ namespace spot
}
}
// G[0..n]((a S b) -> c) rewritten using future operators,
// from Edmond Irani Liu (EIL). GSI stands for "Globally Since Implies."
static formula eil_gsi(int n, std::string a, std::string b, std::string c)
{
formula fa = formula::ap(a);
formula fb = formula::ap(b);
formula res = fb;
for (int i = 1; i <= n; ++i)
{
formula tmp = formula::And({formula::strong_X(i, fa), res});
res = formula::Or({formula::strong_X(i, fb), tmp});
}
return formula::Implies(res, formula::strong_X(n, formula::ap(c)));
}
formula ltl_pattern(ltl_pattern_id pattern, int n, int m)
{
if (n < 0)
@ -1317,6 +1332,8 @@ namespace spot
return dac_pattern(n);
case LTL_EH_PATTERNS:
return eh_pattern(n);
case LTL_EIL_GSI:
return eil_gsi(n, "a", "b", "c");
case LTL_FXG_OR:
return FXG_or_n("p", n);
case LTL_GF_EQUIV:
@ -1418,6 +1435,7 @@ namespace spot
"ccj-beta-prime",
"dac-patterns",
"eh-patterns",
"eil-gsi",
"fxg-or",
"gf-equiv",
"gf-equiv-xn",
@ -1485,6 +1503,7 @@ namespace spot
return 55;
case LTL_EH_PATTERNS:
return 12;
case LTL_EIL_GSI:
case LTL_FXG_OR:
case LTL_GF_EQUIV:
case LTL_GF_EQUIV_XN:
@ -1554,6 +1573,7 @@ namespace spot
case LTL_CCJ_BETA_PRIME:
case LTL_DAC_PATTERNS:
case LTL_EH_PATTERNS:
case LTL_EIL_GSI:
case LTL_FXG_OR:
case LTL_GF_EQUIV:
case LTL_GF_EQUIV_XN:

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017, 2018, 2019 Laboratoire de Recherche et Developpement de
// l'EPITA (LRDE).
// Copyright (C) 2017-2019, 2022 Laboratoire de Recherche et
// Developpement de l'EPITA (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -56,6 +56,8 @@ namespace spot
/// 12 formulas from Etessami and Holzmann.
/// \cite etessami.00.concur
LTL_EH_PATTERNS,
/// Familly sent by Edmond Irani Liu
LTL_EIL_GSI,
/// `F(p0 | XG(p1 | XG(p2 | ... XG(pn))))`
LTL_FXG_OR,
/// `(GFa1 & GFa2 & ... & GFan) <-> GFz`

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014-2018, 2020, 2021 Laboratoire de Recherche et
// Copyright (C) 2014-2018, 2020-2022 Laboratoire de Recherche et
// Développement de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -20,6 +20,7 @@
#pragma once
#include <spot/misc/common.hh>
#include <spot/misc/_config.h>
#include <vector>
#include <type_traits>
#include <tuple>
@ -28,6 +29,9 @@
#include <algorithm>
#include <map>
#include <iostream>
#ifdef SPOT_ENABLE_PTHREAD
# include <thread>
#endif // SPOT_ENABLE_PTHREAD
namespace spot
{
@ -553,10 +557,11 @@ namespace spot
{
std::map<std::vector<unsigned>, unsigned> uniq_;
G& g_;
unsigned acc_sink_;
public:
univ_dest_mapper(G& graph)
: g_(graph)
univ_dest_mapper(G& graph, unsigned sink = -1u)
: g_(graph), acc_sink_(sink)
{
}
@ -566,6 +571,9 @@ namespace spot
std::vector<unsigned> tmp(begin, end);
std::sort(tmp.begin(), tmp.end());
tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
if (acc_sink_ != -1u && tmp.size() > 1)
tmp.erase(std::remove(tmp.begin(), tmp.end(), acc_sink_),
tmp.end());
auto p = uniq_.emplace(tmp, 0);
if (p.second)
p.first->second = g_.new_univ_dests(tmp.begin(), tmp.end());
@ -800,8 +808,23 @@ namespace spot
return *dst_begin;
SPOT_ASSERT(sz > 1);
unsigned d = dests_.size();
dests_.emplace_back(sz);
dests_.insert(dests_.end(), dst_begin, dst_end);
if (!dests_.empty()
&& &*dst_begin >= &dests_.front()
&& &*dst_begin <= &dests_.back()
&& (dests_.capacity() - dests_.size()) < (sz + 1))
{
// If dst_begin...dst_end points into dests_ and dests_ risk
// being reallocated, we have to savea the destination
// states before we lose them.
std::vector<unsigned> tmp(dst_begin, dst_end);
dests_.emplace_back(sz);
dests_.insert(dests_.end(), tmp.begin(), tmp.end());
}
else
{
dests_.emplace_back(sz);
dests_.insert(dests_.end(), dst_begin, dst_end);
}
return ~d;
}
@ -1226,6 +1249,78 @@ namespace spot
std::stable_sort(edges_.begin() + 1, edges_.end(), p);
}
/// \brief Sort all edges by src first, then, within edges of the same
/// source use the predicate
///
/// This will invalidate all iterators, and also destroy edge
/// chains. Call chain_edges_() immediately afterwards unless you
/// know what you are doing.
/// \note: for performance this will work in parallel (if enabled)
/// and make a temporary copy of the edges (needs more ram)
/// \pre This needs the edge_vector to be in a coherent state when called
template<class Predicate = std::less<edge_storage_t>>
void sort_edges_srcfirst_(Predicate p = Predicate(),
parallel_policy ppolicy = parallel_policy())
{
SPOT_ASSERT(!edges_.empty());
const unsigned ns = num_states();
std::vector<unsigned> idx_list(ns+1);
edge_vector_t new_edges;
new_edges.reserve(edges_.size());
new_edges.resize(1);
// This causes edge 0 to be considered as dead.
new_edges[0].next_succ = 0;
// Copy all edges so that they are sorted by src
for (unsigned s = 0; s < ns; ++s)
{
idx_list[s] = new_edges.size();
for (const auto& e : out(s))
new_edges.push_back(e);
}
idx_list[ns] = new_edges.size();
// New edge sorted by source
// If we have few edge or only one threads
// Benchmark few?
auto bne = new_edges.begin();
#ifndef SPOT_ENABLE_PTHREAD
(void) ppolicy;
#else
unsigned nthreads = ppolicy.nthreads();
if (nthreads <= 1)
#endif
{
for (unsigned s = 0u; s < ns; ++s)
std::stable_sort(bne + idx_list[s],
bne + idx_list[s+1], p);
}
#ifdef SPOT_ENABLE_PTHREAD
else
{
static std::vector<std::thread> tv;
SPOT_ASSERT(tv.empty());
tv.resize(nthreads);
// FIXME: Due to the way these thread advance into the state
// vector, they access very close memory location. It would
// seems more cache friendly to have threads work on blocks
// of continuous states.
for (unsigned id = 0; id < nthreads; ++id)
tv[id] = std::thread(
[bne, id, ns, &idx_list, p, nthreads]()
{
for (unsigned s = id; s < ns; s += nthreads)
std::stable_sort(bne + idx_list[s],
bne + idx_list[s+1], p);
return;
});
for (auto& t : tv)
t.join();
tv.clear();
}
#endif
std::swap(edges_, new_edges);
// Like after normal sort_edges, they need to be chained before usage
}
/// \brief Sort edges of the given states
///
/// \tparam Predicate : Comparison type
@ -1243,14 +1338,19 @@ namespace spot
//dump_storage(std::cerr);
auto pi = [&](unsigned t1, unsigned t2)
{return p(edges_[t1], edges_[t2]); };
// Sort the outgoing edges of each selected state according
// to predicate p. Do that in place.
std::vector<unsigned> sort_idx_;
for (unsigned i = 0; i < num_states(); ++i)
unsigned ns = num_states();
for (unsigned i = 0; i < ns; ++i)
{
if (to_sort_ptr && !(*to_sort_ptr)[i])
continue;
sort_idx_.clear();
unsigned t = states_[i].succ;
if (t == 0)
continue;
sort_idx_.clear();
do
{
sort_idx_.push_back(t);

View file

@ -8,5 +8,5 @@ Description: A library of LTL and omega-automata algorithms for model checking
URL: https://spot.lrde.epita.fr/
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lspot
Libs: -L${libdir} -lspot @LIBSPOT_PTHREAD@
Requires: libbddx

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2017, 2018, 2020 Laboratoire de Recherche et Développement de
// l'Epita (LRDE)
// Copyright (C) 2017, 2018, 2020, 2022 Laboratoire de Recherche et
// Développement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
//
@ -400,10 +400,10 @@ namespace spot
}
}
// FIXME I think we only need visbles aps, i.e. if the system has
// following variables, i.e. P_0.var1 and P_0.var2 but the property
// automaton only mention P_0.var2, we do not need to capture (in
// the resulting cube) any atomic proposition for P_0.var1
// FIXME: I think we only need visible aps. E.g., if the system has
// variables P_0.var1 and P_0.var2 but the property automaton only
// mentions P_0.var2, we do not need to capture (in the resulting
// cube) any atomic proposition for P_0.var1
void
kripkecube<cspins_state,
cspins_iterator>::match_aps(std::vector<std::string>& aps,

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
// Developpement de l'Epita
//
// This file is part of Spot, a model checking library.
@ -127,7 +127,7 @@ namespace spot
bool b = it.isnew();
// Insertion failed, delete element
// FIXME Should we add a local cache to avoid useless allocations?
// FIXME: Should we add a local cache to avoid useless allocations?
if (!b)
p_.deallocate(v);
else

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
// Developpement de l'Epita
//
// This file is part of Spot, a model checking library.
@ -251,7 +251,7 @@ namespace spot
uf_element* q;
uf_element* r;
while (true)
do
{
a_root = find(a);
b_root = find(b);
@ -261,28 +261,24 @@ namespace spot
// Update acceptance condition
{
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
a_root->acc |= acc;
acc |= a_root->acc;
a_root->acc = acc;
}
while (a_root->parent.load() != a_root)
{
a_root = find(a_root);
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
a_root->acc |= acc;
acc |= a_root->acc;
a_root->acc = acc;
}
return acc;
}
r = std::max(a_root, b_root);
q = std::min(a_root, b_root);
if (!lock_root(q))
continue;
break;
}
while (!lock_root(q));
uf_element* a_list = lock_list(a);
if (a_list == nullptr)
@ -329,9 +325,8 @@ namespace spot
{
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
q->acc |= acc;
r->acc |= q->acc;
acc |= r->acc;
acc |= r->acc | q->acc;
r->acc = q->acc = acc;
}
while (r->parent.load() != r)
@ -339,8 +334,8 @@ namespace spot
r = find(r);
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
r->acc |= q->acc;
acc |= r->acc;
acc |= r->acc | q->acc;
r->acc = acc;
}
unlock_list(a_list);
@ -360,9 +355,7 @@ namespace spot
a_status = a->list_status_.load();
if (a_status == list_status::BUSY)
{
return a;
}
return a;
if (a_status == list_status::DONE)
break;
@ -407,9 +400,7 @@ namespace spot
b_status = b->list_status_.load();
if (b_status == list_status::BUSY)
{
return b;
}
return b;
if (b_status == list_status::DONE)
break;
@ -556,8 +547,8 @@ namespace spot
{
auto root = uf_.find(w.second);
std::lock_guard<std::mutex> lock(w.second->acc_mutex_);
scc_acc = w.second->acc;
std::lock_guard<std::mutex> lock(root->acc_mutex_);
scc_acc = root->acc;
}
// cycle found in SCC and it contains acceptance condition

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
// Developpement de l'Epita
//
// This file is part of Spot, a model checking library.
@ -191,9 +191,7 @@ namespace spot
{
// Try to insert the new state in the shared map.
auto it = map_.insert(s);
bool b = it.isnew();
SPOT_ASSERT(!b); // should never be new in a red DFS
SPOT_ASSERT(!it.isnew()); // should never be new in a red DFS
bool red = ((*it)).colors->red.load();
bool cyan = ((*it)).colors->l[tid_].cyan;
bool in_Rp = ((*it)).colors->l[tid_].is_in_Rp;

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015-2016, 2018-2021 Laboratoire de Recherche et
// Copyright (C) 2015-2016, 2018-, 20222022 Laboratoire de Recherche et
// Developpement de l'Epita
//
// This file is part of Spot, a model checking library.
@ -32,9 +32,9 @@ namespace spot
{
/// \brief This class implements the sequential emptiness check as
/// presented in "Three SCC-based Emptiness Checks for Generalized
/// B\¨uchi Automata" (Renault et al, LPAR 2013). Among the three
/// emptiness check that has been proposed we opted to implement
/// the Gabow's one.
/// Büchi Automata" (Renault et al, LPAR 2013). Among the three
/// emptiness checks that have been proposed, we opted to implement
/// yGabow's one.
template<typename State, typename SuccIterator,
typename StateHash, typename StateEqual>
class SPOT_API lpar13
@ -62,8 +62,8 @@ namespace spot
size_t
operator()(const product_state that) const noexcept
{
// FIXME! wang32_hash(that.st_prop) could have
// been pre-calculated!
// FIXME: wang32_hash(that.st_prop) could have been
// pre-calculated!
StateHash hasher;
return wang32_hash(that.st_prop) ^ hasher(that.st_kripke);
}
@ -135,7 +135,7 @@ namespace spot
map[newtop])))
{
sys_.recycle(todo.back().it_kripke, tid_);
// FIXME a local storage for twacube iterator?
// FIXME: a local storage for twacube iterator?
todo.pop_back();
if (SPOT_UNLIKELY(found_))
{
@ -346,7 +346,7 @@ namespace spot
ctrx_element* current = front;
while (current != nullptr)
{
// FIXME also display acc?
// FIXME: also display acc?
res = res + " " +
std::to_string(current->prod_st->st_prop) +
+ "*" +

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2011-2014, 2016-2018, 2020-2021 Laboratoire de
## Copyright (C) 2011-2014, 2016-2018, 2020-2022 Laboratoire de
## Recherche et Développement de l'Epita (LRDE).
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2013-2021, 2023 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -111,22 +111,22 @@ namespace spot
return;
if (storage_ == &local_storage_)
{
block_t* new_storage_ = static_cast<block_t*>
block_t* new_storage = static_cast<block_t*>
(malloc(new_block_count * sizeof(block_t)));
if (SPOT_UNLIKELY(!new_storage))
throw std::bad_alloc();
for (size_t i = 0; i < block_count_; ++i)
new_storage_[i] = storage_[i];
storage_ = new_storage_;
new_storage[i] = storage_[i];
storage_ = new_storage;
}
else
{
auto old = storage_;
storage_ = static_cast<block_t*>
(realloc(old, new_block_count * sizeof(block_t)));
if (!storage_)
{
free(old);
throw std::bad_alloc();
}
block_t* new_storage = static_cast<block_t*>
(realloc(storage_, new_block_count * sizeof(block_t)));
if (SPOT_UNLIKELY(!new_storage))
// storage_, untouched, will be freed by the destructor.
throw std::bad_alloc();
storage_ = new_storage;
}
block_count_ = new_block_count;
}
@ -134,8 +134,8 @@ namespace spot
private:
void grow()
{
size_t new_block_count_ = (block_count_ + 1) * 7 / 5;
reserve_blocks(new_block_count_);
size_t new_block_count = (block_count_ + 1) * 7 / 5;
reserve_blocks(new_block_count);
}
public:

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -145,6 +145,27 @@ namespace spot
{
}
};
/// \brief This class is used to tell parallel algorithms what
/// resources they may use.
///
/// Currently, this simply stores an integer indicating the number
/// of threads that the algorithm may create, but in the future it
/// will probably do more.
class SPOT_API parallel_policy
{
unsigned nthreads_;
public:
parallel_policy(unsigned nthreads = 1) : nthreads_(nthreads)
{
}
unsigned nthreads() const
{
return nthreads_;
}
};
}
// This is a workaround for the issue described in GNU GCC bug 89303.

Some files were not shown because too many files have changed in this diff Show more