1 /********************* */
2 /*! \file bv_subtheory_algebraic.h
4 ** Top contributors (to current version):
5 ** Liana Hadarean, Mathias Preiner, Tim King
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief Algebraic solver.
17 #include "cvc4_private.h"
21 #include <unordered_map>
22 #include <unordered_set>
24 #include "theory/bv/bv_subtheory.h"
25 #include "theory/bv/slicer.h"
26 #include "theory/substitutions.h"
32 class AlgebraicSolver
;
34 Node
mergeExplanations(TNode expl1
, TNode expl2
);
35 Node
mergeExplanations(const std::vector
<Node
>& expls
);
38 * Non-context dependent substitution with explanations.
43 struct SubstitutionElement
47 SubstitutionElement() : to(), reason() {}
49 SubstitutionElement(TNode t
, TNode r
) : to(t
), reason(r
) {}
52 struct SubstitutionStackElement
56 SubstitutionStackElement(TNode n
, bool ca
= false)
57 : node(n
), childrenAdded(ca
)
62 typedef std::unordered_map
<Node
, SubstitutionElement
, NodeHashFunction
>
64 typedef std::unordered_map
<Node
, SubstitutionElement
, NodeHashFunction
>
67 Substitutions d_substitutions
;
68 SubstitutionsCache d_cache
;
70 theory::SubstitutionMap
* d_modelMap
;
72 Node
getReason(TNode node
) const;
73 bool hasCache(TNode node
) const;
74 Node
getCache(TNode node
) const;
75 void storeCache(TNode from
, TNode to
, Node rason
);
76 Node
internalApply(TNode node
);
79 SubstitutionEx(theory::SubstitutionMap
* modelMap
);
81 * Returnst true if the substitution map did not contain from.
89 bool addSubstitution(TNode from
, TNode to
, TNode reason
);
90 Node
apply(TNode node
);
91 Node
explain(TNode node
) const;
95 * In-processing worklist element, id keeps track of
99 struct WorklistElement
103 WorklistElement(Node n
, unsigned i
) : node(n
), id(i
) {}
104 WorklistElement() : node(), id(-1) {}
107 typedef std::unordered_map
<Node
, Node
, NodeHashFunction
> NodeNodeMap
;
108 typedef std::unordered_map
<Node
, unsigned, NodeHashFunction
> NodeIdMap
;
109 typedef std::unordered_set
<TNode
, TNodeHashFunction
> TNodeSet
;
111 class ExtractSkolemizer
117 Extract(unsigned h
, unsigned l
) : high(h
), low(l
) {}
123 std::vector
<Extract
> extracts
;
124 ExtractList(unsigned bitwidth
) : base(bitwidth
), extracts() {}
125 ExtractList() : base(1), extracts() {}
126 void addExtract(Extract
& e
);
128 typedef std::unordered_map
<Node
, ExtractList
, NodeHashFunction
> VarExtractMap
;
129 context::Context d_emptyContext
;
130 VarExtractMap d_varToExtract
;
131 theory::SubstitutionMap
* d_modelMap
;
132 theory::SubstitutionMap d_skolemSubst
;
133 theory::SubstitutionMap d_skolemSubstRev
;
135 void storeSkolem(TNode node
, TNode skolem
);
136 void storeExtract(TNode var
, unsigned high
, unsigned low
);
137 void collectExtracts(TNode node
, TNodeSet
& seen
);
138 Node
skolemize(TNode
);
139 Node
unSkolemize(TNode
);
141 Node
mkSkolem(Node node
);
144 ExtractSkolemizer(theory::SubstitutionMap
* modelMap
);
145 void skolemize(std::vector
<WorklistElement
>&);
146 void unSkolemize(std::vector
<WorklistElement
>&);
147 ~ExtractSkolemizer();
156 class AlgebraicSolver
: public SubtheorySolver
160 IntStat d_numCallstoCheck
;
161 IntStat d_numSimplifiesToTrue
;
162 IntStat d_numSimplifiesToFalse
;
165 IntStat d_numUnknown
;
166 TimerStat d_solveTime
;
167 BackedStat
<double> d_useHeuristic
;
172 std::unique_ptr
<SubstitutionMap
> d_modelMap
;
173 std::unique_ptr
<BVQuickCheck
> d_quickSolver
;
174 context::CDO
<bool> d_isComplete
;
176 d_isDifficult
; /**< flag to indicate whether the current assertions
177 contain expensive BV operators */
179 unsigned long d_budget
;
180 std::vector
<Node
> d_explanations
; /**< explanations for assertions indexed by
182 TNodeSet d_inputAssertions
; /**< assertions in current context (for debugging
184 NodeIdMap d_ids
; /**< map from assertions to ids */
185 uint64_t d_numSolved
;
188 /** separate quickXplain module as it can reuse the current SAT solver */
189 std::unique_ptr
<QuickXPlain
> d_quickXplain
;
191 Statistics d_statistics
;
193 void setConflict(TNode conflict
);
194 bool isSubstitutableIn(TNode node
, TNode in
);
195 bool checkExplanation(TNode expl
);
196 void storeExplanation(TNode expl
);
197 void storeExplanation(unsigned id
, TNode expl
);
199 * Apply substitutions and rewriting to the worklist assertions to a fixpoint.
200 * Subsitutions learned store in subst.
205 void processAssertions(std::vector
<WorklistElement
>& worklist
,
206 SubstitutionEx
& subst
);
208 * Attempt to solve the equation in fact, and if successful
209 * add a substitution to subst.
211 * @param fact equation we are trying to solve
212 * @param reason the reason in terms of original assertions
213 * @param subst substitution map
215 * @return true if added a substitution to subst
217 bool solve(TNode fact
, TNode reason
, SubstitutionEx
& subst
);
219 * Run a SAT solver on the given facts with the given budget.
220 * Sets the isComplete flag and conflict accordingly.
224 * @return true if no conflict was detected.
226 bool quickCheck(std::vector
<Node
>& facts
);
229 AlgebraicSolver(context::Context
* c
, BVSolverLazy
* bv
);
232 void preRegister(TNode node
) override
{}
233 bool check(Theory::Effort e
) override
;
234 void explain(TNode literal
, std::vector
<TNode
>& assumptions
) override
236 Unreachable() << "AlgebraicSolver does not propagate.\n";
238 EqualityStatus
getEqualityStatus(TNode a
, TNode b
) override
;
239 bool collectModelValues(TheoryModel
* m
,
240 const std::set
<Node
>& termSet
) override
;
241 Node
getModelValue(TNode node
) override
;
242 bool isComplete() override
;
243 void assertFact(TNode fact
) override
;
247 } // namespace theory