45#include <spot/misc/common.hh>
48#include <initializer_list>
62#if defined(SPOT_BUILD) || defined(SPOT_USES_STRONG_X)
65# define SPOT_HAS_STRONG_X 1
68# define SPOT_WANT_STRONG_X 1
77 enum class op: uint8_t
114#ifdef SPOT_WANT_STRONG_X
137 if (SPOT_UNLIKELY(!refs_))
149 if (SPOT_LIKELY(refs_))
151 else if (SPOT_LIKELY(!saturated_))
163 static const fnode*
ap(
const std::string& name);
172 unsigned min,
unsigned max = unbounded());
176 unsigned max,
const fnode* f);
196 return op_ == o1 || op_ == o2;
201 return op_ == o1 || op_ == o2 || op_ == o3;
206 return op_ == o1 || op_ == o2 || op_ == o3 || op_ == o4;
209 bool is(std::initializer_list<op> l)
const
211 const fnode* n =
this;
227 if (SPOT_UNLIKELY(size_ != 1))
228 report_get_child_of_expecting_single_child_node();
249 report_min_invalid_arg();
257 report_max_invalid_arg();
288 return children + size();
294 if (SPOT_UNLIKELY(i >= size()))
295 report_non_existing_child();
296 const fnode* c = children[i];
297 SPOT_ASSUME(c !=
nullptr);
348 return min_ == 0 && max_ == unbounded();
371 std::ostream&
dump(std::ostream& os)
const;
381 while (pos < s && children[pos]->is_boolean())
414 return is_.sugar_free_boolean;
420 return is_.in_nenoform;
426 return is_.syntactic_si;
432 return is_.sugar_free_ltl;
438 return is_.ltl_formula;
444 return is_.psl_formula;
450 return is_.sere_formula;
468 return is_.universal;
474 return is_.syntactic_safety;
480 return is_.syntactic_guarantee;
486 return is_.syntactic_obligation;
492 return is_.syntactic_recurrence;
498 return is_.syntactic_persistence;
504 return !is_.not_marked;
510 return is_.accepting_eword;
516 return is_.lbt_atomic_props;
522 return is_.spin_atomic_props;
526 static size_t bump_next_id();
527 void setup_props(
op o);
528 void destroy_aux()
const;
530 [[noreturn]]
static void report_non_existing_child();
531 [[noreturn]]
static void report_too_many_children();
532 [[noreturn]]
static void
533 report_get_child_of_expecting_single_child_node();
534 [[noreturn]]
static void report_min_invalid_arg();
535 [[noreturn]]
static void report_max_invalid_arg();
548 fnode(
op o, iter begin, iter end,
bool saturated =
false)
563 saturated_(saturated)
565 size_t s = std::distance(begin, end);
566 if (SPOT_UNLIKELY(s > (
size_t) UINT16_MAX))
567 report_too_many_children();
570 for (
auto i = begin; i != end; ++i)
575 fnode(
op o, std::initializer_list<const fnode*> l,
576 bool saturated =
false)
577 : fnode(o, l.begin(), l.end(), saturated)
581 fnode(
op o,
const fnode* f, uint8_t min, uint8_t max,
582 bool saturated =
false)
583 : op_(o), min_(min), max_(max), saturated_(saturated), size_(1)
589 static const fnode* ff_;
590 static const fnode* tt_;
591 static const fnode* ew_;
592 static const fnode* one_star_;
593 static const fnode* one_plus_;
598 mutable uint8_t saturated_;
600 mutable uint16_t refs_ = 0;
602 static size_t next_id_;
620 bool sugar_free_boolean:1;
623 bool sugar_free_ltl:1;
630 bool syntactic_safety:1;
631 bool syntactic_guarantee:1;
632 bool syntactic_obligation:1;
633 bool syntactic_recurrence:1;
634 bool syntactic_persistence:1;
636 bool accepting_eword:1;
637 bool lbt_atomic_props:1;
638 bool spin_atomic_props:1;
647 const fnode* children[1];
659 operator()(
const fnode* left,
const fnode* right)
const
679 auto get_literal = [](
const fnode* f) ->
const fnode*
688 const fnode* litl = get_literal(left);
689 const fnode* litr = get_literal(right);
702 size_t l = left->
id();
703 size_t r = right->
id();
716 std::ostringstream old;
718 std::ostringstream ord;
720 return old.str() < ord.str();
805 const formula& operator=(formula&& f)
noexcept
807 std::swap(f.ptr_, ptr_);
811 bool operator<(
const formula& other)
const noexcept
813 if (SPOT_UNLIKELY(!other.ptr_))
815 if (SPOT_UNLIKELY(!ptr_))
817 if (
id() < other.id())
819 if (
id() > other.id())
825 return ptr_ < other.ptr_;
828 bool operator<=(
const formula& other)
const noexcept
830 return *
this == other || *
this < other;
833 bool operator>(
const formula& other)
const noexcept
835 return !(*
this <= other);
838 bool operator>=(
const formula& other)
const noexcept
840 return !(*
this < other);
843 bool operator==(
const formula& other)
const noexcept
845 return other.ptr_ == ptr_;
848 bool operator==(std::nullptr_t)
const noexcept
850 return ptr_ ==
nullptr;
853 bool operator!=(
const formula& other)
const noexcept
855 return other.ptr_ != ptr_;
858 bool operator!=(std::nullptr_t)
const noexcept
860 return ptr_ !=
nullptr;
863 explicit operator bool() const noexcept
865 return ptr_ !=
nullptr;
892 report_ap_invalid_arg();
914#define SPOT_DEF_UNOP(Name) \
915 static formula Name(const formula& f) \
917 return unop(op::Name, f); \
920#define SPOT_DEF_UNOP(Name) \
921 static formula Name(const formula& f) \
923 return unop(op::Name, f); \
925 static formula Name(formula&& f) \
927 return unop(op::Name, std::move(f)); \
945 return nested_unop_range(
op::X,
op::Or , level, level, f);
948#if SPOT_WANT_STRONG_X
951 SPOT_DEF_UNOP(strong_X);
959 return nested_unop_range(op::strong_X,
op::Or ,
977 return nested_unop_range(
op::X,
op::Or, min_level, max_level, f);
988 return nested_unop_range(
op::X,
op::And, min_level, max_level, f);
998 SPOT_DEF_UNOP(Closure);
1003 SPOT_DEF_UNOP(NegClosure);
1008 SPOT_DEF_UNOP(NegClosureMarked);
1013 SPOT_DEF_UNOP(first_match);
1047#define SPOT_DEF_BINOP(Name) \
1048 static formula Name(const formula& f, const formula& g) \
1050 return binop(op::Name, f, g); \
1053#define SPOT_DEF_BINOP(Name) \
1054 static formula Name(const formula& f, const formula& g) \
1056 return binop(op::Name, f, g); \
1058 static formula Name(const formula& f, formula&& g) \
1060 return binop(op::Name, f, std::move(g)); \
1062 static formula Name(formula&& f, const formula& g) \
1064 return binop(op::Name, std::move(f), g); \
1066 static formula Name(formula&& f, formula&& g) \
1068 return binop(op::Name, std::move(f), std::move(g)); \
1073 SPOT_DEF_BINOP(Xor);
1078 SPOT_DEF_BINOP(Implies);
1083 SPOT_DEF_BINOP(Equiv);
1108 SPOT_DEF_BINOP(EConcat);
1113 SPOT_DEF_BINOP(EConcatMarked);
1118 SPOT_DEF_BINOP(UConcat);
1120#undef SPOT_DEF_BINOP
1129 std::vector<const fnode*> tmp;
1130 tmp.reserve(l.size());
1133 tmp.emplace_back(f.ptr_->
clone());
1140 std::vector<const fnode*> tmp;
1141 tmp.reserve(l.size());
1151#define SPOT_DEF_MULTOP(Name) \
1152 static formula Name(const std::vector<formula>& l) \
1154 return multop(op::Name, l); \
1157#define SPOT_DEF_MULTOP(Name) \
1158 static formula Name(const std::vector<formula>& l) \
1160 return multop(op::Name, l); \
1163 static formula Name(std::vector<formula>&& l) \
1165 return multop(op::Name, std::move(l)); \
1170 SPOT_DEF_MULTOP(Or);
1175 SPOT_DEF_MULTOP(OrRat);
1180 SPOT_DEF_MULTOP(And);
1185 SPOT_DEF_MULTOP(AndRat);
1190 SPOT_DEF_MULTOP(AndNLM);
1195 SPOT_DEF_MULTOP(Concat);
1200 SPOT_DEF_MULTOP(Fusion);
1202#undef SPOT_DEF_MULTOP
1210 unsigned max = unbounded())
1218 unsigned max = unbounded())
1226#define SPOT_DEF_BUNOP(Name) \
1227 static formula Name(const formula& f, \
1228 unsigned min = 0U, \
1229 unsigned max = unbounded()) \
1231 return bunop(op::Name, f, min, max); \
1234#define SPOT_DEF_BUNOP(Name) \
1235 static formula Name(const formula& f, \
1236 unsigned min = 0U, \
1237 unsigned max = unbounded()) \
1239 return bunop(op::Name, f, min, max); \
1241 static formula Name(formula&& f, \
1242 unsigned min = 0U, \
1243 unsigned max = unbounded()) \
1245 return bunop(op::Name, std::move(f), min, max); \
1250 SPOT_DEF_BUNOP(Star);
1258 SPOT_DEF_BUNOP(FStar);
1260#undef SPOT_DEF_BUNOP
1316 unsigned min,
unsigned max);
1318 unsigned min,
unsigned max);
1342 return ptr_->kind();
1348 return ptr_->kindstr();
1361 return ptr_->is(o1, o2);
1367 return ptr_->is(o1, o2, o3);
1374 return ptr_->is(o1, o2, o3, o4);
1378 bool is(std::initializer_list<op> l)
const
1430 return ptr_->size();
1439 return ptr_->is_leaf();
1459 const fnode*
const* ptr_;
1473 return ptr_ == o.ptr_;
1478 return ptr_ != o.ptr_;
1483 return formula((*ptr_)->clone());
1503 return ptr_->begin();
1515 return formula(ptr_->nth(i)->clone());
1528 return ptr_->is_ff();
1540 return ptr_->is_tt();
1552 return ptr_->is_eword();
1558 return ptr_->is_constant();
1567 return ptr_->is_Kleene_star();
1592 (is(
op::Not) && is_boolean() && is_in_nenoform()));
1600 return ptr_->ap_name();
1607 std::ostream&
dump(std::ostream& os)
const
1609 return ptr_->dump(os);
1619 return formula(ptr_->all_but(i));
1633 return ptr_->boolean_count();
1651 return formula(ptr_->boolean_operands(width));
1654#define SPOT_DEF_PROP(Name) \
1657 return ptr_->Name(); \
1664 SPOT_DEF_PROP(is_boolean);
1666 SPOT_DEF_PROP(is_sugar_free_boolean);
1671 SPOT_DEF_PROP(is_in_nenoform);
1673 SPOT_DEF_PROP(is_syntactic_stutter_invariant);
1675 SPOT_DEF_PROP(is_sugar_free_ltl);
1677 SPOT_DEF_PROP(is_ltl_formula);
1679 SPOT_DEF_PROP(is_psl_formula);
1681 SPOT_DEF_PROP(is_sere_formula);
1684 SPOT_DEF_PROP(is_finite);
1692 SPOT_DEF_PROP(is_eventual);
1702 SPOT_DEF_PROP(is_syntactic_safety);
1704 SPOT_DEF_PROP(is_syntactic_guarantee);
1706 SPOT_DEF_PROP(is_syntactic_obligation);
1708 SPOT_DEF_PROP(is_syntactic_recurrence);
1710 SPOT_DEF_PROP(is_syntactic_persistence);
1713 SPOT_DEF_PROP(is_marked);
1715 SPOT_DEF_PROP(accepts_eword);
1721 SPOT_DEF_PROP(has_lbt_atomic_props);
1730 SPOT_DEF_PROP(has_spin_atomic_props);
1736 template<
typename Trans,
typename... Args>
1739 switch (
op o = kind())
1748#if SPOT_HAS_STRONG_X
1757 return unop(o, trans((*
this)[0], std::forward<Args>(args)...));
1769 formula tmp = trans((*
this)[0], std::forward<Args>(args)...);
1770 return binop(o, tmp,
1771 trans((*
this)[1], std::forward<Args>(args)...));
1781 std::vector<formula> tmp;
1782 tmp.reserve(size());
1784 tmp.emplace_back(trans(f, std::forward<Args>(args)...));
1785 return multop(o, std::move(tmp));
1789 return bunop(o, trans((*
this)[0], std::forward<Args>(args)...),
1803 template<
typename Func,
typename... Args>
1806 if (func(*
this, std::forward<Args>(args)...))
1809 f.
traverse(func, std::forward<Args>(args)...);
1814 [[noreturn]]
static void report_ap_invalid_arg();
1821 bool abbreviated =
false);
1829 std::ostream& operator<<(std::ostream& os,
const formula& f);
Actual storage for formula nodes.
Definition: formula.hh:127
std::string kindstr() const
const fnode * boolean_operands(unsigned *width=nullptr) const
bool is_boolean() const
Definition: formula.hh:406
size_t id() const
Definition: formula.hh:274
bool is_ff() const
Definition: formula.hh:308
bool is_sugar_free_boolean() const
Definition: formula.hh:412
bool is_Kleene_star() const
Definition: formula.hh:344
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:286
unsigned min() const
Definition: formula.hh:246
bool is_syntactic_safety() const
Definition: formula.hh:472
bool is_syntactic_stutter_invariant() const
Definition: formula.hh:424
static const fnode * binop(op o, const fnode *f, const fnode *g)
unsigned size() const
Definition: formula.hh:262
static constexpr uint8_t unbounded()
Definition: formula.hh:157
const fnode * get_child_of(std::initializer_list< op > l) const
Definition: formula.hh:233
unsigned max() const
Definition: formula.hh:254
const fnode * get_child_of(op o) const
Definition: formula.hh:223
const fnode * all_but(unsigned i) const
bool accepts_eword() const
Definition: formula.hh:508
bool is_eventual() const
Definition: formula.hh:460
bool is(op o1, op o2, op o3, op o4) const
Definition: formula.hh:204
static bool instances_check()
safety check for the reference counters
bool is_leaf() const
Definition: formula.hh:268
bool has_spin_atomic_props() const
Definition: formula.hh:520
bool is_eword() const
Definition: formula.hh:332
bool is(op o1, op o2, op o3) const
Definition: formula.hh:199
op kind() const
Definition: formula.hh:179
const fnode * clone() const
Clone an fnode.
Definition: formula.hh:133
bool has_lbt_atomic_props() const
Definition: formula.hh:514
bool is_sugar_free_ltl() const
Definition: formula.hh:430
const std::string & ap_name() const
bool is_syntactic_persistence() const
Definition: formula.hh:496
unsigned boolean_count() const
Definition: formula.hh:377
static const fnode * tt()
Definition: formula.hh:314
bool is_universal() const
Definition: formula.hh:466
bool is_tt() const
Definition: formula.hh:320
bool is_constant() const
Definition: formula.hh:338
bool is_syntactic_recurrence() const
Definition: formula.hh:490
bool is(std::initializer_list< op > l) const
Definition: formula.hh:209
bool is_syntactic_obligation() const
Definition: formula.hh:484
static const fnode * unop(op o, const fnode *f)
const fnode * nth(unsigned i) const
Definition: formula.hh:292
bool is_ltl_formula() const
Definition: formula.hh:436
static const fnode * ff()
Definition: formula.hh:302
bool is_finite() const
Definition: formula.hh:454
bool is_psl_formula() const
Definition: formula.hh:442
static const fnode * eword()
Definition: formula.hh:326
bool is_marked() const
Definition: formula.hh:502
std::ostream & dump(std::ostream &os) const
void destroy() const
Dereference an fnode.
Definition: formula.hh:147
static const fnode * one_plus()
Definition: formula.hh:360
static const fnode * ap(const std::string &name)
bool is(op o1, op o2) const
Definition: formula.hh:194
bool is_in_nenoform() const
Definition: formula.hh:418
static const fnode * bunop(op o, const fnode *f, unsigned min, unsigned max=unbounded())
bool is_syntactic_guarantee() const
Definition: formula.hh:478
static const fnode * multop(op o, std::vector< const fnode * > l)
bool is_sere_formula() const
Definition: formula.hh:448
static const fnode * one_star()
Definition: formula.hh:352
const fnode *const * begin() const
Definition: formula.hh:280
bool is(op o) const
Definition: formula.hh:189
op
Operator types.
Definition: formula.hh:78
@ 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.