SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
StrategyGraph.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <set>
5 #include <tuple>
6 #include <vector>
7 
9 #include <smtrat-solver/Module.h>
10 
11 namespace smtrat {
12 
13  typedef bool (*ConditionEvaluation)( carl::Condition );
14  bool isCondition( carl::Condition _condition );
15 
17  virtual ~AbstractModuleFactory() = default;
18  virtual Module* create(const ModuleInput* _formula, Conditionals& _conditionals, Manager* const _manager) = 0;
19  virtual std::string moduleName() const = 0;
20  };
21 
22  template<typename Module>
24  public:
26  Module* create(const ModuleInput* _formula, Conditionals& _conditionals, Manager* const _manager) {
27  return new Module(_formula, _conditionals, _manager);
28  }
29  std::string moduleName() const {
30  return Module::SettingsType::moduleName;
31  }
32  };
33 
34  template<typename Module>
35  inline std::ostream& operator<<(std::ostream& os, const ModuleFactory<Module>& mf) {
36  return os << mf.moduleName();
37  }
38 
39  typedef std::function<bool(carl::Condition)> ConditionFunction;
40  class BackendLink {
41  private:
42  std::size_t mTarget;
43  std::size_t mPriority;
45  public:
46  BackendLink(std::size_t target, std::size_t priority, const ConditionFunction& cf): mTarget(target), mPriority(priority), mCondition(cf) {}
47 
48  bool checkCondition(const carl::Condition& c) const {
49  return mCondition(c);
50  }
51  std::size_t getTarget() const {
52  return mTarget;
53  }
54  std::size_t getPriority() const {
55  return mPriority;
56  }
57 
58  bool operator<(const BackendLink& rhs) const {
59  return mPriority < rhs.mPriority;
60  }
61 
62  BackendLink& priority(std::size_t p) {
63  mPriority = p;
64  return *this;
65  }
66  template<typename T>
67  BackendLink& condition(const T& f) {
69  return *this;
70  }
71  BackendLink& id(std::size_t& id) {
72  id = mTarget;
73  return *this;
74  }
75  };
76 
77  class StrategyGraph {
78  public:
79  static bool TrueCondition(const carl::Condition& c) {
80  return carl::PROP_TRUE <= c;
81  }
82  private:
83 
84  std::vector<std::unique_ptr<AbstractModuleFactory>> mVertices;
85  std::vector<std::vector<BackendLink>> mEdges;
86  bool mHasBranches = false;
87  std::size_t mNumberOfBranches = 1;
88  std::size_t nextPriority = 1;
89  std::size_t mRoot = 0;
90 
91  std::size_t newVertex(std::unique_ptr<AbstractModuleFactory> factory, const std::initializer_list<BackendLink>& backends) {
92  //SMTRAT_LOG_DEBUG("smtrat.strategygraph", "Creating vertex with " << backends.size() << " backends");
93  //SMTRAT_LOG_DEBUG("smtrat.strategygraph", "Current vertices: " << mVertices.size() << " vs " << mEdges.size());
94  assert(mVertices.size() == mEdges.size());
95  mVertices.push_back(std::move(factory));
96  mEdges.emplace_back(backends);
97  if (backends.size() > 1) {
98  mHasBranches = true;
99  mNumberOfBranches += backends.size() - 1;
100  }
101  return mVertices.size() - 1;
102  }
103  std::size_t getPriority(std::size_t priority) {
104  if (priority == 0) priority = nextPriority;
105  if (priority >= nextPriority) nextPriority = priority + 1;
106  return priority;
107  }
108 
109  void printAsTree(std::ostream& os, std::size_t vertex, std::set<std::size_t>& history, const std::string& indent = "") const {
110  std::string moduleName = "Module";
111  if (mVertices[vertex] != nullptr) moduleName = mVertices[vertex]->moduleName();
112  if (history.count(vertex) > 0) {
113  os << indent << moduleName << " (" << vertex << ") Backlink"<< std::endl;
114  } else {
115  os << indent << moduleName << " (" << vertex << ")"<< std::endl;
116  history.insert(vertex);
117  for (const auto& backend: mEdges[vertex]) {
118  printAsTree(os, backend.getTarget(), history, indent + " ");
119  }
120  }
121  }
122 
123  public:
125  assert(mVertices.size() == mEdges.size());
126  }
127 
128  template<typename Module>
129  BackendLink addBackend(const std::initializer_list<BackendLink>& backends) {
130  std::size_t id = newVertex(std::unique_ptr<ModuleFactory<Module>>(new ModuleFactory<Module>()), backends);
131  for (auto& backend: mEdges[id]) {
132  backend.priority(getPriority(backend.getPriority()));
133  }
134  SMTRAT_LOG_DEBUG("smtrat.strategygraph", "Adding backend " << id);
135  return BackendLink(id, 0, TrueCondition);
136  }
137 
138  BackendLink& addEdge(std::size_t from, std::size_t to) {
139  assert(from < mEdges.size());
140  if (!mEdges[from].empty()) mHasBranches = true;
141  mEdges[from].emplace_back(to, 0, TrueCondition);
142  return mEdges[from].back();
143  }
144 
145  std::size_t addRoot(const std::initializer_list<BackendLink>& backends) {
146  return mRoot = newVertex(nullptr, backends);
147  }
148 
149  bool hasBranches() const {
150  assert(mHasBranches == (mNumberOfBranches > 1));
151  return mHasBranches;
152  }
153  std::size_t numberOfBranches() const {
154  assert(mHasBranches == (mNumberOfBranches > 1));
155  return mNumberOfBranches;
156  }
157  std::size_t getRoot() const {
158  return mRoot;
159  }
160 
161  std::set<std::pair<thread_priority,AbstractModuleFactory*>> getBackends(std::size_t vertex, const carl::Condition& condition) const {
162  std::set<std::pair<thread_priority,AbstractModuleFactory*>> res;
163  SMTRAT_LOG_DEBUG("smtrat.strategygraph", "Getting backends for vertex " << vertex);
164  assert(vertex < mEdges.size());
165  for (const auto& it: mEdges[vertex]) {
166  if (it.checkCondition(condition)) {
167  SMTRAT_LOG_DEBUG("smtrat.strategygraph", "\tfound " << it.getTarget());
168  assert(mVertices[it.getTarget()] != nullptr);
169  res.emplace(thread_priority(it.getPriority(), it.getTarget()), mVertices[it.getTarget()].get());
170  }
171  }
172  return res;
173  }
174 
175  friend std::ostream& operator<<(std::ostream& os, const StrategyGraph& sg) {
176  std::set<std::size_t> history;
177  sg.printAsTree(os, sg.mRoot, history);
178  return os;
179  }
180  };
181 }
Base class for solvers.
Definition: Manager.h:34
The input formula a module has to consider for it's satisfiability check.
Definition: ModuleInput.h:131
A base class for all kind of theory solving methods.
Definition: Module.h:70
std::set< std::pair< thread_priority, AbstractModuleFactory * > > getBackends(std::size_t vertex, const carl::Condition &condition) const
std::size_t nextPriority
Definition: StrategyGraph.h:88
std::vector< std::unique_ptr< AbstractModuleFactory > > mVertices
Definition: StrategyGraph.h:84
friend std::ostream & operator<<(std::ostream &os, const StrategyGraph &sg)
std::size_t newVertex(std::unique_ptr< AbstractModuleFactory > factory, const std::initializer_list< BackendLink > &backends)
Definition: StrategyGraph.h:91
std::size_t numberOfBranches() const
std::size_t mNumberOfBranches
Definition: StrategyGraph.h:87
std::size_t addRoot(const std::initializer_list< BackendLink > &backends)
void printAsTree(std::ostream &os, std::size_t vertex, std::set< std::size_t > &history, const std::string &indent="") const
std::size_t getPriority(std::size_t priority)
std::vector< std::vector< BackendLink > > mEdges
Definition: StrategyGraph.h:85
bool hasBranches() const
BackendLink & addEdge(std::size_t from, std::size_t to)
static bool TrueCondition(const carl::Condition &c)
Definition: StrategyGraph.h:79
std::size_t getRoot() const
BackendLink addBackend(const std::initializer_list< BackendLink > &backends)
Class to create the formulas for axioms.
std::function< bool(carl::Condition)> ConditionFunction
Definition: StrategyGraph.h:39
bool(* ConditionEvaluation)(carl::Condition)
Definition: StrategyGraph.h:13
std::vector< std::atomic_bool * > Conditionals
A vector of atomic bool pointers.
Definition: types.h:17
std::ostream & operator<<(std::ostream &os, CMakeOptionPrinter cmop)
bool isCondition(carl::Condition _condition)
std::pair< std::size_t, std::size_t > thread_priority
Definition: types.h:50
#define SMTRAT_LOG_DEBUG(channel, msg)
Definition: logging.h:35
virtual std::string moduleName() const =0
virtual Module * create(const ModuleInput *_formula, Conditionals &_conditionals, Manager *const _manager)=0
virtual ~AbstractModuleFactory()=default
Module * create(const ModuleInput *_formula, Conditionals &_conditionals, Manager *const _manager)
Definition: StrategyGraph.h:26
std::string moduleName() const
Definition: StrategyGraph.h:29