File tree Expand file tree Collapse file tree 5 files changed +111
-1
lines changed
Expand file tree Collapse file tree 5 files changed +111
-1
lines changed Original file line number Diff line number Diff line change @@ -543,3 +543,40 @@ void hoat::output(std::ostream &out) const
543543
544544 out << " --END--\n " ;
545545}
546+
547+ grapht<graph_nodet<hoat::graph_edget>> hoat::graph () const
548+ {
549+ grapht<graph_nodet<hoat::graph_edget>> graph;
550+
551+ graph.resize (numeric_cast_v<std::size_t >(max_state_number () + 1 ));
552+
553+ for (auto &state : body)
554+ {
555+ for (auto &edge : state.second )
556+ for (auto &dest : edge.dest_states )
557+ {
558+ graph.add_edge (state.first .number , dest);
559+ graph.edge (state.first .number , dest).label = edge.label ;
560+ }
561+ }
562+
563+ return graph;
564+ }
565+
566+ void hoat::buechi_acceptance_cleanup ()
567+ {
568+ using hoa_grapht = grapht<graph_nodet<hoat::graph_edget>>;
569+ auto as_graph = graph ();
570+ for (auto &state : body)
571+ {
572+ if (state.first .is_accepting ())
573+ {
574+ hoa_grapht::patht loop_path;
575+ as_graph.shortest_loop (state.first .number , loop_path);
576+ // when this state is not part of any cycle,
577+ // then we cannot have Buechi acceptance via this state
578+ if (loop_path.empty ())
579+ state.first .acc_sig .clear ();
580+ }
581+ }
582+ }
Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ Author: Daniel Kroening, dkr@amazon.com
99#ifndef CPROVER_TEMPORAL_LOGIC_HOA_H
1010#define CPROVER_TEMPORAL_LOGIC_HOA_H
1111
12+ #include < util/graph.h>
1213#include < util/irep.h>
1314
1415#include < cstdint>
@@ -47,7 +48,7 @@ class hoat
4748 acc_sigt acc_sig; // acceptance sets
4849 };
4950 using edgest = std::list<edget>;
50- using bodyt = std::list <std::pair<state_namet, edgest>>;
51+ using bodyt = std::vector <std::pair<state_namet, edgest>>;
5152 bodyt body;
5253
5354 hoat (headert _header, bodyt _body)
@@ -68,6 +69,19 @@ class hoat
6869
6970 // atomic propositions
7071 std::map<intt, std::string> ap_map;
72+
73+ // convert into a graph
74+ struct graph_edget
75+ {
76+ labelt label;
77+ };
78+
79+ grapht<graph_nodet<graph_edget>> graph () const ;
80+
81+ // Remove accepting states that are not part of a cycle.
82+ // These are irrelevant when using the standard Buechi
83+ // acceptance criterion.
84+ void buechi_acceptance_cleanup ();
7185};
7286
7387#endif // CPROVER_TEMPORAL_LOGIC_HOA_H
Original file line number Diff line number Diff line change @@ -135,6 +135,9 @@ ltl_to_buechi(const exprt &property, message_handlert &message_handler)
135135
136136 message.debug () << hoa << messaget::eom;
137137
138+ // clean up accepting states
139+ hoa.buechi_acceptance_cleanup ();
140+
138141 auto max_state_number = hoa.max_state_number ();
139142 auto state_type = range_typet{0 , max_state_number};
140143 const auto buechi_state = symbol_exprt{" buechi::state" , state_type};
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ SRC = unit_tests.cpp
55
66# Test source files
77SRC += smvlang/expr2smv.cpp \
8+ temporal-logic/hoa.cpp \
89 temporal-logic/ltl_sva_to_string.cpp \
910 temporal-logic/sva_sequence_match.cpp \
1011 temporal-logic/nnf.cpp \
Original file line number Diff line number Diff line change 1+ /* ******************************************************************\
2+
3+ Module: Hanoi Omega Automata (HOA) Format
4+
5+ Author: Daniel Kroening, dkr@amazon.com
6+
7+ \*******************************************************************/
8+
9+ #include < temporal-logic/hoa.h>
10+ #include < testing-utils/use_catch.h>
11+
12+ SCENARIO (" Parsing a HOA from a string" )
13+ {
14+ GIVEN (" A HOA string for Xp" )
15+ {
16+ auto hoa_string =
17+ " HOA: v1.1\n "
18+ " name: X!a0\n "
19+ " States: 4\n "
20+ " Start: 1\n "
21+ " AP: 1 a0\n "
22+ " acc-name: Buchi\n "
23+ " Acceptance: 1 Inf ( 0 )\n "
24+ " properties: trans-labels explicit-labels state-acc complete\n "
25+ " properties: deterministic terminal very-weak\n "
26+ " --BODY--\n "
27+ " State: 0 {0}\n "
28+ " [!0] 2\n "
29+ " [0] 3\n "
30+ " State: 1 {0}\n "
31+ " [t] 0\n "
32+ " State: 2 {0}\n "
33+ " [t] 2\n "
34+ " State: 3\n "
35+ " [t] 3\n "
36+ " --END--\n " ;
37+
38+ auto hoa = hoat::from_string (hoa_string);
39+
40+ REQUIRE (hoa.body .size () == 4 );
41+
42+ REQUIRE (hoa.body [0 ].first .is_accepting ());
43+ REQUIRE (hoa.body [1 ].first .is_accepting ());
44+ REQUIRE (hoa.body [2 ].first .is_accepting ());
45+ REQUIRE (!hoa.body [3 ].first .is_accepting ());
46+
47+ // now remove the extra accepting states
48+ hoa.buechi_acceptance_cleanup ();
49+
50+ REQUIRE (!hoa.body [0 ].first .is_accepting ());
51+ REQUIRE (!hoa.body [1 ].first .is_accepting ());
52+ REQUIRE (hoa.body [2 ].first .is_accepting ());
53+ REQUIRE (!hoa.body [3 ].first .is_accepting ());
54+ }
55+ }
You can’t perform that action at this time.
0 commit comments