GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bv_solver_lazy.h Lines: 19 20 95.0 %
Date: 2021-05-22 Branches: 14 42 33.3 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Mathias Preiner, Liana Hadarean, 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
 * Lazy bit-vector solver.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__BV__BV_SOLVER_LAZY_H
19
#define CVC5__THEORY__BV__BV_SOLVER_LAZY_H
20
21
#include <unordered_map>
22
#include <unordered_set>
23
24
#include "context/cdhashset.h"
25
#include "context/cdlist.h"
26
#include "context/context.h"
27
#include "theory/bv/bv_solver.h"
28
#include "theory/bv/bv_subtheory.h"
29
#include "theory/bv/theory_bv.h"
30
#include "util/hash.h"
31
32
namespace cvc5 {
33
namespace theory {
34
namespace bv {
35
36
class CoreSolver;
37
class InequalitySolver;
38
class AlgebraicSolver;
39
class BitblastSolver;
40
class EagerBitblastSolver;
41
class AbstractionModule;
42
43
class BVSolverLazy : public BVSolver
44
{
45
  /** Back reference to TheoryBV */
46
  TheoryBV& d_bv;
47
48
  /** The context we are using */
49
  context::Context* d_context;
50
51
  /** Context dependent set of atoms we already propagated */
52
  context::CDHashSet<Node> d_alreadyPropagatedSet;
53
  context::CDHashSet<Node> d_sharedTermsSet;
54
55
  std::vector<std::unique_ptr<SubtheorySolver>> d_subtheories;
56
  std::unordered_map<SubTheory, SubtheorySolver*, std::hash<int>>
57
      d_subtheoryMap;
58
59
 public:
60
  BVSolverLazy(TheoryBV& bv,
61
               context::Context* c,
62
               context::UserContext* u,
63
               ProofNodeManager* pnm = nullptr,
64
               std::string name = "");
65
66
  ~BVSolverLazy();
67
68
  //--------------------------------- initialization
69
70
  /**
71
   * Returns true if we need an equality engine. If so, we initialize the
72
   * information regarding how it should be setup. For details, see the
73
   * documentation in Theory::needsEqualityEngine.
74
   */
75
  bool needsEqualityEngine(EeSetupInfo& esi) override;
76
77
  /** finish initialization */
78
  void finishInit() override;
79
  //--------------------------------- end initialization
80
81
  void preRegisterTerm(TNode n) override;
82
83
  bool preCheck(Theory::Effort e) override;
84
85
  bool needsCheckLastEffort() override;
86
87
  void propagate(Theory::Effort e) override;
88
89
  TrustNode explain(TNode n) override;
90
91
  bool collectModelValues(TheoryModel* m,
92
                          const std::set<Node>& termSet) override;
93
94
  std::string identify() const override { return std::string("BVSolverLazy"); }
95
96
  TrustNode ppRewrite(TNode t) override;
97
98
  void ppStaticLearn(TNode in, NodeBuilder& learned) override;
99
100
  void presolve() override;
101
102
  bool applyAbstraction(const std::vector<Node>& assertions,
103
                        std::vector<Node>& new_assertions) override;
104
105
21
  bool isLeaf(TNode node) { return d_bv.isLeaf(node); }
106
107
 private:
108
  class Statistics
109
  {
110
   public:
111
    AverageStat d_avgConflictSize;
112
    TimerStat d_solveTimer;
113
    IntStat d_numCallsToCheckFullEffort;
114
    IntStat d_numCallsToCheckStandardEffort;
115
    TimerStat d_weightComputationTimer;
116
    IntStat d_numMultSlice;
117
    Statistics();
118
  };
119
120
  Statistics d_statistics;
121
122
  void check(Theory::Effort e);
123
  void spendResource(Resource r);
124
125
  typedef std::unordered_set<TNode> TNodeSet;
126
  typedef std::unordered_set<Node> NodeSet;
127
  NodeSet d_staticLearnCache;
128
129
  typedef std::unordered_map<Node, Node> NodeToNode;
130
131
  context::CDO<bool> d_lemmasAdded;
132
133
  // Are we in conflict?
134
  context::CDO<bool> d_conflict;
135
136
  // Invalidate the model cache if check was called
137
  context::CDO<bool> d_invalidateModelCache;
138
139
  /** The conflict node */
140
  Node d_conflictNode;
141
142
  /** Literals to propagate */
143
  context::CDList<Node> d_literalsToPropagate;
144
145
  /** Index of the next literal to propagate */
146
  context::CDO<unsigned> d_literalsToPropagateIndex;
147
148
  /**
149
   * Keeps a map from nodes to the subtheory that propagated it so that we can
150
   * explain it properly.
151
   */
152
  typedef context::CDHashMap<Node, SubTheory> PropagatedMap;
153
  PropagatedMap d_propagatedBy;
154
155
  std::unique_ptr<EagerBitblastSolver> d_eagerSolver;
156
  std::unique_ptr<AbstractionModule> d_abstractionModule;
157
  bool d_calledPreregister;
158
159
4476891
  bool wasPropagatedBySubtheory(TNode literal) const
160
  {
161
4476891
    return d_propagatedBy.find(literal) != d_propagatedBy.end();
162
  }
163
164
1788785
  SubTheory getPropagatingSubtheory(TNode literal) const
165
  {
166
1788785
    Assert(wasPropagatedBySubtheory(literal));
167
1788785
    PropagatedMap::const_iterator find = d_propagatedBy.find(literal);
168
1788785
    return (*find).second;
169
  }
170
171
  /** Should be called to propagate the literal.  */
172
  bool storePropagation(TNode literal, SubTheory subtheory);
173
174
  /**
175
   * Explains why this literal (propagated by subtheory) is true by adding
176
   * assumptions.
177
   */
178
  void explain(TNode literal, std::vector<TNode>& assumptions);
179
180
  void notifySharedTerm(TNode t) override;
181
182
44459
  bool isSharedTerm(TNode t) { return d_sharedTermsSet.contains(t); }
183
184
  EqualityStatus getEqualityStatus(TNode a, TNode b) override;
185
186
  Node getModelValue(TNode var);
187
188
3333024
  inline std::string indent()
189
  {
190
3333024
    std::string indentStr(d_context->getLevel(), ' ');
191
3333024
    return indentStr;
192
  }
193
194
  void setConflict(Node conflict = Node::null());
195
196
6039278
  bool inConflict() { return d_conflict; }
197
198
  void sendConflict();
199
200
1293
  void lemma(TNode node)
201
  {
202
1293
    d_im.lemma(node, InferenceId::BV_LAZY_LEMMA);
203
1293
    d_lemmasAdded = true;
204
1293
  }
205
206
  void checkForLemma(TNode node);
207
208
39463
  size_t numAssertions() { return d_bv.numAssertions(); }
209
210
1397957
  theory::Assertion get() { return d_bv.get(); }
211
212
1874670
  bool done() { return d_bv.done(); }
213
214
  friend class LazyBitblaster;
215
  friend class TLazyBitblaster;
216
  friend class EagerBitblaster;
217
  friend class BitblastSolver;
218
  friend class EqualitySolver;
219
  friend class CoreSolver;
220
  friend class InequalitySolver;
221
  friend class AlgebraicSolver;
222
  friend class EagerBitblastSolver;
223
}; /* class BVSolverLazy */
224
225
}  // namespace bv
226
}  // namespace theory
227
228
}  // namespace cvc5
229
230
#endif /* CVC5__THEORY__BV__BV_SOLVER_LAZY_H */