1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Aina Niemetz, Andrew Reynolds, Haniel Barbosa |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS |
8 |
|
* in the top-level source directory and their institutional affiliations. |
9 |
|
* All rights reserved. See the file COPYING in the top-level source |
10 |
|
* directory for licensing information. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* Common header for unit tests that need an SmtEngine. |
14 |
|
*/ |
15 |
|
|
16 |
|
#ifndef CVC5__TEST__UNIT__TEST_SMT_H |
17 |
|
#define CVC5__TEST__UNIT__TEST_SMT_H |
18 |
|
|
19 |
|
#include "expr/dtype_cons.h" |
20 |
|
#include "expr/node.h" |
21 |
|
#include "expr/node_manager.h" |
22 |
|
#include "expr/skolem_manager.h" |
23 |
|
#include "proof/proof_checker.h" |
24 |
|
#include "smt/smt_engine.h" |
25 |
|
#include "smt/smt_engine_scope.h" |
26 |
|
#include "test.h" |
27 |
|
#include "theory/output_channel.h" |
28 |
|
#include "theory/rewriter.h" |
29 |
|
#include "theory/theory.h" |
30 |
|
#include "theory/theory_state.h" |
31 |
|
#include "theory/valuation.h" |
32 |
|
#include "util/resource_manager.h" |
33 |
|
#include "util/unsafe_interrupt_exception.h" |
34 |
|
|
35 |
|
namespace cvc5 { |
36 |
|
namespace test { |
37 |
|
|
38 |
|
/* -------------------------------------------------------------------------- */ |
39 |
|
/* Test fixtures. */ |
40 |
|
/* -------------------------------------------------------------------------- */ |
41 |
|
|
42 |
640 |
class TestSmt : public TestInternal |
43 |
|
{ |
44 |
|
protected: |
45 |
320 |
void SetUp() override |
46 |
|
{ |
47 |
320 |
d_nodeManager.reset(new NodeManager()); |
48 |
320 |
d_skolemManager = d_nodeManager->getSkolemManager(); |
49 |
320 |
d_nmScope.reset(new NodeManagerScope(d_nodeManager.get())); |
50 |
320 |
d_smtEngine.reset(new SmtEngine(d_nodeManager.get())); |
51 |
320 |
d_smtEngine->finishInit(); |
52 |
320 |
} |
53 |
|
|
54 |
|
std::unique_ptr<NodeManagerScope> d_nmScope; |
55 |
|
std::unique_ptr<NodeManager> d_nodeManager; |
56 |
|
SkolemManager* d_skolemManager; |
57 |
|
std::unique_ptr<SmtEngine> d_smtEngine; |
58 |
|
}; |
59 |
|
|
60 |
1104 |
class TestSmtNoFinishInit : public TestInternal |
61 |
|
{ |
62 |
|
protected: |
63 |
552 |
void SetUp() override |
64 |
|
{ |
65 |
552 |
d_nodeManager.reset(new NodeManager()); |
66 |
552 |
d_skolemManager = d_nodeManager->getSkolemManager(); |
67 |
552 |
d_nmScope.reset(new NodeManagerScope(d_nodeManager.get())); |
68 |
552 |
d_smtEngine.reset(new SmtEngine(d_nodeManager.get())); |
69 |
552 |
} |
70 |
|
|
71 |
|
std::unique_ptr<NodeManagerScope> d_nmScope; |
72 |
|
std::unique_ptr<NodeManager> d_nodeManager; |
73 |
|
SkolemManager* d_skolemManager; |
74 |
|
std::unique_ptr<SmtEngine> d_smtEngine; |
75 |
|
}; |
76 |
|
|
77 |
|
/* -------------------------------------------------------------------------- */ |
78 |
|
/* Helpers. */ |
79 |
|
/* -------------------------------------------------------------------------- */ |
80 |
|
|
81 |
|
/** |
82 |
|
* Very basic OutputChannel for testing simple Theory Behaviour. |
83 |
|
* Stores a call sequence for the output channel |
84 |
|
*/ |
85 |
|
enum OutputChannelCallType |
86 |
|
{ |
87 |
|
CONFLICT, |
88 |
|
PROPAGATE, |
89 |
|
PROPAGATE_AS_DECISION, |
90 |
|
AUG_LEMMA, |
91 |
|
LEMMA, |
92 |
|
EXPLANATION |
93 |
|
}; |
94 |
|
|
95 |
|
inline std::ostream& operator<<(std::ostream& out, OutputChannelCallType type) |
96 |
|
{ |
97 |
|
switch (type) |
98 |
|
{ |
99 |
|
case CONFLICT: return out << "CONFLICT"; |
100 |
|
case PROPAGATE: return out << "PROPAGATE"; |
101 |
|
case PROPAGATE_AS_DECISION: return out << "PROPAGATE_AS_DECISION"; |
102 |
|
case AUG_LEMMA: return out << "AUG_LEMMA"; |
103 |
|
case LEMMA: return out << "LEMMA"; |
104 |
|
case EXPLANATION: return out << "EXPLANATION"; |
105 |
|
default: return out << "UNDEFINED-OutputChannelCallType!" << int(type); |
106 |
|
} |
107 |
|
} |
108 |
|
|
109 |
|
class DummyOutputChannel : public cvc5::theory::OutputChannel |
110 |
|
{ |
111 |
|
public: |
112 |
6 |
DummyOutputChannel() {} |
113 |
6 |
~DummyOutputChannel() override {} |
114 |
|
|
115 |
|
void safePoint(Resource r) override {} |
116 |
|
void conflict(TNode n) override { push(CONFLICT, n); } |
117 |
|
|
118 |
|
void trustedConflict(TrustNode n) override { push(CONFLICT, n.getNode()); } |
119 |
|
|
120 |
|
bool propagate(TNode n) override |
121 |
|
{ |
122 |
|
push(PROPAGATE, n); |
123 |
|
return true; |
124 |
|
} |
125 |
|
|
126 |
4 |
void lemma(TNode n, |
127 |
|
theory::LemmaProperty p = theory::LemmaProperty::NONE) override |
128 |
|
{ |
129 |
4 |
push(LEMMA, n); |
130 |
4 |
} |
131 |
|
|
132 |
|
void trustedLemma(TrustNode n, theory::LemmaProperty p) override |
133 |
|
{ |
134 |
|
push(LEMMA, n.getNode()); |
135 |
|
} |
136 |
|
|
137 |
|
void requirePhase(TNode, bool) override {} |
138 |
|
void setIncomplete(theory::IncompleteId id) override {} |
139 |
|
void handleUserAttribute(const char* attr, theory::Theory* t) override {} |
140 |
|
|
141 |
6 |
void clear() { d_callHistory.clear(); } |
142 |
|
|
143 |
|
Node getIthNode(int i) const |
144 |
|
{ |
145 |
|
Node tmp = (d_callHistory[i]).second; |
146 |
|
return tmp; |
147 |
|
} |
148 |
|
|
149 |
|
OutputChannelCallType getIthCallType(int i) const |
150 |
|
{ |
151 |
|
return (d_callHistory[i]).first; |
152 |
|
} |
153 |
|
|
154 |
|
unsigned getNumCalls() const { return d_callHistory.size(); } |
155 |
|
|
156 |
|
void printIth(std::ostream& os, int i) const |
157 |
|
{ |
158 |
|
os << "[DummyOutputChannel " << i; |
159 |
|
os << " " << getIthCallType(i); |
160 |
|
os << " " << getIthNode(i) << "]"; |
161 |
|
} |
162 |
|
|
163 |
|
private: |
164 |
4 |
void push(OutputChannelCallType call, TNode n) |
165 |
|
{ |
166 |
4 |
d_callHistory.push_back(std::make_pair(call, n)); |
167 |
4 |
} |
168 |
|
|
169 |
|
std::vector<std::pair<enum OutputChannelCallType, Node> > d_callHistory; |
170 |
|
}; |
171 |
|
|
172 |
|
/* -------------------------------------------------------------------------- */ |
173 |
|
|
174 |
84 |
class DummyTheoryRewriter : public theory::TheoryRewriter |
175 |
|
{ |
176 |
|
public: |
177 |
48 |
theory::RewriteResponse preRewrite(TNode n) override |
178 |
|
{ |
179 |
48 |
return theory::RewriteResponse(theory::REWRITE_DONE, n); |
180 |
|
} |
181 |
|
|
182 |
96 |
theory::RewriteResponse postRewrite(TNode n) override |
183 |
|
{ |
184 |
96 |
return theory::RewriteResponse(theory::REWRITE_DONE, n); |
185 |
|
} |
186 |
|
}; |
187 |
|
|
188 |
|
class DummyProofRuleChecker : public ProofRuleChecker |
189 |
|
{ |
190 |
|
public: |
191 |
42 |
DummyProofRuleChecker() {} |
192 |
42 |
~DummyProofRuleChecker() {} |
193 |
|
void registerTo(ProofChecker* pc) override {} |
194 |
|
|
195 |
|
protected: |
196 |
|
Node checkInternal(PfRule id, |
197 |
|
const std::vector<Node>& children, |
198 |
|
const std::vector<Node>& args) override |
199 |
|
{ |
200 |
|
return Node::null(); |
201 |
|
} |
202 |
|
}; |
203 |
|
|
204 |
|
/** Dummy Theory interface. */ |
205 |
|
template <theory::TheoryId theoryId> |
206 |
84 |
class DummyTheory : public theory::Theory |
207 |
|
{ |
208 |
|
public: |
209 |
42 |
DummyTheory(context::Context* ctxt, |
210 |
|
context::UserContext* uctxt, |
211 |
|
theory::OutputChannel& out, |
212 |
|
theory::Valuation valuation, |
213 |
|
const LogicInfo& logicInfo, |
214 |
|
ProofNodeManager* pnm) |
215 |
|
: Theory(theoryId, ctxt, uctxt, out, valuation, logicInfo, pnm), |
216 |
42 |
d_state(ctxt, uctxt, valuation) |
217 |
|
{ |
218 |
|
// use a default theory state object |
219 |
42 |
d_theoryState = &d_state; |
220 |
42 |
} |
221 |
|
|
222 |
36 |
theory::TheoryRewriter* getTheoryRewriter() override { return &d_rewriter; } |
223 |
|
ProofRuleChecker* getProofChecker() override { return &d_checker; } |
224 |
|
|
225 |
|
void registerTerm(TNode n) |
226 |
|
{ |
227 |
|
// check that we registerTerm() a term only once |
228 |
|
ASSERT_TRUE(d_registered.find(n) == d_registered.end()); |
229 |
|
|
230 |
|
for (TNode::iterator i = n.begin(); i != n.end(); ++i) |
231 |
|
{ |
232 |
|
// check that registerTerm() is called in reverse topological order |
233 |
|
ASSERT_TRUE(d_registered.find(*i) != d_registered.end()); |
234 |
|
} |
235 |
|
|
236 |
|
d_registered.insert(n); |
237 |
|
} |
238 |
|
|
239 |
|
void presolve() override { Unimplemented(); } |
240 |
|
void preRegisterTerm(TNode n) override { Unimplemented(); } |
241 |
|
void propagate(Effort level) override { Unimplemented(); } |
242 |
4 |
bool preNotifyFact( |
243 |
|
TNode atom, bool pol, TNode fact, bool isPrereg, bool isInternal) override |
244 |
|
{ |
245 |
|
// do not assert to equality engine, since this theory does not use one |
246 |
4 |
return true; |
247 |
|
} |
248 |
|
TrustNode explain(TNode n) override { return TrustNode::null(); } |
249 |
|
Node getValue(TNode n) { return Node::null(); } |
250 |
|
std::string identify() const override { return "DummyTheory" + d_id; } |
251 |
|
|
252 |
|
std::set<Node> d_registered; |
253 |
|
|
254 |
|
private: |
255 |
|
/** Default theory state object */ |
256 |
|
theory::TheoryState d_state; |
257 |
|
/** |
258 |
|
* This fake theory class is equally useful for bool, uf, arith, etc. It |
259 |
|
* keeps an identifier to identify itself. |
260 |
|
*/ |
261 |
|
std::string d_id; |
262 |
|
/** The theory rewriter for this theory. */ |
263 |
|
DummyTheoryRewriter d_rewriter; |
264 |
|
/** The proof checker for this theory. */ |
265 |
|
DummyProofRuleChecker d_checker; |
266 |
|
}; |
267 |
|
|
268 |
|
/* -------------------------------------------------------------------------- */ |
269 |
|
} // namespace test |
270 |
|
} // namespace cvc5 |
271 |
|
#endif |