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>
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>
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>
33namespace BinaryAnalysis {
40namespace SymbolicExpression {
153using Nodes = std::vector<Ptr>;
237#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
239 friend class boost::serialization::access;
242 void serialize(S &s,
const unsigned version) {
244 s & BOOST_SERIALIZATION_NVP(fields_);
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);
325 return (
TypeClass)((fields_ >> 30) & 0x3);
333 return fields_ & 0x7fff;
342 return secondaryWidth();
351 return secondaryWidth();
371 return fields_ == other.fields_;
374 return !(*
this == other);
391 ASSERT_require(n <= 3);
392 fields_ = (fields_ & 0x3fffffff) | (n << 30);
396 void nBits(
size_t n) {
398 throw Exception(
"type width is out of range");
399 fields_ = (fields_ & 0xffff8000) | n;
403 void secondaryWidth(
size_t n) {
405 throw Exception(
"second width is out of range");
406 fields_ = (fields_ & 0xc0007fff) | (n << 15);
409 size_t secondaryWidth()
const {
410 return (fields_ >> 15) & 0x7fff;
467#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
469 friend class boost::serialization::access;
472 void serialize(S &s,
const unsigned version) {
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_);
500 static const unsigned BOTTOM = 0x00000004;
508 explicit Node(
const std::string &
comment,
unsigned flags=0)
725 return type_.
nBits();
823 void print(std::ostream &stream)
const { node->print(stream, formatter); }
875 void printFlags(std::ostream &o,
unsigned flags,
char &bracket)
const;
878 using EquivPairs = std::map<Node*, std::vector<std::pair<Node*, bool>>>;
879 virtual bool isEquivalentHelper(
Node*, EquivPairs&) = 0;
890 virtual Ptr fold(Nodes::const_iterator , Nodes::const_iterator )
const {
902 size_t operator()(
const Ptr &expr)
const {
908 bool operator()(
const Ptr &a,
const Ptr &b)
const {
909 return a->isEquivalentTo(b);
916 bool operator()(
const Ptr &a,
const Ptr &b)
const;
920class ExprExprHashMap:
public boost::unordered_map<SymbolicExpression::Ptr, SymbolicExpression::Ptr,
921 ExprExprHashMapHasher, ExprExprHashMapCompare> {
935 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
939 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
946 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
950 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
954 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
957 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
960 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator)
const override;
1041 Ptr combine_strengths(
Ptr strength1,
Ptr strength2,
size_t value_width,
const SmtSolverPtr &solver)
const;
1082#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1084 friend class boost::serialization::access;
1087 void serialize(S &s,
const unsigned ) {
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_);
1135 virtual bool isEquivalentHelper(
Node*, EquivPairs&)
override;
1139 virtual uint64_t
nNodes()
const override {
return nnodes_; }
1140 virtual const Nodes&
children()
const override {
return children_; }
1142 virtual size_t nChildren()
const override {
return children_.size(); }
1248#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1250 friend class boost::serialization::access;
1253 void save(S &s,
const unsigned )
const {
1254 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Node);
1255 s & BOOST_SERIALIZATION_NVP(bits_);
1256 s & BOOST_SERIALIZATION_NVP(name_);
1260 void load(S &s,
const unsigned ) {
1261 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Node);
1262 s & BOOST_SERIALIZATION_NVP(bits_);
1263 s & BOOST_SERIALIZATION_NVP(name_);
1264 nextNameCounter(name_);
1267 BOOST_SERIALIZATION_SPLIT_MEMBER();
1305 virtual bool isEquivalentHelper(
Node*, EquivPairs&)
override;
1309 virtual uint64_t
nNodes()
const override {
return 1; }
1363 static uint64_t nextNameCounter(uint64_t useThis = (uint64_t)(-1));
1522std::ostream& operator<<(std::ostream &o,
const Node&);
1538template<
typename InputIterator>
1540nNodes(InputIterator begin, InputIterator end) {
1542 for (InputIterator ii=begin; ii!=end; ++ii) {
1543 uint64_t n = (*ii)->nnodes();
1546 if (total + n < total)
1557template<
typename InputIterator>
1562 typedef std::set<const Node*> SeenNodes;
1570 ASSERT_not_null(node);
1571 if (seen.insert(node).second) {
1585 for (InputIterator ii=begin; ii!=end &&
TERMINATE!=status; ++ii)
1586 status = (*ii)->depthFirstTraversal(visitor);
1587 return visitor.nUnique;
1598template<
typename InputIterator>
1603 NodeCounts nodeCounts;
1604 std::vector<Ptr> result;
1607 ASSERT_not_null(node);
1608 size_t &nSeen = nodeCounts.insertMaybe(node, 0);
1610 result.push_back(
Ptr(
const_cast<Node*
>(node)));
1619 for (InputIterator ii=begin; ii!=end; ++ii)
1620 (*ii)->depthFirstTraversal(visitor);
1621 return visitor.result;
1632template<
class Substitution>
1638 Ptr dst = subber(src, solver);
1639 ASSERT_not_null(dst);
1647 bool anyChildChanged =
false;
1649 newChildren.reserve(inode->
nChildren());
1652 if (newChild != child)
1653 anyChildChanged =
true;
1654 newChildren.push_back(newChild);
1656 if (!anyChildChanged)
1670#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
Extends std::map with methods that return optional values.
Exceptions for symbolic expressions.
Mapping from expression to expression.
Compare two expressions for STL containers.
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.
std::string comment_
Optional comment.
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.
unsigned flags_
Bit 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.
Type type() const
Type of value.
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.
Type of symbolic expression.
static Type none()
Create no type.
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.
Type()
Create an invalid, empty type.
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.
@ INVALID
Default constructed.
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.
bool isEmpty() const
Determines if the vector is empty.
Container associating values with keys.
Holds a value or nothing.
Creates SharedPointer from this.
SharedPointer< Node > sharedFromThis()
Create a shared pointer from this.
Base class for reference counted objects.
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_CONCAT
Concatenation.
@ OP_FP_ISNAN
Floating-point NaN class.
@ OP_OR
Bitwise disjunction.
@ OP_SGE
Signed greater-than-or-equal.
@ OP_FP_ISNEG
Floating-point negative class.
@ OP_ULE
Unsigned less-than-or-equal.
@ OP_FP_MAX
Floating-point maximum.
@ OP_EXTRACT
Extract subsequence of bits.
@ OP_SGT
Signed greater-than.
@ OP_WRITE
Write (update) memory with a new value.
@ OP_FP_GE
Floating-point greater-than or equal.
@ OP_FP_NEGATE
Floating-point negation.
@ OP_FP_ROUND
Floating-point round to integer as FP type.
@ OP_FP_DIV
Floating-point division.
@ OP_FP_EQ
Floating-point equality.
@ OP_FP_MOD
Floating-point remainder.
@ OP_FP_LE
Floating-point less-than or equal.
@ OP_FP_ADD
Floating-point addition.
@ OP_FP_GT
Floating-point greater than.
@ OP_SLE
Signed 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_SMUL
Signed multiplication.
@ OP_FP_MIN
Floating-point minimum.
@ OP_XOR
Bitwise exclusive disjunction.
@ OP_READ
Read a value from memory.
@ OP_UEXTEND
Unsigned extention at msb.
@ OP_SHL1
Shift left, introducing ones at lsb.
@ OP_ASR
Arithmetic shift right.
@ OP_SHR0
Shift right, introducing zeros at msb.
@ OP_UDIV
Signed division.
@ OP_FP_ISNORM
Floating-point normal class.
@ OP_FP_ISPOS
Floating-point positive class.
@ OP_FP_SQRT
Floating-point square root.
@ OP_FP_ABS
Floating-point absolute value.
@ OP_FP_MULADD
Floating-point multiply-add.
@ OP_FP_MUL
Floating-point multiply.
@ OP_MSSB
Most significant set bit or zero.
@ OP_INVERT
Bitwise inversion.
@ OP_SLT
Signed less-than.
@ OP_ULT
Unsigned less-than.
@ OP_NEGATE
Arithmetic negation.
@ OP_FP_LT
Floating-point less-than.
@ OP_FP_ISSUBNORM
Floating-point subnormal class.
@ OP_FP_ISZERO
Floating-point zero class.
@ OP_SET
Set of expressions.
@ OP_AND
Bitwise conjunction.
@ OP_UMUL
Unsigned multiplication.
@ OP_REINTERPRET
Interpret the value as a different type without converting.
@ OP_UGE
Unsigned greater-than-or-equal.
@ OP_SDIV
Signed division.
@ OP_UGT
Unsigned greater-than.
@ OP_UMOD
Unsigned modulus.
@ OP_SEXTEND
Signed extension at msb.
@ 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.
VisitAction
Return type for visitors.
@ TERMINATE
Terminate the traversal.
@ 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.
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 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.