43 #include "misc/common.hh"
46 #include <initializer_list>
55 #include <initializer_list>
61 enum class op: uint8_t
100 class SPOT_API fnode final
109 const fnode* clone()
const
118 if (SPOT_UNLIKELY(!refs_ && id_ > 2))
124 static constexpr uint8_t unbounded()
129 static const fnode*
ap(
const std::string& name);
130 static const fnode* unop(
op o,
const fnode* f);
131 static const fnode* binop(
op o,
const fnode* f,
const fnode* g);
132 static const fnode* multop(
op o, std::vector<const fnode*> l);
133 static const fnode* bunop(
op o,
const fnode* f,
134 uint8_t min, uint8_t max = unbounded());
141 std::string kindstr()
const;
148 bool is(
op o1,
op o2)
const
150 return op_ == o1 || op_ == o2;
153 bool is(std::initializer_list<op> l)
const
155 const fnode* n =
this;
165 const fnode* get_child_of(
op o)
const
173 const fnode* get_child_of(std::initializer_list<op> l)
const
178 c = c->get_child_of(o);
197 unsigned size()
const
207 const fnode*
const* begin()
const
212 const fnode*
const* end()
const
214 return children + size();
217 const fnode* nth(
unsigned i)
const
220 throw std::runtime_error(
"access to non-existing child");
224 static const fnode*
ff()
234 static const fnode*
tt()
244 static const fnode*
eword()
249 bool is_eword()
const
254 bool is_constant()
const
259 bool is_Kleene_star()
const
263 return min_ == 0 && max_ == unbounded();
266 static const fnode* one_star()
273 const std::string& ap_name()
const;
274 std::ostream& dump(std::ostream& os)
const;
276 const fnode* all_but(
unsigned i)
const;
278 unsigned boolean_count()
const
282 while (pos < s && children[pos]->is_boolean())
287 const fnode* boolean_operands(
unsigned* width =
nullptr)
const;
291 static bool instances_check();
297 bool is_boolean()
const
302 bool is_sugar_free_boolean()
const
304 return is_.sugar_free_boolean;
307 bool is_in_nenoform()
const
309 return is_.in_nenoform;
312 bool is_syntactic_stutter_invariant()
const
314 return is_.syntactic_si;
317 bool is_sugar_free_ltl()
const
319 return is_.sugar_free_ltl;
322 bool is_ltl_formula()
const
324 return is_.ltl_formula;
327 bool is_psl_formula()
const
329 return is_.psl_formula;
332 bool is_sere_formula()
const
334 return is_.sere_formula;
337 bool is_finite()
const
342 bool is_eventual()
const
347 bool is_universal()
const
349 return is_.universal;
352 bool is_syntactic_safety()
const
354 return is_.syntactic_safety;
357 bool is_syntactic_guarantee()
const
359 return is_.syntactic_guarantee;
362 bool is_syntactic_obligation()
const
364 return is_.syntactic_obligation;
367 bool is_syntactic_recurrence()
const
369 return is_.syntactic_recurrence;
372 bool is_syntactic_persistence()
const
374 return is_.syntactic_persistence;
377 bool is_marked()
const
379 return !is_.not_marked;
382 bool accepts_eword()
const
384 return is_.accepting_eword;
387 bool has_lbt_atomic_props()
const
389 return is_.lbt_atomic_props;
392 bool has_spin_atomic_props()
const
394 return is_.spin_atomic_props;
398 void setup_props(
op o);
399 void destroy_aux()
const;
401 static const fnode* unique(
const fnode*);
406 fnode(
const fnode&) =
delete;
407 fnode& operator=(
const fnode&) =
delete;
412 fnode(
op o, iter begin, iter end)
414 size_t s = std::distance(begin, end);
415 if (s > (
size_t) UINT16_MAX)
416 throw std::runtime_error(
"too many children for formula");
419 for (
auto i = begin; i != end; ++i)
424 fnode(
op o, std::initializer_list<const fnode*> l)
425 : fnode(o, l.begin(), l.end())
429 fnode(
op o,
const fnode* f, uint8_t min, uint8_t max)
438 static const fnode* ff_;
439 static const fnode* tt_;
440 static const fnode* ew_;
441 static const fnode* one_star_;
448 mutable uint16_t refs_ = 0;
450 static size_t next_id_;
468 bool sugar_free_boolean:1;
471 bool sugar_free_ltl:1;
478 bool syntactic_safety:1;
479 bool syntactic_guarantee:1;
480 bool syntactic_obligation:1;
481 bool syntactic_recurrence:1;
482 bool syntactic_persistence:1;
484 bool accepting_eword:1;
485 bool lbt_atomic_props:1;
486 bool spin_atomic_props:1;
495 const fnode* children[1];
500 int atomic_prop_cmp(
const fnode* f,
const fnode* g);
505 operator()(
const fnode* left,
const fnode* right)
const
513 bool lib = left->is_boolean();
514 if (lib != right->is_boolean())
520 bool lconst = left->is_constant();
521 if (lconst != right->is_constant())
525 auto get_literal = [](
const fnode* f) ->
const fnode*
534 const fnode* litl = get_literal(left);
535 const fnode* litr = get_literal(right);
541 int cmp = atomic_prop_cmp(litl, litr);
548 size_t l = left->id();
549 size_t r = right->id();
562 std::ostringstream old;
564 std::ostringstream ord;
566 return old.str() < ord.str();
583 formula(std::nullptr_t) noexcept
612 const formula& operator=(std::nullptr_t)
629 std::swap(f.ptr_, ptr_);
633 bool operator<(
const formula& other)
const noexcept
635 if (SPOT_UNLIKELY(!other.ptr_))
637 if (SPOT_UNLIKELY(!ptr_))
639 if (
id() < other.
id())
641 if (
id() > other.
id())
647 return ptr_ < other.ptr_;
650 bool operator<=(
const formula& other)
const noexcept
652 return *
this == other || *
this < other;
655 bool operator>(
const formula& other)
const noexcept
657 return !(*
this <= other);
660 bool operator>=(
const formula& other)
const noexcept
662 return !(*
this < other);
665 bool operator==(
const formula& other)
const noexcept
667 return other.ptr_ == ptr_;
670 bool operator==(std::nullptr_t)
const noexcept
672 return ptr_ ==
nullptr;
675 bool operator!=(
const formula& other)
const noexcept
677 return other.ptr_ != ptr_;
680 bool operator!=(std::nullptr_t)
const noexcept
682 return ptr_ !=
nullptr;
685 operator bool()
const
687 return ptr_ !=
nullptr;
697 return fnode::unbounded();
703 return formula(fnode::ap(name));
712 return formula(fnode::unop(o, f.ptr_->clone()));
724 #define SPOT_DEF_UNOP(Name) \
725 static formula Name(const formula& f) \
727 return unop(op::Name, f); \
730 #define SPOT_DEF_UNOP(Name) \
731 static formula Name(const formula& f) \
733 return unop(op::Name, f); \
735 static formula Name(formula&& f) \
737 return unop(op::Name, std::move(f)); \
782 return formula(fnode::binop(o, f.ptr_->clone(), g.ptr_->clone()));
788 return formula(fnode::binop(o, f.ptr_->clone(), g.to_node_()));
791 static formula binop(
op o, formula&& f,
const formula& g)
793 return formula(fnode::binop(o, f.
to_node_(), g.ptr_->clone()));
796 static formula binop(
op o, formula&& f, formula&& g)
798 return formula(fnode::binop(o, f.
to_node_(), g.to_node_()));
803 #define SPOT_DEF_BINOP(Name) \
804 static formula Name(const formula& f, const formula& g) \
806 return binop(op::Name, f, g); \
809 #define SPOT_DEF_BINOP(Name) \
810 static formula Name(const formula& f, const formula& g) \
812 return binop(op::Name, f, g); \
814 static formula Name(const formula& f, formula&& g) \
816 return binop(op::Name, f, std::move(g)); \
818 static formula Name(formula&& f, const formula& g) \
820 return binop(op::Name, std::move(f), g); \
822 static formula Name(formula&& f, formula&& g) \
824 return binop(op::Name, std::move(f), std::move(g)); \
876 #undef SPOT_DEF_BINOP
885 std::vector<const fnode*> tmp;
886 tmp.reserve(l.size());
889 tmp.push_back(f.ptr_->clone());
890 return formula(fnode::multop(o, std::move(tmp)));
894 static formula multop(
op o, std::vector<formula>&& l)
896 std::vector<const fnode*> tmp;
897 tmp.reserve(l.size());
901 return formula(fnode::multop(o, std::move(tmp)));
907 #define SPOT_DEF_MULTOP(Name) \
908 static formula Name(const std::vector<formula>& l) \
910 return multop(op::Name, l); \
913 #define SPOT_DEF_MULTOP(Name) \
914 static formula Name(const std::vector<formula>& l) \
916 return multop(op::Name, l); \
919 static formula Name(std::vector<formula>&& l) \
921 return multop(op::Name, std::move(l)); \
958 #undef SPOT_DEF_MULTOP
966 uint8_t max = unbounded())
968 return formula(fnode::bunop(o, f.ptr_->clone(), min, max));
974 uint8_t max = unbounded())
982 #define SPOT_DEF_BUNOP(Name) \
983 static formula Name(const formula& f, \
985 uint8_t max = unbounded()) \
987 return bunop(op::Name, f, min, max); \
990 #define SPOT_DEF_BUNOP(Name) \
991 static formula Name(const formula& f, \
993 uint8_t max = unbounded()) \
995 return bunop(op::Name, f, min, max); \
997 static formula Name(formula&& f, \
999 uint8_t max = unbounded()) \
1001 return bunop(op::Name, std::move(f), min, max); \
1004 SPOT_DEF_BUNOP(
Star);
1028 SPOT_DEF_BUNOP(
FStar);
1031 #undef SPOT_DEF_BUNOP
1038 static formula sugar_goto(
const formula& b, uint8_t min, uint8_t max);
1045 static formula sugar_equal(
const formula& b, uint8_t min, uint8_t max);
1048 const fnode* to_node_()
1068 return ptr_->kind();
1074 return ptr_->kindstr();
1084 bool is(
op o1,
op o2)
const
1087 return ptr_->is(o1, o2);
1091 bool is(std::initializer_list<op> l)
const
1109 formula get_child_of(std::initializer_list<op> l)
const
1143 return ptr_->size();
1160 class SPOT_API formula_child_iterator final
1163 const fnode*
const* ptr_;
1165 formula_child_iterator()
1170 formula_child_iterator(
const fnode*
const* f)
1175 bool operator==(formula_child_iterator o)
1177 return ptr_ == o.ptr_;
1180 bool operator!=(formula_child_iterator o)
1182 return ptr_ != o.ptr_;
1187 return formula((*ptr_)->clone());
1190 formula_child_iterator operator++()
1196 formula_child_iterator operator++(
int)
1207 return ptr_->begin();
1219 return formula(ptr_->nth(i)->clone());
1232 return ptr_->is_ff();
1244 return ptr_->is_tt();
1250 return formula(fnode::eword());
1256 return ptr_->is_eword();
1262 return ptr_->is_constant();
1271 return ptr_->is_Kleene_star();
1277 return formula(fnode::one_star()->clone());
1288 (is(
op::Not) && is_boolean() && is_in_nenoform()));
1296 return ptr_->ap_name();
1303 std::ostream&
dump(std::ostream& os)
const
1305 return ptr_->dump(os);
1315 return formula(ptr_->all_but(i));
1329 return ptr_->boolean_count();
1347 return formula(ptr_->boolean_operands(width));
1350 #define SPOT_DEF_PROP(Name) \
1353 return ptr_->Name(); \
1360 SPOT_DEF_PROP(is_boolean);
1362 SPOT_DEF_PROP(is_sugar_free_boolean);
1367 SPOT_DEF_PROP(is_in_nenoform);
1369 SPOT_DEF_PROP(is_syntactic_stutter_invariant);
1371 SPOT_DEF_PROP(is_sugar_free_ltl);
1373 SPOT_DEF_PROP(is_ltl_formula);
1375 SPOT_DEF_PROP(is_psl_formula);
1377 SPOT_DEF_PROP(is_sere_formula);
1380 SPOT_DEF_PROP(is_finite);
1398 SPOT_DEF_PROP(is_eventual);
1419 SPOT_DEF_PROP(is_universal);
1424 SPOT_DEF_PROP(is_syntactic_safety);
1426 SPOT_DEF_PROP(is_syntactic_guarantee);
1428 SPOT_DEF_PROP(is_syntactic_obligation);
1430 SPOT_DEF_PROP(is_syntactic_recurrence);
1432 SPOT_DEF_PROP(is_syntactic_persistence);
1435 SPOT_DEF_PROP(is_marked);
1437 SPOT_DEF_PROP(accepts_eword);
1443 SPOT_DEF_PROP(has_lbt_atomic_props);
1452 SPOT_DEF_PROP(has_spin_atomic_props);
1453 #undef SPOT_DEF_PROP
1456 template<
typename Trans>
1459 switch (
op o = kind())
1473 return unop(o, trans((*
this)[0]));
1485 formula tmp = trans((*
this)[0]);
1486 return binop(o, tmp, trans((*
this)[1]));
1496 std::vector<formula> tmp;
1497 tmp.reserve(size());
1499 tmp.push_back(trans(f));
1500 return multop(o, std::move(tmp));
1504 return bunop(o, trans((*
this)[0]), min(), max());
1514 template<
typename Func>
1526 std::ostream& print_formula_props(std::ostream& out,
const formula& f,
1527 bool abbreviated =
false);
1531 std::list<std::string> list_formula_props(
const formula& f);
1535 std::ostream& operator<<(std::ostream& os,
const formula& f);
Definition: formula.hh:1539
Non-Length-Matching Rational-And.
marked version of the Negated PSL Clusure
op
Operator types.
Definition: formula.hh:61
Actual storage for formula nodes.
Definition: formula.hh:106
strong release (dual of weak until)