1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Gereon Kremer, 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 |
|
* Extensions to the theory of arithmetic incomplete handling of nonlinear |
14 |
|
* multiplication via axiom instantiations. |
15 |
|
*/ |
16 |
|
|
17 |
|
#ifndef CVC5__THEORY__ARITH__NL__NONLINEAR_EXTENSION_H |
18 |
|
#define CVC5__THEORY__ARITH__NL__NONLINEAR_EXTENSION_H |
19 |
|
|
20 |
|
#include <map> |
21 |
|
#include <vector> |
22 |
|
|
23 |
|
#include "expr/node.h" |
24 |
|
#include "smt/env_obj.h" |
25 |
|
#include "theory/arith/nl/cad_solver.h" |
26 |
|
#include "theory/arith/nl/ext/ext_state.h" |
27 |
|
#include "theory/arith/nl/ext/factoring_check.h" |
28 |
|
#include "theory/arith/nl/ext/monomial_bounds_check.h" |
29 |
|
#include "theory/arith/nl/ext/monomial_check.h" |
30 |
|
#include "theory/arith/nl/ext/proof_checker.h" |
31 |
|
#include "theory/arith/nl/ext/split_zero_check.h" |
32 |
|
#include "theory/arith/nl/ext/tangent_plane_check.h" |
33 |
|
#include "theory/arith/nl/ext_theory_callback.h" |
34 |
|
#include "theory/arith/nl/iand_solver.h" |
35 |
|
#include "theory/arith/nl/icp/icp_solver.h" |
36 |
|
#include "theory/arith/nl/nl_model.h" |
37 |
|
#include "theory/arith/nl/pow2_solver.h" |
38 |
|
#include "theory/arith/nl/stats.h" |
39 |
|
#include "theory/arith/nl/strategy.h" |
40 |
|
#include "theory/arith/nl/transcendental/transcendental_solver.h" |
41 |
|
#include "theory/ext_theory.h" |
42 |
|
#include "theory/theory.h" |
43 |
|
#include "util/result.h" |
44 |
|
|
45 |
|
namespace cvc5 { |
46 |
|
namespace theory { |
47 |
|
namespace eq { |
48 |
|
class EqualityEngine; |
49 |
|
} |
50 |
|
namespace arith { |
51 |
|
|
52 |
|
class InferenceManager; |
53 |
|
class TheoryArith; |
54 |
|
|
55 |
|
namespace nl { |
56 |
|
|
57 |
|
class NlLemma; |
58 |
|
|
59 |
|
/** Non-linear extension class |
60 |
|
* |
61 |
|
* This class implements model-based refinement schemes |
62 |
|
* for non-linear arithmetic, described in: |
63 |
|
* |
64 |
|
* - "Invariant Checking of NRA Transition Systems |
65 |
|
* via Incremental Reduction to LRA with EUF" by |
66 |
|
* Cimatti et al., TACAS 2017. |
67 |
|
* |
68 |
|
* - Section 5 of "Desiging Theory Solvers with |
69 |
|
* Extensions" by Reynolds et al., FroCoS 2017. |
70 |
|
* |
71 |
|
* - "Satisfiability Modulo Transcendental |
72 |
|
* Functions via Incremental Linearization" by Cimatti |
73 |
|
* et al., CADE 2017. |
74 |
|
* |
75 |
|
* It's main functionality is a check(...) method, |
76 |
|
* which is called by TheoryArithPrivate either: |
77 |
|
* (1) at full effort with no conflicts or lemmas emitted, or |
78 |
|
* (2) at last call effort. |
79 |
|
* In this method, this class calls d_im.lemma(...) |
80 |
|
* for valid arithmetic theory lemmas, based on the current set of assertions, |
81 |
|
* where d_im is the inference manager of TheoryArith. |
82 |
|
*/ |
83 |
|
class NonlinearExtension : EnvObj |
84 |
|
{ |
85 |
|
typedef context::CDHashSet<Node> NodeSet; |
86 |
|
|
87 |
|
public: |
88 |
|
NonlinearExtension(Env& env, TheoryArith& containing, ArithState& state); |
89 |
|
~NonlinearExtension(); |
90 |
|
/** |
91 |
|
* Does non-context dependent setup for a node connected to a theory. |
92 |
|
*/ |
93 |
|
void preRegisterTerm(TNode n); |
94 |
|
/** Check at effort level e. |
95 |
|
* |
96 |
|
* This call may result in (possibly multiple) calls to d_im.lemma(...) |
97 |
|
* where d_im is the inference manager of TheoryArith. |
98 |
|
* |
99 |
|
* If e is FULL, then we add lemmas based on context-depedent |
100 |
|
* simplification (see Reynolds et al FroCoS 2017). |
101 |
|
* |
102 |
|
* If e is LAST_CALL, we add lemmas based on model-based refinement |
103 |
|
* (see additionally Cimatti et al., TACAS 2017). The lemmas added at this |
104 |
|
* effort may be computed during a call to interceptModel as described below. |
105 |
|
*/ |
106 |
|
void check(Theory::Effort e); |
107 |
|
/** intercept model |
108 |
|
* |
109 |
|
* This method is called during TheoryArith::collectModelInfo, which is |
110 |
|
* invoked after the linear arithmetic solver passes a full effort check |
111 |
|
* with no lemmas. |
112 |
|
* |
113 |
|
* The argument arithModel is a map of the form { v1 -> c1, ..., vn -> cn } |
114 |
|
* which represents the linear arithmetic theory solver's contribution to the |
115 |
|
* current candidate model. That is, its collectModelInfo method is requesting |
116 |
|
* that equalities v1 = c1, ..., vn = cn be added to the current model, where |
117 |
|
* v1, ..., vn are arithmetic variables and c1, ..., cn are constants. Notice |
118 |
|
* arithmetic variables may be real-valued terms belonging to other theories, |
119 |
|
* or abstractions of applications of multiplication (kind NONLINEAR_MULT). |
120 |
|
* |
121 |
|
* This method requests that the non-linear solver inspect this model and |
122 |
|
* do any number of the following: |
123 |
|
* (1) Construct lemmas based on a model-based refinement procedure inspired |
124 |
|
* by Cimatti et al., TACAS 2017., |
125 |
|
* (2) In the case that the nonlinear solver finds that the current |
126 |
|
* constraints are satisfiable, it may "repair" the values in the argument |
127 |
|
* arithModel so that it satisfies certain nonlinear constraints. This may |
128 |
|
* involve e.g. solving for variables in nonlinear equations. |
129 |
|
*/ |
130 |
|
void interceptModel(std::map<Node, Node>& arithModel, |
131 |
|
const std::set<Node>& termSet); |
132 |
|
/** Does this class need a call to check(...) at last call effort? */ |
133 |
44999 |
bool needsCheckLastEffort() const { return d_needsLastCall; } |
134 |
|
/** presolve |
135 |
|
* |
136 |
|
* This function is called during TheoryArith's presolve command. |
137 |
|
* In this function, we send lemmas we accumulated during preprocessing, |
138 |
|
* for instance, definitional lemmas from expandDefinitions are sent out |
139 |
|
* on the output channel of TheoryArith in this function. |
140 |
|
*/ |
141 |
|
void presolve(); |
142 |
|
|
143 |
|
/** Process side effect se */ |
144 |
|
void processSideEffect(const NlLemma& se); |
145 |
|
|
146 |
|
private: |
147 |
|
/** Model-based refinement |
148 |
|
* |
149 |
|
* This is the main entry point of this class for generating lemmas on the |
150 |
|
* output channel of the theory of arithmetic. |
151 |
|
* |
152 |
|
* It is currently run at last call effort. It applies lemma schemas |
153 |
|
* described in Reynolds et al. FroCoS 2017 that are based on ruling out |
154 |
|
* the current candidate model. |
155 |
|
* |
156 |
|
* This function returns whether we found a satisfying assignment |
157 |
|
* (Result::Sat::SAT), or not (Result::Sat::UNSAT). Note that UNSAT does not |
158 |
|
* necessarily means the whole query is UNSAT, but that the linear model was |
159 |
|
* refuted by a lemma. |
160 |
|
*/ |
161 |
|
Result::Sat modelBasedRefinement(const std::set<Node>& termSet); |
162 |
|
|
163 |
|
/** get assertions |
164 |
|
* |
165 |
|
* Let M be the set of assertions known by THEORY_ARITH. This function adds a |
166 |
|
* set of literals M' to assertions such that M' and M are equivalent. |
167 |
|
* |
168 |
|
* Examples of how M' differs with M: |
169 |
|
* (1) M' may not include t < c (in M) if t < c' is in M' for c' < c, where |
170 |
|
* c and c' are constants, |
171 |
|
* (2) M' may contain t = c if both t >= c and t <= c are in M. |
172 |
|
*/ |
173 |
|
void getAssertions(std::vector<Node>& assertions); |
174 |
|
/** check model |
175 |
|
* |
176 |
|
* Returns the subset of assertions whose concrete values we cannot show are |
177 |
|
* true in the current model. Notice that we typically cannot compute concrete |
178 |
|
* values for assertions involving transcendental functions. Any assertion |
179 |
|
* whose model value cannot be computed is included in the return value of |
180 |
|
* this function. |
181 |
|
*/ |
182 |
|
std::vector<Node> checkModelEval(const std::vector<Node>& assertions); |
183 |
|
|
184 |
|
//---------------------------check model |
185 |
|
/** Check model |
186 |
|
* |
187 |
|
* Checks the current model based on solving for equalities, and using error |
188 |
|
* bounds on the Taylor approximation. |
189 |
|
* |
190 |
|
* If this function returns true, then all assertions in the input argument |
191 |
|
* "assertions" are satisfied for all interpretations of variables within |
192 |
|
* their computed bounds (as stored in d_check_model_bounds). |
193 |
|
* |
194 |
|
* For details, see Section 3 of Cimatti et al CADE 2017 under the heading |
195 |
|
* "Detecting Satisfiable Formulas". |
196 |
|
*/ |
197 |
|
bool checkModel(const std::vector<Node>& assertions); |
198 |
|
//---------------------------end check model |
199 |
|
/** compute relevant assertions */ |
200 |
|
void computeRelevantAssertions(const std::vector<Node>& assertions, |
201 |
|
std::vector<Node>& keep); |
202 |
|
|
203 |
|
/** run check strategy |
204 |
|
* |
205 |
|
* Check assertions for consistency in the effort LAST_CALL with a subset of |
206 |
|
* the assertions, false_asserts, that evaluate to false in the current model. |
207 |
|
* |
208 |
|
* xts : the list of (non-reduced) extended terms in the current context. |
209 |
|
* |
210 |
|
* This method adds lemmas to d_im directly. |
211 |
|
*/ |
212 |
|
void runStrategy(Theory::Effort effort, |
213 |
|
const std::vector<Node>& assertions, |
214 |
|
const std::vector<Node>& false_asserts, |
215 |
|
const std::vector<Node>& xts); |
216 |
|
|
217 |
|
/** commonly used terms */ |
218 |
|
Node d_zero; |
219 |
|
Node d_one; |
220 |
|
Node d_neg_one; |
221 |
|
Node d_true; |
222 |
|
// The theory of arithmetic containing this extension. |
223 |
|
TheoryArith& d_containing; |
224 |
|
/** A reference to the arithmetic state object */ |
225 |
|
ArithState& d_astate; |
226 |
|
InferenceManager& d_im; |
227 |
|
/** The statistics class */ |
228 |
|
NlStats d_stats; |
229 |
|
// needs last call effort |
230 |
|
bool d_needsLastCall; |
231 |
|
/** |
232 |
|
* The number of times we have the called main check method |
233 |
|
* (modelBasedRefinement). This counter is used for interleaving strategies. |
234 |
|
*/ |
235 |
|
unsigned d_checkCounter; |
236 |
|
/** The callback for the extended theory below */ |
237 |
|
NlExtTheoryCallback d_extTheoryCb; |
238 |
|
/** Extended theory, responsible for context-dependent simplification. */ |
239 |
|
ExtTheory d_extTheory; |
240 |
|
/** The non-linear model object |
241 |
|
* |
242 |
|
* This class is responsible for computing model values for arithmetic terms |
243 |
|
* and for establishing when we are able to answer "SAT". |
244 |
|
*/ |
245 |
|
NlModel d_model; |
246 |
|
|
247 |
|
/** The transcendental extension object |
248 |
|
* |
249 |
|
* This is the subsolver responsible for running the procedure for |
250 |
|
* transcendental functions. |
251 |
|
*/ |
252 |
|
transcendental::TranscendentalSolver d_trSlv; |
253 |
|
/** The proof checker for proofs of the nlext. */ |
254 |
|
ExtProofRuleChecker d_proofChecker; |
255 |
|
/** |
256 |
|
* Holds common lookup data for the checks implemented in the "nl-ext" |
257 |
|
* solvers (from Cimatti et al., TACAS 2017). |
258 |
|
*/ |
259 |
|
ExtState d_extState; |
260 |
|
/** Solver for factoring lemmas. */ |
261 |
|
FactoringCheck d_factoringSlv; |
262 |
|
/** Solver for lemmas about monomial bounds. */ |
263 |
|
MonomialBoundsCheck d_monomialBoundsSlv; |
264 |
|
/** Solver for lemmas about monomials. */ |
265 |
|
MonomialCheck d_monomialSlv; |
266 |
|
/** Solver for lemmas that split multiplication at zero. */ |
267 |
|
SplitZeroCheck d_splitZeroSlv; |
268 |
|
/** Solver for tangent plane lemmas. */ |
269 |
|
TangentPlaneCheck d_tangentPlaneSlv; |
270 |
|
/** The CAD-based solver */ |
271 |
|
CadSolver d_cadSlv; |
272 |
|
/** The ICP-based solver */ |
273 |
|
icp::ICPSolver d_icpSlv; |
274 |
|
/** The integer and solver |
275 |
|
* |
276 |
|
* This is the subsolver responsible for running the procedure for |
277 |
|
* constraints involving integer and. |
278 |
|
*/ |
279 |
|
IAndSolver d_iandSlv; |
280 |
|
|
281 |
|
/** The pow2 solver |
282 |
|
* |
283 |
|
* This is the subsolver responsible for running the procedure for |
284 |
|
* constraints involving powers of 2. |
285 |
|
*/ |
286 |
|
Pow2Solver d_pow2Slv; |
287 |
|
|
288 |
|
/** The strategy for the nonlinear extension. */ |
289 |
|
Strategy d_strategy; |
290 |
|
|
291 |
|
/** |
292 |
|
* The approximations computed during collectModelInfo. For details, see |
293 |
|
* NlModel::getModelValueRepair. |
294 |
|
*/ |
295 |
|
std::map<Node, std::pair<Node, Node>> d_approximations; |
296 |
|
/** |
297 |
|
* The witnesses computed during collectModelInfo. For details, see |
298 |
|
* NlModel::getModelValueRepair. |
299 |
|
*/ |
300 |
|
std::map<Node, Node> d_witnesses; |
301 |
|
}; /* class NonlinearExtension */ |
302 |
|
|
303 |
|
} // namespace nl |
304 |
|
} // namespace arith |
305 |
|
} // namespace theory |
306 |
|
} // namespace cvc5 |
307 |
|
|
308 |
|
#endif /* CVC5__THEORY__ARITH__NONLINEAR_EXTENSION_H */ |