43 #include <spot/misc/common.hh>
46 #include <initializer_list>
55 #include <initializer_list>
62 enum class op: uint8_t
101 class SPOT_API fnode final
110 const fnode* clone()
const
114 if (SPOT_UNLIKELY(!refs_))
121 if (SPOT_LIKELY(refs_))
123 else if (SPOT_LIKELY(id_ > 2) && SPOT_LIKELY(!saturated_))
128 static constexpr uint8_t unbounded()
133 static const fnode*
ap(
const std::string& name);
134 static const fnode* unop(
op o,
const fnode* f);
135 static const fnode* binop(
op o,
const fnode* f,
const fnode* g);
136 static const fnode* multop(
op o, std::vector<const fnode*> l);
137 static const fnode* bunop(
op o,
const fnode* f,
138 uint8_t min, uint8_t max = unbounded());
145 std::string kindstr()
const;
152 bool is(
op o1,
op o2)
const
154 return op_ == o1 || op_ == o2;
157 bool is(std::initializer_list<op> l)
const
159 const fnode* n =
this;
169 const fnode* get_child_of(
op o)
const
177 const fnode* get_child_of(std::initializer_list<op> l)
const
182 c = c->get_child_of(o);
201 unsigned size()
const
211 const fnode*
const* begin()
const
216 const fnode*
const* end()
const
218 return children + size();
221 const fnode* nth(
unsigned i)
const
224 throw std::runtime_error(
"access to non-existing child");
228 static const fnode*
ff()
238 static const fnode*
tt()
248 static const fnode*
eword()
253 bool is_eword()
const
258 bool is_constant()
const
263 bool is_Kleene_star()
const
267 return min_ == 0 && max_ == unbounded();
270 static const fnode* one_star()
277 const std::string& ap_name()
const;
278 std::ostream& dump(std::ostream& os)
const;
280 const fnode* all_but(
unsigned i)
const;
282 unsigned boolean_count()
const
286 while (pos < s && children[pos]->is_boolean())
291 const fnode* boolean_operands(
unsigned* width =
nullptr)
const;
295 static bool instances_check();
301 bool is_boolean()
const
306 bool is_sugar_free_boolean()
const
308 return is_.sugar_free_boolean;
311 bool is_in_nenoform()
const
313 return is_.in_nenoform;
316 bool is_syntactic_stutter_invariant()
const
318 return is_.syntactic_si;
321 bool is_sugar_free_ltl()
const
323 return is_.sugar_free_ltl;
326 bool is_ltl_formula()
const
328 return is_.ltl_formula;
331 bool is_psl_formula()
const
333 return is_.psl_formula;
336 bool is_sere_formula()
const
338 return is_.sere_formula;
341 bool is_finite()
const
346 bool is_eventual()
const
351 bool is_universal()
const
353 return is_.universal;
356 bool is_syntactic_safety()
const
358 return is_.syntactic_safety;
361 bool is_syntactic_guarantee()
const
363 return is_.syntactic_guarantee;
366 bool is_syntactic_obligation()
const
368 return is_.syntactic_obligation;
371 bool is_syntactic_recurrence()
const
373 return is_.syntactic_recurrence;
376 bool is_syntactic_persistence()
const
378 return is_.syntactic_persistence;
381 bool is_marked()
const
383 return !is_.not_marked;
386 bool accepts_eword()
const
388 return is_.accepting_eword;
391 bool has_lbt_atomic_props()
const
393 return is_.lbt_atomic_props;
396 bool has_spin_atomic_props()
const
398 return is_.spin_atomic_props;
402 void setup_props(
op o);
403 void destroy_aux()
const;
405 static const fnode* unique(
const fnode*);
410 fnode(
const fnode&) =
delete;
411 fnode& operator=(
const fnode&) =
delete;
416 fnode(
op o, iter begin, iter end)
418 size_t s = std::distance(begin, end);
419 if (s > (
size_t) UINT16_MAX)
420 throw std::runtime_error(
"too many children for formula");
423 for (
auto i = begin; i != end; ++i)
428 fnode(
op o, std::initializer_list<const fnode*> l)
429 : fnode(o, l.begin(), l.end())
433 fnode(
op o,
const fnode* f, uint8_t min, uint8_t max)
442 static const fnode* ff_;
443 static const fnode* tt_;
444 static const fnode* ew_;
445 static const fnode* one_star_;
450 mutable uint8_t saturated_ = 0;
452 mutable uint16_t refs_ = 0;
454 static size_t next_id_;
472 bool sugar_free_boolean:1;
475 bool sugar_free_ltl:1;
482 bool syntactic_safety:1;
483 bool syntactic_guarantee:1;
484 bool syntactic_obligation:1;
485 bool syntactic_recurrence:1;
486 bool syntactic_persistence:1;
488 bool accepting_eword:1;
489 bool lbt_atomic_props:1;
490 bool spin_atomic_props:1;
499 const fnode* children[1];
504 int atomic_prop_cmp(
const fnode* f,
const fnode* g);
509 operator()(
const fnode* left,
const fnode* right)
const
517 bool lib = left->is_boolean();
518 if (lib != right->is_boolean())
524 bool lconst = left->is_constant();
525 if (lconst != right->is_constant())
529 auto get_literal = [](
const fnode* f) ->
const fnode*
538 const fnode* litl = get_literal(left);
539 const fnode* litr = get_literal(right);
545 int cmp = atomic_prop_cmp(litl, litr);
552 size_t l = left->id();
553 size_t r = right->id();
566 std::ostringstream old;
568 std::ostringstream ord;
570 return old.str() < ord.str();
587 formula(std::nullptr_t) noexcept
616 const formula& operator=(std::nullptr_t)
633 std::swap(f.ptr_, ptr_);
637 bool operator<(
const formula& other)
const noexcept
639 if (SPOT_UNLIKELY(!other.ptr_))
641 if (SPOT_UNLIKELY(!ptr_))
643 if (
id() < other.
id())
645 if (
id() > other.
id())
651 return ptr_ < other.ptr_;
654 bool operator<=(
const formula& other)
const noexcept
656 return *
this == other || *
this < other;
659 bool operator>(
const formula& other)
const noexcept
661 return !(*
this <= other);
664 bool operator>=(
const formula& other)
const noexcept
666 return !(*
this < other);
669 bool operator==(
const formula& other)
const noexcept
671 return other.ptr_ == ptr_;
674 bool operator==(std::nullptr_t)
const noexcept
676 return ptr_ ==
nullptr;
679 bool operator!=(
const formula& other)
const noexcept
681 return other.ptr_ != ptr_;
684 bool operator!=(std::nullptr_t)
const noexcept
686 return ptr_ !=
nullptr;
689 operator bool()
const
691 return ptr_ !=
nullptr;
701 return fnode::unbounded();
707 return formula(fnode::ap(name));
716 return formula(fnode::unop(o, f.ptr_->clone()));
728 #define SPOT_DEF_UNOP(Name) \
729 static formula Name(const formula& f) \
731 return unop(op::Name, f); \
734 #define SPOT_DEF_UNOP(Name) \
735 static formula Name(const formula& f) \
737 return unop(op::Name, f); \
739 static formula Name(formula&& f) \
741 return unop(op::Name, std::move(f)); \
786 return formula(fnode::binop(o, f.ptr_->clone(), g.ptr_->clone()));
792 return formula(fnode::binop(o, f.ptr_->clone(), g.to_node_()));
795 static formula binop(
op o, formula&& f,
const formula& g)
797 return formula(fnode::binop(o, f.
to_node_(), g.ptr_->clone()));
800 static formula binop(
op o, formula&& f, formula&& g)
802 return formula(fnode::binop(o, f.
to_node_(), g.to_node_()));
807 #define SPOT_DEF_BINOP(Name) \
808 static formula Name(const formula& f, const formula& g) \
810 return binop(op::Name, f, g); \
813 #define SPOT_DEF_BINOP(Name) \
814 static formula Name(const formula& f, const formula& g) \
816 return binop(op::Name, f, g); \
818 static formula Name(const formula& f, formula&& g) \
820 return binop(op::Name, f, std::move(g)); \
822 static formula Name(formula&& f, const formula& g) \
824 return binop(op::Name, std::move(f), g); \
826 static formula Name(formula&& f, formula&& g) \
828 return binop(op::Name, std::move(f), std::move(g)); \
880 #undef SPOT_DEF_BINOP
889 std::vector<const fnode*> tmp;
890 tmp.reserve(l.size());
893 tmp.push_back(f.ptr_->clone());
894 return formula(fnode::multop(o, std::move(tmp)));
898 static formula multop(
op o, std::vector<formula>&& l)
900 std::vector<const fnode*> tmp;
901 tmp.reserve(l.size());
905 return formula(fnode::multop(o, std::move(tmp)));
911 #define SPOT_DEF_MULTOP(Name) \
912 static formula Name(const std::vector<formula>& l) \
914 return multop(op::Name, l); \
917 #define SPOT_DEF_MULTOP(Name) \
918 static formula Name(const std::vector<formula>& l) \
920 return multop(op::Name, l); \
923 static formula Name(std::vector<formula>&& l) \
925 return multop(op::Name, std::move(l)); \
962 #undef SPOT_DEF_MULTOP
970 uint8_t max = unbounded())
972 return formula(fnode::bunop(o, f.ptr_->clone(), min, max));
978 uint8_t max = unbounded())
986 #define SPOT_DEF_BUNOP(Name) \
987 static formula Name(const formula& f, \
989 uint8_t max = unbounded()) \
991 return bunop(op::Name, f, min, max); \
994 #define SPOT_DEF_BUNOP(Name) \
995 static formula Name(const formula& f, \
997 uint8_t max = unbounded()) \
999 return bunop(op::Name, f, min, max); \
1001 static formula Name(formula&& f, \
1003 uint8_t max = unbounded()) \
1005 return bunop(op::Name, std::move(f), min, max); \
1008 SPOT_DEF_BUNOP(
Star);
1032 SPOT_DEF_BUNOP(
FStar);
1035 #undef SPOT_DEF_BUNOP
1042 static formula sugar_goto(
const formula& b, uint8_t min, uint8_t max);
1049 static formula sugar_equal(
const formula& b, uint8_t min, uint8_t max);
1052 const fnode* to_node_()
1072 return ptr_->kind();
1078 return ptr_->kindstr();
1088 bool is(
op o1,
op o2)
const
1091 return ptr_->is(o1, o2);
1095 bool is(std::initializer_list<op> l)
const
1113 formula get_child_of(std::initializer_list<op> l)
const
1147 return ptr_->size();
1164 class SPOT_API formula_child_iterator final
1167 const fnode*
const* ptr_;
1169 formula_child_iterator()
1174 formula_child_iterator(
const fnode*
const* f)
1179 bool operator==(formula_child_iterator o)
1181 return ptr_ == o.ptr_;
1184 bool operator!=(formula_child_iterator o)
1186 return ptr_ != o.ptr_;
1191 return formula((*ptr_)->clone());
1194 formula_child_iterator operator++()
1200 formula_child_iterator operator++(
int)
1211 return ptr_->begin();
1223 return formula(ptr_->nth(i)->clone());
1236 return ptr_->is_ff();
1248 return ptr_->is_tt();
1254 return formula(fnode::eword());
1260 return ptr_->is_eword();
1266 return ptr_->is_constant();
1275 return ptr_->is_Kleene_star();
1281 return formula(fnode::one_star()->clone());
1292 (is(
op::Not) && is_boolean() && is_in_nenoform()));
1300 return ptr_->ap_name();
1307 std::ostream&
dump(std::ostream& os)
const
1309 return ptr_->dump(os);
1319 return formula(ptr_->all_but(i));
1333 return ptr_->boolean_count();
1351 return formula(ptr_->boolean_operands(width));
1354 #define SPOT_DEF_PROP(Name) \
1357 return ptr_->Name(); \
1364 SPOT_DEF_PROP(is_boolean);
1366 SPOT_DEF_PROP(is_sugar_free_boolean);
1371 SPOT_DEF_PROP(is_in_nenoform);
1373 SPOT_DEF_PROP(is_syntactic_stutter_invariant);
1375 SPOT_DEF_PROP(is_sugar_free_ltl);
1377 SPOT_DEF_PROP(is_ltl_formula);
1379 SPOT_DEF_PROP(is_psl_formula);
1381 SPOT_DEF_PROP(is_sere_formula);
1384 SPOT_DEF_PROP(is_finite);
1402 SPOT_DEF_PROP(is_eventual);
1423 SPOT_DEF_PROP(is_universal);
1428 SPOT_DEF_PROP(is_syntactic_safety);
1430 SPOT_DEF_PROP(is_syntactic_guarantee);
1432 SPOT_DEF_PROP(is_syntactic_obligation);
1434 SPOT_DEF_PROP(is_syntactic_recurrence);
1436 SPOT_DEF_PROP(is_syntactic_persistence);
1439 SPOT_DEF_PROP(is_marked);
1441 SPOT_DEF_PROP(accepts_eword);
1447 SPOT_DEF_PROP(has_lbt_atomic_props);
1456 SPOT_DEF_PROP(has_spin_atomic_props);
1457 #undef SPOT_DEF_PROP
1460 template<
typename Trans>
1463 switch (
op o = kind())
1477 return unop(o, trans((*
this)[0]));
1489 formula tmp = trans((*
this)[0]);
1490 return binop(o, tmp, trans((*
this)[1]));
1500 std::vector<formula> tmp;
1501 tmp.reserve(size());
1503 tmp.push_back(trans(f));
1504 return multop(o, std::move(tmp));
1508 return bunop(o, trans((*
this)[0]), min(), max());
1518 template<
typename Func>
1530 std::ostream& print_formula_props(std::ostream& out,
const formula& f,
1531 bool abbreviated =
false);
1535 std::list<std::string> list_formula_props(
const formula& f);
1539 std::ostream& operator<<(std::ostream& os,
const formula& f);
Definition: formula.hh:1543
Non-Length-Matching Rational-And.
marked version of the Negated PSL Clusure
op
Operator types.
Definition: formula.hh:62
Actual storage for formula nodes.
Definition: formula.hh:107
strong release (dual of weak until)