GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/congruence_manager.h Lines: 3 3 100.0 %
Date: 2021-08-14 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Alex Ozdemir, Tim King, Andrew Reynolds
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
 * [[ Add one-line brief description here ]]
14
 *
15
 * [[ Add lengthier description here ]]
16
 * \todo document this file
17
 */
18
19
#include "cvc5_private.h"
20
21
#pragma once
22
23
#include "context/cdhashmap.h"
24
#include "context/cdlist.h"
25
#include "context/cdmaybe.h"
26
#include "context/cdtrail_queue.h"
27
#include "proof/trust_node.h"
28
#include "theory/arith/arith_utilities.h"
29
#include "theory/arith/arithvar.h"
30
#include "theory/arith/callbacks.h"
31
#include "theory/arith/constraint_forward.h"
32
#include "theory/uf/equality_engine_notify.h"
33
#include "util/dense_map.h"
34
#include "util/statistics_stats.h"
35
36
namespace cvc5 {
37
38
class ProofNodeManager;
39
class EagerProofGenerator;
40
41
namespace context {
42
class Context;
43
class UserContext;
44
}
45
46
namespace theory {
47
struct EeSetupInfo;
48
49
namespace eq {
50
class ProofEqEngine;
51
class EqualityEngine;
52
}
53
54
namespace arith {
55
56
class ArithVariables;
57
58
class ArithCongruenceManager {
59
private:
60
  context::CDRaised d_inConflict;
61
  RaiseEqualityEngineConflict d_raiseConflict;
62
63
  /**
64
   * The set of ArithVars equivalent to a pair of terms.
65
   * If this is 0 or cannot be 0, this can be signalled.
66
   * The pair of terms for the congruence is stored in watched equalities.
67
   */
68
  DenseSet d_watchedVariables;
69
  /** d_watchedVariables |-> (= x y) */
70
  ArithVarToNodeMap d_watchedEqualities;
71
72
73
9853
  class ArithCongruenceNotify : public eq::EqualityEngineNotify {
74
  private:
75
    ArithCongruenceManager& d_acm;
76
  public:
77
    ArithCongruenceNotify(ArithCongruenceManager& acm);
78
79
    bool eqNotifyTriggerPredicate(TNode predicate, bool value) override;
80
81
    bool eqNotifyTriggerTermEquality(TheoryId tag,
82
                                     TNode t1,
83
                                     TNode t2,
84
                                     bool value) override;
85
86
    void eqNotifyConstantTermMerge(TNode t1, TNode t2) override;
87
    void eqNotifyNewClass(TNode t) override;
88
    void eqNotifyMerge(TNode t1, TNode t2) override;
89
    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override;
90
  };
91
  ArithCongruenceNotify d_notify;
92
93
  context::CDList<Node> d_keepAlive;
94
95
  /** Store the propagations. */
96
  context::CDTrailQueue<Node> d_propagatations;
97
98
  /* This maps the node a theory engine will request on an explain call to
99
   * to its corresponding PropUnit.
100
   * This is node is potentially both the propagation or
101
   * Rewriter::rewrite(propagation).
102
   */
103
  typedef context::CDHashMap<Node, size_t> ExplainMap;
104
  ExplainMap d_explanationMap;
105
106
  ConstraintDatabase& d_constraintDatabase;
107
  SetupLiteralCallBack d_setupLiteral;
108
109
  const ArithVariables& d_avariables;
110
111
  /** The equality engine being used by this class */
112
  eq::EqualityEngine* d_ee;
113
  /** The equality engine we allocated */
114
  std::unique_ptr<eq::EqualityEngine> d_allocEe;
115
  /** The sat context */
116
  context::Context* d_satContext;
117
  /** The user context */
118
  context::UserContext* d_userContext;
119
120
  /** proof manager */
121
  ProofNodeManager* d_pnm;
122
  /** A proof generator for storing proofs of facts that are asserted to the EQ
123
   * engine. Note that these proofs **are not closed**; they may contain
124
   * literals from the explanation of their fact as unclosed assumptions.
125
   * This makes these proofs SAT-context depdent.
126
   *
127
   * This is why this generator is separate from the TheoryArithPrivate
128
   * generator, which stores closed proofs.
129
   */
130
  std::unique_ptr<EagerProofGenerator> d_pfGenEe;
131
  /** A proof generator for TrustNodes sent to TheoryArithPrivate.
132
   *
133
   * When TheoryArithPrivate requests an explanation from
134
   * ArithCongruenceManager, it can request a TrustNode for that explanation.
135
   * This proof generator is the one used in that TrustNode: it stores the
136
   * (closed) proofs of implications proved by the
137
   * ArithCongruenceManager/EqualityEngine.
138
   *
139
   * It is insufficient to just use the ProofGenerator from the ProofEqEngine,
140
   * since sometimes the ArithCongruenceManager needs to add some
141
   * arith-specific reasoning to extend the proof (e.g. rewriting the result
142
   * into a normal form).
143
   * */
144
  std::unique_ptr<EagerProofGenerator> d_pfGenExplain;
145
146
  /** Pointer to the proof equality engine of TheoryArith */
147
  theory::eq::ProofEqEngine* d_pfee;
148
  /** The proof equality engine we allocated */
149
  std::unique_ptr<eq::ProofEqEngine> d_allocPfee;
150
151
  /** Raise a conflict node `conflict` to the theory of arithmetic.
152
   *
153
   * When proofs are enabled, a (closed) proof of the conflict should be
154
   * provided.
155
   */
156
  void raiseConflict(Node conflict, std::shared_ptr<ProofNode> pf = nullptr);
157
  /**
158
   * Are proofs enabled? This is true if a non-null proof manager was provided
159
   * to the constructor of this class.
160
   */
161
  bool isProofEnabled() const;
162
163
 public:
164
  bool inConflict() const;
165
166
  bool hasMorePropagations() const;
167
168
  const Node getNextPropagation();
169
170
  bool canExplain(TNode n) const;
171
172
private:
173
  Node externalToInternal(TNode n) const;
174
175
  void pushBack(TNode n);
176
177
  void pushBack(TNode n, TNode r);
178
179
  void pushBack(TNode n, TNode r, TNode w);
180
181
  bool propagate(TNode x);
182
  void explain(TNode literal, std::vector<TNode>& assumptions);
183
184
  /** Assert this literal to the eq engine. Common functionality for
185
   *   * assertionToEqualityEngine(..)
186
   *   * equalsConstant(c)
187
   *   * equalsConstant(lb, ub)
188
   * If proof is off, then just asserts.
189
   */
190
  void assertLitToEqualityEngine(Node lit,
191
                                 TNode reason,
192
                                 std::shared_ptr<ProofNode> pf);
193
  /** This sends a shared term to the uninterpreted equality engine. */
194
  void assertionToEqualityEngine(bool eq,
195
                                 ArithVar s,
196
                                 TNode reason,
197
                                 std::shared_ptr<ProofNode> pf);
198
199
  /** Check for proof for this or a symmetric fact
200
   *
201
   * The proof submitted to this method are stored in `d_pfGenEe`, and should
202
   * have closure properties consistent with the documentation for that member.
203
   *
204
   * @returns whether this or a symmetric fact has a proof.
205
   */
206
  bool hasProofFor(TNode f) const;
207
  /**
208
   * Sets the proof for this fact and the symmetric one.
209
   *
210
   * The proof submitted to this method are stored in `d_pfGenEe`, and should
211
   * have closure properties consistent with the documentation for that member.
212
   * */
213
  void setProofFor(TNode f, std::shared_ptr<ProofNode> pf) const;
214
215
  /** Dequeues the delay queue and asserts these equalities.*/
216
  void enableSharedTerms();
217
  void dequeueLiterals();
218
219
  void enqueueIntoNB(const std::set<TNode> all, NodeBuilder& nb);
220
221
  /**
222
   * Determine an explaination for `internal`. That is a conjunction of theory
223
   * literals which imply `internal`.
224
   *
225
   * The TrustNode here is a trusted propagation.
226
   */
227
  TrustNode explainInternal(TNode internal);
228
229
 public:
230
  ArithCongruenceManager(context::Context* satContext,
231
                         context::UserContext* u,
232
                         ConstraintDatabase&,
233
                         SetupLiteralCallBack,
234
                         const ArithVariables&,
235
                         RaiseEqualityEngineConflict raiseConflict,
236
                         ProofNodeManager* pnm);
237
  ~ArithCongruenceManager();
238
239
  //--------------------------------- initialization
240
  /**
241
   * Returns true if we need an equality engine, see
242
   * Theory::needsEqualityEngine.
243
   */
244
  bool needsEqualityEngine(EeSetupInfo& esi);
245
  /**
246
   * Finish initialize. This class is instructed by TheoryArithPrivate to use
247
   * the equality engine ee.
248
   */
249
  void finishInit(eq::EqualityEngine* ee);
250
  //--------------------------------- end initialization
251
252
  /**
253
   * Return the trust node for the explanation of literal. The returned
254
   * trust node is generated by the proof equality engine of this class.
255
   */
256
  TrustNode explain(TNode literal);
257
258
  void explain(TNode lit, NodeBuilder& out);
259
260
  void addWatchedPair(ArithVar s, TNode x, TNode y);
261
262
6359394
  inline bool isWatchedVariable(ArithVar s) const {
263
6359394
    return d_watchedVariables.isMember(s);
264
  }
265
266
  /** Assert an equality. */
267
  void watchedVariableIsZero(ConstraintCP eq);
268
269
  /** Assert a conjunction from lb and ub. */
270
  void watchedVariableIsZero(ConstraintCP lb, ConstraintCP ub);
271
272
  /** Assert that the value cannot be zero. */
273
  void watchedVariableCannotBeZero(ConstraintCP c);
274
275
  /** Assert that the value cannot be zero. */
276
  void watchedVariableCannotBeZero(ConstraintCP c, ConstraintCP d);
277
278
279
  /** Assert that the value is congruent to a constant. */
280
  void equalsConstant(ConstraintCP eq);
281
  void equalsConstant(ConstraintCP lb, ConstraintCP ub);
282
283
 private:
284
  class Statistics {
285
  public:
286
    IntStat d_watchedVariables;
287
    IntStat d_watchedVariableIsZero;
288
    IntStat d_watchedVariableIsNotZero;
289
290
    IntStat d_equalsConstantCalls;
291
292
    IntStat d_propagations;
293
    IntStat d_propagateConstraints;
294
    IntStat d_conflicts;
295
296
    Statistics();
297
  } d_statistics;
298
299
};/* class ArithCongruenceManager */
300
301
std::vector<Node> andComponents(TNode an);
302
303
}  // namespace arith
304
}  // namespace theory
305
}  // namespace cvc5