GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/test_smt.h Lines: 40 73 54.8 %
Date: 2021-05-22 Branches: 30 151 19.9 %

Line Exec Source
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/proof_checker.h"
23
#include "expr/skolem_manager.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
588
class TestSmt : public TestInternal
43
{
44
 protected:
45
294
  void SetUp() override
46
  {
47
294
    d_nodeManager.reset(new NodeManager());
48
294
    d_skolemManager = d_nodeManager->getSkolemManager();
49
294
    d_nmScope.reset(new NodeManagerScope(d_nodeManager.get()));
50
294
    d_smtEngine.reset(new SmtEngine(d_nodeManager.get()));
51
294
    d_smtEngine->finishInit();
52
294
  }
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
1088
class TestSmtNoFinishInit : public TestInternal
61
{
62
 protected:
63
544
  void SetUp() override
64
  {
65
544
    d_nodeManager.reset(new NodeManager());
66
544
    d_skolemManager = d_nodeManager->getSkolemManager();
67
544
    d_nmScope.reset(new NodeManagerScope(d_nodeManager.get()));
68
544
    d_smtEngine.reset(new SmtEngine(d_nodeManager.get()));
69
544
  }
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(theory::TrustNode n) override
119
  {
120
    push(CONFLICT, n.getNode());
121
  }
122
123
  bool propagate(TNode n) override
124
  {
125
    push(PROPAGATE, n);
126
    return true;
127
  }
128
129
2
  void lemma(TNode n,
130
             theory::LemmaProperty p = theory::LemmaProperty::NONE) override
131
  {
132
2
    push(LEMMA, n);
133
2
  }
134
135
  void trustedLemma(theory::TrustNode n, theory::LemmaProperty p) override
136
  {
137
    push(LEMMA, n.getNode());
138
  }
139
140
  void requirePhase(TNode, bool) override {}
141
  void setIncomplete(theory::IncompleteId id) override {}
142
  void handleUserAttribute(const char* attr, theory::Theory* t) override {}
143
144
2
  void splitLemma(TNode n, bool removable = false) override { push(LEMMA, n); }
145
146
6
  void clear() { d_callHistory.clear(); }
147
148
  Node getIthNode(int i) const
149
  {
150
    Node tmp = (d_callHistory[i]).second;
151
    return tmp;
152
  }
153
154
  OutputChannelCallType getIthCallType(int i) const
155
  {
156
    return (d_callHistory[i]).first;
157
  }
158
159
  unsigned getNumCalls() const { return d_callHistory.size(); }
160
161
  void printIth(std::ostream& os, int i) const
162
  {
163
    os << "[DummyOutputChannel " << i;
164
    os << " " << getIthCallType(i);
165
    os << " " << getIthNode(i) << "]";
166
  }
167
168
 private:
169
4
  void push(OutputChannelCallType call, TNode n)
170
  {
171
4
    d_callHistory.push_back(std::make_pair(call, n));
172
4
  }
173
174
  std::vector<std::pair<enum OutputChannelCallType, Node> > d_callHistory;
175
};
176
177
/* -------------------------------------------------------------------------- */
178
179
84
class DummyTheoryRewriter : public theory::TheoryRewriter
180
{
181
 public:
182
48
  theory::RewriteResponse preRewrite(TNode n) override
183
  {
184
48
    return theory::RewriteResponse(theory::REWRITE_DONE, n);
185
  }
186
187
96
  theory::RewriteResponse postRewrite(TNode n) override
188
  {
189
96
    return theory::RewriteResponse(theory::REWRITE_DONE, n);
190
  }
191
};
192
193
class DummyProofRuleChecker : public ProofRuleChecker
194
{
195
 public:
196
42
  DummyProofRuleChecker() {}
197
42
  ~DummyProofRuleChecker() {}
198
  void registerTo(ProofChecker* pc) override {}
199
200
 protected:
201
  Node checkInternal(PfRule id,
202
                     const std::vector<Node>& children,
203
                     const std::vector<Node>& args) override
204
  {
205
    return Node::null();
206
  }
207
};
208
209
/** Dummy Theory interface.  */
210
template <theory::TheoryId theoryId>
211
84
class DummyTheory : public theory::Theory
212
{
213
 public:
214
42
  DummyTheory(context::Context* ctxt,
215
              context::UserContext* uctxt,
216
              theory::OutputChannel& out,
217
              theory::Valuation valuation,
218
              const LogicInfo& logicInfo,
219
              ProofNodeManager* pnm)
220
      : Theory(theoryId, ctxt, uctxt, out, valuation, logicInfo, pnm),
221
42
        d_state(ctxt, uctxt, valuation)
222
  {
223
    // use a default theory state object
224
42
    d_theoryState = &d_state;
225
42
  }
226
227
36
  theory::TheoryRewriter* getTheoryRewriter() override { return &d_rewriter; }
228
  ProofRuleChecker* getProofChecker() override { return &d_checker; }
229
230
  void registerTerm(TNode n)
231
  {
232
    // check that we registerTerm() a term only once
233
    ASSERT_TRUE(d_registered.find(n) == d_registered.end());
234
235
    for (TNode::iterator i = n.begin(); i != n.end(); ++i)
236
    {
237
      // check that registerTerm() is called in reverse topological order
238
      ASSERT_TRUE(d_registered.find(*i) != d_registered.end());
239
    }
240
241
    d_registered.insert(n);
242
  }
243
244
  void presolve() override { Unimplemented(); }
245
  void preRegisterTerm(TNode n) override { Unimplemented(); }
246
  void propagate(Effort level) override { Unimplemented(); }
247
4
  bool preNotifyFact(
248
      TNode atom, bool pol, TNode fact, bool isPrereg, bool isInternal) override
249
  {
250
    // do not assert to equality engine, since this theory does not use one
251
4
    return true;
252
  }
253
  theory::TrustNode explain(TNode n) override
254
  {
255
    return theory::TrustNode::null();
256
  }
257
  Node getValue(TNode n) { return Node::null(); }
258
  std::string identify() const override { return "DummyTheory" + d_id; }
259
260
  std::set<Node> d_registered;
261
262
 private:
263
  /** Default theory state object */
264
  theory::TheoryState d_state;
265
  /**
266
   * This fake theory class is equally useful for bool, uf, arith, etc.  It
267
   * keeps an identifier to identify itself.
268
   */
269
  std::string d_id;
270
  /** The theory rewriter for this theory. */
271
  DummyTheoryRewriter d_rewriter;
272
  /** The proof checker for this theory. */
273
  DummyProofRuleChecker d_checker;
274
};
275
276
/* -------------------------------------------------------------------------- */
277
}  // namespace test
278
}  // namespace cvc5
279
#endif