ROSE 0.11.145.192
SymbolicExpression.h
1#ifndef ROSE_BinaryAnalysis_SymbolicExpression_H
2#define ROSE_BinaryAnalysis_SymbolicExpression_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
5#include <Rose/BinaryAnalysis/BasicTypes.h>
6#include <Rose/Exception.h>
7
8#include "Map.h"
9
10#include <boost/any.hpp>
11#include <boost/lexical_cast.hpp>
12#include <boost/logic/tribool.hpp>
13#include <boost/serialization/access.hpp>
14#include <boost/serialization/base_object.hpp>
15#include <boost/serialization/export.hpp>
16#include <boost/serialization/split_member.hpp>
17#include <boost/serialization/string.hpp>
18#include <boost/serialization/vector.hpp>
19#include <boost/unordered_map.hpp>
20#include <cassert>
21#include <inttypes.h>
22#include <Sawyer/Attribute.h>
23#include <Sawyer/BitVector.h>
24#include <Sawyer/Optional.h>
25#include <Sawyer/Set.h>
26#include <Sawyer/SharedPointer.h>
27#include <Sawyer/SmallObject.h>
28#include <set>
29#include <string>
30#include <vector>
31
32namespace Rose {
33namespace BinaryAnalysis {
34
40namespace SymbolicExpression {
41
43// Basic Types and settings
45
54extern bool serializeVariableIds;
55
57namespace TypeStyle {
63}
64
65
68public:
69 explicit Exception(const std::string &mesg): Rose::Exception(mesg) {}
70};
71
150
151std::string toStr(Operator);
152
153using Nodes = std::vector<Ptr>;
154using RenameMap = Map<uint64_t, uint64_t>;
155
157using Hash = uint64_t;
158
181
188
193extern const uint64_t MAX_NNODES; // defined in .C so we don't pollute user namespace with limit macros
194
206class Visitor {
207public:
208 virtual ~Visitor() {}
209
210 virtual VisitAction preVisit(const Ptr&);
211 virtual VisitAction postVisit(const Ptr&);
212
213 virtual VisitAction preVisit(const Node*);
214 virtual VisitAction postVisit(const Node*);
215};
216
218// Expression type information
220
222class Type {
223public:
231
232private:
233 // We use a 32-bit data member and pack into it the totalWidth (15 bits: 0 through 14), the secondaryWidth (15 bits: 15 through 29),
234 // and the type class (2 bits: 30 and 31).
235 uint32_t fields_;
236
237#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
238private:
239 friend class boost::serialization::access;
240
241 template<class S>
242 void serialize(S &s, const unsigned version) {
243 if (version >= 1) {
244 s & BOOST_SERIALIZATION_NVP(fields_);
245 } else {
246 TypeClass t = typeClass();
247 size_t z1 = nBits();
248 size_t z2 = secondaryWidth();
249 s & boost::serialization::make_nvp("typeClass_", t);
250 s & boost::serialization::make_nvp("totalWidth_", z1);
251 s & boost::serialization::make_nvp("secondaryWidth_", z2);
252 typeClass(t);
253 nBits(z1);
254 secondaryWidth(z2);
255 }
256 }
257#endif
258
262public:
264 : fields_(0) {
266 nBits(0);
267 secondaryWidth(0);
268 }
269
270private:
271 Type(TypeClass tc, size_t w1, size_t w2)
272 : fields_(0) {
273 typeClass(tc);
274 nBits(w1);
275 secondaryWidth(w2);
276 }
277
278public:
282 static Type none() {
283 return Type();
284 }
285
291 static Type integer(size_t nBits) {
292 return Type(INTEGER, nBits, 0);
293 }
294
298 static Type memory(size_t addressWidth, size_t valueWidth) {
299 return Type(MEMORY, valueWidth, addressWidth);
300 }
301
311 return Type(FP, 1 /*sign bit*/ + exponentWidth + significandWidth - 1 /*implied bit*/, exponentWidth);
312 }
313
317 bool isValid() const {
318 return typeClass() != INVALID;
319 }
320
325 return (TypeClass)((fields_ >> 30) & 0x3);
326 }
327
332 size_t nBits() const {
333 return fields_ & 0x7fff;
334 }
335
340 size_t addressWidth() const {
341 ASSERT_require(MEMORY == typeClass());
342 return secondaryWidth();
343 }
344
349 size_t exponentWidth() const {
350 ASSERT_require(FP == typeClass());
351 return secondaryWidth();
352 }
353
359 size_t significandWidth() const {
360 ASSERT_require(FP == typeClass());
361 ASSERT_require(nBits() > 1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
362 return nBits() - (1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
363 }
364
370 bool operator==(const Type &other) const {
371 return fields_ == other.fields_;
372 }
373 bool operator!=(const Type &other) const {
374 return !(*this == other);
375 }
379 bool operator<(const Type &other) const;
380
382 void print(std::ostream&, TypeStyle::Flag style = TypeStyle::FULL) const;
383
385 std::string toString(TypeStyle::Flag style = TypeStyle::FULL) const;
386
387private:
388 // mutators are all private
389 void typeClass(TypeClass tc) {
390 unsigned n = tc;
391 ASSERT_require(n <= 3);
392 fields_ = (fields_ & 0x3fffffff) | (n << 30);
393 }
394
395 // mutators are all private
396 void nBits(size_t n) {
397 if (n > 0x7fff)
398 throw Exception("type width is out of range");
399 fields_ = (fields_ & 0xffff8000) | n;
400 }
401
402 // mutators are all private
403 void secondaryWidth(size_t n) {
404 if (n > 0x7fff)
405 throw Exception("second width is out of range");
406 fields_ = (fields_ & 0xc0007fff) | (n << 15);
407 }
408
409 size_t secondaryWidth() const {
410 return (fields_ >> 15) & 0x7fff;
411 }
412};
413
415// Base Node Type
417
455class Node
456 : public Sawyer::SharedObject,
457 public Sawyer::SharedFromThis<Node>,
458 public Sawyer::SmallObject,
459 public Sawyer::Attribute::Storage<> { // Attributes are not significant for hashing or arithmetic
460protected:
461 Type type_;
462 unsigned flags_;
463 std::string comment_;
464 mutable Hash hashval_;
465 boost::any userData_;
467#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
468private:
469 friend class boost::serialization::access;
470
471 template<class S>
472 void serialize(S &s, const unsigned version) {
473 if (version < 1)
474 ASSERT_not_reachable("SymbolicExpression version " + boost::lexical_cast<std::string>(version) + " is no longer supported");
475 s & BOOST_SERIALIZATION_NVP(type_);
476 s & BOOST_SERIALIZATION_NVP(flags_);
477 s & BOOST_SERIALIZATION_NVP(comment_);
478 s & BOOST_SERIALIZATION_NVP(hashval_);
479 // s & userData_;
480 }
481#endif
482
483public:
484 // Bit flags
485
487 static const unsigned RESERVED_FLAGS = 0x0000ffff;
488
490 static const unsigned INDETERMINATE = 0x00000001;
491
496 static const unsigned UNSPECIFIED = 0x00000002;
497
500 static const unsigned BOTTOM = 0x00000004;
501
502public:
503 virtual ~Node() {}
504
505protected:
506 Node()
507 : type_(Type::integer(0)), flags_(0), hashval_(0) {}
508 explicit Node(const std::string &comment, unsigned flags=0)
509 : type_(Type::integer(0)), flags_(flags), comment_(comment), hashval_(0) {}
510
511public:
513 Type type() const {
514 return type_;
515 }
516
523 static boost::logic::tribool (*mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr&);
524
530 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
531
533 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
534
540 virtual bool isEquivalentTo(const Ptr &other) = 0;
541
547 virtual int compareStructure(const Ptr &other) = 0;
548
554 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
555
563 Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver = SmtSolverPtr());
564
572 Ptr renameVariables(ExprExprHashMap &index /*in,out*/, size_t &nextVariableId /*in,out*/,
573 const SmtSolverPtr &solver = SmtSolverPtr());
574
578 virtual Operator getOperator() const = 0;
579
583 virtual size_t nChildren() const = 0;
584
591 virtual const Ptr& child(size_t idx) const = 0;
592 virtual const Node* childRaw(size_t idx) const = 0;
598 virtual const Nodes& children() const = 0;
599
605
610
612 bool isIntegerExpr() const {
613 return type_.typeClass() == Type::INTEGER;
614 }
615
617 bool isFloatingPointExpr() const {
618 return type_.typeClass() == Type::FP;
619 }
620
622 bool isMemoryExpr() const {
623 return type_.typeClass() == Type::MEMORY;
624 }
625
629 bool isScalarExpr() const {
631 }
632
634 virtual bool isConstant() const = 0;
635
637 bool isIntegerConstant() const {
638 return isIntegerExpr() && isConstant();
639 }
640
643 return isFloatingPointExpr() && isConstant();
644 }
645
649 bool isScalarConstant() const {
651 }
652
654 bool isFloatingPointNan() const;
655
661 virtual bool isVariable2() const = 0;
662
667
669 bool isIntegerVariable() const {
670 return isIntegerExpr() && isVariable2();
671 }
672
675 return isFloatingPointExpr() && isVariable2();
676 }
677
679 bool isMemoryVariable() const {
680 return isMemoryExpr() && isVariable2();
681 }
682
686 bool isScalarVariable() const {
688 }
689
698 const std::string& comment() const {
699 return comment_;
700 }
701 void comment(const std::string &s) {
702 comment_ = s;
703 }
713 void userData(boost::any &data) {
714 userData_ = data;
715 }
716 const boost::any& userData() const {
717 return userData_;
718 }
724 size_t nBits() const {
725 return type_.nBits();
726 }
727
732 unsigned flags() const {
733 return flags_;
734 }
735
739 Ptr newFlags(unsigned flags) const;
740
744 size_t domainWidth() const {
745 return type_.addressWidth();
746 }
747
751 bool isScalar() const {
752 return type_.typeClass() != Type::MEMORY;
753 }
754
760
776 virtual uint64_t nNodes() const = 0;
777
779 uint64_t nNodesUnique() const;
780
782 std::set<LeafPtr> getVariables() const;
783
805 bool isHashed() const {
806 return hashval_ != 0;
807 }
808
811 Hash hash() const;
812
813 // used internally to set the hash value
814 void hash(Hash) const;
815
818 private:
819 Ptr node;
820 Formatter &formatter;
821 public:
822 WithFormatter(const Ptr &node, Formatter &formatter): node(node), formatter(formatter) {}
823 void print(std::ostream &stream) const { node->print(stream, formatter); }
824 };
825
847 virtual void print(std::ostream&, Formatter&) const = 0;
848 void print(std::ostream &o) const { Formatter fmt; print(o, fmt); }
852 std::string toString() const;
853
855 void assertAcyclic() const;
856
862 std::vector<Ptr> findCommonSubexpressions() const;
863
869 bool matchAddVariableConstant(LeafPtr &variable/*out*/, LeafPtr &constant/*out*/) const;
870
873
874protected:
875 void printFlags(std::ostream &o, unsigned flags, char &bracket) const;
876
877public: // only used internally
878 using EquivPairs = std::map<Node*, std::vector<std::pair<Node*, bool>>>;
879 virtual bool isEquivalentHelper(Node*, EquivPairs&) = 0;
880};
881
884public:
885 virtual ~Simplifier() {}
886
890 virtual Ptr fold(Nodes::const_iterator /*begin*/, Nodes::const_iterator /*end*/) const {
891 return Ptr();
892 }
893
896 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const {
897 return Ptr();
898 }
899};
900
902 size_t operator()(const Ptr &expr) const {
903 return expr->hash();
904 }
905};
906
908 bool operator()(const Ptr &a, const Ptr &b) const {
909 return a->isEquivalentTo(b);
910 }
911};
912
915public:
916 bool operator()(const Ptr &a, const Ptr &b) const;
917};
918
920class ExprExprHashMap: public boost::unordered_map<SymbolicExpression::Ptr, SymbolicExpression::Ptr,
921 ExprExprHashMapHasher, ExprExprHashMapCompare> {
922public:
923 ExprExprHashMap invert() const;
924};
925
928
929
931// Simplification
933
935 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
936 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
937};
939 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
940 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
941};
943 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
944};
946 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
947 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
948};
950 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
951 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
952};
954 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
955};
957 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
958};
960 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
961 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
962};
964 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
965};
967 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
968};
970 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
971};
973 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
974};
976 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
977};
979 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
980};
982 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
983};
985 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
986};
988 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
989};
991 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
992};
994 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
995};
997 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
998};
1000 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1001};
1003 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1004};
1006 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1007};
1009 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1010};
1012 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1013};
1015 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1016};
1018 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1019};
1021 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1022};
1024 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1025};
1027 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1028};
1030 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1031};
1033 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1034};
1036 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1037};
1039 bool newbits;
1040 ShiftSimplifier(bool newbits): newbits(newbits) {}
1041 Ptr combine_strengths(Ptr strength1, Ptr strength2, size_t value_width, const SmtSolverPtr &solver) const;
1042};
1044 ShlSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1045 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1046};
1048 ShrSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1049 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1050};
1052 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1053};
1055 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1056};
1058 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1059};
1060
1061
1062
1064// Interior Nodes
1066
1073class Interior: public Node {
1074private:
1075 Operator op_;
1076 Nodes children_;
1077 uint64_t nnodes_; // total number of nodes; self + children's nnodes
1078
1079 //--------------------------------------------------------
1080 // Serialization
1081 //--------------------------------------------------------
1082#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1083private:
1084 friend class boost::serialization::access;
1085
1086 template<class S>
1087 void serialize(S &s, const unsigned /*version*/) {
1088 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1089 s & BOOST_SERIALIZATION_NVP(op_);
1090 s & BOOST_SERIALIZATION_NVP(children_);
1091 s & BOOST_SERIALIZATION_NVP(nnodes_);
1092 }
1093#endif
1094
1095 //--------------------------------------------------------
1096 // Real constructors
1097 //--------------------------------------------------------
1098private:
1099 Interior(); // needed for serialization
1100 // Only constructs, does not simplify.
1101 Interior(const Type&, Operator, const Nodes &arguments, const std::string &comment, unsigned flags);
1102
1103 //--------------------------------------------------------
1104 // Allocating constructors
1105 //--------------------------------------------------------
1106public:
1110 static Ptr instance(Operator op, const Ptr &a,
1111 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1112 static Ptr instance(const Type &type, Operator op, const Ptr &a,
1113 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1114 static Ptr instance(Operator op, const Ptr &a, const Ptr &b,
1115 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1116 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b,
1117 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1118 static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1119 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1120 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1121 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1122 static Ptr instance(Operator op, const Nodes &arguments,
1123 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1124 static Ptr instance(const Type &type, Operator op, const Nodes &arguments,
1125 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1128 //--------------------------------------------------------
1129 // Overrides
1130 //--------------------------------------------------------
1131public:
1132 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1133 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1134 virtual bool isEquivalentTo(const Ptr &other) override;
1135 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1136 virtual int compareStructure(const Ptr& other) override;
1137 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1138 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1139 virtual uint64_t nNodes() const override { return nnodes_; }
1140 virtual const Nodes& children() const override { return children_; }
1141 virtual Operator getOperator() const override { return op_; }
1142 virtual size_t nChildren() const override { return children_.size(); }
1143 virtual const Ptr& child(size_t idx) const override;
1144 virtual Node* childRaw(size_t idx) const override;
1145 virtual Sawyer::Optional<uint64_t> toUnsigned() const override { return Sawyer::Nothing(); }
1146 virtual Sawyer::Optional<int64_t> toSigned() const override { return Sawyer::Nothing(); }
1147 virtual bool isConstant() const override { return false; }
1148 virtual bool isVariable2() const override { return false; }
1149
1150 //--------------------------------------------------------
1151 // Simplification
1152 //--------------------------------------------------------
1153public:
1158
1162
1168
1174
1182
1187
1192
1196 Ptr identity(uint64_t ident, const SmtSolverPtr &solver = SmtSolverPtr());
1197
1203
1206
1210 Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver = SmtSolverPtr());
1211
1212 //--------------------------------------------------------
1213 // Functions specific to internal nodes
1214 //--------------------------------------------------------
1215public:
1216 virtual void print(std::ostream&, Formatter&) const override;
1217
1218protected:
1220 void addChild(const Ptr &child);
1221
1225 void adjustWidth(const Type&);
1226
1229 void adjustBitFlags(unsigned extraFlags);
1230};
1231
1232
1234// Leaf Nodes
1236
1240class Leaf: public Node {
1241private:
1242 Sawyer::Container::BitVector bits_; // Value for constants if size > 0
1243 uint64_t name_; // Variable ID for variables when bits_.size() == 0
1244
1245 //--------------------------------------------------------
1246 // Serialization
1247 //--------------------------------------------------------
1248#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1249private:
1250 friend class boost::serialization::access;
1251
1252 template<class S>
1253 void save(S &s, const unsigned /*version*/) const {
1254 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1255 s & BOOST_SERIALIZATION_NVP(bits_);
1256 s & BOOST_SERIALIZATION_NVP(name_);
1257 }
1258
1259 template<class S>
1260 void load(S &s, const unsigned /*version*/) {
1261 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1262 s & BOOST_SERIALIZATION_NVP(bits_);
1263 s & BOOST_SERIALIZATION_NVP(name_);
1264 nextNameCounter(name_);
1265 }
1266
1267 BOOST_SERIALIZATION_SPLIT_MEMBER();
1268#endif
1269
1270 //--------------------------------------------------------
1271 // Private constructors. Use create methods instead.
1272 //--------------------------------------------------------
1273private:
1274 Leaf()
1275 : name_(0) {}
1276 explicit Leaf(const std::string &comment, unsigned flags=0)
1277 : Node(comment, flags), name_(0) {}
1278
1279 // Allocating constructors.
1280public:
1283 const std::string &comment = "", unsigned flags = 0);
1284
1286 static LeafPtr createVariable(const Type&, const uint64_t id,
1287 const std::string &comment = "", unsigned flags = 0);
1288
1291 const std::string &comment = "", unsigned flags = 0);
1292
1293 //--------------------------------------------------------
1294 // Override base class implementations
1295 //--------------------------------------------------------
1296public:
1297 virtual size_t nChildren() const override { return 0; }
1298 virtual const Ptr& child(size_t idx) const override;
1299 virtual const Node* childRaw(size_t) const override { return nullptr; }
1300 virtual const Nodes& children() const override;
1301 virtual Operator getOperator() const override { return OP_NONE; }
1302 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1303 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1304 virtual bool isEquivalentTo(const Ptr &other) override;
1305 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1306 virtual int compareStructure(const Ptr& other) override;
1307 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1308 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1309 virtual uint64_t nNodes() const override { return 1; }
1310 virtual Sawyer::Optional<uint64_t> toUnsigned() const override;
1311 virtual Sawyer::Optional<int64_t> toSigned() const override;
1312 virtual bool isConstant() const override { return !bits_.isEmpty(); }
1313 virtual bool isVariable2() const override { return !isConstant(); }
1314 virtual void print(std::ostream&, Formatter&) const override;
1315
1316 //--------------------------------------------------------
1317 // Leaf-specific methods
1318 //--------------------------------------------------------
1319public:
1322
1324 bool isIntegerVariable() const {
1325 return type().typeClass() == Type::INTEGER && !isConstant();
1326 }
1327
1330 return type().typeClass() == Type::FP && !isConstant();
1331 }
1332
1335
1337 bool isMemoryVariable() const {
1338 return type().typeClass() == Type::MEMORY && !isConstant();
1339 }
1340
1345 uint64_t nameId() const;
1346
1351 std::string toString() const;
1352
1354 void printAsSigned(std::ostream&, Formatter&, bool asSigned = true) const;
1355
1357 void printAsUnsigned(std::ostream &o, Formatter &f) const {
1358 printAsSigned(o, f, false);
1359 }
1360
1361private:
1362 // Obtain or register a name ID
1363 static uint64_t nextNameCounter(uint64_t useThis = (uint64_t)(-1));
1364};
1365
1367// Factories
1369
1375LeafPtr makeVariable(const Type&, const std::string &comment="", unsigned flags=0);
1376LeafPtr makeVariable(const Type&, uint64_t id, const std::string &comment="", unsigned flags=0);
1377LeafPtr makeConstant(const Type&, const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1378LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0);
1379LeafPtr makeIntegerVariable(size_t nBits, uint64_t id, const std::string &comment="", unsigned flags=0);
1380LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0);
1381LeafPtr makeIntegerConstant(const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1382LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0);
1383LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0);
1384LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, uint64_t id, const std::string &comment="", unsigned flags=0);
1385LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1386LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, uint64_t id, const std::string &comment="", unsigned flags=0);
1387LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0);
1388LeafPtr makeFloatingPointConstant(double, const std::string &comment="", unsigned flags=0);
1389LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1398Ptr makeAdd(const Ptr&a, const Ptr &b,
1399 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1400Ptr makeAsr(const Ptr &sa, const Ptr &a,
1401 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1402Ptr makeAnd(const Ptr &a, const Ptr &b,
1403 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1404Ptr makeOr(const Ptr &a, const Ptr &b,
1405 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1406Ptr makeXor(const Ptr &a, const Ptr &b,
1407 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1408Ptr makeConcat(const Ptr &hi, const Ptr &lo,
1409 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1410Ptr makeConvert(const Ptr &a, const Type &b,
1411 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1412Ptr makeEq(const Ptr &a, const Ptr &b,
1413 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1414Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a,
1415 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1417 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1419 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1421 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1423 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1425 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1427 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1429 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1430Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b,
1431 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1432Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c,
1433 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1435 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1436Ptr makeMax(const Ptr &a, const Ptr &b,
1437 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1438Ptr makeMin(const Ptr &a, const Ptr &b,
1439 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1441 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1442Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c,
1443 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1444Ptr makeNe(const Ptr &a, const Ptr &b,
1445 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1447 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1448Ptr makeRead(const Ptr &mem, const Ptr &addr,
1449 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1450Ptr makeReinterpret(const Ptr &a, const Type &b,
1451 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1452Ptr makeRol(const Ptr &sa, const Ptr &a,
1453 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1454Ptr makeRor(const Ptr &sa, const Ptr &a,
1455 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1457 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1458Ptr makeSet(const Ptr &a, const Ptr &b,
1459 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1460Ptr makeSet(const Ptr &a, const Ptr &b, const Ptr &c,
1461 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1462Ptr makeSignedDiv(const Ptr &a, const Ptr &b,
1463 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1464Ptr makeSignExtend(const Ptr &newSize, const Ptr &a,
1465 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1466Ptr makeSignedGe(const Ptr &a, const Ptr &b,
1467 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1468Ptr makeSignedGt(const Ptr &a, const Ptr &b,
1469 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1470Ptr makeShl0(const Ptr &sa, const Ptr &a,
1471 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1472Ptr makeShl1(const Ptr &sa, const Ptr &a,
1473 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1474Ptr makeShr0(const Ptr &sa, const Ptr &a,
1475 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1476Ptr makeShr1(const Ptr &sa, const Ptr &a,
1477 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1479 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1480Ptr makeSignedLe(const Ptr &a, const Ptr &b,
1481 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1482Ptr makeSignedLt(const Ptr &a, const Ptr &b,
1483 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1484Ptr makeSignedMax(const Ptr &a, const Ptr &b,
1485 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1486Ptr makeSignedMin(const Ptr &a, const Ptr &b,
1487 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1488Ptr makeSignedMod(const Ptr &a, const Ptr &b,
1489 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1490Ptr makeSignedMul(const Ptr &a, const Ptr &b,
1491 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1493 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1494Ptr makeDiv(const Ptr &a, const Ptr &b,
1495 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1496Ptr makeExtend(const Ptr &newSize, const Ptr &a,
1497 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1498Ptr makeGe(const Ptr &a, const Ptr &b,
1499 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1500Ptr makeGt(const Ptr &a, const Ptr &b,
1501 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1502Ptr makeLe(const Ptr &a, const Ptr &b,
1503 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1504Ptr makeLt(const Ptr &a, const Ptr &b,
1505 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1506Ptr makeMod(const Ptr &a, const Ptr &b,
1507 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1508Ptr makeMul(const Ptr &a, const Ptr &b,
1509 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1510Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a,
1511 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1513 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1518// Miscellaneous functions
1520
1521
1522std::ostream& operator<<(std::ostream &o, const Node&);
1523std::ostream& operator<<(std::ostream &o, const Node::WithFormatter&);
1524
1526Ptr setToIte(const Ptr&, const SmtSolverPtr &solver = SmtSolverPtr(), const LeafPtr &var = LeafPtr());
1527
1532Hash hash(const std::vector<Ptr>&);
1533
1538template<typename InputIterator>
1539uint64_t
1540nNodes(InputIterator begin, InputIterator end) {
1541 uint64_t total = 0;
1542 for (InputIterator ii=begin; ii!=end; ++ii) {
1543 uint64_t n = (*ii)->nnodes();
1544 if (MAX_NNODES==n)
1545 return MAX_NNODES;
1546 if (total + n < total)
1547 return MAX_NNODES;
1548 total += n;
1549 }
1550 return total;
1551}
1552
1557template<typename InputIterator>
1558uint64_t
1559nNodesUnique(InputIterator begin, InputIterator end)
1560{
1561 struct T1: Visitor {
1562 typedef std::set<const Node*> SeenNodes;
1563
1564 SeenNodes seen; // nodes that we've already seen, and the subtree size
1565 uint64_t nUnique; // number of unique nodes
1566
1567 T1(): nUnique(0) {}
1568
1569 VisitAction preVisit(const Node *node) override {
1570 ASSERT_not_null(node);
1571 if (seen.insert(node).second) {
1572 ++nUnique;
1573 return CONTINUE; // this node has not been seen before; traverse into children
1574 } else {
1575 return TRUNCATE; // this node has been seen already; skip over the children
1576 }
1577 }
1578
1579 VisitAction postVisit(const Node*) override {
1580 return CONTINUE;
1581 }
1582 } visitor;
1583
1584 VisitAction status = CONTINUE;
1585 for (InputIterator ii=begin; ii!=end && TERMINATE!=status; ++ii)
1586 status = (*ii)->depthFirstTraversal(visitor);
1587 return visitor.nUnique;
1588}
1589
1596std::vector<Ptr> findCommonSubexpressions(const std::vector<Ptr>&);
1597
1598template<typename InputIterator>
1599std::vector<Ptr>
1600findCommonSubexpressions(InputIterator begin, InputIterator end) {
1602 struct T1: Visitor {
1603 NodeCounts nodeCounts;
1604 std::vector<Ptr> result;
1605
1606 VisitAction preVisit(const Node *node) override {
1607 ASSERT_not_null(node);
1608 size_t &nSeen = nodeCounts.insertMaybe(node, 0);
1609 if (2 == ++nSeen)
1610 result.push_back(Ptr(const_cast<Node*>(node)));
1611 return nSeen>1 ? TRUNCATE : CONTINUE;
1612 }
1613
1614 VisitAction postVisit(const Node*) override {
1615 return CONTINUE;
1616 }
1617 } visitor;
1618
1619 for (InputIterator ii=begin; ii!=end; ++ii)
1620 (*ii)->depthFirstTraversal(visitor);
1621 return visitor.result;
1622}
1632template<class Substitution>
1633Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver = SmtSolverPtr()) {
1634 if (!src)
1635 return Ptr(); // no input implies no output
1636
1637 // Try substituting the whole expression, returning the result.
1638 Ptr dst = subber(src, solver);
1639 ASSERT_not_null(dst);
1640 if (dst != src)
1641 return dst;
1642
1643 // Try substituting all the subexpressions.
1644 const Interior *inode = src->isInteriorNodeRaw();
1645 if (!inode)
1646 return src;
1647 bool anyChildChanged = false;
1648 Nodes newChildren;
1649 newChildren.reserve(inode->nChildren());
1650 for (const Ptr &child: inode->children()) {
1651 Ptr newChild = substitute(child, subber, solver);
1652 if (newChild != child)
1653 anyChildChanged = true;
1654 newChildren.push_back(newChild);
1655 }
1656 if (!anyChildChanged)
1657 return src;
1658
1659 // Some subexpression changed, so build a new expression
1660 return Interior::instance(inode->getOperator(), newChildren, solver, inode->comment(), inode->flags());
1661}
1662
1663} // namespace
1664
1665using SymbolicExpressionPtr = SymbolicExpression::Ptr;
1666
1667} // namespace
1668} // namespace
1669
1670#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1675#endif
1676
1677#endif
1678#endif
Extends std::map with methods that return optional values.
Definition util/Map.h:13
Compare two expressions for STL containers.
Controls formatting of expression trees when printing.
size_t max_depth
If non-zero, then replace deep parts of expressions with "...".
ShowComments show_comments
Show node comments when printing?
@ CMT_BEFORE
Like CMT_INSTEAD, but show the name as a comment.
@ CMT_INSTEAD
Like CMT_AFTER, but show comments instead of variable names.
RenameMap renames
Map for renaming variables to use smaller integers.
bool show_type
Show data type inside square brackets.
bool add_renames
Add additional entries to the renames as variables are encountered?
bool use_hexadecimal
Show values in hexadecimal and decimal rather than just decimal.
bool show_flags
Show user-defined flags inside square brackets.
bool do_rename
Use the renames map to rename variables to shorter names?
Interior node of an expression tree for instruction semantics.
virtual Node * childRaw(size_t idx) const override
Argument.
Ptr poisonNan(const SmtSolverPtr &solver=SmtSolverPtr())
Returns NaN if any argument is NaN.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
Ptr involutary()
Simplifies involutary operators.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
static Ptr instance(Operator op, const Nodes &arguments, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
Ptr additiveNesting(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies nested shift-like operators.
Ptr identity(uint64_t ident, const SmtSolverPtr &solver=SmtSolverPtr())
Removes identity arguments.
static Ptr instance(const Type &type, Operator op, const Nodes &arguments, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
Ptr foldConstants(const Simplifier &)
Perform constant folding.
Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver=SmtSolverPtr())
Simplify an interior node.
void adjustWidth(const Type &)
Adjust width based on operands.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
InteriorPtr commutative()
Simplifies commutative operators by sorting arguments.
virtual bool isVariable2() const override
True if this expression is a variable.
static Ptr instance(Operator op, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
void adjustBitFlags(unsigned extraFlags)
Adjust user-defined bit flags.
InteriorPtr associative()
Simplifies non-associative operators by flattening the specified interior node with its children that...
virtual const Ptr & child(size_t idx) const override
Argument.
Ptr simplifyTop(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies the specified interior node.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
InteriorPtr idempotent(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies idempotent operators.
virtual const Nodes & children() const override
Arguments.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
Ptr unaryNoOp()
Replaces a binary operator with its only argument.
static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual size_t nChildren() const override
Number of arguments.
void addChild(const Ptr &child)
Appends child as a new child of this node.
virtual bool isConstant() const override
True if this expression is a constant.
virtual Operator getOperator() const override
Operator for interior nodes.
Leaf node of an expression tree for instruction semantics.
virtual const Nodes & children() const override
Arguments.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
bool isIntegerVariable() const
Is this node an integer variable?
bool isFloatingPointVariable() const
Is this node a floating-point variable?
virtual bool isConstant() const override
True if this expression is a constant.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
virtual bool isVariable2() const override
True if this expression is a variable.
static LeafPtr createConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Create a constant.
void printAsUnsigned(std::ostream &o, Formatter &f) const
Prints an integer constant interpreted as an unsigned value.
virtual const Node * childRaw(size_t) const override
Argument.
static LeafPtr createVariable(const Type &, const uint64_t id, const std::string &comment="", unsigned flags=0)
Create an existing variable.
virtual size_t nChildren() const override
Number of arguments.
std::string toString() const
Returns a string for the leaf.
bool isFloatingPointNan() const
Is this node a floating-point NaN constant?
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
virtual Operator getOperator() const override
Operator for interior nodes.
void printAsSigned(std::ostream &, Formatter &, bool asSigned=true) const
Prints an integer constant interpreted as a signed value.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
bool isMemoryVariable() const
Is this node a memory variable?
const Sawyer::Container::BitVector & bits() const
Property: Bits stored for numeric constants.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
uint64_t nameId() const
Returns the name ID of a free variable.
static LeafPtr createVariable(const Type &, const std::string &comment="", unsigned flags=0)
Create a new variable.
virtual const Ptr & child(size_t idx) const override
Argument.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
Base class for symbolic expression nodes.
size_t domainWidth() const
Property: Width for memory expressions.
bool isIntegerVariable() const
True if this expression is an integer variable.
virtual bool isConstant() const =0
True if this expression is a constant.
std::string toString() const
Convert expression to string.
virtual size_t nChildren() const =0
Number of arguments.
static const unsigned UNSPECIFIED
Value is somehow unspecified.
InteriorPtr isInteriorNode() const
Dynamic cast of this object to an interior node.
virtual void print(std::ostream &, Formatter &) const =0
Print the expression to a stream.
Hash hash() const
Returns (and caches) the hash value for this node.
WithFormatter operator+(Formatter &fmt)
Combines a node with a formatter for printing.
Sawyer::Optional< uint64_t > variableId() const
Variable ID number.
bool isHashed() const
Returns true if this node has a hash value computed and cached.
bool isFloatingPointNan() const
True if this expression is a floating-point NaN constant.
InteriorPtr isOperator(Operator) const
True (non-null) if this node is the specified operator.
static boost::logic::tribool(* mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr &)
User-supplied predicate to augment alias checking.
uint64_t nNodesUnique() const
Number of unique nodes in expression.
bool isFloatingPointVariable() const
True if this expression is a floating-point variable.
virtual const Node * childRaw(size_t idx) const =0
Argument.
Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite expression by substituting subexpressions.
boost::any userData_
Additional user-specified data.
void print(std::ostream &o) const
Print the expression to a stream.
bool isScalarConstant() const
True if this expression is a scalar constant.
bool isScalar() const
Check whether expression is scalar.
bool isFloatingPointConstant() const
True if this epxression is a floating-point constant.
bool isIntegerConstant() const
True if this expression is an integer constant.
Ptr newFlags(unsigned flags) const
Sets flags.
void comment(const std::string &s)
Property: Comment.
bool isMemoryVariable() const
True if this expression is a memory state variable.
virtual const Nodes & children() const =0
Arguments.
bool isScalarVariable() const
True if this expression is a scalar variable.
void userData(boost::any &data)
Property: User-defined data.
Hash hashval_
Optional hash used as a quick way to indicate that two expressions are different.
virtual uint64_t nNodes() const =0
Computes the size of an expression by counting the number of nodes.
size_t nBits() const
Property: Number of significant bits.
virtual Sawyer::Optional< int64_t > toSigned() const =0
The signed integer value of the expression.
const std::string & comment() const
Property: Comment.
virtual VisitAction depthFirstTraversal(Visitor &) const =0
Traverse the expression.
virtual bool isEquivalentTo(const Ptr &other)=0
Tests two expressions for structural equivalence.
bool matchAddVariableConstant(LeafPtr &variable, LeafPtr &constant) const
Determine whether an expression is a variable plus a constant.
LeafPtr isLeafNode() const
Dynamic cast of this object to a leaf node.
void assertAcyclic() const
Asserts that expressions are acyclic.
Interior * isInteriorNodeRaw() const
Dynamic cast of this object to an interior node.
virtual bool isVariable2() const =0
True if this expression is a variable.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions must be equal (cannot be unequal).
virtual Sawyer::Optional< uint64_t > toUnsigned() const =0
The unsigned integer value of the expression.
bool isScalarExpr() const
True if the expression is a scalar type.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr())=0
Substitute one value for another.
static const unsigned BOTTOM
Value represents bottom in dataflow analysis.
bool isMemoryExpr() const
True if this expression is of a memory type.
Ptr renameVariables(ExprExprHashMap &index, size_t &nextVariableId, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite using lowest numbered variable names.
bool isFloatingPointExpr() const
True if this expression is of a floating-point type.
bool isIntegerExpr() const
True if this expression is of an integer type.
virtual Operator getOperator() const =0
Operator for interior nodes.
std::set< LeafPtr > getVariables() const
Returns the variables appearing in the expression.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions might be equal, but not necessarily be equal.
static const unsigned RESERVED_FLAGS
These flags are reserved for use within ROSE.
unsigned flags() const
Property: User-defined bit flags.
virtual const Ptr & child(size_t idx) const =0
Argument.
virtual int compareStructure(const Ptr &other)=0
Compare two expressions structurally for sorting.
std::vector< Ptr > findCommonSubexpressions() const
Find common subexpressions.
static const unsigned INDETERMINATE
Value is somehow indeterminate.
Leaf * isLeafNodeRaw() const
Dynamic cast of this object to a leaf node.
const boost::any & userData() const
Property: User-defined data.
WithFormatter withFormat(Formatter &fmt)
Combines a node with a formatter for printing.
Operator-specific simplification methods.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const
Constant folding.
bool operator<(const Type &other) const
Type comparison.
std::string toString(TypeStyle::Flag style=TypeStyle::FULL) const
Print the type to a string.
TypeClass typeClass() const
Property: Type class.
size_t significandWidth() const
Property: Significand width.
void print(std::ostream &, TypeStyle::Flag style=TypeStyle::FULL) const
Print the type.
static Type floatingPoint(size_t exponentWidth, size_t significandWidth)
Create a new floating-point type.
static Type memory(size_t addressWidth, size_t valueWidth)
Create a new memory type.
size_t addressWidth() const
Property: Width of memory addresses.
static Type integer(size_t nBits)
Create a new integer type.
size_t nBits() const
Property: Total width of values.
bool operator==(const Type &other) const
Type equality.
size_t exponentWidth() const
Property: Exponent width.
bool isValid() const
Check whether this object is valid.
bool operator!=(const Type &other) const
Type equality.
Base class for visiting nodes during expression traversal.
Base class for all ROSE exceptions.
API and storage for attributes.
Definition Attribute.h:215
bool isEmpty() const
Determines if the vector is empty.
Definition BitVector.h:203
Container associating values with keys.
Definition Sawyer/Map.h:72
Ordered set of values.
Definition Set.h:56
Represents no value.
Definition Optional.h:36
Holds a value or nothing.
Definition Optional.h:56
Creates SharedPointer from this.
SharedPointer< Node > sharedFromThis()
Create a shared pointer from this.
Base class for reference counted objects.
Small object support.
Definition SmallObject.h:19
Flag
Flag to pass as type stringification style.
@ ABBREVIATED
Use abbreviated names if possible.
Ptr makeSignedLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeNe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNan(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsSignedPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeXor(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeRead(const Ptr &mem, const Ptr &addr, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeVariable(const Type &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeNegate(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t Hash
Hash of symbolic expression.
Ptr makeAsr(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
const uint64_t MAX_NNODES
Maximum number of nodes that can be reported.
Ptr makeIsInfinite(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeRound(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::Container::Set< Ptr, ExpressionLessp > ExpressionSet
Set of expressions ordered by hash.
LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0)
Leaf constructor.
LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeSignedGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShl0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeConcat(const Ptr &hi, const Ptr &lo, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr setToIte(const Ptr &, const SmtSolverPtr &solver=SmtSolverPtr(), const LeafPtr &var=LeafPtr())
Convert a set to an ite expression.
Ptr makeMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Operator
Operators for interior nodes of the expression tree.
@ OP_SGE
Signed greater-than-or-equal.
@ OP_FP_ISNEG
Floating-point negative class.
@ OP_EXTRACT
Extract subsequence of bits.
@ OP_WRITE
Write (update) memory with a new value.
@ OP_FP_GE
Floating-point greater-than or equal.
@ OP_FP_ROUND
Floating-point round to integer as FP type.
@ OP_FP_LE
Floating-point less-than or equal.
@ OP_LSSB
Least significant set bit or zero.
@ OP_SHR1
Shift right, introducing ones at msb.
@ OP_SHL0
Shift left, introducing zeros at lsb.
@ OP_XOR
Bitwise exclusive disjunction.
@ OP_SHL1
Shift left, introducing ones at lsb.
@ OP_SHR0
Shift right, introducing zeros at msb.
@ OP_FP_ISNORM
Floating-point normal class.
@ OP_FP_ISPOS
Floating-point positive class.
@ OP_FP_ABS
Floating-point absolute value.
@ OP_FP_MULADD
Floating-point multiply-add.
@ OP_MSSB
Most significant set bit or zero.
@ OP_FP_ISSUBNORM
Floating-point subnormal class.
@ OP_REINTERPRET
Interpret the value as a different type without converting.
@ OP_UGE
Unsigned greater-than-or-equal.
@ OP_FP_ISINFINITE
Floating-point infinity class.
@ OP_CONVERT
Convert from one type to another.
Ptr makeSignExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t nNodes(InputIterator begin, InputIterator end)
Counts the number of nodes.
Hash hash(const std::vector< Ptr > &)
Hash zero or more expressions.
Ptr makeMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShl1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeReinterpret(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t nNodesUnique(InputIterator begin, InputIterator end)
Counts the number of unique nodes.
Ptr makeConvert(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNeg(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSet(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeShr1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeOr(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeAnd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeRol(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShr0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
@ TRUNCATE
For a pre-order depth-first visit, do not descend into children.
@ CONTINUE
Continue the traversal as normal.
Ptr makeSqrt(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeZerop(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsSubnorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool serializeVariableIds
Whether to serialize variable IDs.
Ptr makeInvert(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeEq(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeAdd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::SharedPointer< Leaf > LeafPtr
Reference counting pointer.
Ptr makeRor(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver=SmtSolverPtr())
On-the-fly substitutions.
std::vector< Ptr > findCommonSubexpressions(const std::vector< Ptr > &)
Find common subexpressions.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
The ROSE library.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.