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

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Dejan Jovanovic, Haniel Barbosa, Tim King
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
 * This class transforms a sequence of formulas into clauses.
14
 *
15
 * This class takes a sequence of formulas.
16
 * It outputs a stream of clauses that is propositionally
17
 * equi-satisfiable with the conjunction of the formulas.
18
 * This stream is maintained in an online fashion.
19
 *
20
 * Unlike other parts of the system it is aware of the PropEngine's
21
 * internals such as the representation and translation of [??? -Chris]
22
 */
23
24
#include "cvc5_private.h"
25
26
#ifndef CVC5__PROP__CNF_STREAM_H
27
#define CVC5__PROP__CNF_STREAM_H
28
29
#include "context/cdhashset.h"
30
#include "context/cdinsert_hashmap.h"
31
#include "context/cdlist.h"
32
#include "expr/node.h"
33
#include "prop/proof_cnf_stream.h"
34
#include "prop/registrar.h"
35
#include "prop/sat_solver_types.h"
36
37
namespace cvc5 {
38
39
class Env;
40
41
namespace prop {
42
43
class ProofCnfStream;
44
class PropEngine;
45
class SatSolver;
46
47
/** A policy for how literals for formulas are handled in cnf_stream */
48
enum class FormulaLitPolicy : uint32_t
49
{
50
  // literals for formulas are notified
51
  TRACK_AND_NOTIFY,
52
  // literals for formulas are added to node map
53
  TRACK,
54
  // literals for formulas are kept internal (default)
55
  INTERNAL,
56
};
57
58
/**
59
 * Implements the following recursive algorithm
60
 * http://people.inf.ethz.ch/daniekro/classes/251-0247-00/f2007/readings/Tseitin70.pdf
61
 * in a single pass.
62
 *
63
 * The general idea is to introduce a new literal that will be equivalent to
64
 * each subexpression in the constructed equi-satisfiable formula, then
65
 * substitute the new literal for the formula, and so on, recursively.
66
 */
67
16046
class CnfStream {
68
  friend PropEngine;
69
  friend ProofCnfStream;
70
71
 public:
72
  /** Cache of what nodes have been registered to a literal. */
73
  typedef context::CDInsertHashMap<SatLiteral, TNode, SatLiteralHashFunction>
74
      LiteralToNodeMap;
75
76
  /** Cache of what literals have been registered to a node. */
77
  typedef context::CDInsertHashMap<Node, SatLiteral> NodeToLiteralMap;
78
79
  /**
80
   * Constructs a CnfStream that performs equisatisfiable CNF transformations
81
   * and sends the generated clauses and to the given SAT solver. This does not
82
   * take ownership of satSolver, registrar, or context.
83
   *
84
   * @param satSolver the sat solver to use.
85
   * @param registrar the entity that takes care of preregistration of Nodes.
86
   * @param context the context that the CNF should respect.
87
   * @param env Reference to the environment of the smt engine. Assertions
88
   * will not be dumped if env == nullptr.
89
   * @param rm the resource manager of the CNF stream
90
   * @param flpol policy for literals corresponding to formulas (those that are
91
   * not-theory literals).
92
   * @param name string identifier to distinguish between different instances
93
   * even for non-theory literals.
94
   */
95
  CnfStream(SatSolver* satSolver,
96
            Registrar* registrar,
97
            context::Context* context,
98
            Env* env,
99
            ResourceManager* rm,
100
            FormulaLitPolicy flpol = FormulaLitPolicy::INTERNAL,
101
            std::string name = "");
102
  /**
103
   * Convert a given formula to CNF and assert it to the SAT solver.
104
   *
105
   * @param node node to convert and assert
106
   * @param removable whether the sat solver can choose to remove the clauses
107
   * @param negated whether we are asserting the node negated
108
   * @param input whether it is an input assertion (rather than a lemma). This
109
   * information is only relevant for unsat core tracking.
110
   */
111
  void convertAndAssert(TNode node,
112
                        bool removable,
113
                        bool negated,
114
                        bool input = false);
115
  /**
116
   * Get the node that is represented by the given SatLiteral.
117
   * @param literal the literal from the sat solver
118
   * @return the actual node
119
   */
120
  TNode getNode(const SatLiteral& literal);
121
122
  /**
123
   * Returns true iff the node has an assigned literal (it might not be
124
   * translated).
125
   * @param node the node
126
   */
127
  bool hasLiteral(TNode node) const;
128
129
  /**
130
   * Ensure that the given node will have a designated SAT literal that is
131
   * definitionally equal to it.  The result of this function is that the Node
132
   * can be queried via getSatValue(). Essentially, this is like a "convert-but-
133
   * don't-assert" version of convertAndAssert().
134
   */
135
  void ensureLiteral(TNode n);
136
137
  /**
138
   * Returns the literal that represents the given node in the SAT CNF
139
   * representation.
140
   * @param node [Presumably there are some constraints on the kind of
141
   * node? E.g., it needs to be a boolean? -Chris]
142
   */
143
  SatLiteral getLiteral(TNode node);
144
145
  /**
146
   * Returns the Boolean variables from the input problem.
147
   */
148
  void getBooleanVariables(std::vector<TNode>& outputVariables) const;
149
150
  /**
151
   * For SAT/theory relevancy. Returns true if node is a "notify formula".
152
   * Returns true if node is formula that we are being notified about that
153
   * is not a theory atom.
154
   *
155
   * Note this is only ever true when the policy passed to this class is
156
   * FormulaLitPolicy::TRACK_AND_NOTIFY.
157
   */
158
  bool isNotifyFormula(TNode node) const;
159
160
  /** Retrieves map from nodes to literals. */
161
  const CnfStream::NodeToLiteralMap& getTranslationCache() const;
162
163
  /** Retrieves map from literals to nodes. */
164
  const CnfStream::LiteralToNodeMap& getNodeCache() const;
165
166
 protected:
167
  /**
168
   * Same as above, except that uses the saved d_removable flag. It calls the
169
   * dedicated converter for the possible formula kinds.
170
   */
171
  void convertAndAssert(TNode node, bool negated);
172
  /** Specific converters for each formula kind. */
173
  void convertAndAssertAnd(TNode node, bool negated);
174
  void convertAndAssertOr(TNode node, bool negated);
175
  void convertAndAssertXor(TNode node, bool negated);
176
  void convertAndAssertIff(TNode node, bool negated);
177
  void convertAndAssertImplies(TNode node, bool negated);
178
  void convertAndAssertIte(TNode node, bool negated);
179
180
  /**
181
   * Transforms the node into CNF recursively and yields a literal
182
   * definitionally equal to it.
183
   *
184
   * This method also populates caches, kept in d_cnfStream, between formulas
185
   * and literals to avoid redundant work and to retrieve formulas from literals
186
   * and vice-versa.
187
   *
188
   * @param node the formula to transform
189
   * @param negated whether the literal is negated
190
   * @return the literal representing the root of the formula
191
   */
192
  SatLiteral toCNF(TNode node, bool negated = false);
193
194
  /**
195
   * Specific clausifiers that clausify a formula based on the given formula
196
   * kind and introduce a literal definitionally equal to it.
197
   */
198
  void handleXor(TNode node);
199
  void handleImplies(TNode node);
200
  void handleIff(TNode node);
201
  void handleIte(TNode node);
202
  void handleAnd(TNode node);
203
  void handleOr(TNode node);
204
205
  /** Stores the literal of the given node in d_literalToNodeMap.
206
   *
207
   * Note that n must already have a literal associated to it in
208
   * d_nodeToLiteralMap.
209
   */
210
  void ensureMappingForLiteral(TNode n);
211
212
  /** The SAT solver we will be using */
213
  SatSolver* d_satSolver;
214
215
  /** Pointer to the env of the smt engine */
216
  Env* d_env;
217
218
  /** Boolean variables that we translated */
219
  context::CDList<TNode> d_booleanVariables;
220
221
  /** Formulas that we translated that we are notifying */
222
  context::CDHashSet<Node> d_notifyFormulas;
223
224
  /** Map from nodes to literals */
225
  NodeToLiteralMap d_nodeToLiteralMap;
226
227
  /** Map from literals to nodes */
228
  LiteralToNodeMap d_literalToNodeMap;
229
230
  /**
231
   * True if the lit-to-Node map should be kept for all lits, not just
232
   * theory lits.  This is true if e.g. replay logging is on, which
233
   * dumps the Nodes corresponding to decision literals.
234
   */
235
  const FormulaLitPolicy d_flitPolicy;
236
237
  /** The "registrar" for pre-registration of terms */
238
  Registrar* d_registrar;
239
240
  /** The name of this CNF stream*/
241
  std::string d_name;
242
243
  /**
244
   * Are we asserting a removable clause (true) or a permanent clause (false).
245
   * This is set at the beginning of convertAndAssert so that it doesn't
246
   * need to be passed on over the stack.  Only pure clauses can be asserted
247
   * as removable.
248
   */
249
  bool d_removable;
250
251
  /**
252
   * Asserts the given clause to the sat solver.
253
   * @param node the node giving rise to this clause
254
   * @param clause the clause to assert
255
   * @return whether the clause was asserted in the SAT solver.
256
   */
257
  bool assertClause(TNode node, SatClause& clause);
258
259
  /**
260
   * Asserts the unit clause to the sat solver.
261
   * @param node the node giving rise to this clause
262
   * @param a the unit literal of the clause
263
   * @return whether the clause was asserted in the SAT solver.
264
   */
265
  bool assertClause(TNode node, SatLiteral a);
266
267
  /**
268
   * Asserts the binary clause to the sat solver.
269
   * @param node the node giving rise to this clause
270
   * @param a the first literal in the clause
271
   * @param b the second literal in the clause
272
   * @return whether the clause was asserted in the SAT solver.
273
   */
274
  bool assertClause(TNode node, SatLiteral a, SatLiteral b);
275
276
  /**
277
   * Asserts the ternary clause to the sat solver.
278
   * @param node the node giving rise to this clause
279
   * @param a the first literal in the clause
280
   * @param b the second literal in the clause
281
   * @param c the thirs literal in the clause
282
   * @return whether the clause was asserted in the SAT solver.
283
   */
284
  bool assertClause(TNode node, SatLiteral a, SatLiteral b, SatLiteral c);
285
286
  /**
287
   * Acquires a new variable from the SAT solver to represent the node
288
   * and inserts the necessary data it into the mapping tables.
289
   * @param node a formula
290
   * @param isTheoryAtom is this a theory atom that needs to be asserted to
291
   * theory.
292
   * @param preRegister whether to preregister the atom with the theory
293
   * @param canEliminate whether the sat solver can safely eliminate this
294
   * variable.
295
   * @return the literal corresponding to the formula
296
   */
297
  SatLiteral newLiteral(TNode node, bool isTheoryAtom = false,
298
                        bool preRegister = false, bool canEliminate = true);
299
300
  /**
301
   * Constructs a new literal for an atom and returns it.  Calls
302
   * newLiteral().
303
   *
304
   * @param node the node to convert; there should be no boolean
305
   * structure in this expression.  Assumed to not be in the
306
   * translation cache.
307
   */
308
  SatLiteral convertAtom(TNode node);
309
310
  /** Pointer to resource manager for associated SmtEngine */
311
  ResourceManager* d_resourceManager;
312
313
 private:
314
  struct Statistics
315
  {
316
    Statistics(const std::string& name);
317
    TimerStat d_cnfConversionTime;
318
  } d_stats;
319
320
}; /* class CnfStream */
321
322
}  // namespace prop
323
}  // namespace cvc5
324
325
#endif /* CVC5__PROP__CNF_STREAM_H */