GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/prop/prop_engine.h Lines: 1 1 100.0 %
Date: 2021-11-07 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Dejan Jovanovic
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
 * The PropEngine (propositional engine).
14
 *
15
 * Main interface point between cvc5's SMT infrastructure and the SAT solver.
16
 */
17
18
#include "cvc5_private.h"
19
20
#ifndef CVC5__PROP_ENGINE_H
21
#define CVC5__PROP_ENGINE_H
22
23
#include "context/cdlist.h"
24
#include "expr/node.h"
25
#include "proof/trust_node.h"
26
#include "prop/skolem_def_manager.h"
27
#include "theory/output_channel.h"
28
#include "theory/skolem_lemma.h"
29
#include "util/result.h"
30
31
namespace cvc5 {
32
33
class Env;
34
class ResourceManager;
35
class ProofNodeManager;
36
class TheoryEngine;
37
38
namespace decision {
39
class DecisionEngine;
40
}
41
42
namespace prop {
43
44
class CnfStream;
45
class CDCLTSatSolverInterface;
46
class ProofCnfStream;
47
class PropPfManager;
48
class TheoryProxy;
49
50
/**
51
 * PropEngine is the abstraction of a Sat Solver, providing methods for
52
 * solving the SAT problem and conversion to CNF (via the CnfStream).
53
 */
54
class PropEngine
55
{
56
 public:
57
  /**
58
   * Create a PropEngine with a particular decision and theory engine.
59
   */
60
  PropEngine(TheoryEngine* te, Env& env);
61
62
  /**
63
   * Destructor.
64
   */
65
  ~PropEngine();
66
67
  /**
68
   * Finish initialize. Call this after construction just before we are
69
   * ready to use this class. Should be called after TheoryEngine::finishInit.
70
   * This method converts and asserts true and false into the CNF stream.
71
   */
72
  void finishInit();
73
74
  /**
75
   * This is called by SolverEngine, at shutdown time, just before
76
   * destruction.  It is important because there are destruction
77
   * ordering issues between some parts of the system (notably between
78
   * PropEngine and Theory).  For now, there's nothing to do here in
79
   * the PropEngine.
80
   */
81
15268
  void shutdown() {}
82
83
  /**
84
   * Preprocess the given node. Return the REWRITE trust node corresponding to
85
   * rewriting node. New lemmas and skolems are added to ppLemmas and
86
   * ppSkolems respectively.
87
   *
88
   * @param node The assertion to preprocess,
89
   * @param ppLemmas The lemmas to add to the set of assertions, which tracks
90
   * their corresponding skolems,
91
   * @return The (REWRITE) trust node corresponding to rewritten node via
92
   * preprocessing.
93
   */
94
  TrustNode preprocess(TNode node, std::vector<theory::SkolemLemma>& ppLemmas);
95
  /**
96
   * Remove term ITEs (and more generally, term formulas) from the given node.
97
   * Return the REWRITE trust node corresponding to rewriting node. New lemmas
98
   * and skolems are added to ppLemmas and ppSkolems respectively. This can
99
   * be seen a subset of the above preprocess method, which also does theory
100
   * preprocessing and rewriting.
101
   *
102
   * @param node The assertion to preprocess,
103
   * @param ppLemmas The lemmas to add to the set of assertions, which tracks
104
   * their corresponding skolems.
105
   * @return The (REWRITE) trust node corresponding to rewritten node via
106
   * preprocessing.
107
   */
108
  TrustNode removeItes(TNode node, std::vector<theory::SkolemLemma>& ppLemmas);
109
110
  /**
111
   * Converts the given formulas to CNF and assert the CNF to the SAT solver.
112
   * These formulas are asserted permanently for the current context.
113
   * Information about which assertions correspond to skolem definitions is
114
   * contained in skolemMap.
115
   *
116
   * @param assertions the formulas to assert
117
   * @param skolemMap a map which says which skolem (if any) each assertion
118
   * corresponds to. For example, if (ite C (= k a) (= k b)) is the i^th
119
   * assertion, then skolemMap may contain the entry { i -> k }.
120
   */
121
  void assertInputFormulas(const std::vector<Node>& assertions,
122
                           std::unordered_map<size_t, Node>& skolemMap);
123
124
  /**
125
   * Converts the given formula to CNF and assert the CNF to the SAT solver.
126
   * The formula can be removed by the SAT solver after backtracking lower
127
   * than the (SAT and SMT) level at which it was asserted.
128
   *
129
   * @param trn the trust node storing the formula to assert
130
   * @param p the properties of the lemma
131
   */
132
  void assertLemma(TrustNode tlemma, theory::LemmaProperty p);
133
134
  /**
135
   * If ever n is decided upon, it must be in the given phase.  This
136
   * occurs *globally*, i.e., even if the literal is untranslated by
137
   * user pop and retranslated, it keeps this phase.  The associated
138
   * variable will _always_ be phase-locked.
139
   *
140
   * @param n the node in question; must have an associated SAT literal
141
   * @param phase the phase to use
142
   */
143
  void requirePhase(TNode n, bool phase);
144
145
  /**
146
   * Return whether the given literal is a SAT decision.  Either phase
147
   * is permitted; that is, if "lit" is a SAT decision, this function
148
   * returns true for both lit and the negation of lit.
149
   */
150
  bool isDecision(Node lit) const;
151
152
  /**
153
   * Return SAT context level at which `lit` was decided on.
154
   *
155
   * @param lit: The node in question, must have an associated SAT literal.
156
   * @return Decision level of the SAT variable of `lit` (phase is disregarded),
157
   *         or -1 if `lit` has not been assigned yet.
158
   */
159
  int32_t getDecisionLevel(Node lit) const;
160
161
  /**
162
   * Return the user-context level when `lit` was introduced..
163
   *
164
   * @return User-context level or -1 if not yet introduced.
165
   */
166
  int32_t getIntroLevel(Node lit) const;
167
168
  /**
169
   * Checks the current context for satisfiability.
170
   *
171
   */
172
  Result checkSat();
173
174
  /**
175
   * Get the value of a boolean variable.
176
   *
177
   * @return mkConst<true>, mkConst<false>, or Node::null() if
178
   * unassigned.
179
   */
180
  Node getValue(TNode node) const;
181
182
  /**
183
   * Return true if node has an associated SAT literal.
184
   */
185
  bool isSatLiteral(TNode node) const;
186
187
  /**
188
   * Check if the node has a value and return it if yes.
189
   */
190
  bool hasValue(TNode node, bool& value) const;
191
192
  /**
193
   * Returns the Boolean variables known to the SAT solver.
194
   */
195
  void getBooleanVariables(std::vector<TNode>& outputVariables) const;
196
197
  /**
198
   * Ensure that the given node will have a designated SAT literal
199
   * that is definitionally equal to it. Note that theory preprocessing is
200
   * applied to n. The node returned by this method can be subsequently queried
201
   * via getSatValue().
202
   */
203
  Node ensureLiteral(TNode n);
204
  /**
205
   * This returns the theory-preprocessed form of term n. This rewrites and
206
   * preprocesses n, which notice may involve adding clauses to the SAT solver
207
   * if preprocessing n involves introducing new skolems.
208
   */
209
  Node getPreprocessedTerm(TNode n);
210
  /**
211
   * Same as above, but also compute the skolems in n and in the lemmas
212
   * corresponding to their definition.
213
   *
214
   * Note this will include skolems that occur in the definition lemma
215
   * for all skolems in sks. This is run until a fixed point is reached.
216
   * For example, if k1 has definition (ite A (= k1 k2) (= k1 x)) where k2 is
217
   * another skolem introduced by term formula removal, then calling this
218
   * method on (P k1) will include both k1 and k2 in sks, and their definitions
219
   * in skAsserts.
220
   *
221
   * Notice that this method is not frequently used. It is used for algorithms
222
   * that explicitly care about knowing which skolems occur in the preprocessed
223
   * form of a term, recursively.
224
   */
225
  Node getPreprocessedTerm(TNode n,
226
                           std::vector<Node>& skAsserts,
227
                           std::vector<Node>& sks);
228
229
  /**
230
   * Push the context level.
231
   */
232
  void push();
233
234
  /**
235
   * Pop the context level.
236
   */
237
  void pop();
238
239
  /*
240
   * Reset the decisions in the DPLL(T) SAT solver at the current assertion
241
   * level.
242
   */
243
  void resetTrail();
244
245
  /**
246
   * Get the assertion level of the SAT solver.
247
   */
248
  unsigned getAssertionLevel() const;
249
250
  /**
251
   * Return true if we are currently searching (either in this or
252
   * another thread).
253
   */
254
  bool isRunning() const;
255
256
  /**
257
   * Interrupt a running solver (cause a timeout).
258
   *
259
   * Can potentially throw a ModalException.
260
   */
261
  void interrupt();
262
263
  /**
264
   * Informs the ResourceManager that a resource has been spent.  If out of
265
   * resources, can throw an UnsafeInterruptException exception.
266
   */
267
  void spendResource(Resource r);
268
269
  /**
270
   * For debugging.  Return true if "expl" is a well-formed
271
   * explanation for "node," meaning:
272
   *
273
   * 1. expl is either a SAT literal or an AND of SAT literals
274
   *    currently assigned true;
275
   * 2. node is assigned true;
276
   * 3. node does not appear in expl; and
277
   * 4. node was assigned after all of the literals in expl
278
   */
279
  bool properExplanation(TNode node, TNode expl) const;
280
281
  /** Retrieve this modules proof CNF stream. */
282
  ProofCnfStream* getProofCnfStream();
283
284
  /** Checks that the proof is closed w.r.t. asserted formulas to this engine as
285
   * well as to the given assertions. */
286
  void checkProof(const context::CDList<Node>& assertions);
287
288
  /**
289
   * Return the prop engine proof. This should be called only when proofs are
290
   * enabled. Returns a proof of false whose free assumptions are the
291
   * preprocessed assertions.
292
   */
293
  std::shared_ptr<ProofNode> getProof();
294
295
  /** Is proof enabled? */
296
  bool isProofEnabled() const;
297
298
  /** Retrieve unsat core from SAT solver for assumption-based unsat cores. */
299
  void getUnsatCore(std::vector<Node>& core);
300
301
  /** Return the prop engine proof for assumption-based unsat cores. */
302
  std::shared_ptr<ProofNode> getRefutation();
303
304
 private:
305
  /** Dump out the satisfying assignment (after SAT result) */
306
  void printSatisfyingAssignment();
307
308
  /**
309
   * Converts the given formula to CNF and asserts the CNF to the SAT solver.
310
   * The formula can be removed by the SAT solver after backtracking lower
311
   * than the (SAT and SMT) level at which it was asserted.
312
   *
313
   * @param trn the trust node storing the formula to assert
314
   * @param removable whether this lemma can be quietly removed based
315
   * on an activity heuristic
316
   */
317
  void assertTrustedLemmaInternal(TrustNode trn, bool removable);
318
  /**
319
   * Assert node as a formula to the CNF stream
320
   * @param node The formula to assert
321
   * @param negated Whether to assert the negation of node
322
   * @param removable Whether the formula is removable
323
   * @param input Whether the formula came from the input
324
   * @param pg Pointer to a proof generator that can provide a proof of node
325
   * (or its negation if negated is true).
326
   */
327
  void assertInternal(TNode node,
328
                      bool negated,
329
                      bool removable,
330
                      bool input,
331
                      ProofGenerator* pg = nullptr);
332
  /**
333
   * Assert lemmas internal, where trn is a trust node corresponding to a
334
   * formula to assert to the CNF stream, ppLemmas are the skolem definitions
335
   * obtained from preprocessing it, and removable is whether the lemma is
336
   * removable.
337
   */
338
  void assertLemmasInternal(TrustNode trn,
339
                            const std::vector<theory::SkolemLemma>& ppLemmas,
340
                            bool removable);
341
342
  /**
343
   * Indicates that the SAT solver is currently solving something and we should
344
   * not mess with it's internal state.
345
   */
346
  bool d_inCheckSat;
347
348
  /** The theory engine we will be using */
349
  TheoryEngine* d_theoryEngine;
350
351
  /** Reference to the environment */
352
  Env& d_env;
353
354
  /** The decision engine we will be using */
355
  std::unique_ptr<decision::DecisionEngine> d_decisionEngine;
356
357
  /** The skolem definition manager */
358
  std::unique_ptr<SkolemDefManager> d_skdm;
359
360
  /** SAT solver's proxy back to theories; kept around for dtor cleanup */
361
  TheoryProxy* d_theoryProxy;
362
363
  /** The SAT solver proxy */
364
  CDCLTSatSolverInterface* d_satSolver;
365
366
  /** List of all of the assertions that need to be made */
367
  std::vector<Node> d_assertionList;
368
369
  /** The CNF converter in use */
370
  CnfStream* d_cnfStream;
371
  /** Proof-producing CNF converter */
372
  std::unique_ptr<ProofCnfStream> d_pfCnfStream;
373
374
  /** The proof manager for prop engine */
375
  std::unique_ptr<PropPfManager> d_ppm;
376
377
  /** Whether we were just interrupted (or not) */
378
  bool d_interrupted;
379
380
  /**
381
   * Stores assumptions added via assertInternal() if assumption-based unsat
382
   * cores are enabled.
383
   */
384
  context::CDList<Node> d_assumptions;
385
};
386
387
}  // namespace prop
388
}  // namespace cvc5
389
390
#endif /* CVC5__PROP_ENGINE_H */