45#include <spot/misc/common.hh>
48#include <initializer_list>
64# define SPOT_HAS_STRONG_X 1
68# define SPOT_WANT_STRONG_X 1
76 enum class op: uint8_t
163 if (SPOT_UNLIKELY(!refs_))
175 if (SPOT_LIKELY(refs_))
177 else if (SPOT_LIKELY(!saturated_))
189 static const fnode*
ap(
const std::string& name);
198 unsigned min,
unsigned max = unbounded());
202 unsigned max,
const fnode* f);
222 return op_ == o1 || op_ == o2;
227 return op_ == o1 || op_ == o2 || op_ == o3;
232 return op_ == o1 || op_ == o2 || op_ == o3 || op_ == o4;
235 bool is(std::initializer_list<op> l)
const
237 const fnode* n =
this;
253 if (SPOT_UNLIKELY(size_ != 1))
254 report_get_child_of_expecting_single_child_node();
275 report_min_invalid_arg();
283 report_max_invalid_arg();
314 return children + size();
320 if (SPOT_UNLIKELY(i >= size()))
321 report_non_existing_child();
322 const fnode* c = children[i];
323 SPOT_ASSUME(c !=
nullptr);
374 return min_ == 0 && max_ == unbounded();
397 std::ostream&
dump(std::ostream& os)
const;
407 while (pos < s && children[pos]->is_boolean())
440 return is_.sugar_free_boolean;
446 return is_.in_nenoform;
452 return is_.syntactic_si;
458 return is_.sugar_free_ltl;
464 return is_.ltl_formula;
470 return is_.psl_formula;
476 return is_.sere_formula;
494 return is_.universal;
500 return is_.syntactic_safety;
506 return is_.syntactic_guarantee;
512 return is_.syntactic_obligation;
518 return is_.syntactic_recurrence;
524 return is_.syntactic_persistence;
530 return !is_.not_marked;
536 return is_.accepting_eword;
542 return is_.lbt_atomic_props;
548 return is_.spin_atomic_props;
576 static size_t bump_next_id();
577 void setup_props(
op o);
578 void destroy_aux()
const;
580 [[noreturn]]
static void report_non_existing_child();
581 [[noreturn]]
static void report_too_many_children();
582 [[noreturn]]
static void
583 report_get_child_of_expecting_single_child_node();
584 [[noreturn]]
static void report_min_invalid_arg();
585 [[noreturn]]
static void report_max_invalid_arg();
598 fnode(
op o, iter begin, iter end,
bool saturated =
false)
613 saturated_(saturated)
615 size_t s = std::distance(begin, end);
616 if (SPOT_UNLIKELY(s > (
size_t) UINT16_MAX))
617 report_too_many_children();
620 for (
auto i = begin; i != end; ++i)
625 fnode(
op o, std::initializer_list<const fnode*> l,
626 bool saturated =
false)
627 : fnode(o, l.begin(), l.end(), saturated)
631 fnode(
op o,
const fnode* f, uint8_t min, uint8_t max,
632 bool saturated =
false)
633 : op_(o), min_(min), max_(max), saturated_(saturated), size_(1)
639 static const fnode* ff_;
640 static const fnode* tt_;
641 static const fnode* ew_;
642 static const fnode* one_star_;
643 static const fnode* one_plus_;
648 mutable uint8_t saturated_;
650 mutable uint16_t refs_ = 0;
652 static size_t next_id_;
670 bool sugar_free_boolean:1;
673 bool sugar_free_ltl:1;
680 bool syntactic_safety:1;
681 bool syntactic_guarantee:1;
682 bool syntactic_obligation:1;
683 bool syntactic_recurrence:1;
684 bool syntactic_persistence:1;
686 bool accepting_eword:1;
687 bool lbt_atomic_props:1;
688 bool spin_atomic_props:1;
701 const fnode* children[1];
713 operator()(
const fnode* left,
const fnode* right)
const
733 auto get_literal = [](
const fnode* f) ->
const fnode*
742 const fnode* litl = get_literal(left);
743 const fnode* litr = get_literal(right);
756 size_t l = left->
id();
757 size_t r = right->
id();
770 std::ostringstream old;
772 std::ostringstream ord;
774 return old.str() < ord.str();
859 const formula& operator=(formula&& f)
noexcept
861 std::swap(f.ptr_, ptr_);
865 bool operator<(
const formula& other)
const noexcept
867 if (SPOT_UNLIKELY(!other.ptr_))
869 if (SPOT_UNLIKELY(!ptr_))
871 if (
id() < other.id())
873 if (
id() > other.id())
879 return ptr_ < other.ptr_;
882 bool operator<=(
const formula& other)
const noexcept
884 return *
this == other || *
this < other;
887 bool operator>(
const formula& other)
const noexcept
889 return !(*
this <= other);
892 bool operator>=(
const formula& other)
const noexcept
894 return !(*
this < other);
897 bool operator==(
const formula& other)
const noexcept
899 return other.ptr_ == ptr_;
902 bool operator==(std::nullptr_t)
const noexcept
904 return ptr_ ==
nullptr;
907 bool operator!=(
const formula& other)
const noexcept
909 return other.ptr_ != ptr_;
912 bool operator!=(std::nullptr_t)
const noexcept
914 return ptr_ !=
nullptr;
917 explicit operator bool() const noexcept
919 return ptr_ !=
nullptr;
946 report_ap_invalid_arg();
968#define SPOT_DEF_UNOP(Name) \
969 static formula Name(const formula& f) \
971 return unop(op::Name, f); \
974#define SPOT_DEF_UNOP(Name) \
975 static formula Name(const formula& f) \
977 return unop(op::Name, f); \
979 static formula Name(formula&& f) \
981 return unop(op::Name, std::move(f)); \
999 return nested_unop_range(
op::X,
op::Or , level, level, f);
1004 SPOT_DEF_UNOP(strong_X);
1029 return nested_unop_range(
op::X,
op::Or, min_level, max_level, f);
1040 return nested_unop_range(
op::X,
op::And, min_level, max_level, f);
1050 SPOT_DEF_UNOP(Closure);
1055 SPOT_DEF_UNOP(NegClosure);
1060 SPOT_DEF_UNOP(NegClosureMarked);
1065 SPOT_DEF_UNOP(first_match);
1099#define SPOT_DEF_BINOP(Name) \
1100 static formula Name(const formula& f, const formula& g) \
1102 return binop(op::Name, f, g); \
1105#define SPOT_DEF_BINOP(Name) \
1106 static formula Name(const formula& f, const formula& g) \
1108 return binop(op::Name, f, g); \
1110 static formula Name(const formula& f, formula&& g) \
1112 return binop(op::Name, f, std::move(g)); \
1114 static formula Name(formula&& f, const formula& g) \
1116 return binop(op::Name, std::move(f), g); \
1118 static formula Name(formula&& f, formula&& g) \
1120 return binop(op::Name, std::move(f), std::move(g)); \
1125 SPOT_DEF_BINOP(Xor);
1130 SPOT_DEF_BINOP(Implies);
1135 SPOT_DEF_BINOP(Equiv);
1160 SPOT_DEF_BINOP(EConcat);
1165 SPOT_DEF_BINOP(EConcatMarked);
1170 SPOT_DEF_BINOP(UConcat);
1172#undef SPOT_DEF_BINOP
1181 std::vector<const fnode*> tmp;
1182 tmp.reserve(l.size());
1185 tmp.emplace_back(f.ptr_->
clone());
1192 std::vector<const fnode*> tmp;
1193 tmp.reserve(l.size());
1203#define SPOT_DEF_MULTOP(Name) \
1204 static formula Name(const std::vector<formula>& l) \
1206 return multop(op::Name, l); \
1209#define SPOT_DEF_MULTOP(Name) \
1210 static formula Name(const std::vector<formula>& l) \
1212 return multop(op::Name, l); \
1215 static formula Name(std::vector<formula>&& l) \
1217 return multop(op::Name, std::move(l)); \
1222 SPOT_DEF_MULTOP(Or);
1227 SPOT_DEF_MULTOP(OrRat);
1232 SPOT_DEF_MULTOP(And);
1237 SPOT_DEF_MULTOP(AndRat);
1242 SPOT_DEF_MULTOP(AndNLM);
1247 SPOT_DEF_MULTOP(Concat);
1252 SPOT_DEF_MULTOP(Fusion);
1254#undef SPOT_DEF_MULTOP
1262 unsigned max = unbounded())
1270 unsigned max = unbounded())
1278#define SPOT_DEF_BUNOP(Name) \
1279 static formula Name(const formula& f, \
1280 unsigned min = 0U, \
1281 unsigned max = unbounded()) \
1283 return bunop(op::Name, f, min, max); \
1286#define SPOT_DEF_BUNOP(Name) \
1287 static formula Name(const formula& f, \
1288 unsigned min = 0U, \
1289 unsigned max = unbounded()) \
1291 return bunop(op::Name, f, min, max); \
1293 static formula Name(formula&& f, \
1294 unsigned min = 0U, \
1295 unsigned max = unbounded()) \
1297 return bunop(op::Name, std::move(f), min, max); \
1302 SPOT_DEF_BUNOP(Star);
1310 SPOT_DEF_BUNOP(FStar);
1312#undef SPOT_DEF_BUNOP
1368 unsigned min,
unsigned max);
1370 unsigned min,
unsigned max);
1394 return ptr_->kind();
1400 return ptr_->kindstr();
1413 return ptr_->is(o1, o2);
1419 return ptr_->is(o1, o2, o3);
1426 return ptr_->is(o1, o2, o3, o4);
1430 bool is(std::initializer_list<op> l)
const
1482 return ptr_->size();
1491 return ptr_->is_leaf();
1511 const fnode*
const* ptr_;
1525 return ptr_ == o.ptr_;
1530 return ptr_ != o.ptr_;
1535 return formula((*ptr_)->clone());
1555 return ptr_->begin();
1567 return formula(ptr_->nth(i)->clone());
1580 return ptr_->is_ff();
1592 return ptr_->is_tt();
1604 return ptr_->is_eword();
1610 return ptr_->is_constant();
1619 return ptr_->is_Kleene_star();
1644 (is(
op::Not) && is_boolean() && is_in_nenoform()));
1652 return ptr_->ap_name();
1659 std::ostream&
dump(std::ostream& os)
const
1661 return ptr_->dump(os);
1671 return formula(ptr_->all_but(i));
1685 return ptr_->boolean_count();
1703 return formula(ptr_->boolean_operands(width));
1706#define SPOT_DEF_PROP(Name) \
1709 return ptr_->Name(); \
1716 SPOT_DEF_PROP(is_boolean);
1718 SPOT_DEF_PROP(is_sugar_free_boolean);
1723 SPOT_DEF_PROP(is_in_nenoform);
1725 SPOT_DEF_PROP(is_syntactic_stutter_invariant);
1727 SPOT_DEF_PROP(is_sugar_free_ltl);
1729 SPOT_DEF_PROP(is_ltl_formula);
1731 SPOT_DEF_PROP(is_psl_formula);
1733 SPOT_DEF_PROP(is_sere_formula);
1736 SPOT_DEF_PROP(is_finite);
1744 SPOT_DEF_PROP(is_eventual);
1756 SPOT_DEF_PROP(is_syntactic_safety);
1760 SPOT_DEF_PROP(is_syntactic_guarantee);
1765 SPOT_DEF_PROP(is_delta1);
1770 SPOT_DEF_PROP(is_syntactic_obligation);
1772 SPOT_DEF_PROP(is_sigma2);
1774 SPOT_DEF_PROP(is_pi2);
1779 SPOT_DEF_PROP(is_syntactic_recurrence);
1784 SPOT_DEF_PROP(is_syntactic_persistence);
1789 SPOT_DEF_PROP(is_delta2);
1792 SPOT_DEF_PROP(is_marked);
1794 SPOT_DEF_PROP(accepts_eword);
1800 SPOT_DEF_PROP(has_lbt_atomic_props);
1809 SPOT_DEF_PROP(has_spin_atomic_props);
1815 template<
typename Trans,
typename... Args>
1818 switch (
op o = kind())
1827#if SPOT_HAS_STRONG_X
1836 return unop(o, trans((*
this)[0], std::forward<Args>(args)...));
1848 formula tmp = trans((*
this)[0], std::forward<Args>(args)...);
1849 return binop(o, tmp,
1850 trans((*
this)[1], std::forward<Args>(args)...));
1860 std::vector<formula> tmp;
1861 tmp.reserve(size());
1863 tmp.emplace_back(trans(f, std::forward<Args>(args)...));
1864 return multop(o, std::move(tmp));
1868 return bunop(o, trans((*
this)[0], std::forward<Args>(args)...),
1882 template<
typename Func,
typename... Args>
1885 if (func(*
this, std::forward<Args>(args)...))
1888 f.
traverse(func, std::forward<Args>(args)...);
1893 [[noreturn]]
static void report_ap_invalid_arg();
1900 bool abbreviated =
false);
1908 std::ostream& operator<<(std::ostream& os,
const formula& f);
Actual storage for formula nodes.
Definition: formula.hh:153
bool is_pi2() const
Definition: formula.hh:558
std::string kindstr() const
const fnode * boolean_operands(unsigned *width=nullptr) const
bool is_boolean() const
Definition: formula.hh:432
size_t id() const
Definition: formula.hh:300
bool is_ff() const
Definition: formula.hh:334
bool is_sugar_free_boolean() const
Definition: formula.hh:438
bool is_Kleene_star() const
Definition: formula.hh:370
static const fnode * nested_unop_range(op uo, op bo, unsigned min, unsigned max, const fnode *f)
const fnode *const * end() const
Definition: formula.hh:312
unsigned min() const
Definition: formula.hh:272
bool is_syntactic_safety() const
Definition: formula.hh:498
bool is_syntactic_stutter_invariant() const
Definition: formula.hh:450
static const fnode * binop(op o, const fnode *f, const fnode *g)
bool is_delta2() const
Definition: formula.hh:570
unsigned size() const
Definition: formula.hh:288
static constexpr uint8_t unbounded()
Definition: formula.hh:183
const fnode * get_child_of(std::initializer_list< op > l) const
Definition: formula.hh:259
unsigned max() const
Definition: formula.hh:280
const fnode * get_child_of(op o) const
Definition: formula.hh:249
const fnode * all_but(unsigned i) const
bool accepts_eword() const
Definition: formula.hh:534
bool is_eventual() const
Definition: formula.hh:486
bool is(op o1, op o2, op o3, op o4) const
Definition: formula.hh:230
static bool instances_check()
safety check for the reference counters
bool is_leaf() const
Definition: formula.hh:294
bool has_spin_atomic_props() const
Definition: formula.hh:546
bool is_eword() const
Definition: formula.hh:358
bool is(op o1, op o2, op o3) const
Definition: formula.hh:225
op kind() const
Definition: formula.hh:205
const fnode * clone() const
Clone an fnode.
Definition: formula.hh:159
bool has_lbt_atomic_props() const
Definition: formula.hh:540
bool is_sugar_free_ltl() const
Definition: formula.hh:456
const std::string & ap_name() const
bool is_syntactic_persistence() const
Definition: formula.hh:522
unsigned boolean_count() const
Definition: formula.hh:403
static const fnode * tt()
Definition: formula.hh:340
bool is_universal() const
Definition: formula.hh:492
bool is_tt() const
Definition: formula.hh:346
bool is_constant() const
Definition: formula.hh:364
bool is_syntactic_recurrence() const
Definition: formula.hh:516
bool is(std::initializer_list< op > l) const
Definition: formula.hh:235
bool is_syntactic_obligation() const
Definition: formula.hh:510
static const fnode * unop(op o, const fnode *f)
const fnode * nth(unsigned i) const
Definition: formula.hh:318
bool is_ltl_formula() const
Definition: formula.hh:462
static const fnode * ff()
Definition: formula.hh:328
bool is_finite() const
Definition: formula.hh:480
bool is_sigma2() const
Definition: formula.hh:552
bool is_psl_formula() const
Definition: formula.hh:468
bool is_delta1() const
Definition: formula.hh:564
static const fnode * eword()
Definition: formula.hh:352
bool is_marked() const
Definition: formula.hh:528
std::ostream & dump(std::ostream &os) const
void destroy() const
Dereference an fnode.
Definition: formula.hh:173
static const fnode * one_plus()
Definition: formula.hh:386
static const fnode * ap(const std::string &name)
bool is(op o1, op o2) const
Definition: formula.hh:220
bool is_in_nenoform() const
Definition: formula.hh:444
static const fnode * bunop(op o, const fnode *f, unsigned min, unsigned max=unbounded())
bool is_syntactic_guarantee() const
Definition: formula.hh:504
static const fnode * multop(op o, std::vector< const fnode * > l)
bool is_sere_formula() const
Definition: formula.hh:474
static const fnode * one_star()
Definition: formula.hh:378
const fnode *const * begin() const
Definition: formula.hh:306
bool is(op o) const
Definition: formula.hh:215
op
Operator types.
Definition: formula.hh:77
@ first_match
first_match(sere)
@ EConcatMarked
Seq, Marked.
@ NegClosure
Negated PSL Closure.
@ M
strong release (dual of weak until)
@ NegClosureMarked
marked version of the Negated PSL Closure
@ And
(omega-Rational) And
@ AndNLM
Non-Length-Matching Rational-And.
@ R
release (dual of until)
bool is_universal(const const_twa_graph_ptr &aut)
Return true iff aut is universal.
Definition: automata.hh:26
int atomic_prop_cmp(const fnode *f, const fnode *g)
Order two atomic propositions.
std::list< std::string > list_formula_props(const formula &f)
List the properties of formula f.
std::ostream & print_formula_props(std::ostream &out, const formula &f, bool abbreviated=false)
Print the properties of formula f on stream out.