GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bv_subtheory_algebraic.h Lines: 0 18 0.0 %
Date: 2021-05-22 Branches: 0 10 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Liana Hadarean, Mathias Preiner, 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
 * Algebraic solver.
14
 */
15
16
#include "cvc5_private.h"
17
18
#pragma once
19
20
#include <unordered_map>
21
#include <unordered_set>
22
23
#include "theory/bv/bv_subtheory.h"
24
#include "theory/bv/slicer.h"
25
#include "theory/substitutions.h"
26
27
namespace cvc5 {
28
namespace theory {
29
namespace bv {
30
31
class AlgebraicSolver;
32
33
Node mergeExplanations(TNode expl1, TNode expl2);
34
Node mergeExplanations(const std::vector<Node>& expls);
35
36
/**
37
 * Non-context dependent substitution with explanations.
38
 *
39
 */
40
class SubstitutionEx
41
{
42
  struct SubstitutionElement
43
  {
44
    Node to;
45
    Node reason;
46
    SubstitutionElement() : to(), reason() {}
47
48
    SubstitutionElement(TNode t, TNode r) : to(t), reason(r) {}
49
  };
50
51
  struct SubstitutionStackElement
52
  {
53
    TNode node;
54
    bool childrenAdded;
55
    SubstitutionStackElement(TNode n, bool ca = false)
56
        : node(n), childrenAdded(ca)
57
    {
58
    }
59
  };
60
61
  typedef std::unordered_map<Node, SubstitutionElement> Substitutions;
62
  typedef std::unordered_map<Node, SubstitutionElement> SubstitutionsCache;
63
64
  Substitutions d_substitutions;
65
  SubstitutionsCache d_cache;
66
  bool d_cacheInvalid;
67
  theory::SubstitutionMap* d_modelMap;
68
69
  Node getReason(TNode node) const;
70
  bool hasCache(TNode node) const;
71
  Node getCache(TNode node) const;
72
  void storeCache(TNode from, TNode to, Node rason);
73
  Node internalApply(TNode node);
74
75
 public:
76
  SubstitutionEx(theory::SubstitutionMap* modelMap);
77
  /**
78
   * Returnst true if the substitution map did not contain from.
79
   *
80
   * @param from
81
   * @param to
82
   * @param reason
83
   *
84
   * @return
85
   */
86
  bool addSubstitution(TNode from, TNode to, TNode reason);
87
  Node apply(TNode node);
88
  Node explain(TNode node) const;
89
};
90
91
/**
92
 * In-processing worklist element, id keeps track of
93
 * original assertion.
94
 *
95
 */
96
struct WorklistElement
97
{
98
  Node node;
99
  unsigned id;
100
  WorklistElement(Node n, unsigned i) : node(n), id(i) {}
101
  WorklistElement() : node(), id(-1) {}
102
};
103
104
typedef std::unordered_map<Node, Node> NodeNodeMap;
105
typedef std::unordered_map<Node, unsigned> NodeIdMap;
106
typedef std::unordered_set<TNode> TNodeSet;
107
108
class ExtractSkolemizer
109
{
110
  struct Extract
111
  {
112
    unsigned high;
113
    unsigned low;
114
    Extract(unsigned h, unsigned l) : high(h), low(l) {}
115
  };
116
117
  struct ExtractList
118
  {
119
    Base base;
120
    std::vector<Extract> extracts;
121
    ExtractList(unsigned bitwidth) : base(bitwidth), extracts() {}
122
    ExtractList() : base(1), extracts() {}
123
    void addExtract(Extract& e);
124
  };
125
  typedef std::unordered_map<Node, ExtractList> VarExtractMap;
126
  context::Context d_emptyContext;
127
  VarExtractMap d_varToExtract;
128
  theory::SubstitutionMap* d_modelMap;
129
  theory::SubstitutionMap d_skolemSubst;
130
  theory::SubstitutionMap d_skolemSubstRev;
131
132
  void storeSkolem(TNode node, TNode skolem);
133
  void storeExtract(TNode var, unsigned high, unsigned low);
134
  void collectExtracts(TNode node, TNodeSet& seen);
135
  Node skolemize(TNode);
136
  Node unSkolemize(TNode);
137
138
  Node mkSkolem(Node node);
139
140
 public:
141
  ExtractSkolemizer(theory::SubstitutionMap* modelMap);
142
  void skolemize(std::vector<WorklistElement>&);
143
  void unSkolemize(std::vector<WorklistElement>&);
144
  ~ExtractSkolemizer();
145
};
146
147
class BVQuickCheck;
148
class QuickXPlain;
149
150
/**
151
 * AlgebraicSolver
152
 */
153
class AlgebraicSolver : public SubtheorySolver
154
{
155
  struct Statistics
156
  {
157
    IntStat d_numCallstoCheck;
158
    IntStat d_numSimplifiesToTrue;
159
    IntStat d_numSimplifiesToFalse;
160
    IntStat d_numUnsat;
161
    IntStat d_numSat;
162
    IntStat d_numUnknown;
163
    TimerStat d_solveTime;
164
    ValueStat<double> d_useHeuristic;
165
    Statistics();
166
  };
167
168
  std::unique_ptr<SubstitutionMap> d_modelMap;
169
  std::unique_ptr<BVQuickCheck> d_quickSolver;
170
  context::CDO<bool> d_isComplete;
171
  context::CDO<bool>
172
      d_isDifficult; /**< flag to indicate whether the current assertions
173
                        contain expensive BV operators */
174
175
  unsigned long d_budget;
176
  std::vector<Node> d_explanations; /**< explanations for assertions indexed by
177
                                       assertion id */
178
  TNodeSet d_inputAssertions; /**< assertions in current context (for debugging
179
                                 purposes only) */
180
  NodeIdMap d_ids;            /**< map from assertions to ids */
181
  uint64_t d_numSolved;
182
  uint64_t d_numCalls;
183
184
  /** separate quickXplain module as it can reuse the current SAT solver */
185
  std::unique_ptr<QuickXPlain> d_quickXplain;
186
187
  Statistics d_statistics;
188
  bool useHeuristic();
189
  void setConflict(TNode conflict);
190
  bool isSubstitutableIn(TNode node, TNode in);
191
  bool checkExplanation(TNode expl);
192
  void storeExplanation(TNode expl);
193
  void storeExplanation(unsigned id, TNode expl);
194
  /**
195
   * Apply substitutions and rewriting to the worklist assertions to a fixpoint.
196
   * Subsitutions learned store in subst.
197
   *
198
   * @param worklist
199
   * @param subst
200
   */
201
  void processAssertions(std::vector<WorklistElement>& worklist,
202
                         SubstitutionEx& subst);
203
  /**
204
   * Attempt to solve the equation in fact, and if successful
205
   * add a substitution to subst.
206
   *
207
   * @param fact equation we are trying to solve
208
   * @param reason the reason in terms of original assertions
209
   * @param subst substitution map
210
   *
211
   * @return true if added a substitution to subst
212
   */
213
  bool solve(TNode fact, TNode reason, SubstitutionEx& subst);
214
  /**
215
   * Run a SAT solver on the given facts with the given budget.
216
   * Sets the isComplete flag and conflict accordingly.
217
   *
218
   * @param facts
219
   *
220
   * @return true if no conflict was detected.
221
   */
222
  bool quickCheck(std::vector<Node>& facts);
223
224
 public:
225
  AlgebraicSolver(context::Context* c, BVSolverLazy* bv);
226
  ~AlgebraicSolver();
227
228
  void preRegister(TNode node) override {}
229
  bool check(Theory::Effort e) override;
230
  void explain(TNode literal, std::vector<TNode>& assumptions) override
231
  {
232
    Unreachable() << "AlgebraicSolver does not propagate.\n";
233
  }
234
  EqualityStatus getEqualityStatus(TNode a, TNode b) override;
235
  bool collectModelValues(TheoryModel* m,
236
                          const std::set<Node>& termSet) override;
237
  Node getModelValue(TNode node) override;
238
  bool isComplete() override;
239
  void assertFact(TNode fact) override;
240
};
241
242
}  // namespace bv
243
}  // namespace theory
244
}  // namespace cvc5