spot  2.14.5
formula.hh
Go to the documentation of this file.
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 
21 #pragma once
22 
29 
32 
35 
38 
41 
44 
45 #include <spot/misc/common.hh>
46 #include <memory>
47 #include <cstdint>
48 #include <initializer_list>
49 #include <cassert>
50 #include <vector>
51 #include <string>
52 #include <iterator>
53 #include <iosfwd>
54 #include <sstream>
55 #include <list>
56 #include <cstddef>
57 #include <limits>
58 
59 // strong_X was conditionally defined starting with version 2.9.
60 // You had to "#define SPOT_USES_STRONG_X 1" before including this
61 // file to get the definition. Since Spot 2.13, it is always defined,
62 // so users may have to update their code. The following macro
63 // is only defined when strong_X exists.
64 # define SPOT_HAS_STRONG_X 1
65 // This was defined since 2.9 along with SPOT_HAS_STRONG_X when
66 // SPOT_USES_STRONG_X was defined so we are keeping it just in case
67 // someone depends on it.
68 # define SPOT_WANT_STRONG_X 1
69 
70 namespace spot
71 {
72 
73 
76  enum class op: uint8_t
77  {
78  ff,
79  tt,
80  eword,
81  ap,
82  // unary operators
83  Not,
84  X,
85  F,
86  G,
87  Closure,
88  NegClosure,
90  // binary operators
91  Xor,
92  Implies,
93  Equiv,
94  U,
95  R,
96  W,
97  M,
98  EConcat,
100  UConcat,
101  // n-ary operators
102  Or,
103  OrRat,
104  And,
105  AndRat,
106  AndNLM,
107  Concat,
108  Fusion,
109  // star-like operators
110  Star,
111  FStar,
112  first_match,
113  // strong_X was introduced in Spot 2.9, but was hidden from the
114  // public API by default in order not to break existing code.
115  //
116  // Starting with Spot 2.13, strong_X will be part of the public
117  // API by default. If you have a switch case listing all possible
118  // operators, strong_X needs to be part of it. If you have code
119  // using Spot but that you also want to support versions older
120  // than 2.13, there are two ways to do that
121  //
122  // Option 1: define SPOT_USES_STRONG_X before including this file.
123  //
124  // #define SPOT_USES_STRONG_X 1
125  // #include <spot/tl/formula.hh>
126  //
127  // This will force any version of Spot since 2.9 to define
128  // strong_X. It won't work with older Spot versions, where
129  // strong_X did not exist.
130  //
131  // Option 2: make any code using strong_X conditional on
132  // SPOT_HAS_STRONG_X. Typically, a switch over all possible
133  // operators would include something like this:
134  //
135  // #if SPOT_HAS_STRONG_X
136  // case op::strong_X:
137  // /* do something */
138  // #endif
139  //
140  // The two options are not mutually exclusive. Using both allows
141  // you to use strong_X whenever it exists.
142  strong_X,
143  };
144 
145 #ifndef SWIG
152  class SPOT_API fnode final
153  {
154  public:
159  const fnode* clone() const
160  {
161  // Saturate.
162  ++refs_;
163  if (SPOT_UNLIKELY(!refs_))
164  saturated_ = 1;
165  return this;
166  }
167 
173  void destroy() const
174  {
175  if (SPOT_LIKELY(refs_))
176  --refs_;
177  else if (SPOT_LIKELY(!saturated_))
178  // last reference to a node that is not a constant
179  destroy_aux();
180  }
181 
183  static constexpr uint8_t unbounded()
184  {
185  return UINT8_MAX;
186  }
187 
189  static const fnode* ap(const std::string& name);
191  static const fnode* unop(op o, const fnode* f);
193  static const fnode* binop(op o, const fnode* f, const fnode* g);
195  static const fnode* multop(op o, std::vector<const fnode*> l);
197  static const fnode* bunop(op o, const fnode* f,
198  unsigned min, unsigned max = unbounded());
199 
201  static const fnode* nested_unop_range(op uo, op bo, unsigned min,
202  unsigned max, const fnode* f);
203 
205  op kind() const
206  {
207  return op_;
208  }
209 
211  std::string kindstr() const;
212 
215  bool is(op o) const
216  {
217  return op_ == o;
218  }
219 
220  bool is(op o1, op o2) const
221  {
222  return op_ == o1 || op_ == o2;
223  }
224 
225  bool is(op o1, op o2, op o3) const
226  {
227  return op_ == o1 || op_ == o2 || op_ == o3;
228  }
229 
230  bool is(op o1, op o2, op o3, op o4) const
231  {
232  return op_ == o1 || op_ == o2 || op_ == o3 || op_ == o4;
233  }
234 
235  bool is(std::initializer_list<op> l) const
236  {
237  const fnode* n = this;
238  for (auto o: l)
239  {
240  if (!n->is(o))
241  return false;
242  n = n->nth(0);
243  }
244  return true;
245  }
247 
249  const fnode* get_child_of(op o) const
250  {
251  if (op_ != o)
252  return nullptr;
253  if (SPOT_UNLIKELY(size_ != 1))
254  report_get_child_of_expecting_single_child_node();
255  return nth(0);
256  }
257 
259  const fnode* get_child_of(std::initializer_list<op> l) const
260  {
261  auto c = this;
262  for (auto o: l)
263  {
264  c = c->get_child_of(o);
265  if (c == nullptr)
266  return c;
267  }
268  return c;
269  }
270 
272  unsigned min() const
273  {
274  if (SPOT_UNLIKELY(op_ != op::FStar && op_ != op::Star))
275  report_min_invalid_arg();
276  return min_;
277  }
278 
280  unsigned max() const
281  {
282  if (SPOT_UNLIKELY(op_ != op::FStar && op_ != op::Star))
283  report_max_invalid_arg();
284  return max_;
285  }
286 
288  unsigned size() const
289  {
290  return size_;
291  }
292 
294  bool is_leaf() const
295  {
296  return size_ == 0;
297  }
298 
300  size_t id() const
301  {
302  return id_;
303  }
304 
306  const fnode*const* begin() const
307  {
308  return children;
309  }
310 
312  const fnode*const* end() const
313  {
314  return children + size();
315  }
316 
318  const fnode* nth(unsigned i) const
319  {
320  if (SPOT_UNLIKELY(i >= size()))
321  report_non_existing_child();
322  const fnode* c = children[i];
323  SPOT_ASSUME(c != nullptr);
324  return c;
325  }
326 
328  static const fnode* ff()
329  {
330  return ff_;
331  }
332 
334  bool is_ff() const
335  {
336  return op_ == op::ff;
337  }
338 
340  static const fnode* tt()
341  {
342  return tt_;
343  }
344 
346  bool is_tt() const
347  {
348  return op_ == op::tt;
349  }
350 
352  static const fnode* eword()
353  {
354  return ew_;
355  }
356 
358  bool is_eword() const
359  {
360  return op_ == op::eword;
361  }
362 
364  bool is_constant() const
365  {
366  return op_ == op::ff || op_ == op::tt || op_ == op::eword;
367  }
368 
370  bool is_Kleene_star() const
371  {
372  if (op_ != op::Star)
373  return false;
374  return min_ == 0 && max_ == unbounded();
375  }
376 
378  static const fnode* one_star()
379  {
380  if (!one_star_)
381  one_star_ = new fnode(op::Star, tt_, 0, unbounded(), true);
382  return one_star_;
383  }
384 
386  static const fnode* one_plus()
387  {
388  if (!one_plus_)
389  one_plus_ = new fnode(op::Star, tt_, 1, unbounded(), true);
390  return one_plus_;
391  }
392 
394  const std::string& ap_name() const;
395 
397  std::ostream& dump(std::ostream& os) const;
398 
400  const fnode* all_but(unsigned i) const;
401 
403  unsigned boolean_count() const
404  {
405  unsigned pos = 0;
406  unsigned s = size();
407  while (pos < s && children[pos]->is_boolean())
408  ++pos;
409  return pos;
410  }
411 
413  const fnode* boolean_operands(unsigned* width = nullptr) const;
414 
425  static bool instances_check();
426 
428  // Properties //
430 
432  bool is_boolean() const
433  {
434  return is_.boolean;
435  }
436 
439  {
440  return is_.sugar_free_boolean;
441  }
442 
444  bool is_in_nenoform() const
445  {
446  return is_.in_nenoform;
447  }
448 
451  {
452  return is_.syntactic_si;
453  }
454 
456  bool is_sugar_free_ltl() const
457  {
458  return is_.sugar_free_ltl;
459  }
460 
462  bool is_ltl_formula() const
463  {
464  return is_.ltl_formula;
465  }
466 
468  bool is_psl_formula() const
469  {
470  return is_.psl_formula;
471  }
472 
474  bool is_sere_formula() const
475  {
476  return is_.sere_formula;
477  }
478 
480  bool is_finite() const
481  {
482  return is_.finite;
483  }
484 
486  bool is_eventual() const
487  {
488  return is_.eventual;
489  }
490 
492  bool is_universal() const
493  {
494  return is_.universal;
495  }
496 
498  bool is_syntactic_safety() const
499  {
500  return is_.syntactic_safety;
501  }
502 
505  {
506  return is_.syntactic_guarantee;
507  }
508 
511  {
512  return is_.syntactic_obligation;
513  }
514 
517  {
518  return is_.syntactic_recurrence;
519  }
520 
523  {
524  return is_.syntactic_persistence;
525  }
526 
528  bool is_marked() const
529  {
530  return !is_.not_marked;
531  }
532 
534  bool accepts_eword() const
535  {
536  return is_.accepting_eword;
537  }
538 
540  bool has_lbt_atomic_props() const
541  {
542  return is_.lbt_atomic_props;
543  }
544 
547  {
548  return is_.spin_atomic_props;
549  }
550 
552  bool is_sigma2() const
553  {
554  return is_.sigma2;
555  }
556 
558  bool is_pi2() const
559  {
560  return is_.pi2;
561  }
562 
564  bool is_delta1() const
565  {
566  return is_.delta1;
567  }
568 
570  bool is_delta2() const
571  {
572  return is_.delta2;
573  }
574 
575  private:
576  static size_t bump_next_id();
577  void setup_props(op o);
578  void destroy_aux() const;
579 
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();
586 
587  static const fnode* unique(fnode*);
588 
589  // Destruction may only happen via destroy().
590  ~fnode() = default;
591  // Disallow copies.
592  fnode(const fnode&) = delete;
593  fnode& operator=(const fnode&) = delete;
594 
595 
596 
597  template<class iter>
598  fnode(op o, iter begin, iter end, bool saturated = false)
599  // Clang has some optimization where is it able to combine the
600  // 4 movb initializing op_,min_,max_,saturated_ into a single
601  // movl. Also it can optimize the three byte-comparisons of
602  // is_Kleene_star() into a single masked 32-bit comparison.
603  // The latter optimization triggers warnings from valgrind if
604  // min_ and max_ are not initialized. So to benefit from the
605  // initialization optimization and the is_Kleene_star()
606  // optimization in Clang, we always initialize min_ and max_
607  // with this compiler. Do not do it the rest of the time,
608  // since the optimization is not done.
609  : op_(o),
610 #if __llvm__
611  min_(0), max_(0),
612 #endif
613  saturated_(saturated)
614  {
615  size_t s = std::distance(begin, end);
616  if (SPOT_UNLIKELY(s > (size_t) UINT16_MAX))
617  report_too_many_children();
618  size_ = s;
619  auto pos = children;
620  for (auto i = begin; i != end; ++i)
621  *pos++ = *i;
622  setup_props(o);
623  }
624 
625  fnode(op o, std::initializer_list<const fnode*> l,
626  bool saturated = false)
627  : fnode(o, l.begin(), l.end(), saturated)
628  {
629  }
630 
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)
634  {
635  children[0] = f;
636  setup_props(o);
637  }
638 
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_;
644 
645  op op_; // operator
646  uint8_t min_; // range minimum (for star-like operators)
647  uint8_t max_; // range maximum;
648  mutable uint8_t saturated_;
649  uint16_t size_; // number of children
650  mutable uint16_t refs_ = 0; // reference count - 1;
651  size_t id_; // Also used as hash.
652  static size_t next_id_;
653 
654  struct ltl_prop
655  {
656  // All properties here should be expressed in such a way
657  // that property(f && g) is just property(f)&property(g).
658  // This allows us to compute all properties of a compound
659  // formula in one operation.
660  //
661  // For instance we do not use a property that says "has
662  // temporal operator", because it would require an OR between
663  // the two arguments. Instead we have a property that
664  // says "no temporal operator", and that one is computed
665  // with an AND between the arguments.
666  //
667  // Also choose a name that makes sense when prefixed with
668  // "the formula is".
669  bool boolean:1; // No temporal operators.
670  bool sugar_free_boolean:1; // Only AND, OR, and NOT operators.
671  bool in_nenoform:1; // Negative Normal Form.
672  bool syntactic_si:1; // LTL-X or siPSL
673  bool sugar_free_ltl:1; // No F and G operators.
674  bool ltl_formula:1; // Only LTL operators.
675  bool psl_formula:1; // Only PSL operators.
676  bool sere_formula:1; // Only SERE operators.
677  bool finite:1; // Finite SERE formulae, or Bool+X forms.
678  bool eventual:1; // Purely eventual formula.
679  bool universal:1; // Purely universal formula.
680  bool syntactic_safety:1; // Syntactic Safety Property (S).
681  bool syntactic_guarantee:1; // Syntactic Guarantee Property (G).
682  bool syntactic_obligation:1; // Syntactic Obligation Property (O).
683  bool syntactic_recurrence:1; // Syntactic Recurrence Property (R).
684  bool syntactic_persistence:1; // Syntactic Persistence Property (P).
685  bool not_marked:1; // No occurrence of EConcatMarked.
686  bool accepting_eword:1; // Accepts the empty word.
687  bool lbt_atomic_props:1; // Use only atomic propositions like p42.
688  bool spin_atomic_props:1; // Use only spin-compatible atomic props.
689  bool delta1:1; // Boolean combination of (S) and (G).
690  bool sigma2:1; // Boolean comb. of (S) with X/F/U/M possibly applied.
691  bool pi2:1; // Boolean comb. of (G) with X/G/R/W possibly applied.
692  bool delta2:1; // Boolean combination of (Σ₂) and (Π₂).
693  };
694  union
695  {
696  // Use an unsigned for fast computation of all properties.
697  unsigned props;
698  ltl_prop is_;
699  };
700 
701  const fnode* children[1];
702  };
703 
705  SPOT_API
706  int atomic_prop_cmp(const fnode* f, const fnode* g);
707 
708  class SPOT_API formula;
709 
711  {
712  bool
713  operator()(const fnode* left, const fnode* right) const
714  {
715  SPOT_ASSERT(left);
716  SPOT_ASSERT(right);
717  if (left == right)
718  return false;
719 
720  // We want Boolean formulae first.
721  bool lib = left->is_boolean();
722  if (lib != right->is_boolean())
723  return lib;
724 
725  // We have two Boolean formulae
726  if (lib)
727  {
728  bool lconst = left->is_constant();
729  if (lconst != right->is_constant())
730  return lconst;
731  if (!lconst)
732  {
733  auto get_literal = [](const fnode* f) -> const fnode*
734  {
735  if (f->is(op::Not))
736  f = f->nth(0);
737  if (f->is(op::ap))
738  return f;
739  return nullptr;
740  };
741  // Literals should come first
742  const fnode* litl = get_literal(left);
743  const fnode* litr = get_literal(right);
744  if (!litl != !litr)
745  return litl;
746  if (litl)
747  {
748  // And they should be sorted alphabetically
749  int cmp = atomic_prop_cmp(litl, litr);
750  if (cmp)
751  return cmp < 0;
752  }
753  }
754  }
755 
756  size_t l = left->id();
757  size_t r = right->id();
758  if (l != r)
759  return l < r;
760  // Because the hash code assigned to each formula is the
761  // number of formulae constructed so far, it is very unlikely
762  // that we will ever reach a case were two different formulae
763  // have the same hash. This will happen only ever with have
764  // produced 256**sizeof(size_t) formulae (i.e. max_count has
765  // looped back to 0 and started over). In that case we can
766  // order two formulas by looking at their text representation.
767  // We could be more efficient and look at their AST, but it's
768  // not worth the burden. (Also ordering pointers is ruled out
769  // because it breaks the determinism of the implementation.)
770  std::ostringstream old;
771  left->dump(old);
772  std::ostringstream ord;
773  right->dump(ord);
774  return old.str() < ord.str();
775  }
776 
777  SPOT_API bool
778  operator()(const formula& left, const formula& right) const;
779 };
780 
781 #endif // SWIG
782 
785  class SPOT_API formula final
786  {
787  friend struct formula_ptr_less_than_bool_first;
788  const fnode* ptr_;
789  public:
794  explicit formula(const fnode* f) noexcept
795  : ptr_(f)
796  {
797  }
798 
804  formula(std::nullptr_t) noexcept
805  : ptr_(nullptr)
806  {
807  }
808 
810  formula() noexcept
811  : ptr_(nullptr)
812  {
813  }
814 
816  formula(const formula& f) noexcept
817  : ptr_(f.ptr_)
818  {
819  if (ptr_)
820  ptr_->clone();
821  }
822 
824  formula(formula&& f) noexcept
825  : ptr_(f.ptr_)
826  {
827  f.ptr_ = nullptr;
828  }
829 
832  {
833  if (ptr_)
834  ptr_->destroy();
835  }
836 
844  const formula& operator=(std::nullptr_t)
845  {
846  this->~formula();
847  ptr_ = nullptr;
848  return *this;
849  }
850 
851  const formula& operator=(const formula& f)
852  {
853  this->~formula();
854  if ((ptr_ = f.ptr_))
855  ptr_->clone();
856  return *this;
857  }
858 
859  const formula& operator=(formula&& f) noexcept
860  {
861  std::swap(f.ptr_, ptr_);
862  return *this;
863  }
864 
865  bool operator<(const formula& other) const noexcept
866  {
867  if (SPOT_UNLIKELY(!other.ptr_))
868  return false;
869  if (SPOT_UNLIKELY(!ptr_))
870  return true;
871  if (id() < other.id())
872  return true;
873  if (id() > other.id())
874  return false;
875  // The case where id()==other.id() but ptr_ != other.ptr_ is
876  // very unlikely (we would need to build more than UINT_MAX
877  // formulas), so let's just compare pointers, and ignore the
878  // fact that it may introduce some nondeterminism.
879  return ptr_ < other.ptr_;
880  }
881 
882  bool operator<=(const formula& other) const noexcept
883  {
884  return *this == other || *this < other;
885  }
886 
887  bool operator>(const formula& other) const noexcept
888  {
889  return !(*this <= other);
890  }
891 
892  bool operator>=(const formula& other) const noexcept
893  {
894  return !(*this < other);
895  }
896 
897  bool operator==(const formula& other) const noexcept
898  {
899  return other.ptr_ == ptr_;
900  }
901 
902  bool operator==(std::nullptr_t) const noexcept
903  {
904  return ptr_ == nullptr;
905  }
906 
907  bool operator!=(const formula& other) const noexcept
908  {
909  return other.ptr_ != ptr_;
910  }
911 
912  bool operator!=(std::nullptr_t) const noexcept
913  {
914  return ptr_ != nullptr;
915  }
916 
917  explicit operator bool() const noexcept
918  {
919  return ptr_ != nullptr;
920  }
921 
923  // Forwarded functions //
925 
927  static constexpr uint8_t unbounded()
928  {
929  return fnode::unbounded();
930  }
931 
933  static formula ap(const std::string& name)
934  {
935  return formula(fnode::ap(name));
936  }
937 
943  static formula ap(const formula& a)
944  {
945  if (SPOT_UNLIKELY(a.kind() != op::ap))
946  report_ap_invalid_arg();
947  return a;
948  }
949 
954  static formula unop(op o, const formula& f)
955  {
956  return formula(fnode::unop(o, f.ptr_->clone()));
957  }
958 
959 #ifndef SWIG
960  static formula unop(op o, formula&& f)
961  {
962  return formula(fnode::unop(o, f.to_node_()));
963  }
964 #endif // !SWIG
966 
967 #ifdef SWIG
968 #define SPOT_DEF_UNOP(Name) \
969  static formula Name(const formula& f) \
970  { \
971  return unop(op::Name, f); \
972  }
973 #else // !SWIG
974 #define SPOT_DEF_UNOP(Name) \
975  static formula Name(const formula& f) \
976  { \
977  return unop(op::Name, f); \
978  } \
979  static formula Name(formula&& f) \
980  { \
981  return unop(op::Name, std::move(f)); \
982  }
983 #endif // !SWIG
986  SPOT_DEF_UNOP(Not);
988 
991  SPOT_DEF_UNOP(X);
993 
997  static formula X(unsigned level, const formula& f)
998  {
999  return nested_unop_range(op::X, op::Or /* unused */, level, level, f);
1000  }
1001 
1004  SPOT_DEF_UNOP(strong_X);
1006 
1010  static formula strong_X(unsigned level, const formula& f)
1011  {
1012  return nested_unop_range(op::strong_X, op::Or /* unused */,
1013  level, level, f);
1014  }
1015 
1018  SPOT_DEF_UNOP(F);
1020 
1027  static formula F(unsigned min_level, unsigned max_level, const formula& f)
1028  {
1029  return nested_unop_range(op::X, op::Or, min_level, max_level, f);
1030  }
1031 
1038  static formula G(unsigned min_level, unsigned max_level, const formula& f)
1039  {
1040  return nested_unop_range(op::X, op::And, min_level, max_level, f);
1041  }
1042 
1045  SPOT_DEF_UNOP(G);
1047 
1050  SPOT_DEF_UNOP(Closure);
1052 
1055  SPOT_DEF_UNOP(NegClosure);
1057 
1060  SPOT_DEF_UNOP(NegClosureMarked);
1062 
1065  SPOT_DEF_UNOP(first_match);
1067 #undef SPOT_DEF_UNOP
1068 
1074  static formula binop(op o, const formula& f, const formula& g)
1075  {
1076  return formula(fnode::binop(o, f.ptr_->clone(), g.ptr_->clone()));
1077  }
1078 
1079 #ifndef SWIG
1080  static formula binop(op o, const formula& f, formula&& g)
1081  {
1082  return formula(fnode::binop(o, f.ptr_->clone(), g.to_node_()));
1083  }
1084 
1085  static formula binop(op o, formula&& f, const formula& g)
1086  {
1087  return formula(fnode::binop(o, f.to_node_(), g.ptr_->clone()));
1088  }
1089 
1090  static formula binop(op o, formula&& f, formula&& g)
1091  {
1092  return formula(fnode::binop(o, f.to_node_(), g.to_node_()));
1093  }
1095 
1096 #endif //SWIG
1097 
1098 #ifdef SWIG
1099 #define SPOT_DEF_BINOP(Name) \
1100  static formula Name(const formula& f, const formula& g) \
1101  { \
1102  return binop(op::Name, f, g); \
1103  }
1104 #else // !SWIG
1105 #define SPOT_DEF_BINOP(Name) \
1106  static formula Name(const formula& f, const formula& g) \
1107  { \
1108  return binop(op::Name, f, g); \
1109  } \
1110  static formula Name(const formula& f, formula&& g) \
1111  { \
1112  return binop(op::Name, f, std::move(g)); \
1113  } \
1114  static formula Name(formula&& f, const formula& g) \
1115  { \
1116  return binop(op::Name, std::move(f), g); \
1117  } \
1118  static formula Name(formula&& f, formula&& g) \
1119  { \
1120  return binop(op::Name, std::move(f), std::move(g)); \
1121  }
1122 #endif // !SWIG
1125  SPOT_DEF_BINOP(Xor);
1127 
1130  SPOT_DEF_BINOP(Implies);
1132 
1135  SPOT_DEF_BINOP(Equiv);
1137 
1140  SPOT_DEF_BINOP(U);
1142 
1145  SPOT_DEF_BINOP(R);
1147 
1150  SPOT_DEF_BINOP(W);
1152 
1155  SPOT_DEF_BINOP(M);
1157 
1160  SPOT_DEF_BINOP(EConcat);
1162 
1165  SPOT_DEF_BINOP(EConcatMarked);
1167 
1170  SPOT_DEF_BINOP(UConcat);
1172 #undef SPOT_DEF_BINOP
1173 
1179  static formula multop(op o, const std::vector<formula>& l)
1180  {
1181  std::vector<const fnode*> tmp;
1182  tmp.reserve(l.size());
1183  for (auto f: l)
1184  if (f.ptr_)
1185  tmp.emplace_back(f.ptr_->clone());
1186  return formula(fnode::multop(o, std::move(tmp)));
1187  }
1188 
1189 #ifndef SWIG
1190  static formula multop(op o, std::vector<formula>&& l)
1191  {
1192  std::vector<const fnode*> tmp;
1193  tmp.reserve(l.size());
1194  for (auto f: l)
1195  if (f.ptr_)
1196  tmp.emplace_back(f.to_node_());
1197  return formula(fnode::multop(o, std::move(tmp)));
1198  }
1199 #endif // !SWIG
1201 
1202 #ifdef SWIG
1203 #define SPOT_DEF_MULTOP(Name) \
1204  static formula Name(const std::vector<formula>& l) \
1205  { \
1206  return multop(op::Name, l); \
1207  }
1208 #else // !SWIG
1209 #define SPOT_DEF_MULTOP(Name) \
1210  static formula Name(const std::vector<formula>& l) \
1211  { \
1212  return multop(op::Name, l); \
1213  } \
1214  \
1215  static formula Name(std::vector<formula>&& l) \
1216  { \
1217  return multop(op::Name, std::move(l)); \
1218  }
1219 #endif // !SWIG
1222  SPOT_DEF_MULTOP(Or);
1224 
1227  SPOT_DEF_MULTOP(OrRat);
1229 
1232  SPOT_DEF_MULTOP(And);
1234 
1237  SPOT_DEF_MULTOP(AndRat);
1239 
1242  SPOT_DEF_MULTOP(AndNLM);
1244 
1247  SPOT_DEF_MULTOP(Concat);
1249 
1252  SPOT_DEF_MULTOP(Fusion);
1254 #undef SPOT_DEF_MULTOP
1255 
1260  static formula bunop(op o, const formula& f,
1261  unsigned min = 0U,
1262  unsigned max = unbounded())
1263  {
1264  return formula(fnode::bunop(o, f.ptr_->clone(), min, max));
1265  }
1266 
1267 #ifndef SWIG
1268  static formula bunop(op o, formula&& f,
1269  unsigned min = 0U,
1270  unsigned max = unbounded())
1271  {
1272  return formula(fnode::bunop(o, f.to_node_(), min, max));
1273  }
1274 #endif // !SWIG
1276 
1277 #if SWIG
1278 #define SPOT_DEF_BUNOP(Name) \
1279  static formula Name(const formula& f, \
1280  unsigned min = 0U, \
1281  unsigned max = unbounded()) \
1282  { \
1283  return bunop(op::Name, f, min, max); \
1284  }
1285 #else // !SWIG
1286 #define SPOT_DEF_BUNOP(Name) \
1287  static formula Name(const formula& f, \
1288  unsigned min = 0U, \
1289  unsigned max = unbounded()) \
1290  { \
1291  return bunop(op::Name, f, min, max); \
1292  } \
1293  static formula Name(formula&& f, \
1294  unsigned min = 0U, \
1295  unsigned max = unbounded()) \
1296  { \
1297  return bunop(op::Name, std::move(f), min, max); \
1298  }
1299 #endif
1302  SPOT_DEF_BUNOP(Star);
1304 
1310  SPOT_DEF_BUNOP(FStar);
1312 #undef SPOT_DEF_BUNOP
1313 
1325  static const formula nested_unop_range(op uo, op bo, unsigned min,
1326  unsigned max, formula f)
1327  {
1328  return formula(fnode::nested_unop_range(uo, bo, min, max,
1329  f.ptr_->clone()));
1330  }
1331 
1337  static formula sugar_goto(const formula& b, unsigned min, unsigned max);
1338 
1344  static formula sugar_equal(const formula& b, unsigned min, unsigned max);
1345 
1367  static formula sugar_delay(const formula& a, const formula& b,
1368  unsigned min, unsigned max);
1369  static formula sugar_delay(const formula& b,
1370  unsigned min, unsigned max);
1372 
1373 #ifndef SWIG
1383  const fnode* to_node_()
1384  {
1385  auto tmp = ptr_;
1386  ptr_ = nullptr;
1387  return tmp;
1388  }
1389 #endif
1390 
1392  op kind() const
1393  {
1394  return ptr_->kind();
1395  }
1396 
1398  std::string kindstr() const
1399  {
1400  return ptr_->kindstr();
1401  }
1402 
1404  bool is(op o) const
1405  {
1406  return ptr_->is(o);
1407  }
1408 
1409 #ifndef SWIG
1411  bool is(op o1, op o2) const
1412  {
1413  return ptr_->is(o1, o2);
1414  }
1415 
1417  bool is(op o1, op o2, op o3) const
1418  {
1419  return ptr_->is(o1, o2, o3);
1420  }
1421 
1424  bool is(op o1, op o2, op o3, op o4) const
1425  {
1426  return ptr_->is(o1, o2, o3, o4);
1427  }
1428 
1430  bool is(std::initializer_list<op> l) const
1431  {
1432  return ptr_->is(l);
1433  }
1434 #endif
1435 
1440  {
1441  auto f = ptr_->get_child_of(o);
1442  if (f)
1443  f->clone();
1444  return formula(f);
1445  }
1446 
1447 #ifndef SWIG
1454  formula get_child_of(std::initializer_list<op> l) const
1455  {
1456  auto f = ptr_->get_child_of(l);
1457  if (f)
1458  f->clone();
1459  return formula(f);
1460  }
1461 #endif
1462 
1466  unsigned min() const
1467  {
1468  return ptr_->min();
1469  }
1470 
1474  unsigned max() const
1475  {
1476  return ptr_->max();
1477  }
1478 
1480  unsigned size() const
1481  {
1482  return ptr_->size();
1483  }
1484 
1489  bool is_leaf() const
1490  {
1491  return ptr_->is_leaf();
1492  }
1493 
1502  size_t id() const
1503  {
1504  return ptr_->id();
1505  }
1506 
1507 #ifndef SWIG
1509  class SPOT_API formula_child_iterator final
1510  {
1511  const fnode*const* ptr_;
1512  public:
1514  : ptr_(nullptr)
1515  {
1516  }
1517 
1518  formula_child_iterator(const fnode*const* f)
1519  : ptr_(f)
1520  {
1521  }
1522 
1523  bool operator==(formula_child_iterator o)
1524  {
1525  return ptr_ == o.ptr_;
1526  }
1527 
1528  bool operator!=(formula_child_iterator o)
1529  {
1530  return ptr_ != o.ptr_;
1531  }
1532 
1533  formula operator*()
1534  {
1535  return formula((*ptr_)->clone());
1536  }
1537 
1538  formula_child_iterator operator++()
1539  {
1540  ++ptr_;
1541  return *this;
1542  }
1543 
1544  formula_child_iterator operator++(int)
1545  {
1546  auto tmp = *this;
1547  ++ptr_;
1548  return tmp;
1549  }
1550  };
1551 
1554  {
1555  return ptr_->begin();
1556  }
1557 
1560  {
1561  return ptr_->end();
1562  }
1563 
1565  formula operator[](unsigned i) const
1566  {
1567  return formula(ptr_->nth(i)->clone());
1568  }
1569 #endif
1570 
1572  static formula ff()
1573  {
1574  return formula(fnode::ff());
1575  }
1576 
1578  bool is_ff() const
1579  {
1580  return ptr_->is_ff();
1581  }
1582 
1584  static formula tt()
1585  {
1586  return formula(fnode::tt());
1587  }
1588 
1590  bool is_tt() const
1591  {
1592  return ptr_->is_tt();
1593  }
1594 
1596  static formula eword()
1597  {
1598  return formula(fnode::eword());
1599  }
1600 
1602  bool is_eword() const
1603  {
1604  return ptr_->is_eword();
1605  }
1606 
1608  bool is_constant() const
1609  {
1610  return ptr_->is_constant();
1611  }
1612 
1617  bool is_Kleene_star() const
1618  {
1619  return ptr_->is_Kleene_star();
1620  }
1621 
1624  {
1625  // no need to clone, 1[*] is not reference counted
1626  return formula(fnode::one_star());
1627  }
1628 
1631  {
1632  // no need to clone, 1[+] is not reference counted
1633  return formula(fnode::one_plus());
1634  }
1635 
1638  bool is_literal() const
1639  {
1640  return (is(op::ap) ||
1641  // If f is in nenoform, Not can only occur in front of
1642  // an atomic proposition. So this way we do not have
1643  // to check the type of the child.
1644  (is(op::Not) && is_boolean() && is_in_nenoform()));
1645  }
1646 
1650  const std::string& ap_name() const
1651  {
1652  return ptr_->ap_name();
1653  }
1654 
1659  std::ostream& dump(std::ostream& os) const
1660  {
1661  return ptr_->dump(os);
1662  }
1663 
1669  formula all_but(unsigned i) const
1670  {
1671  return formula(ptr_->all_but(i));
1672  }
1673 
1683  unsigned boolean_count() const
1684  {
1685  return ptr_->boolean_count();
1686  }
1687 
1701  formula boolean_operands(unsigned* width = nullptr) const
1702  {
1703  return formula(ptr_->boolean_operands(width));
1704  }
1705 
1706 #define SPOT_DEF_PROP(Name) \
1707  bool Name() const \
1708  { \
1709  return ptr_->Name(); \
1710  }
1712  // Properties //
1714 
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);
1752  SPOT_DEF_PROP(is_universal);
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);
1810 #undef SPOT_DEF_PROP
1811 
1815  template<typename Trans, typename... Args>
1816  formula map(Trans trans, Args&&... args)
1817  {
1818  switch (op o = kind())
1819  {
1820  case op::ff:
1821  case op::tt:
1822  case op::eword:
1823  case op::ap:
1824  return *this;
1825  case op::Not:
1826  case op::X:
1827 #if SPOT_HAS_STRONG_X
1828  case op::strong_X:
1829 #endif
1830  case op::F:
1831  case op::G:
1832  case op::Closure:
1833  case op::NegClosure:
1834  case op::NegClosureMarked:
1835  case op::first_match:
1836  return unop(o, trans((*this)[0], std::forward<Args>(args)...));
1837  case op::Xor:
1838  case op::Implies:
1839  case op::Equiv:
1840  case op::U:
1841  case op::R:
1842  case op::W:
1843  case op::M:
1844  case op::EConcat:
1845  case op::EConcatMarked:
1846  case op::UConcat:
1847  {
1848  formula tmp = trans((*this)[0], std::forward<Args>(args)...);
1849  return binop(o, tmp,
1850  trans((*this)[1], std::forward<Args>(args)...));
1851  }
1852  case op::Or:
1853  case op::OrRat:
1854  case op::And:
1855  case op::AndRat:
1856  case op::AndNLM:
1857  case op::Concat:
1858  case op::Fusion:
1859  {
1860  std::vector<formula> tmp;
1861  tmp.reserve(size());
1862  for (auto f: *this)
1863  tmp.emplace_back(trans(f, std::forward<Args>(args)...));
1864  return multop(o, std::move(tmp));
1865  }
1866  case op::Star:
1867  case op::FStar:
1868  return bunop(o, trans((*this)[0], std::forward<Args>(args)...),
1869  min(), max());
1870  }
1871  SPOT_UNREACHABLE();
1872  }
1873 
1882  template<typename Func, typename... Args>
1883  void traverse(Func func, Args&&... args)
1884  {
1885  if (func(*this, std::forward<Args>(args)...))
1886  return;
1887  for (auto f: *this)
1888  f.traverse(func, std::forward<Args>(args)...);
1889  }
1890 
1891  private:
1892 #ifndef SWIG
1893  [[noreturn]] static void report_ap_invalid_arg();
1894 #endif
1895  };
1896 
1898  SPOT_API
1899  std::ostream& print_formula_props(std::ostream& out, const formula& f,
1900  bool abbreviated = false);
1901 
1903  SPOT_API
1904  std::list<std::string> list_formula_props(const formula& f);
1905 
1907  SPOT_API
1908  std::ostream& operator<<(std::ostream& os, const formula& f);
1909 }
1910 
1911 #ifndef SWIG
1912 namespace std
1913 {
1914  template <>
1915  struct hash<spot::formula>
1916  {
1917  size_t operator()(const spot::formula& x) const noexcept
1918  {
1919  return x.id();
1920  }
1921  };
1922 }
1923 #endif
Actual storage for formula nodes.
Definition: formula.hh:153
bool is_pi2() const
Definition: formula.hh:558
const fnode *const * begin() const
Definition: formula.hh:306
const fnode *const * end() const
Definition: formula.hh:312
std::string kindstr() const
std::ostream & dump(std::ostream &os) 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
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
bool is_delta2() const
Definition: formula.hh:570
unsigned size() const
Definition: formula.hh:288
static constexpr uint8_t unbounded()
Definition: formula.hh:183
static const fnode * eword()
Definition: formula.hh:352
const fnode * get_child_of(op o) const
Definition: formula.hh:249
unsigned max() const
Definition: formula.hh:280
static const fnode * ff()
Definition: formula.hh:328
const fnode * boolean_operands(unsigned *width=nullptr) const
bool accepts_eword() const
Definition: formula.hh:534
bool is_eventual() const
Definition: formula.hh:486
const std::string & ap_name() const
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
static const fnode * tt()
Definition: formula.hh:340
bool is(op o1, op o2, op o3) const
Definition: formula.hh:225
op kind() const
Definition: formula.hh:205
bool has_lbt_atomic_props() const
Definition: formula.hh:540
bool is_sugar_free_ltl() const
Definition: formula.hh:456
bool is_syntactic_persistence() const
Definition: formula.hh:522
static const fnode * nested_unop_range(op uo, op bo, unsigned min, unsigned max, const fnode *f)
unsigned boolean_count() const
Definition: formula.hh:403
bool is_universal() const
Definition: formula.hh:492
bool is_tt() const
Definition: formula.hh:346
const fnode * get_child_of(std::initializer_list< op > l) const
Definition: formula.hh:259
static const fnode * one_plus()
Definition: formula.hh:386
const fnode * nth(unsigned i) const
Definition: formula.hh:318
bool is_constant() const
Definition: formula.hh:364
static const fnode * binop(op o, const fnode *f, const fnode *g)
static const fnode * one_star()
Definition: formula.hh:378
const fnode * all_but(unsigned i) const
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)
bool is_ltl_formula() const
Definition: formula.hh:462
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 * multop(op o, std::vector< const fnode * > l)
bool is_marked() const
Definition: formula.hh:528
void destroy() const
Dereference an fnode.
Definition: formula.hh:173
static const fnode * bunop(op o, const fnode *f, unsigned min, unsigned max=unbounded())
bool is(op o1, op o2) const
Definition: formula.hh:220
bool is_in_nenoform() const
Definition: formula.hh:444
static const fnode * ap(const std::string &name)
bool is_syntactic_guarantee() const
Definition: formula.hh:504
bool is_sere_formula() const
Definition: formula.hh:474
const fnode * clone() const
Clone an fnode.
Definition: formula.hh:159
bool is(op o) const
Definition: formula.hh:215
Allow iterating over children.
Definition: formula.hh:1510
Main class for temporal logic formula.
Definition: formula.hh:786
unsigned boolean_count() const
number of Boolean children
Definition: formula.hh:1683
bool is_leaf() const
Whether the formula is a leaf.
Definition: formula.hh:1489
size_t id() const
Return the id of a formula.
Definition: formula.hh:1502
static formula bunop(op o, formula &&f, unsigned min=0U, unsigned max=unbounded())
Define a bounded unary-operator (i.e. star-like)
Definition: formula.hh:1268
formula map(Trans trans, Args &&... args)
Clone this node after applying trans to its children.
Definition: formula.hh:1816
static formula bunop(op o, const formula &f, unsigned min=0U, unsigned max=unbounded())
Define a bounded unary-operator (i.e. star-like)
Definition: formula.hh:1260
static formula G(unsigned min_level, unsigned max_level, const formula &f)
Construct G[n:m].
Definition: formula.hh:1038
static formula binop(op o, const formula &f, const formula &g)
Construct a binary operator.
Definition: formula.hh:1074
bool is(op o) const
Return true if the formula is of kind o.
Definition: formula.hh:1404
static formula multop(op o, std::vector< formula > &&l)
Construct an n-ary operator.
Definition: formula.hh:1190
formula(formula &&f) noexcept
Move-construct a formula.
Definition: formula.hh:824
formula(const fnode *f) noexcept
Create a formula from an fnode.
Definition: formula.hh:794
bool is(op o1, op o2) const
Return true if the formula is of kind o1 or o2.
Definition: formula.hh:1411
static formula one_plus()
Return a copy of the formula 1[+].
Definition: formula.hh:1630
static formula sugar_delay(const formula &b, unsigned min, unsigned max)
Create the SERE a ##[n:m] b
static formula one_star()
Return a copy of the formula 1[*].
Definition: formula.hh:1623
unsigned min() const
Return start of the range for star-like operators.
Definition: formula.hh:1466
static constexpr uint8_t unbounded()
Unbounded constant to use as end of range for bounded operators.
Definition: formula.hh:927
static formula unop(op o, formula &&f)
Build a unary operator.
Definition: formula.hh:960
static formula eword()
Return the empty word constant.
Definition: formula.hh:1596
formula all_but(unsigned i) const
clone this formula, omitting child i
Definition: formula.hh:1669
static formula ff()
Return the false constant.
Definition: formula.hh:1572
static formula binop(op o, const formula &f, formula &&g)
Construct a binary operator.
Definition: formula.hh:1080
op kind() const
Return top-most operator.
Definition: formula.hh:1392
static formula multop(op o, const std::vector< formula > &l)
Construct an n-ary operator.
Definition: formula.hh:1179
unsigned size() const
Return the number of children.
Definition: formula.hh:1480
static formula sugar_goto(const formula &b, unsigned min, unsigned max)
Create a SERE equivalent to b[->min..max]
bool is_tt() const
Whether the formula is the true constant.
Definition: formula.hh:1590
bool is(op o1, op o2, op o3, op o4) const
Definition: formula.hh:1424
std::string kindstr() const
Return the name of the top-most operator.
Definition: formula.hh:1398
formula(const formula &f) noexcept
Clone a formula.
Definition: formula.hh:816
formula_child_iterator end() const
Allow iterating over children.
Definition: formula.hh:1559
static formula binop(op o, formula &&f, formula &&g)
Construct a binary operator.
Definition: formula.hh:1090
static formula ap(const formula &a)
Build an atomic proposition from... an atomic proposition.
Definition: formula.hh:943
formula get_child_of(std::initializer_list< op > l) const
Remove all operators in l and return the child.
Definition: formula.hh:1454
bool is_eword() const
Whether the formula is the empty word constant.
Definition: formula.hh:1602
static formula sugar_delay(const formula &a, const formula &b, unsigned min, unsigned max)
Create the SERE a ##[n:m] b
void traverse(Func func, Args &&... args)
Apply func to each subformula.
Definition: formula.hh:1883
static formula F(unsigned min_level, unsigned max_level, const formula &f)
Construct F[n:m].
Definition: formula.hh:1027
formula(std::nullptr_t) noexcept
Create a null formula.
Definition: formula.hh:804
static formula ap(const std::string &name)
Build an atomic proposition.
Definition: formula.hh:933
const std::string & ap_name() const
Print the name of an atomic proposition.
Definition: formula.hh:1650
bool is(op o1, op o2, op o3) const
Return true if the formula is of kind o1 or o2 or o3.
Definition: formula.hh:1417
const formula & operator=(std::nullptr_t)
Reset a formula to null.
Definition: formula.hh:844
unsigned max() const
Return end of the range for star-like operators.
Definition: formula.hh:1474
static formula X(unsigned level, const formula &f)
Construct an X[n].
Definition: formula.hh:997
bool is_ff() const
Whether the formula is the false constant.
Definition: formula.hh:1578
formula_child_iterator begin() const
Allow iterating over children.
Definition: formula.hh:1553
bool is_constant() const
Whether the formula is op::ff, op::tt, or op::eword.
Definition: formula.hh:1608
~formula()
Destroy a formula.
Definition: formula.hh:831
std::ostream & dump(std::ostream &os) const
Print the formula for debugging.
Definition: formula.hh:1659
formula get_child_of(op o) const
Remove operator o and return the child.
Definition: formula.hh:1439
const fnode * to_node_()
Return the underlying pointer to the formula.
Definition: formula.hh:1383
bool is(std::initializer_list< op > l) const
Return true if the formulas nests all the operators in l.
Definition: formula.hh:1430
formula operator[](unsigned i) const
Return children number i.
Definition: formula.hh:1565
static formula strong_X(unsigned level, const formula &f)
Construct a strong_X[n].
Definition: formula.hh:1010
bool is_Kleene_star() const
Test whether the formula represent a Kleene star.
Definition: formula.hh:1617
static formula binop(op o, formula &&f, const formula &g)
Construct a binary operator.
Definition: formula.hh:1085
bool is_literal() const
Whether the formula is an atomic proposition or its negation.
Definition: formula.hh:1638
static formula tt()
Return the true constant.
Definition: formula.hh:1584
formula() noexcept
Default initialize a formula to nullptr.
Definition: formula.hh:810
static formula sugar_equal(const formula &b, unsigned min, unsigned max)
Create the SERE b[=min..max]
static formula unop(op o, const formula &f)
Build a unary operator.
Definition: formula.hh:954
formula boolean_operands(unsigned *width=nullptr) const
return a clone of the current node, restricted to its Boolean children
Definition: formula.hh:1701
static const formula nested_unop_range(op uo, op bo, unsigned min, unsigned max, formula f)
Nested operator construction (syntactic sugar).
Definition: formula.hh:1325
op
Operator types.
Definition: formula.hh:77
@ X
Next.
@ first_match
first_match(sere)
@ EConcatMarked
Seq, Marked.
@ Star
Star.
@ UConcat
Triggers.
@ Or
(omega-Rational) Or
@ Equiv
Equivalence.
@ NegClosure
Negated PSL Closure.
@ U
until
@ EConcat
Seq.
@ FStar
Fustion Star.
@ W
weak until
@ ap
Atomic proposition.
@ ff
False.
@ M
strong release (dual of weak until)
@ NegClosureMarked
marked version of the Negated PSL Closure
@ strong_X
strong Next
@ Xor
Exclusive Or.
@ F
Eventually.
@ OrRat
Rational Or.
@ Not
Negation.
@ tt
True.
@ Fusion
Fusion.
@ Closure
PSL Closure.
@ And
(omega-Rational) And
@ AndNLM
Non-Length-Matching Rational-And.
@ eword
Empty word.
@ AndRat
Rational And.
@ G
Globally.
@ R
release (dual of until)
@ Concat
Concatenation.
@ Implies
Implication.
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.
Definition: formula.hh:711

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.1