SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
ExpressionVisitor.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <type_traits>
5 
6 #include <optional>
7 #include <boost/variant.hpp>
8 
9 #include "Expression.h"
10 #include "ExpressionPool.h"
11 
12 namespace smtrat {
13 namespace expression {
14 
15  class ExpressionVisitor: public boost::static_visitor<> {
16  public:
17  typedef std::function<void(const Expression&)> VisitorFunction;
18  private:
19  std::optional<VisitorFunction> mPre;
20  std::optional<VisitorFunction> mPost;
21  public:
22  void setPre(const VisitorFunction& f) {
23  mPre = f;
24  }
25  void setPost(const VisitorFunction& f) {
26  mPost = f;
27  }
28 
29  void visit(const Expression& expression) {
30  if (mPre) (*mPre)(expression);
31  boost::apply_visitor(*this, expression.getContent().content);
32  if (mPost) (*mPost)(expression);
33  }
34 
35  void operator()(carl::Variable::Arg) {
36  }
37  void operator()(const ITEExpression& expr) {
38  visit(expr.condition);
39  visit(expr.thencase);
40  visit(expr.elsecase);
41  }
42  void operator()(const QuantifierExpression& expr) {
43  visit(expr.expression);
44  }
45  void operator()(const UnaryExpression& expr) {
46  visit(expr.expression);
47  }
48  void operator()(const BinaryExpression& expr) {
49  visit(expr.lhs);
50  visit(expr.rhs);
51  }
52  void operator()(const NaryExpression& expr) {
53  for (const auto& e: expr.expressions) {
54  visit(e);
55  }
56  }
57  };
58 
59  class ExpressionModifier: public boost::static_visitor<const ExpressionContent*> {
60  public:
61  typedef std::function<const ExpressionContent*(const Expression&)> VisitorFunction;
62  private:
63  std::optional<VisitorFunction> mPre;
64  std::optional<VisitorFunction> mPost;
65 
67  const ExpressionContent* content = _content;
68  if (mPre) {
69  const ExpressionContent* tmp = (*mPre)(Expression(content));
70  if (tmp != nullptr) content = tmp;
71  }
72  {
73  const ExpressionContent* tmp = boost::apply_visitor(*this, content->content);
74  if (tmp != nullptr) content = tmp;
75  }
76  if (mPost) {
77  const ExpressionContent* tmp = (*mPost)(Expression(content));
78  if (tmp != nullptr) content = tmp;
79  }
80  if (content == _content) return nullptr;
81  return content;
82  }
83  public:
84  void setPre(const VisitorFunction& f) {
85  mPre = f;
86  }
87  void setPost(const VisitorFunction& f) {
88  mPost = f;
89  }
90 
91  Expression visit(const Expression& expression) {
92  const ExpressionContent* tmp = internalVisit(expression.mContent);
93  if (tmp != nullptr) return Expression(tmp);
94  return expression;
95  }
96 
97  const ExpressionContent* operator()(carl::Variable::Arg) {
98  return nullptr;
99  }
104  if (c == nullptr && t == nullptr && e == nullptr) return nullptr;
105  if (c == nullptr) c = expr.condition.mContent;
106  if (t == nullptr) t = expr.thencase.mContent;
107  if (e == nullptr) e = expr.elsecase.mContent;
109  }
112  if (e == nullptr) return nullptr;
113  return ExpressionPool::create(expr.type, std::vector<carl::Variable>(expr.variables), Expression(e));
114  }
117  if (e == nullptr) return nullptr;
118  return ExpressionPool::create(expr.type, Expression(e));
119  }
121  const ExpressionContent* l = internalVisit(expr.lhs.mContent);
122  const ExpressionContent* r = internalVisit(expr.rhs.mContent);
123  if (l == nullptr && r == nullptr) return nullptr;
124  if (l == nullptr) l = expr.lhs.mContent;
125  if (r == nullptr) r = expr.rhs.mContent;
126  return ExpressionPool::create(expr.type, Expression(l), Expression(r));
127  }
129  Expressions res;
130  bool changed = false;
131  for (const auto& e: expr.expressions) {
132  const ExpressionContent* tmp = internalVisit(e.mContent);
133  if (tmp == nullptr) res.push_back(e);
134  else {
135  res.push_back(Expression(tmp));
136  changed = true;
137  }
138  }
139  if (!changed) return nullptr;
140  return ExpressionPool::create(expr.type, std::move(res));
141  }
142  };
143 }
144 }
const ExpressionContent * operator()(const NaryExpression &expr)
void setPost(const VisitorFunction &f)
const ExpressionContent * operator()(carl::Variable::Arg)
std::optional< VisitorFunction > mPost
const ExpressionContent * operator()(const QuantifierExpression &expr)
void setPre(const VisitorFunction &f)
std::optional< VisitorFunction > mPre
std::function< const ExpressionContent *(const Expression &)> VisitorFunction
const ExpressionContent * operator()(const BinaryExpression &expr)
const ExpressionContent * internalVisit(const ExpressionContent *_content)
const ExpressionContent * operator()(const ITEExpression &expr)
const ExpressionContent * operator()(const UnaryExpression &expr)
Expression visit(const Expression &expression)
const ExpressionContent * create(carl::Variable::Arg var)
void operator()(const UnaryExpression &expr)
void operator()(const BinaryExpression &expr)
std::optional< VisitorFunction > mPre
void setPre(const VisitorFunction &f)
std::optional< VisitorFunction > mPost
void visit(const Expression &expression)
std::function< void(const Expression &)> VisitorFunction
void operator()(carl::Variable::Arg)
void operator()(const QuantifierExpression &expr)
void operator()(const NaryExpression &expr)
void setPost(const VisitorFunction &f)
void operator()(const ITEExpression &expr)
const ExpressionContent * mContent
Definition: Expression.h:17
const ExpressionContent & getContent() const
Definition: Expression.h:37
std::vector< Expression > Expressions
Class to create the formulas for axioms.
expression::Expression Expression
std::vector< carl::Variable > variables