cvc4-1.4
expr_template.h
Go to the documentation of this file.
1/********************* */
17#include "cvc4_public.h"
18
19// putting the constant-payload #includes up here allows circularity
20// (some of them may require a completely-defined Expr type). This
21// way, those #includes can forward-declare some stuff to get Expr's
22// getConst<> template instantiations correct, and then #include
23// "expr.h" safely, then go on to completely declare their own stuff.
24${includes}
25
26#ifndef __CVC4__EXPR_H
27#define __CVC4__EXPR_H
28
29#include <string>
30#include <iostream>
31#include <iterator>
32#include <stdint.h>
33
34#include "util/exception.h"
35#include "util/language.h"
36#include "util/hash.h"
37#include "expr/options.h"
38
39// This is a hack, but an important one: if there's an error, the
40// compiler directs the user to the template file instead of the
41// generated one. We don't want the user to modify the generated one,
42// since it'll get overwritten on a later build.
43#line 44 "${template}"
44
45namespace CVC4 {
46
47// The internal expression representation
48template <bool ref_count>
49class NodeTemplate;
50
51class NodeManager;
52
53class Expr;
54class ExprManager;
55class SmtEngine;
56class Type;
57class TypeCheckingException;
58class TypeCheckingExceptionPrivate;
59
60namespace expr {
61 namespace pickle {
62 class Pickler;
63 }/* CVC4::expr::pickle namespace */
64}/* CVC4::expr namespace */
65
66namespace prop {
67 class TheoryProxy;
68}/* CVC4::prop namespace */
69
70struct ExprManagerMapCollection;
71
72struct ExprHashFunction;
73
74namespace smt {
75 class SmtEnginePrivate;
76}/* CVC4::smt namespace */
77
78namespace expr {
79 class CVC4_PUBLIC ExprSetDepth;
80 class CVC4_PUBLIC ExprPrintTypes;
81 class CVC4_PUBLIC ExprDag;
82 class CVC4_PUBLIC ExprSetLanguage;
83
84 class ExportPrivate;
85}/* CVC4::expr namespace */
86
90class CVC4_PUBLIC TypeCheckingException : public Exception {
91
92 friend class SmtEngine;
93 friend class smt::SmtEnginePrivate;
94
95private:
96
98 Expr* d_expr;
99
100protected:
101
102 TypeCheckingException() throw() : Exception() {}
103 TypeCheckingException(ExprManager* em,
104 const TypeCheckingExceptionPrivate* exc) throw();
105
106public:
107
108 TypeCheckingException(const Expr& expr, std::string message) throw();
109
111 TypeCheckingException(const TypeCheckingException& t) throw();
112
114 ~TypeCheckingException() throw();
115
121 Expr getExpression() const throw();
122
128 void toStream(std::ostream& out) const throw();
129
130 friend class ExprManager;
131};/* class TypeCheckingException */
132
136class CVC4_PUBLIC ExportUnsupportedException : public Exception {
137public:
138 ExportUnsupportedException() throw():
139 Exception("export unsupported") {
140 }
141 ExportUnsupportedException(const char* msg) throw():
142 Exception(msg) {
143 }
144};/* class DatatypeExportUnsupportedException */
145
146std::ostream& operator<<(std::ostream& out,
147 const TypeCheckingException& e) CVC4_PUBLIC;
148
155std::ostream& operator<<(std::ostream& out, const Expr& e) CVC4_PUBLIC;
156
157// for hash_maps, hash_sets..
158struct ExprHashFunction {
159 size_t operator()(CVC4::Expr e) const;
160};/* struct ExprHashFunction */
161
166class CVC4_PUBLIC Expr {
167
169 NodeTemplate<true>* d_node;
170
172 ExprManager* d_exprManager;
173
180 Expr(ExprManager* em, NodeTemplate<true>* node);
181
182public:
183
185 Expr();
186
192 Expr(const Expr& e);
193
195 ~Expr();
196
205 Expr& operator=(const Expr& e);
206
214 bool operator==(const Expr& e) const;
215
222 bool operator!=(const Expr& e) const;
223
234 bool operator<(const Expr& e) const;
235
246 bool operator>(const Expr& e) const;
247
258 bool operator<=(const Expr& e) const { return !(*this > e); }
259
270 bool operator>=(const Expr& e) const { return !(*this < e); }
271
278 unsigned long getId() const;
279
285 Kind getKind() const;
286
292 size_t getNumChildren() const;
293
300 Expr operator[](unsigned i) const;
301
305 std::vector<Expr> getChildren() const {
306 return std::vector<Expr>(begin(), end());
307 }
308
312 Expr notExpr() const;
313
318 Expr andExpr(const Expr& e) const;
319
324 Expr orExpr(const Expr& e) const;
325
330 Expr xorExpr(const Expr& e) const;
331
336 Expr iffExpr(const Expr& e) const;
337
342 Expr impExpr(const Expr& e) const;
343
349 Expr iteExpr(const Expr& then_e, const Expr& else_e) const;
350
354 class const_iterator : public std::iterator<std::input_iterator_tag, Expr> {
355 ExprManager* d_exprManager;
356 void* d_iterator;
357
358 explicit const_iterator(ExprManager*, void*);
359
360 friend class Expr;// to access void* constructor
361
362 public:
363 const_iterator();
364 const_iterator(const const_iterator& it);
365 const_iterator& operator=(const const_iterator& it);
366 ~const_iterator();
367 bool operator==(const const_iterator& it) const;
368 bool operator!=(const const_iterator& it) const {
369 return !(*this == it);
370 }
371 const_iterator& operator++();
372 const_iterator operator++(int);
373 Expr operator*() const;
374 };/* class Expr::const_iterator */
375
379 const_iterator begin() const;
380
384 const_iterator end() const;
385
391 bool hasOperator() const;
392
399 Expr getOperator() const;
400
425 Type getType(bool check = false) const throw (TypeCheckingException);
426
430 Expr substitute(Expr e, Expr replacement) const;
431
435 Expr substitute(const std::vector<Expr> exes,
436 const std::vector<Expr>& replacements) const;
437
441 Expr substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const;
442
447 std::string toString() const;
448
461 void toStream(std::ostream& out, int toDepth = -1, bool types = false, size_t dag = 1,
462 OutputLanguage language = language::output::LANG_AUTO) const;
463
469 bool isNull() const;
470
476 bool isVariable() const;
477
483 bool isConst() const;
484
485 /* A note on isAtomic() and isAtomicFormula() (in CVC3 parlance)..
486 *
487 * It has been decided for now to hold off on implementations of
488 * these functions, as they may only be needed in CNF conversion,
489 * where it's pointless to do a lazy isAtomic determination by
490 * searching through the DAG, and storing it, since the result will
491 * only be used once. For more details see the 4/27/2010 CVC4
492 * developer's meeting notes at:
493 *
494 * http://goedel.cims.nyu.edu/wiki/Meeting_Minutes_-_April_27,_2010#isAtomic.28.29_and_isAtomicFormula.28.29
495 */
496 // bool containsDecision(); // is "atomic"
497 // bool properlyContainsDecision(); // maybe not atomic but all children are
498
500 template <class T>
501 const T& getConst() const;
502
506 ExprManager* getExprManager() const;
507
513 Expr exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap, uint32_t flags = 0) const;
514
529 typedef expr::ExprSetDepth setdepth;
530
544 typedef expr::ExprPrintTypes printtypes;
545
549 typedef expr::ExprDag dag;
550
554 typedef expr::ExprSetLanguage setlanguage;
555
562 void printAst(std::ostream& out, int indent = 0) const;
563
564private:
565
572 void debugPrint();
573
578 NodeTemplate<true> getNode() const throw();
579
584 NodeTemplate<false> getTNode() const throw();
585
586 // Friend to access the actual internal expr information and private methods
587 friend class SmtEngine;
588 friend class smt::SmtEnginePrivate;
589 friend class ExprManager;
590 friend class NodeManager;
591 friend class TypeCheckingException;
592 friend class expr::pickle::Pickler;
593 friend class prop::TheoryProxy;
594 friend class expr::ExportPrivate;
595 friend std::ostream& CVC4::operator<<(std::ostream& out, const Expr& e);
596 template <bool ref_count> friend class NodeTemplate;
597
598};/* class Expr */
599
600namespace expr {
601
621class CVC4_PUBLIC ExprSetDepth {
625 static const int s_iosIndex;
626
631 static const int s_defaultPrintDepth = -1;
632
636 long d_depth;
637
638public:
642 ExprSetDepth(long depth) : d_depth(depth) {}
643
644 inline void applyDepth(std::ostream& out) {
645 out.iword(s_iosIndex) = d_depth;
646 }
647
648 static inline long getDepth(std::ostream& out) {
649 long& l = out.iword(s_iosIndex);
650 if(l == 0) {
651 // set the default print depth on this ostream
652 if(&Options::current() != NULL) {
653 l = options::defaultExprDepth();
654 }
655 if(l == 0) {
656 // if called from outside the library, we may not have options
657 // available to us at this point (or perhaps the output language
658 // is not set in Options). Default to something reasonable, but
659 // don't set "l" since that would make it "sticky" for this
660 // stream.
661 return s_defaultPrintDepth;
662 }
663 }
664 return l;
665 }
666
667 static inline void setDepth(std::ostream& out, long depth) {
668 out.iword(s_iosIndex) = depth;
669 }
670
677 class Scope {
678 std::ostream& d_out;
679 long d_oldDepth;
680
681 public:
682
683 inline Scope(std::ostream& out, long depth) :
684 d_out(out),
685 d_oldDepth(ExprSetDepth::getDepth(out)) {
686 ExprSetDepth::setDepth(out, depth);
687 }
688
689 inline ~Scope() {
690 ExprSetDepth::setDepth(d_out, d_oldDepth);
691 }
692
693 };/* class ExprSetDepth::Scope */
694
695};/* class ExprSetDepth */
696
706class CVC4_PUBLIC ExprPrintTypes {
710 static const int s_iosIndex;
711
715 bool d_printTypes;
716
717public:
721 ExprPrintTypes(bool printTypes) : d_printTypes(printTypes) {}
722
723 inline void applyPrintTypes(std::ostream& out) {
724 out.iword(s_iosIndex) = d_printTypes;
725 }
726
727 static inline bool getPrintTypes(std::ostream& out) {
728 return out.iword(s_iosIndex);
729 }
730
731 static inline void setPrintTypes(std::ostream& out, bool printTypes) {
732 out.iword(s_iosIndex) = printTypes;
733 }
734
741 class Scope {
742 std::ostream& d_out;
743 bool d_oldPrintTypes;
744
745 public:
746
747 inline Scope(std::ostream& out, bool printTypes) :
748 d_out(out),
749 d_oldPrintTypes(ExprPrintTypes::getPrintTypes(out)) {
750 ExprPrintTypes::setPrintTypes(out, printTypes);
751 }
752
753 inline ~Scope() {
754 ExprPrintTypes::setPrintTypes(d_out, d_oldPrintTypes);
755 }
756
757 };/* class ExprPrintTypes::Scope */
758
759};/* class ExprPrintTypes */
760
764class CVC4_PUBLIC ExprDag {
768 static const int s_iosIndex;
769
774 static const size_t s_defaultDag = 1;
775
779 size_t d_dag;
780
781public:
785 explicit ExprDag(bool dag) : d_dag(dag ? 1 : 0) {}
786
792 explicit ExprDag(int dag) : d_dag(dag < 0 ? 0 : dag) {}
793
794 inline void applyDag(std::ostream& out) {
795 // (offset by one to detect whether default has been set yet)
796 out.iword(s_iosIndex) = static_cast<long>(d_dag) + 1;
797 }
798
799 static inline size_t getDag(std::ostream& out) {
800 long& l = out.iword(s_iosIndex);
801 if(l == 0) {
802 // set the default dag setting on this ostream
803 // (offset by one to detect whether default has been set yet)
804 if(&Options::current() != NULL) {
805 l = options::defaultDagThresh() + 1;
806 }
807 if(l == 0) {
808 // if called from outside the library, we may not have options
809 // available to us at this point (or perhaps the output language
810 // is not set in Options). Default to something reasonable, but
811 // don't set "l" since that would make it "sticky" for this
812 // stream.
813 return s_defaultDag + 1;
814 }
815 }
816 return static_cast<size_t>(l - 1);
817 }
818
819 static inline void setDag(std::ostream& out, size_t dag) {
820 // (offset by one to detect whether default has been set yet)
821 out.iword(s_iosIndex) = static_cast<long>(dag) + 1;
822 }
823
830 class Scope {
831 std::ostream& d_out;
832 size_t d_oldDag;
833
834 public:
835
836 inline Scope(std::ostream& out, size_t dag) :
837 d_out(out),
838 d_oldDag(ExprDag::getDag(out)) {
839 ExprDag::setDag(out, dag);
840 }
841
842 inline ~Scope() {
843 ExprDag::setDag(d_out, d_oldDag);
844 }
845
846 };/* class ExprDag::Scope */
847
848};/* class ExprDag */
849
853class CVC4_PUBLIC ExprSetLanguage {
857 static const int s_iosIndex;
858
864 static const int s_defaultOutputLanguage = language::output::LANG_AUTO;
865
869 OutputLanguage d_language;
870
871public:
875 ExprSetLanguage(OutputLanguage l) : d_language(l) {}
876
877 inline void applyLanguage(std::ostream& out) {
878 // (offset by one to detect whether default has been set yet)
879 out.iword(s_iosIndex) = int(d_language) + 1;
880 }
881
882 static inline OutputLanguage getLanguage(std::ostream& out) {
883 long& l = out.iword(s_iosIndex);
884 if(l == 0) {
885 // set the default language on this ostream
886 // (offset by one to detect whether default has been set yet)
887 if(&Options::current() != NULL) {
888 l = options::outputLanguage() + 1;
889 }
890 if(l <= 0 || l > language::output::LANG_MAX) {
891 // if called from outside the library, we may not have options
892 // available to us at this point (or perhaps the output language
893 // is not set in Options). Default to something reasonable, but
894 // don't set "l" since that would make it "sticky" for this
895 // stream.
896 return OutputLanguage(s_defaultOutputLanguage);
897 }
898 }
899 return OutputLanguage(l - 1);
900 }
901
902 static inline void setLanguage(std::ostream& out, OutputLanguage l) {
903 // (offset by one to detect whether default has been set yet)
904 out.iword(s_iosIndex) = int(l) + 1;
905 }
906
913 class Scope {
914 std::ostream& d_out;
915 OutputLanguage d_oldLanguage;
916
917 public:
918
919 inline Scope(std::ostream& out, OutputLanguage language) :
920 d_out(out),
921 d_oldLanguage(ExprSetLanguage::getLanguage(out)) {
922 ExprSetLanguage::setLanguage(out, language);
923 }
924
925 inline ~Scope() {
926 ExprSetLanguage::setLanguage(d_out, d_oldLanguage);
927 }
928
929 };/* class ExprSetLanguage::Scope */
930
931};/* class ExprSetLanguage */
932
933}/* CVC4::expr namespace */
934
935${getConst_instantiations}
936
937#line 938 "${template}"
938
939namespace expr {
940
950inline std::ostream& operator<<(std::ostream& out, ExprSetDepth sd) {
951 sd.applyDepth(out);
952 return out;
953}
954
964inline std::ostream& operator<<(std::ostream& out, ExprPrintTypes pt) {
965 pt.applyPrintTypes(out);
966 return out;
967}
968
978inline std::ostream& operator<<(std::ostream& out, ExprDag d) {
979 d.applyDag(out);
980 return out;
981}
982
992inline std::ostream& operator<<(std::ostream& out, ExprSetLanguage l) {
993 l.applyLanguage(out);
994 return out;
995}
996
997}/* CVC4::expr namespace */
998
999inline size_t ExprHashFunction::operator()(CVC4::Expr e) const {
1000 return (size_t) e.getId();
1001}
1002
1003}/* CVC4 namespace */
1004
1005#endif /* __CVC4__EXPR_H */
void * Expr
void * Type
void * ExprManager
Class encapsulating CVC4 expressions and methods for constructing new expressions.
Definition expr.h:227
unsigned long getId() const
Get the ID of this expression (used for the comparison operators).
Macros that should be defined everywhere during the building of the libraries and driver binary,...
#define CVC4_PUBLIC
Definition cvc4_public.h:30
CVC4's exception base class and some associated utilities.
[[ Add one-line brief description here ]]
Definition of input and output languages.
bool operator!=(const Cardinality &c, CVC3CardinalityKind d)
bool operator==(const Cardinality &c, CVC3CardinalityKind d)
@ $
marks the upper-bound of this enumeration
struct CVC4::options::out__option_t out
TheoryId & operator++(TheoryId &id)
Definition kind.h:610
Definition expr.h:106
::CVC4::kind::Kind_t Kind
Definition kind.h:279
language::output::Language OutputLanguage
Definition language.h:166
std::ostream & operator<<(std::ostream &out, const TypeCheckingException &e)
STL namespace.