spot 2.16
Loading...
Searching...
No Matches
acc.hh
1// -*- coding: utf-8 -*-
2// Copyright (C) by the Spot authors, see the AUTHORS file for details.
3//
4// This file is part of Spot, a model checking library.
5//
6// Spot is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 3 of the License, or
9// (at your option) any later version.
10//
11// Spot is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14// License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#pragma once
20
21#include <functional>
22#include <limits>
23#include <sstream>
24#include <stdexcept>
25#include <vector>
26#include <iostream>
27#include <algorithm>
28#include <numeric>
29#include <bddx.h>
30#include <tuple>
31#include <spot/misc/_config.h>
32#include <spot/misc/bitset.hh>
33#include <spot/misc/trival.hh>
34
35namespace spot
36{
37 namespace internal
38 {
39 class mark_container;
40 }
41
44
53 class SPOT_API acc_cond
54 {
55#ifndef SWIG
56 private:
57 [[noreturn]] static void report_too_many_sets();
58#endif
59 public:
60
75 struct mark_t
76 {
77 private:
78 // configure guarantees that SPOT_MAX_ACCSETS % (8*sizeof(unsigned)) == 0
79 typedef bitset<SPOT_MAX_ACCSETS / (8*sizeof(unsigned))> _value_t;
80 _value_t id;
81
82 mark_t(_value_t id) noexcept
83 : id(id)
84 {
85 }
86
87 public:
89 mark_t() = default;
90
91#ifndef SWIG
93 template<class iterator>
94 mark_t(const iterator& begin, const iterator& end)
95 : mark_t(_value_t::zero())
96 {
97 for (iterator i = begin; i != end; ++i)
98 if (SPOT_LIKELY(*i < SPOT_MAX_ACCSETS))
99 set(*i);
100 else
101 report_too_many_sets();
102 }
103
105 mark_t(std::initializer_list<unsigned> vals)
106 : mark_t(vals.begin(), vals.end())
107 {
108 }
109#endif
110
116 constexpr static unsigned max_accsets()
117 {
118 return SPOT_MAX_ACCSETS;
119 }
120
126 static mark_t all()
127 {
128 return mark_t(_value_t::mone());
129 }
130
132 size_t hash() const noexcept
133 {
134 std::hash<decltype(id)> h;
135 return h(id);
136 }
137
139 bool operator==(mark_t o) const
140 {
141 return id == o.id;
142 }
143
145 bool operator!=(mark_t o) const
146 {
147 return id != o.id;
148 }
149
151 bool operator<(mark_t o) const
152 {
153 return id < o.id;
154 }
155
157 bool operator<=(mark_t o) const
158 {
159 return id <= o.id;
160 }
161
163 bool operator>(mark_t o) const
164 {
165 return id > o.id;
166 }
167
169 bool operator>=(mark_t o) const
170 {
171 return id >= o.id;
172 }
173
175 explicit operator bool() const
176 {
177 return !!id;
178 }
179
181 bool has(unsigned u) const
182 {
183 return !!this->operator&(mark_t({0}) << u);
184 }
185
187 void set(unsigned u)
188 {
189 id.set(u);
190 }
191
193 void clear(unsigned u)
194 {
195 id.clear(u);
196 }
197
200 {
201 id &= r.id;
202 return *this;
203 }
204
207 {
208 id |= r.id;
209 return *this;
210 }
211
214 {
215 id &= ~r.id;
216 return *this;
217 }
218
221 {
222 id ^= r.id;
223 return *this;
224 }
225
228 {
229 return id & r.id;
230 }
231
234 {
235 return id | r.id;
236 }
237
240 {
241 return id & ~r.id;
242 }
243
246 {
247 return ~id;
248 }
249
252 {
253 return id ^ r.id;
254 }
255
256#if SPOT_DEBUG || defined(SWIGPYTHON)
257# define SPOT_WRAP_OP(ins) \
258 try \
259 { \
260 ins; \
261 } \
262 catch (const std::runtime_error& e) \
263 { \
264 report_too_many_sets(); \
265 }
266#else
267# define SPOT_WRAP_OP(ins) ins;
268#endif
270 mark_t operator<<(unsigned i) const
271 {
272 SPOT_WRAP_OP(return id << i);
273 }
274
276 mark_t& operator<<=(unsigned i)
277 {
278 SPOT_WRAP_OP(id <<= i; return *this);
279 }
280
282 mark_t operator>>(unsigned i) const
283 {
284 SPOT_WRAP_OP(return id >> i);
285 }
286
288 mark_t& operator>>=(unsigned i)
289 {
290 SPOT_WRAP_OP(id >>= i; return *this);
291 }
292#undef SPOT_WRAP_OP
293
299 {
300 // strip every bit of id that is marked in y
301 // 100101110100.strip(
302 // 001011001000)
303 // == 10 1 11 100
304 // == 10111100
305
306 auto xv = id; // 100101110100
307 auto yv = y.id; // 001011001000
308
309 while (yv && xv)
310 {
311 // Mask for everything after the last 1 in y
312 auto rm = (~yv) & (yv - 1); // 000000000111
313 // Mask for everything before the last 1 in y
314 auto lm = ~(yv ^ (yv - 1)); // 111111110000
315 xv = ((xv & lm) >> 1) | (xv & rm);
316 yv = (yv & lm) >> 1;
317 }
318 return xv;
319 }
320
323 bool subset(mark_t m) const
324 {
325 return !((*this) - m);
326 }
327
330 bool proper_subset(mark_t m) const
331 {
332 return *this != m && this->subset(m);
333 }
334
336 unsigned count() const
337 {
338 return id.count();
339 }
340
345 unsigned max_set() const
346 {
347 if (id)
348 return id.highest()+1;
349 else
350 return 0;
351 }
352
357 unsigned min_set() const
358 {
359 if (id)
360 return id.lowest()+1;
361 else
362 return 0;
363 }
364
370 {
371 return id & -id;
372 }
373
375 bool is_singleton() const
376 {
377#if __GNUC__
378 /* With GCC and Clang, count() is implemented using popcount. */
379 return count() == 1;
380#else
381 return id && !(id & (id - 1));
382#endif
383 }
384
386 bool has_many() const
387 {
388#if __GNUC__
389 /* With GCC and Clang, count() is implemented using popcount. */
390 return count() > 1;
391#else
392 return !!(id & (id - 1));
393#endif
394 }
395
399 mark_t& remove_some(unsigned n)
400 {
401 while (n--)
402 id &= id - 1;
403 return *this;
404 }
405
407 template<class iterator>
408 void fill(iterator here) const;
409
411 spot::internal::mark_container sets() const;
412
414 std::string as_string() const;
415 };
416
418 enum class acc_op : unsigned
419 { Inf, Fin, InfNeg, FinNeg, And, Or };
420
429 {
431 struct {
439 unsigned size:24;
440 } sub;
441 };
442
455 struct SPOT_API acc_code: public std::vector<acc_word>
456 {
460
462 bool operator==(const acc_code& other) const
463 {
464 // We have two ways to represent t, unfortunately.
465 if (is_t() && other.is_t())
466 return true;
467 unsigned pos = size();
468 if (other.size() != pos)
469 return false;
470 while (pos > 0)
471 {
472 auto op = (*this)[pos - 1].sub.op;
473 auto sz = (*this)[pos - 1].sub.size;
474 if (other[pos - 1].sub.op != op ||
475 other[pos - 1].sub.size != sz)
476 return false;
477 switch (op)
478 {
479 case acc_cond::acc_op::And:
480 case acc_cond::acc_op::Or:
481 --pos;
482 break;
483 case acc_cond::acc_op::Inf:
484 case acc_cond::acc_op::InfNeg:
485 case acc_cond::acc_op::Fin:
486 case acc_cond::acc_op::FinNeg:
487 pos -= 2;
488 if (other[pos].mark != (*this)[pos].mark)
489 return false;
490 break;
491 }
492 }
493 return true;
494 };
495
497 bool operator<(const acc_code& other) const
498 {
499 // We have two ways to represent t, unfortunately.
500 if (is_t() && other.is_t())
501 return false;
502 unsigned pos = size();
503 auto osize = other.size();
504 if (pos < osize)
505 return true;
506 if (pos > osize)
507 return false;
508 while (pos > 0)
509 {
510 auto op = (*this)[pos - 1].sub.op;
511 auto oop = other[pos - 1].sub.op;
512 if (op < oop)
513 return true;
514 if (op > oop)
515 return false;
516 auto sz = (*this)[pos - 1].sub.size;
517 auto osz = other[pos - 1].sub.size;
518 if (sz < osz)
519 return true;
520 if (sz > osz)
521 return false;
522 switch (op)
523 {
524 case acc_cond::acc_op::And:
525 case acc_cond::acc_op::Or:
526 --pos;
527 break;
528 case acc_cond::acc_op::Inf:
529 case acc_cond::acc_op::InfNeg:
530 case acc_cond::acc_op::Fin:
531 case acc_cond::acc_op::FinNeg:
532 {
533 pos -= 2;
534 auto m = (*this)[pos].mark;
535 auto om = other[pos].mark;
536 if (m < om)
537 return true;
538 if (m > om)
539 return false;
540 break;
541 }
542 }
543 }
544 return false;
545 }
546
548 bool operator>(const acc_code& other) const
549 {
550 return other < *this;
551 }
552
554 bool operator<=(const acc_code& other) const
555 {
556 return !(other < *this);
557 }
558
560 bool operator>=(const acc_code& other) const
561 {
562 return !(*this < other);
563 }
564
566 bool operator!=(const acc_code& other) const
567 {
568 return !(*this == other);
569 }
570
575 bool is_t() const
576 {
577 // We store "t" as an empty condition, or as Inf({}).
578 unsigned s = size();
579 return s == 0 || ((*this)[s - 1].sub.op == acc_op::Inf
580 && !((*this)[s - 2].mark));
581 }
582
589 bool is_f() const
590 {
591 // We store "f" as Fin({}).
592 unsigned s = size();
593 return s > 1
594 && (*this)[s - 1].sub.op == acc_op::Fin && !((*this)[s - 2].mark);
595 }
596
597 private:
602 static constexpr size_t max_acc_formula_size_ = (1U << 24) - 1;
603
604#ifndef SWIG
606 [[noreturn]] static void report_too_large_acceptance_formula_()
607 {
608 throw std::runtime_error("acceptance formula is too large");
609 }
610#endif
611
612 public:
619 static acc_code f()
620 {
621 acc_code res;
622 res.resize(2);
623 res[0].mark = {};
624 res[1].sub.op = acc_op::Fin;
625 res[1].sub.size = 1;
626 return res;
627 }
628
633 static acc_code t()
634 {
635 return {};
636 }
637
646 {
647 acc_code res;
648 res.resize(2);
649 res[0].mark = m;
650 res[1].sub.op = acc_op::Fin;
651 res[1].sub.size = 1;
652 return res;
653 }
654
655 static acc_code fin(std::initializer_list<unsigned> vals)
656 {
657 return fin(mark_t(vals));
658 }
660
678 {
679 acc_code res;
680 res.resize(2);
681 res[0].mark = m;
682 res[1].sub.op = acc_op::FinNeg;
683 res[1].sub.size = 1;
684 return res;
685 }
686
687 static acc_code fin_neg(std::initializer_list<unsigned> vals)
688 {
689 return fin_neg(mark_t(vals));
690 }
692
702 {
703 acc_code res;
704 res.resize(2);
705 res[0].mark = m;
706 res[1].sub.op = acc_op::Inf;
707 res[1].sub.size = 1;
708 return res;
709 }
710
711 static acc_code inf(std::initializer_list<unsigned> vals)
712 {
713 return inf(mark_t(vals));
714 }
716
734 {
735 acc_code res;
736 res.resize(2);
737 res[0].mark = m;
738 res[1].sub.op = acc_op::InfNeg;
739 res[1].sub.size = 1;
740 return res;
741 }
742
743 static acc_code inf_neg(std::initializer_list<unsigned> vals)
744 {
745 return inf_neg(mark_t(vals));
746 }
748
753 {
754 return inf({0});
755 }
756
761 {
762 return fin({0});
763 }
764
770 static acc_code generalized_buchi(unsigned n)
771 {
772 if (n == 0)
773 return inf({});
774 acc_cond::mark_t m = mark_t::all();
775 m >>= mark_t::max_accsets() - n;
776 return inf(m);
777 }
778
785 {
786 if (n == 0)
787 return fin({});
788 acc_cond::mark_t m = mark_t::all();
789 m >>= mark_t::max_accsets() - n;
790 return fin(m);
791 }
792
797 static acc_code rabin(unsigned n)
798 {
799 acc_cond::acc_code res = f();
800 while (n > 0)
801 {
802 res |= inf({2*n - 1}) & fin({2*n - 2});
803 --n;
804 }
805 return res;
806 }
807
812 static acc_code streett(unsigned n)
813 {
814 acc_cond::acc_code res = t();
815 while (n > 0)
816 {
817 res &= inf({2*n - 1}) | fin({2*n - 2});
818 --n;
819 }
820 return res;
821 }
822
835 template<class Iterator>
836 static acc_code generalized_rabin(Iterator begin, Iterator end)
837 {
838 acc_cond::acc_code res = f();
839 unsigned n = 0;
840 for (Iterator i = begin; i != end; ++i)
841 {
842 unsigned f = n++;
843 acc_cond::mark_t m = {};
844 for (unsigned ni = *i; ni > 0; --ni)
845 m.set(n++);
846 auto pair = inf(m) & fin({f});
847 std::swap(pair, res);
848 res |= std::move(pair);
849 }
850 return res;
851 }
852
860 static acc_code parity(bool is_max, bool is_odd, unsigned sets);
861 static acc_code parity_max(bool is_odd, unsigned sets)
862 {
863 return parity(true, is_odd, sets);
864 }
865 static acc_code parity_max_odd(unsigned sets)
866 {
867 return parity_max(true, sets);
868 }
869 static acc_code parity_max_even(unsigned sets)
870 {
871 return parity_max(false, sets);
872 }
873 static acc_code parity_min(bool is_odd, unsigned sets)
874 {
875 return parity(false, is_odd, sets);
876 }
877 static acc_code parity_min_odd(unsigned sets)
878 {
879 return parity_min(true, sets);
880 }
881 static acc_code parity_min_even(unsigned sets)
882 {
883 return parity_min(false, sets);
884 }
886
903 static acc_code random(unsigned n, double reuse = 0.0);
904
907 {
908 if (is_t() || r.is_f())
909 {
910 *this = r;
911 return *this;
912 }
913 if (is_f() || r.is_t())
914 return *this;
915 unsigned s = size() - 1;
916 unsigned rs = r.size() - 1;
917 // We want to group all Inf(x) operators:
918 // Inf(a) & Inf(b) = Inf(a & b)
919 if (((*this)[s].sub.op == acc_op::Inf
920 && r[rs].sub.op == acc_op::Inf)
921 || ((*this)[s].sub.op == acc_op::InfNeg
922 && r[rs].sub.op == acc_op::InfNeg))
923 {
924 (*this)[s - 1].mark |= r[rs - 1].mark;
925 return *this;
926 }
927
928 // In the more complex scenarios, left and right may both
929 // be conjunctions, and Inf(x) might be a member of each
930 // side. Find it if it exists.
931 // left_inf points to the left Inf mark if any.
932 // right_inf points to the right Inf mark if any.
933 acc_word* left_inf = nullptr;
934 if ((*this)[s].sub.op == acc_op::And)
935 {
936 auto start = &(*this)[s] - (*this)[s].sub.size;
937 auto pos = &(*this)[s] - 1;
938 pop_back();
939 while (pos > start)
940 {
941 if (pos->sub.op == acc_op::Inf)
942 {
943 left_inf = pos - 1;
944 break;
945 }
946 pos -= pos->sub.size + 1;
947 }
948 }
949 else if ((*this)[s].sub.op == acc_op::Inf)
950 {
951 left_inf = &(*this)[s - 1];
952 }
953
954 const acc_word* right_inf = nullptr;
955 auto right_end = &r.back();
956 if (right_end->sub.op == acc_op::And)
957 {
958 auto start = &r[0];
959 auto pos = --right_end;
960 while (pos > start)
961 {
962 if (pos->sub.op == acc_op::Inf)
963 {
964 right_inf = pos - 1;
965 break;
966 }
967 pos -= pos->sub.size + 1;
968 }
969 }
970 else if (right_end->sub.op == acc_op::Inf)
971 {
972 right_inf = right_end - 1;
973 }
974
975 acc_cond::mark_t carry = {};
976 if (left_inf && right_inf)
977 {
978 carry = left_inf->mark;
979 auto pos = left_inf - &(*this)[0];
980 erase(begin() + pos, begin() + pos + 2);
981 }
982 auto sz = size();
983 insert(end(), &r[0], right_end + 1);
984 if (carry)
985 (*this)[sz + (right_inf - &r[0])].mark |= carry;
986
987 acc_word w = {};
988 w.sub.op = acc_op::And;
989 auto new_size = size();
990 if (SPOT_UNLIKELY(new_size > max_acc_formula_size_))
991 report_too_large_acceptance_formula_();
992 w.sub.size = new_size;
993 emplace_back(w);
994 return *this;
995 }
996
999 {
1000 acc_code res = *this;
1001 res &= r;
1002 return res;
1003 }
1004
1005#ifndef SWIG
1008 {
1009 acc_code res = *this;
1010 res &= r;
1011 return res;
1012 }
1013#endif // SWIG
1014
1017 {
1018 if (is_t() || r.is_f())
1019 return *this;
1020 if (is_f() || r.is_t())
1021 {
1022 *this = r;
1023 return *this;
1024 }
1025 unsigned s = size() - 1;
1026 unsigned rs = r.size() - 1;
1027 // Fin(a) | Fin(b) = Fin(a | b)
1028 if (((*this)[s].sub.op == acc_op::Fin
1029 && r[rs].sub.op == acc_op::Fin)
1030 || ((*this)[s].sub.op == acc_op::FinNeg
1031 && r[rs].sub.op == acc_op::FinNeg))
1032 {
1033 (*this)[s - 1].mark |= r[rs - 1].mark;
1034 return *this;
1035 }
1036
1037 // In the more complex scenarios, left and right may both
1038 // be disjunctions, and Fin(x) might be a member of each
1039 // side. Find it if it exists.
1040 // left_inf points to the left Inf mark if any.
1041 // right_inf points to the right Inf mark if any.
1042 acc_word* left_fin = nullptr;
1043 if ((*this)[s].sub.op == acc_op::Or)
1044 {
1045 auto start = &(*this)[s] - (*this)[s].sub.size;
1046 auto pos = &(*this)[s] - 1;
1047 pop_back();
1048 while (pos > start)
1049 {
1050 if (pos->sub.op == acc_op::Fin)
1051 {
1052 left_fin = pos - 1;
1053 break;
1054 }
1055 pos -= pos->sub.size + 1;
1056 }
1057 }
1058 else if ((*this)[s].sub.op == acc_op::Fin)
1059 {
1060 left_fin = &(*this)[s - 1];
1061 }
1062
1063 const acc_word* right_fin = nullptr;
1064 auto right_end = &r.back();
1065 if (right_end->sub.op == acc_op::Or)
1066 {
1067 auto start = &r[0];
1068 auto pos = --right_end;
1069 while (pos > start)
1070 {
1071 if (pos->sub.op == acc_op::Fin)
1072 {
1073 right_fin = pos - 1;
1074 break;
1075 }
1076 pos -= pos->sub.size + 1;
1077 }
1078 }
1079 else if (right_end->sub.op == acc_op::Fin)
1080 {
1081 right_fin = right_end - 1;
1082 }
1083
1084 acc_cond::mark_t carry = {};
1085 if (left_fin && right_fin)
1086 {
1087 carry = left_fin->mark;
1088 auto pos = (left_fin - &(*this)[0]);
1089 this->erase(begin() + pos, begin() + pos + 2);
1090 }
1091 auto sz = size();
1092 insert(end(), &r[0], right_end + 1);
1093 if (carry)
1094 (*this)[sz + (right_fin - &r[0])].mark |= carry;
1095 acc_word w = {};
1096 w.sub.op = acc_op::Or;
1097 auto new_size = size();
1098 if (SPOT_UNLIKELY(new_size > max_acc_formula_size_))
1099 report_too_large_acceptance_formula_();
1100 w.sub.size = new_size;
1101 emplace_back(w);
1102 return *this;
1103 }
1104
1105#ifndef SWIG
1108 {
1109 acc_code res = *this;
1110 res |= r;
1111 return res;
1112 }
1113#endif // SWIG
1114
1117 {
1118 acc_code res = *this;
1119 res |= r;
1120 return res;
1121 }
1122
1128 acc_code& operator<<=(unsigned sets)
1129 {
1130 if (SPOT_UNLIKELY(sets >= mark_t::max_accsets()))
1131 report_too_many_sets();
1132 if (empty())
1133 return *this;
1134 unsigned pos = size();
1135 do
1136 {
1137 switch ((*this)[pos - 1].sub.op)
1138 {
1139 case acc_cond::acc_op::And:
1140 case acc_cond::acc_op::Or:
1141 --pos;
1142 break;
1143 case acc_cond::acc_op::Inf:
1144 case acc_cond::acc_op::InfNeg:
1145 case acc_cond::acc_op::Fin:
1146 case acc_cond::acc_op::FinNeg:
1147 pos -= 2;
1148 (*this)[pos].mark <<= sets;
1149 break;
1150 }
1151 }
1152 while (pos > 0);
1153 return *this;
1154 }
1155
1159 acc_code operator<<(unsigned sets) const
1160 {
1161 acc_code res = *this;
1162 res <<= sets;
1163 return res;
1164 }
1165
1172 bool is_dnf() const;
1173
1180 bool is_cnf() const;
1181
1193
1201
1206 bdd to_bdd(const bdd* map) const;
1207
1216 std::vector<acc_code> top_disjuncts() const;
1217
1226 std::vector<acc_code> top_conjuncts() const;
1227
1239
1254
1268
1281
1286 int fin_one() const;
1287
1308 std::pair<int, acc_code> fin_one_extract() const;
1309
1328 std::tuple<int, acc_cond::acc_code, acc_cond::acc_code>
1330 std::tuple<int, acc_cond::acc_code, acc_cond::acc_code>
1333
1349 std::vector<std::pair<acc_cond::mark_t, acc_cond::acc_code>>
1351
1364 std::vector<std::vector<int>>
1365 missing(mark_t inf, bool accepting) const;
1366
1369 bool accepting(mark_t inf) const;
1370
1377 bool inf_satisfiable(mark_t inf) const;
1378
1391 mark_t always_present) const;
1392
1407 mark_t always_present) const;
1408
1419 std::vector<unsigned> symmetries() const;
1420
1434 acc_code remove(acc_cond::mark_t rem, bool missing) const;
1435
1440 acc_code strip(acc_cond::mark_t rem, bool missing) const;
1443
1450
1453
1465 std::vector<std::pair<acc_cond::mark_t, acc_cond::mark_t>>
1467
1475
1477 std::pair<acc_cond::mark_t, acc_cond::mark_t> used_inf_fin_sets() const;
1478
1483 std::ostream&
1484 to_html(std::ostream& os,
1485 std::function<void(std::ostream&, int)>
1486 set_printer = nullptr) const;
1487
1492 std::ostream&
1493 to_text(std::ostream& os,
1494 std::function<void(std::ostream&, int)>
1495 set_printer = nullptr) const;
1496
1501 std::ostream&
1502 to_latex(std::ostream& os,
1503 std::function<void(std::ostream&, int)>
1504 set_printer = nullptr) const;
1505
1528 acc_code(const char* input);
1529
1534 {
1535 }
1536
1538 acc_code(const acc_word* other)
1539 : std::vector<acc_word>(other - other->sub.size, other + 1)
1540 {
1541 }
1542
1543 };
1544
1552 acc_cond(unsigned n_sets = 0, const acc_code& code = {})
1553 : num_(0U), all_({}), code_(code)
1554 {
1555 add_sets(n_sets);
1556 uses_fin_acceptance_ = check_fin_acceptance();
1557 }
1558
1563 acc_cond(const acc_code& code)
1564 : num_(0U), all_({}), code_(code)
1565 {
1566 add_sets(code.used_sets().max_set());
1567 uses_fin_acceptance_ = check_fin_acceptance();
1568 }
1569
1572 : num_(o.num_), all_(o.all_), code_(o.code_),
1573 uses_fin_acceptance_(o.uses_fin_acceptance_)
1574 {
1575 }
1576
1579 {
1580 num_ = o.num_;
1581 all_ = o.all_;
1582 code_ = o.code_;
1583 uses_fin_acceptance_ = o.uses_fin_acceptance_;
1584 return *this;
1585 }
1586
1587 ~acc_cond()
1588 {
1589 }
1590
1594 void set_acceptance(const acc_code& code)
1595 {
1596 code_ = code;
1597 uses_fin_acceptance_ = check_fin_acceptance();
1598 }
1599
1602 {
1603 return code_;
1604 }
1605
1608 {
1609 return code_;
1610 }
1611
1613 bool operator==(const acc_cond& other) const
1614 {
1615 if (other.num_sets() != num_)
1616 return false;
1617 const acc_code& ocode = other.get_acceptance();
1618 // We have two ways to represent t, unfortunately.
1619 return (ocode == code_ || (ocode.is_t() && code_.is_t()));
1620 }
1621
1623 bool operator!=(const acc_cond& other) const
1624 {
1625 return !(*this == other);
1626 }
1627
1630 {
1631 return uses_fin_acceptance_;
1632 }
1633
1635 bool is_t() const
1636 {
1637 return code_.is_t();
1638 }
1639
1644 bool is_all() const
1645 {
1646 return num_ == 0 && is_t();
1647 }
1648
1650 bool is_f() const
1651 {
1652 return code_.is_f();
1653 }
1654
1659 bool is_none() const
1660 {
1661 return num_ == 0 && is_f();
1662 }
1663
1668 bool is_buchi() const
1669 {
1670 unsigned s = code_.size();
1671 return num_ == 1 &&
1672 s == 2 && code_[1].sub.op == acc_op::Inf && code_[0].mark == all_sets();
1673 }
1674
1679 bool is_co_buchi() const
1680 {
1681 return num_ == 1 && is_generalized_co_buchi();
1682 }
1683
1687 {
1688 set_acceptance(inf(all_sets()));
1689 }
1690
1694 {
1695 set_acceptance(fin(all_sets()));
1696 }
1697
1703 {
1704 unsigned s = code_.size();
1705 return (s == 0 && num_ == 0) || (s == 2 && code_[1].sub.op == acc_op::Inf
1706 && code_[0].mark == all_sets());
1707 }
1708
1714 {
1715 unsigned s = code_.size();
1716 return (s == 2 &&
1717 code_[1].sub.op == acc_op::Fin && code_[0].mark == all_sets());
1718 }
1719
1731 int is_rabin() const;
1732
1744 int is_streett() const;
1745
1755 struct SPOT_API rs_pair
1756 {
1757#ifndef SWIG
1758 rs_pair() = default;
1760 rs_pair(const rs_pair&) = default;
1762 rs_pair& operator=(const rs_pair&) = default;
1763#endif
1764
1767 fin(fin),
1768 inf(inf)
1769 {}
1772
1774 bool operator==(rs_pair o) const
1775 {
1776 return fin == o.fin && inf == o.inf;
1777 }
1779 bool operator!=(rs_pair o) const
1780 {
1781 return fin != o.fin || inf != o.inf;
1782 }
1784 bool operator<(rs_pair o) const
1785 {
1786 return fin < o.fin || (!(o.fin < fin) && inf < o.inf);
1787 }
1789 bool operator<=(rs_pair o) const
1790 {
1791 return !(o < *this);
1792 }
1794 bool operator>(rs_pair o) const
1795 {
1796 return o < *this;
1797 }
1799 bool operator>=(rs_pair o) const
1800 {
1801 return !(*this < o);
1802 }
1803 };
1814 bool is_streett_like(std::vector<rs_pair>& pairs) const;
1815
1826 bool is_rabin_like(std::vector<rs_pair>& pairs) const;
1827
1837 bool is_generalized_rabin(std::vector<unsigned>& pairs) const;
1838
1851 bool is_generalized_streett(std::vector<unsigned>& pairs) const;
1852
1862 bool is_parity(bool& max, bool& odd, bool equiv = false) const;
1863
1864
1867 bool is_parity() const
1868 {
1869 bool max;
1870 bool odd;
1871 return is_parity(max, odd);
1872 }
1873
1882 {
1883 return acc_cond(num_, code_.unit_propagation());
1884 }
1885
1890 std::pair<bool, acc_cond::mark_t> unsat_mark() const
1891 {
1892 return sat_unsat_mark(false);
1893 }
1898 std::pair<bool, acc_cond::mark_t> sat_mark() const
1899 {
1900 return sat_unsat_mark(true);
1901 }
1902
1903 protected:
1907 std::pair<bool, acc_cond::mark_t> sat_unsat_mark(bool) const;
1908
1909 public:
1918 static acc_code inf(mark_t mark)
1919 {
1920 return acc_code::inf(mark);
1921 }
1922
1923 static acc_code inf(std::initializer_list<unsigned> vals)
1924 {
1925 return inf(mark_t(vals.begin(), vals.end()));
1926 }
1928
1946 {
1947 return acc_code::inf_neg(mark);
1948 }
1949
1950 static acc_code inf_neg(std::initializer_list<unsigned> vals)
1951 {
1952 return inf_neg(mark_t(vals.begin(), vals.end()));
1953 }
1955
1963 static acc_code fin(mark_t mark)
1964 {
1965 return acc_code::fin(mark);
1966 }
1967
1968 static acc_code fin(std::initializer_list<unsigned> vals)
1969 {
1970 return fin(mark_t(vals.begin(), vals.end()));
1971 }
1973
1991 {
1992 return acc_code::fin_neg(mark);
1993 }
1994
1995 static acc_code fin_neg(std::initializer_list<unsigned> vals)
1996 {
1997 return fin_neg(mark_t(vals.begin(), vals.end()));
1998 }
2000
2005 unsigned add_sets(unsigned num)
2006 {
2007 if (num == 0)
2008 return -1U;
2009 unsigned j = num_;
2010 num += j;
2011 if (num > mark_t::max_accsets())
2012 report_too_many_sets();
2013 // Make sure we do not update if we raised an exception.
2014 num_ = num;
2015 all_ = all_sets_();
2016 return j;
2017 }
2018
2023 unsigned add_set()
2024 {
2025 return add_sets(1);
2026 }
2027
2029 mark_t mark(unsigned u) const
2030 {
2031 SPOT_ASSERT(u < num_sets());
2032 return mark_t({u});
2033 }
2034
2039 mark_t comp(const mark_t& l) const
2040 {
2041 return all_ ^ l;
2042 }
2043
2046 {
2047 return all_;
2048 }
2049
2052 bool accepting(mark_t inf) const
2053 {
2054 return code_.accepting(inf);
2055 }
2056
2062 bool inf_satisfiable(mark_t inf) const
2063 {
2064 return code_.inf_satisfiable(inf);
2065 }
2066
2073 {
2074 return {num_sets(), code_.keep_one_inf_per_branch()};
2075 }
2076
2088 trival maybe_accepting(mark_t infinitely_often, mark_t always_present) const
2089 {
2090 return code_.maybe_accepting(infinitely_often, always_present);
2091 }
2092
2106 trival
2107 weakly_accepting(mark_t infinitely_often, mark_t always_present) const
2108 {
2109 return code_.weakly_accepting(infinitely_often, always_present);
2110 }
2111
2126
2128 unsigned num_sets() const
2129 {
2130 return num_;
2131 }
2132
2140 template<class iterator>
2141 mark_t useless(iterator begin, iterator end) const
2142 {
2143 mark_t u = {}; // The set of useless sets
2144 for (unsigned x = 0; x < num_; ++x)
2145 {
2146 // Skip sets that are already known to be useless.
2147 if (u.has(x))
2148 continue;
2149 auto all = comp(u | mark_t({x}));
2150 // Iterate over all mark_t, and keep track of
2151 // set numbers that always appear with x.
2152 for (iterator y = begin; y != end; ++y)
2153 {
2154 const mark_t& v = *y;
2155 if (v.has(x))
2156 {
2157 all &= v;
2158 if (!all)
2159 break;
2160 }
2161 }
2162 u |= all;
2163 }
2164 return u;
2165 }
2166
2180 acc_cond remove(mark_t rem, bool missing) const
2181 {
2182 return {num_sets(), code_.remove(rem, missing)};
2183 }
2184
2189 acc_cond strip(mark_t rem, bool missing) const
2190 {
2191 return
2192 { num_sets() - (all_sets() & rem).count(), code_.strip(rem, missing) };
2193 }
2194
2197 {
2198 return {num_sets(), code_.force_inf(m)};
2199 }
2200
2204 {
2205 return {num_sets(), code_.remove(all_sets() - rem, true)};
2206 }
2207
2219 std::string name(const char* fmt = "alo") const;
2220
2235 {
2236 return code_.fin_unit();
2237 }
2238
2252 {
2253 return code_.mafins();
2254 }
2255
2260 std::vector<std::pair<mark_t, acc_cond>> mafins_split() const
2261 {
2262 auto v = code_.mafins_split();
2263 std::vector<std::pair<mark_t, acc_cond>> result;
2264 result.reserve(v.size());
2265 for (auto& [m, c] : v)
2266 result.emplace_back(m, acc_cond(num_, c));
2267 return result;
2268 }
2269
2282 {
2283 return code_.inf_unit();
2284 }
2285
2290 int fin_one() const
2291 {
2292 return code_.fin_one();
2293 }
2294
2315 std::pair<int, acc_cond> fin_one_extract() const
2316 {
2317 auto [f, c] = code_.fin_one_extract();
2318 return {f, {num_sets(), std::move(c)}};
2319 }
2320
2339 std::tuple<int, acc_cond, acc_cond>
2341 {
2342 auto [f, l, r] = code_.fin_unit_one_split();
2343 return {f, {num_sets(), std::move(l)}, {num_sets(), std::move(r)}};
2344 }
2345 std::tuple<int, acc_cond, acc_cond>
2347 {
2348 auto [f, l, r] = code_.fin_unit_one_split_improved();
2349 return {f, {num_sets(), std::move(l)}, {num_sets(), std::move(r)}};
2350 }
2352
2361 std::vector<acc_cond> top_disjuncts() const;
2362
2371 std::vector<acc_cond> top_conjuncts() const;
2372
2373 protected:
2376 {
2377 return mark_t::all() >> (spot::acc_cond::mark_t::max_accsets() - num_);
2378 }
2379
2380 unsigned num_;
2384 bool uses_fin_acceptance_ = false;
2385
2386 };
2387
2392 typedef std::vector<acc_cond::rs_pair> rs_pairs;
2393
2395 explicit rs_pairs_view(const rs_pairs& p, const acc_cond::mark_t& m)
2396 : pairs_(p), view_marks_(m) {}
2397
2399 explicit rs_pairs_view(const rs_pairs& p)
2400 : rs_pairs_view(p, acc_cond::mark_t::all()) {}
2401
2404 {
2405 return do_view([&](const acc_cond::rs_pair& p)
2406 {
2407 return visible(p.inf) ? p.inf : acc_cond::mark_t({});
2408 });
2409 }
2410
2413 {
2414 return do_view([&](const acc_cond::rs_pair& p)
2415 {
2416 return visible(p.fin) ? p.fin : acc_cond::mark_t({});
2417 });
2418 }
2419
2422 {
2423 return do_view([&](const acc_cond::rs_pair& p)
2424 {
2425 return !visible(p.inf) && visible(p.fin) ? p.fin
2426 : acc_cond::mark_t({});
2427 });
2428 }
2429
2432 {
2433 return do_view([&](const acc_cond::rs_pair& p)
2434 {
2435 return !visible(p.fin) && visible(p.inf) ? p.inf
2436 : acc_cond::mark_t({});
2437 });
2438 }
2439
2444 {
2445 acc_cond::mark_t res = {};
2446 for (const auto& p: pairs_)
2447 if (p.fin.has(mark) && visible(p.fin) && visible(p.inf))
2448 res |= p.inf;
2449 return res;
2450 }
2451
2453 const rs_pairs& pairs() const
2454 {
2455 return pairs_;
2456 }
2457
2458 private:
2459 template<typename filter>
2460 acc_cond::mark_t do_view(const filter& filt) const
2461 {
2462 acc_cond::mark_t res = {};
2463 for (const auto& p: pairs_)
2464 res |= filt(p);
2465 return res;
2466 }
2467
2468 bool visible(const acc_cond::mark_t& v) const
2469 {
2470 return !!(view_marks_ & v);
2471 }
2472
2473 const rs_pairs& pairs_;
2474 acc_cond::mark_t view_marks_;
2475 };
2476
2477
2478 SPOT_API
2479 std::ostream& operator<<(std::ostream& os, const acc_cond& acc);
2480
2481 // The next two operators used to be declared as friend inside the
2482 // acc_cond::mark_t and acc_cond::acc_code, but Swig 4.2.1
2483 // introduced a bug with friend operators. See
2484 // https://github.com/swig/swig/issues/2845
2485
2486 SPOT_API
2487 std::ostream& operator<<(std::ostream& os, acc_cond::mark_t m);
2488
2490 SPOT_API
2491 std::ostream& operator<<(std::ostream& os,
2492 const acc_cond::acc_code& code);
2493
2495
2496 namespace internal
2497 {
2498 class SPOT_API mark_iterator
2499 {
2500 public:
2501 typedef unsigned value_type;
2502 typedef const value_type& reference;
2503 typedef const value_type* pointer;
2504 typedef std::ptrdiff_t difference_type;
2505 typedef std::forward_iterator_tag iterator_category;
2506
2507 mark_iterator() noexcept
2508 : m_({})
2509 {
2510 }
2511
2512 mark_iterator(acc_cond::mark_t m) noexcept
2513 : m_(m)
2514 {
2515 }
2516
2517 bool operator==(mark_iterator m) const
2518 {
2519 return m_ == m.m_;
2520 }
2521
2522 bool operator!=(mark_iterator m) const
2523 {
2524 return m_ != m.m_;
2525 }
2526
2527 value_type operator*() const
2528 {
2529 SPOT_ASSERT(m_);
2530 return m_.min_set() - 1;
2531 }
2532
2533 mark_iterator& operator++()
2534 {
2535 m_.clear(this->operator*());
2536 return *this;
2537 }
2538
2539 mark_iterator operator++(int)
2540 {
2541 mark_iterator it = *this;
2542 ++(*this);
2543 return it;
2544 }
2545 private:
2546 acc_cond::mark_t m_;
2547 };
2548
2549 class SPOT_API mark_container
2550 {
2551 public:
2552 mark_container(spot::acc_cond::mark_t m) noexcept
2553 : m_(m)
2554 {
2555 }
2556
2557 mark_iterator begin() const
2558 {
2559 return {m_};
2560 }
2561 mark_iterator end() const
2562 {
2563 return {};
2564 }
2565 private:
2567 };
2568 }
2569
2570 inline spot::internal::mark_container acc_cond::mark_t::sets() const
2571 {
2572 return {*this};
2573 }
2574
2575 template<class iterator>
2576 void acc_cond::mark_t::fill(iterator here) const
2577 {
2578 for (unsigned s : sets())
2579 *here++ = s;
2580 }
2581}
2582
2583namespace std
2584{
2587 template<>
2588 struct hash<spot::acc_cond::mark_t>
2589 {
2591 size_t operator()(spot::acc_cond::mark_t m) const noexcept
2592 {
2593 return m.hash();
2594 }
2595 };
2596}
An acceptance condition.
Definition acc.hh:54
const acc_code & get_acceptance() const
Retrieve the acceptance formula.
Definition acc.hh:1601
bool inf_satisfiable(mark_t inf) const
Assuming that we will visit at least all sets in inf, is there any chance that we will satisfy the co...
Definition acc.hh:2062
mark_t all_sets() const
Construct a mark_t with all declared sets.
Definition acc.hh:2045
static acc_code fin_neg(mark_t mark)
Construct a generalized co-Büchi acceptance for complemented sets.
Definition acc.hh:1990
mark_t mafins() const
Find a Fin(i) that is mandatory.
Definition acc.hh:2251
static acc_code inf_neg(mark_t mark)
Construct a generalized Büchi acceptance for complemented sets.
Definition acc.hh:1945
acc_cond unit_propagation()
Remove superfluous Fin and Inf by unit propagation.
Definition acc.hh:1881
void set_generalized_co_buchi()
Change the acceptance condition to generalized-co-Büchi, over all declared sets.
Definition acc.hh:1693
std::pair< int, acc_cond > fin_one_extract() const
Return one acceptance set i that appears as Fin(i) in the condition, and all disjuncts containing it ...
Definition acc.hh:2315
bool operator==(const acc_cond &other) const
Equality: same number of sets and equivalent formula.
Definition acc.hh:1613
static acc_code fin(mark_t mark)
Construct a generalized co-Büchi acceptance.
Definition acc.hh:1963
bool is_co_buchi() const
Whether the acceptance condition is "co-Büchi".
Definition acc.hh:1679
bool accepting(mark_t inf) const
Check whether visiting exactly all sets inf infinitely often satisfies the acceptance condition.
Definition acc.hh:2052
static acc_code inf(mark_t mark)
Construct a generalized Büchi acceptance.
Definition acc.hh:1918
unsigned num_
Number of declared acceptance sets.
Definition acc.hh:2380
bool is_generalized_buchi() const
Whether the acceptance condition is "generalized-Büchi".
Definition acc.hh:1702
static acc_code fin_neg(std::initializer_list< unsigned > vals)
Construct a generalized co-Büchi acceptance for complemented sets.
Definition acc.hh:1995
static acc_code inf(std::initializer_list< unsigned > vals)
Construct a generalized Büchi acceptance.
Definition acc.hh:1923
unsigned add_set()
Add a single set to the acceptance condition.
Definition acc.hh:2023
bool check_fin_acceptance() const
Recompute whether the formula uses Fin acceptance.
bool is_parity(bool &max, bool &odd, bool equiv=false) const
Check if the acceptance condition matches one of the four type of parity acceptance defined in the HO...
std::vector< acc_cond > top_disjuncts() const
Return the top-level disjuncts.
mark_t mark(unsigned u) const
Build a mark_t with a single set.
Definition acc.hh:2029
void set_generalized_buchi()
Change the acceptance condition to generalized-Büchi, over all declared sets.
Definition acc.hh:1686
acc_cond force_inf(mark_t m) const
For all x in m, replaces Fin(x) by false.
Definition acc.hh:2196
acc_cond remove(mark_t rem, bool missing) const
Remove all the acceptance sets in rem.
Definition acc.hh:2180
acc_cond(unsigned n_sets=0, const acc_code &code={})
Build an acceptance condition.
Definition acc.hh:1552
unsigned add_sets(unsigned num)
Add more sets to the acceptance condition.
Definition acc.hh:2005
bool is_parity() const
Check if the acceptance condition matches one of the four type of parity acceptance defined in the HO...
Definition acc.hh:1867
bool is_t() const
Whether the acceptance formula is "t" (true)
Definition acc.hh:1635
trival weakly_accepting(mark_t infinitely_often, mark_t always_present) const
Check if cycles in a SCC are all accepting, all rejecting, or mixed.
Definition acc.hh:2107
bool is_generalized_rabin(std::vector< unsigned > &pairs) const
Is the acceptance condition generalized-Rabin?
acc_op
Operators for acceptance formulas.
Definition acc.hh:419
mark_t comp(const mark_t &l) const
Complement a mark_t.
Definition acc.hh:2039
acc_cond keep_one_inf_per_branch() const
Rewrite an acceptance condition by keeping at most one Inf(x) on each disjunctive branch.
Definition acc.hh:2072
acc_cond & operator=(const acc_cond &o)
Copy an acceptance condition.
Definition acc.hh:1578
acc_code & get_acceptance()
Retrieve the acceptance formula.
Definition acc.hh:1607
static acc_code fin(std::initializer_list< unsigned > vals)
Construct a generalized co-Büchi acceptance.
Definition acc.hh:1968
bool is_generalized_co_buchi() const
Whether the acceptance condition is "generalized-co-Büchi".
Definition acc.hh:1713
std::tuple< int, acc_cond, acc_cond > fin_unit_one_split_improved() const
Split an acceptance condition, trying to select one unit-Fin.
Definition acc.hh:2346
acc_cond restrict_to(mark_t rem) const
Restrict an acceptance condition to a subset of set numbers that are occurring at some point.
Definition acc.hh:2203
trival maybe_accepting(mark_t infinitely_often, mark_t always_present) const
Check potential acceptance of an SCC.
Definition acc.hh:2088
std::string name(const char *fmt="alo") const
Return the name of this acceptance condition, in the specified format.
bool is_none() const
Whether the acceptance condition is "none".
Definition acc.hh:1659
void set_acceptance(const acc_code &code)
Change the acceptance formula.
Definition acc.hh:1594
int is_rabin() const
Check if the acceptance condition matches the Rabin acceptance of the HOA format.
bool uses_fin_acceptance_
Whether the formula contains any Fin term.
Definition acc.hh:2384
bool is_rabin_like(std::vector< rs_pair > &pairs) const
Test whether an acceptance condition is Rabin-like and returns each Rabin pair in an std::vector<rs_p...
mark_t accepting_sets(mark_t inf) const
Return an accepting subset of inf.
bool is_all() const
Whether the acceptance condition is "all".
Definition acc.hh:1644
acc_cond strip(mark_t rem, bool missing) const
Remove acceptance sets, and shift set numbers.
Definition acc.hh:2189
int fin_one() const
Return one acceptance set i that appear as Fin(i) in the condition.
Definition acc.hh:2290
mark_t all_sets_() const
Returns a mark with one bit set per declared acceptance set.
Definition acc.hh:2375
mark_t useless(iterator begin, iterator end) const
Compute useless acceptance sets given a list of mark_t that occur in an SCC.
Definition acc.hh:2141
int is_streett() const
Check if the acceptance condition matches the Streett acceptance of the HOA format.
mark_t fin_unit() const
Find a Fin(i) that is a unit clause.
Definition acc.hh:2234
std::vector< std::pair< mark_t, acc_cond > > mafins_split() const
Split an acceptance condition into disjuncts according to mandatory fins.
Definition acc.hh:2260
mark_t all_
Precomputed all_sets_() value.
Definition acc.hh:2381
bool is_generalized_streett(std::vector< unsigned > &pairs) const
Is the acceptance condition generalized-Streett?
std::pair< bool, acc_cond::mark_t > unsat_mark() const
Return an unsatisfying mark if one exists.
Definition acc.hh:1890
acc_cond(const acc_code &code)
Build an acceptance condition.
Definition acc.hh:1563
std::pair< bool, acc_cond::mark_t > sat_unsat_mark(bool) const
Shared implementation for sat_mark() and unsat_mark().
acc_cond(const acc_cond &o)
Copy an acceptance condition.
Definition acc.hh:1571
std::pair< bool, acc_cond::mark_t > sat_mark() const
Return a satisfying mark if one exists.
Definition acc.hh:1898
acc_code code_
Definition acc.hh:2382
bool operator!=(const acc_cond &other) const
Inequality comparison.
Definition acc.hh:1623
static acc_code inf_neg(std::initializer_list< unsigned > vals)
Construct a generalized Büchi acceptance for complemented sets.
Definition acc.hh:1950
bool is_streett_like(std::vector< rs_pair > &pairs) const
Test whether an acceptance condition is Streett-like and returns each Streett pair in an std::vector<...
bool is_buchi() const
Whether the acceptance condition is "Büchi".
Definition acc.hh:1668
std::vector< acc_cond > top_conjuncts() const
Return the top-level conjuncts.
std::tuple< int, acc_cond, acc_cond > fin_unit_one_split() const
Split an acceptance condition, trying to select one unit-Fin.
Definition acc.hh:2340
mark_t inf_unit() const
Find a Inf(i) that is a unit clause.
Definition acc.hh:2281
bool uses_fin_acceptance() const
Whether the acceptance condition uses Fin terms.
Definition acc.hh:1629
bool is_f() const
Whether the acceptance formula is "f" (false)
Definition acc.hh:1650
unsigned num_sets() const
The number of sets used in the acceptance condition.
Definition acc.hh:2128
A fixed-size bitset backed by N unsigned words.
Definition bitset.hh:40
A class implementing Kleene's three-valued logic.
Definition trival.hh:33
op
Operator types.
Definition formula.hh:85
@ Or
(omega-Rational) Or
@ U
until
@ And
(omega-Rational) And
scc_info_options operator&(scc_info_options left, scc_info_options right)
Bitwise AND of two scc_info_options values.
Definition sccinfo.hh:427
Definition automata.hh:26
std::ostream & operator<<(std::ostream &os, const mc_algorithm &ma)
Print an mc_algorithm value to a stream.
Definition mc.hh:74
constexpr bool operator==(trival a, trival b)
Equality comparison of two trival values.
Definition trival.hh:134
constexpr bool operator!=(trival a, trival b)
Inequality comparison of two trival values.
Definition trival.hh:140
An acceptance formula.
Definition acc.hh:456
static acc_code parity_max(bool is_odd, unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:861
std::tuple< int, acc_cond::acc_code, acc_cond::acc_code > fin_unit_one_split() const
Split an acceptance condition, trying to select one unit-Fin.
std::vector< std::vector< int > > missing(mark_t inf, bool accepting) const
Help closing accepting or rejecting cycle.
bool operator!=(const acc_code &other) const
Inequality comparison of acceptance formulas.
Definition acc.hh:566
mark_t mafins() const
Find a Fin(i) that is mandatory.
std::ostream & to_html(std::ostream &os, std::function< void(std::ostream &, int)> set_printer=nullptr) const
Print the acceptance formula as HTML.
static acc_code inf(mark_t m)
Construct a generalized Büchi acceptance.
Definition acc.hh:701
acc_code to_cnf() const
Convert the acceptance formula into disjunctive normal form.
acc_code operator&(acc_code &&r) const
Conjunct the current condition with r.
Definition acc.hh:1007
acc_code force_inf(mark_t m) const
For all x in m, replaces Fin(x) by false.
static acc_code inf_neg(std::initializer_list< unsigned > vals)
Construct a generalized Büchi acceptance for complemented sets.
Definition acc.hh:743
std::vector< std::pair< acc_cond::mark_t, acc_cond::mark_t > > useless_colors_patterns() const
Find patterns of useless colors.
trival maybe_accepting(mark_t infinitely_often, mark_t always_present) const
Check potential acceptance of an SCC.
acc_code operator|(const acc_code &r) const
Disjunct the current condition with r.
Definition acc.hh:1116
std::vector< acc_code > top_conjuncts() const
Return the top-level conjuncts.
acc_code operator|(acc_code &&r) const
Disjunct the current condition with r.
Definition acc.hh:1107
static acc_code fin(std::initializer_list< unsigned > vals)
Construct a generalized co-Büchi acceptance.
Definition acc.hh:655
bool is_dnf() const
Whether the acceptance formula is in disjunctive normal form.
std::vector< acc_code > top_disjuncts() const
Return the top-level disjuncts.
acc_code operator&(const acc_code &r) const
Conjunct the current condition with r.
Definition acc.hh:998
static acc_code inf(std::initializer_list< unsigned > vals)
Construct a generalized Büchi acceptance.
Definition acc.hh:711
static acc_code parity_min_even(unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:881
static acc_code parity(bool is_max, bool is_odd, unsigned sets)
Build a parity acceptance condition.
mark_t used_once_sets() const
Return the sets that appears only once in the acceptance.
acc_code & operator<<=(unsigned sets)
Apply a left shift to all mark_t that appear in the condition.
Definition acc.hh:1128
bool is_f() const
Is this the "false" acceptance condition?
Definition acc.hh:589
static acc_code generalized_buchi(unsigned n)
Build a generalized-Büchi acceptance condition with n sets.
Definition acc.hh:770
bool operator>(const acc_code &other) const
Greater-than comparison of acceptance formulas.
Definition acc.hh:548
static acc_code parity_min_odd(unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:877
acc_code(const acc_word *other)
Copy a part of another acceptance formula.
Definition acc.hh:1538
mark_t fin_unit() const
Find a Fin(i) that is a unit clause.
trival weakly_accepting(mark_t infinitely_often, mark_t always_present) const
Check if cycles in a SCC are all accepting, all rejecting, or mixed.
static acc_code parity_max_even(unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:869
static acc_code f()
Construct the "false" acceptance condition.
Definition acc.hh:619
bool accepting(mark_t inf) const
Check whether visiting exactly all sets inf infinitely often satisfies the acceptance condition.
static acc_code parity_max_odd(unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:865
std::ostream & to_latex(std::ostream &os, std::function< void(std::ostream &, int)> set_printer=nullptr) const
Print the acceptance formula as LaTeX.
std::pair< int, acc_code > fin_one_extract() const
Return one acceptance set i that appears as Fin(i) in the condition, and all disjuncts containing it ...
bool is_t() const
Is this the "true" acceptance condition?
Definition acc.hh:575
acc_code operator<<(unsigned sets) const
Apply a left shift to all mark_t that appear in the condition.
Definition acc.hh:1159
static acc_code random(unsigned n, double reuse=0.0)
Build a random acceptance condition.
static acc_code rabin(unsigned n)
Build a Rabin condition with n pairs.
Definition acc.hh:797
acc_code()
Build an empty acceptance formula.
Definition acc.hh:1533
std::tuple< int, acc_cond::acc_code, acc_cond::acc_code > fin_unit_one_split_improved() const
Split an acceptance condition, trying to select one unit-Fin.
acc_code keep_one_inf_per_branch() const
Rewrite an acceptance condition by keeping at most one Inf(x) on each disjunctive branch.
bool operator==(const acc_code &other) const
Equality comparison of acceptance formulas.
Definition acc.hh:462
static acc_code cobuchi()
Build a co-Büchi acceptance condition.
Definition acc.hh:760
acc_code complement() const
Complement an acceptance formula.
static acc_code inf_neg(mark_t m)
Construct a generalized Büchi acceptance for complemented sets.
Definition acc.hh:733
bdd to_bdd(const bdd *map) const
Convert the acceptance formula into a BDD.
std::ostream & to_text(std::ostream &os, std::function< void(std::ostream &, int)> set_printer=nullptr) const
Print the acceptance formula as text.
int fin_one() const
Return one acceptance set i that appears as Fin(i) in the condition.
bool operator<=(const acc_code &other) const
Less-or-equal comparison of acceptance formulas.
Definition acc.hh:554
acc_cond::mark_t used_sets() const
Return the set of sets appearing in the condition.
bool operator>=(const acc_code &other) const
Greater-or-equal comparison of acceptance formulas.
Definition acc.hh:560
std::pair< acc_cond::mark_t, acc_cond::mark_t > used_inf_fin_sets() const
Return the sets used as Inf or Fin in the acceptance condition.
acc_code strip(acc_cond::mark_t rem, bool missing) const
Remove acceptance sets, and shift set numbers.
acc_code(const char *input)
Construct an acc_code from a string.
static acc_code fin_neg(std::initializer_list< unsigned > vals)
Construct a generalized co-Büchi acceptance for complemented sets.
Definition acc.hh:687
std::vector< std::pair< acc_cond::mark_t, acc_cond::acc_code > > mafins_split() const
Split an acceptance conditions into disjuncts according to mandatory fins.
acc_code & operator&=(const acc_code &r)
Conjunct the current condition in place with r.
Definition acc.hh:906
mark_t inf_unit() const
Find a Inf(i) that is a unit clause.
static acc_code streett(unsigned n)
Build a Streett condition with n pairs.
Definition acc.hh:812
acc_code unit_propagation()
Apply unit propagation to simplify the formula.
static acc_code t()
Construct the "true" acceptance condition.
Definition acc.hh:633
std::vector< unsigned > symmetries() const
compute the symmetry class of the acceptance sets.
static acc_code fin_neg(mark_t m)
Construct a generalized co-Büchi acceptance for complemented sets.
Definition acc.hh:677
bool operator<(const acc_code &other) const
Lexicographic less-than comparison on acceptance formulas.
Definition acc.hh:497
static acc_code parity_min(bool is_odd, unsigned sets)
Build a parity acceptance condition.
Definition acc.hh:873
static acc_code fin(mark_t m)
Construct a generalized co-Büchi acceptance.
Definition acc.hh:645
acc_code & operator|=(const acc_code &r)
Disjunct the current condition in place with r.
Definition acc.hh:1016
bool inf_satisfiable(mark_t inf) const
Assuming that we will visit infinitely often at least all sets in inf, is there any chance that we wi...
bool is_cnf() const
Whether the acceptance formula is in conjunctive normal form.
static acc_code buchi()
Build a Büchi acceptance condition.
Definition acc.hh:752
static acc_code generalized_co_buchi(unsigned n)
Build a generalized-co-Büchi acceptance condition with n sets.
Definition acc.hh:784
acc_code remove(acc_cond::mark_t rem, bool missing) const
Remove all the acceptance sets in rem.
acc_code to_dnf() const
Convert the acceptance formula into disjunctive normal form.
static acc_code generalized_rabin(Iterator begin, Iterator end)
Build a generalized Rabin condition.
Definition acc.hh:836
An acceptance mark.
Definition acc.hh:76
std::string as_string() const
Returns a string representation of this mark.
static constexpr unsigned max_accsets()
The maximum number of acceptance sets supported by this implementation.
Definition acc.hh:116
mark_t operator~() const
Bitwise complement.
Definition acc.hh:245
bool is_singleton() const
Whether the mark contains only one bit set.
Definition acc.hh:375
mark_t lowest() const
A mark_t where all bits have been removed except the lowest one.
Definition acc.hh:369
unsigned max_set() const
The number of the highest set used plus one.
Definition acc.hh:345
mark_t & remove_some(unsigned n)
Remove n bits that were set.
Definition acc.hh:399
size_t hash() const noexcept
Returns a hash value for this mark.
Definition acc.hh:132
bool operator<=(mark_t o) const
Less-or-equal comparison.
Definition acc.hh:157
static mark_t all()
A mark_t with all bits set to one.
Definition acc.hh:126
spot::internal::mark_container sets() const
Returns some iterable object that contains the used sets.
Definition acc.hh:2570
bool proper_subset(mark_t m) const
Whether the set of bits represented by *this is a proper subset of those represented by m.
Definition acc.hh:330
mark_t strip(mark_t y) const
Remove bits indexed by y and compact the remaining bits.
Definition acc.hh:298
mark_t(const iterator &begin, const iterator &end)
Create a mark_t from a range of set numbers.
Definition acc.hh:94
mark_t & operator-=(mark_t r)
Difference-assignment (removes bits set in r).
Definition acc.hh:213
unsigned count() const
Number of bits set.
Definition acc.hh:336
mark_t & operator<<=(unsigned i)
Left-shift-assignment.
Definition acc.hh:276
mark_t operator>>(unsigned i) const
Right-shift all acceptance set indices by i.
Definition acc.hh:282
mark_t operator^(mark_t r) const
Symmetric difference.
Definition acc.hh:251
mark_t operator-(mark_t r) const
Difference (bits in this mark but not in r).
Definition acc.hh:239
mark_t()=default
Initialize an empty mark_t.
mark_t(std::initializer_list< unsigned > vals)
Create a mark_t from a list of set numbers.
Definition acc.hh:105
bool operator!=(mark_t o) const
Inequality comparison.
Definition acc.hh:145
mark_t operator<<(unsigned i) const
Left-shift all acceptance set indices by i.
Definition acc.hh:270
mark_t & operator^=(mark_t r)
Symmetric-difference-assignment.
Definition acc.hh:220
bool operator>=(mark_t o) const
Greater-or-equal comparison.
Definition acc.hh:169
bool has_many() const
Whether the mark contains at least two bits set.
Definition acc.hh:386
void clear(unsigned u)
Remove acceptance set u from this mark.
Definition acc.hh:193
mark_t & operator|=(mark_t r)
Union-assignment.
Definition acc.hh:206
unsigned min_set() const
The number of the lowest set used plus one.
Definition acc.hh:357
mark_t operator&(mark_t r) const
Intersection.
Definition acc.hh:227
mark_t & operator>>=(unsigned i)
Right-shift-assignment.
Definition acc.hh:288
bool has(unsigned u) const
Returns true iff acceptance set u is in this mark.
Definition acc.hh:181
bool operator<(mark_t o) const
Less-than comparison.
Definition acc.hh:151
bool operator>(mark_t o) const
Greater-than comparison.
Definition acc.hh:163
mark_t & operator&=(mark_t r)
Intersection-assignment.
Definition acc.hh:199
mark_t operator|(mark_t r) const
Union.
Definition acc.hh:233
bool operator==(mark_t o) const
Equality comparison.
Definition acc.hh:139
bool subset(mark_t m) const
Whether the set of bits represented by *this is a subset of those represented by m.
Definition acc.hh:323
void fill(iterator here) const
Fill a container with the indices of the bits that are set.
Definition acc.hh:2576
void set(unsigned u)
Add acceptance set u to this mark.
Definition acc.hh:187
Rabin/streett pairs used by is_rabin_like and is_streett_like.
Definition acc.hh:1756
rs_pair(acc_cond::mark_t fin, acc_cond::mark_t inf) noexcept
Construct a pair with Fin mark fin and Inf mark inf.
Definition acc.hh:1766
rs_pair & operator=(const rs_pair &)=default
Copy-assignment operator.
rs_pair(const rs_pair &)=default
Copy constructor.
bool operator<=(rs_pair o) const
Less-or-equal comparison.
Definition acc.hh:1789
acc_cond::mark_t fin
The Fin acceptance mark of this pair.
Definition acc.hh:1770
bool operator>=(rs_pair o) const
Greater-or-equal comparison.
Definition acc.hh:1799
bool operator>(rs_pair o) const
Greater-than comparison.
Definition acc.hh:1794
bool operator<(rs_pair o) const
Less-than comparison (lexicographic on fin then inf).
Definition acc.hh:1784
bool operator==(rs_pair o) const
Equality comparison.
Definition acc.hh:1774
bool operator!=(rs_pair o) const
Inequality comparison.
Definition acc.hh:1779
acc_cond::mark_t inf
The Inf acceptance mark of this pair.
Definition acc.hh:1771
A view over Rabin-Streett pairs restricted to a subset of acceptance marks.
Definition acc.hh:2390
std::vector< acc_cond::rs_pair > rs_pairs
Type alias for a vector of Rabin-Streett pairs.
Definition acc.hh:2392
acc_cond::mark_t fins() const
Returns the union of all visible Fin marks across all pairs.
Definition acc.hh:2412
rs_pairs_view(const rs_pairs &p, const acc_cond::mark_t &m)
Create a view of pairs p restricted to marks visible in m.
Definition acc.hh:2395
rs_pairs_view(const rs_pairs &p)
Create an unrestricted view of all pairs in p.
Definition acc.hh:2399
acc_cond::mark_t paired_with_fin(unsigned mark) const
Returns all Inf marks paired with a Fin containing mark.
Definition acc.hh:2443
acc_cond::mark_t fins_alone() const
Returns Fin marks from pairs whose Inf part is not visible.
Definition acc.hh:2421
acc_cond::mark_t infs_alone() const
Returns Inf marks from pairs whose Fin part is not visible.
Definition acc.hh:2431
const rs_pairs & pairs() const
Returns a reference to the underlying vector of pairs.
Definition acc.hh:2453
acc_cond::mark_t infs() const
Returns the union of all visible Inf marks across all pairs.
Definition acc.hh:2403
A "node" in an acceptance formulas.
Definition acc.hh:429
mark_t mark
A set of acceptance marks.
Definition acc.hh:430
acc_op op
Operator (6 possible values, stored in 8 bits)
Definition acc.hh:433
unsigned size
Size of the subtree.
Definition acc.hh:439
struct spot::acc_cond::acc_word::@5 sub
An operator node with its subtree size.

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.8