GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/solver_engine.h Lines: 1 1 100.0 %
Date: 2021-11-07 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
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
 * SolverEngine: the main public entry point of libcvc5.
14
 */
15
16
#include "cvc5_public.h"
17
18
#ifndef CVC5__SMT__SOLVER_ENGINE_H
19
#define CVC5__SMT__SOLVER_ENGINE_H
20
21
#include <map>
22
#include <memory>
23
#include <string>
24
#include <vector>
25
26
#include "context/cdhashmap_forward.h"
27
#include "cvc5_export.h"
28
#include "options/options.h"
29
#include "smt/smt_mode.h"
30
#include "theory/logic_info.h"
31
#include "util/result.h"
32
33
namespace cvc5 {
34
35
template <bool ref_count>
36
class NodeTemplate;
37
typedef NodeTemplate<true> Node;
38
typedef NodeTemplate<false> TNode;
39
class TypeNode;
40
41
class Env;
42
class NodeManager;
43
class TheoryEngine;
44
class UnsatCore;
45
class StatisticsRegistry;
46
class Printer;
47
class ResourceManager;
48
struct InstantiationList;
49
50
/* -------------------------------------------------------------------------- */
51
52
namespace api {
53
class Solver;
54
}  // namespace api
55
56
/* -------------------------------------------------------------------------- */
57
58
namespace context {
59
class Context;
60
class UserContext;
61
}  // namespace context
62
63
/* -------------------------------------------------------------------------- */
64
65
namespace preprocessing {
66
class PreprocessingPassContext;
67
}
68
69
/* -------------------------------------------------------------------------- */
70
71
namespace prop {
72
class PropEngine;
73
}  // namespace prop
74
75
/* -------------------------------------------------------------------------- */
76
77
namespace smt {
78
/** Utilities */
79
class SolverEngineState;
80
class AbstractValues;
81
class Assertions;
82
class ResourceOutListener;
83
class SmtNodeManagerListener;
84
class OptionsManager;
85
class Preprocessor;
86
class CheckModels;
87
/** Subsolvers */
88
class SmtSolver;
89
class SygusSolver;
90
class AbductionSolver;
91
class InterpolationSolver;
92
class QuantElimSolver;
93
94
struct SolverEngineStatistics;
95
class SolverEngineScope;
96
class PfManager;
97
class UnsatCoreManager;
98
99
}  // namespace smt
100
101
/* -------------------------------------------------------------------------- */
102
103
namespace theory {
104
class TheoryModel;
105
class Rewriter;
106
class QuantifiersEngine;
107
}  // namespace theory
108
109
/* -------------------------------------------------------------------------- */
110
111
class CVC5_EXPORT SolverEngine
112
{
113
  friend class ::cvc5::api::Solver;
114
  friend class ::cvc5::smt::SolverEngineState;
115
  friend class ::cvc5::smt::SolverEngineScope;
116
117
  /* .......................................................................  */
118
 public:
119
  /* .......................................................................  */
120
121
  /**
122
   * Construct an SolverEngine with the given expression manager.
123
   * If provided, optr is a pointer to a set of options that should initialize
124
   * the values of the options object owned by this class.
125
   */
126
  SolverEngine(NodeManager* nm, const Options* optr = nullptr);
127
  /** Destruct the SMT engine.  */
128
  ~SolverEngine();
129
130
  //--------------------------------------------- concerning the state
131
132
  /**
133
   * This is the main initialization procedure of the SolverEngine.
134
   *
135
   * Should be called whenever the final options and logic for the problem are
136
   * set (at least, those options that are not permitted to change after
137
   * assertions and queries are made).
138
   *
139
   * Internally, this creates the theory engine, prop engine, decision engine,
140
   * and other utilities whose initialization depends on the final set of
141
   * options being set.
142
   *
143
   * This post-construction initialization is automatically triggered by the
144
   * use of the SolverEngine; e.g. when the first formula is asserted, a call
145
   * to simplify() is issued, a scope is pushed, etc.
146
   */
147
  void finishInit();
148
  /**
149
   * Return true if this SolverEngine is fully initialized (post-construction)
150
   * by the above call.
151
   */
152
  bool isFullyInited() const;
153
  /**
154
   * Return true if a checkEntailed() or checkSatisfiability() has been made.
155
   */
156
  bool isQueryMade() const;
157
  /** Return the user context level.  */
158
  size_t getNumUserLevels() const;
159
  /** Return the current mode of the solver. */
160
  SmtMode getSmtMode() const;
161
  /**
162
   * Whether the SmtMode allows for get-value, get-model, get-assignment, etc.
163
   * This is equivalent to:
164
   * getSmtMode()==SmtMode::SAT || getSmtMode()==SmtMode::SAT_UNKNOWN
165
   */
166
  bool isSmtModeSat() const;
167
  /**
168
   * Returns the most recent result of checkSat/checkEntailed or
169
   * (set-info :status).
170
   */
171
  Result getStatusOfLastCommand() const;
172
  //--------------------------------------------- end concerning the state
173
174
  /**
175
   * Set the logic of the script.
176
   * @throw ModalException, LogicException
177
   */
178
  void setLogic(const std::string& logic);
179
180
  /**
181
   * Set the logic of the script.
182
   * @throw ModalException, LogicException
183
   */
184
  void setLogic(const char* logic);
185
186
  /**
187
   * Set the logic of the script.
188
   * @throw ModalException
189
   */
190
  void setLogic(const LogicInfo& logic);
191
192
  /** Get the logic information currently set. */
193
  const LogicInfo& getLogicInfo() const;
194
195
  /** Get the logic information set by the user. */
196
  LogicInfo getUserLogicInfo() const;
197
198
  /**
199
   * Set information about the script executing.
200
   */
201
  void setInfo(const std::string& key, const std::string& value);
202
203
  /** Return true if given keyword is a valid SMT-LIB v2 get-info flag. */
204
  bool isValidGetInfoFlag(const std::string& key) const;
205
206
  /** Query information about the SMT environment.  */
207
  std::string getInfo(const std::string& key) const;
208
209
  /**
210
   * Set an aspect of the current SMT execution environment.
211
   * @throw OptionException, ModalException
212
   */
213
  void setOption(const std::string& key, const std::string& value);
214
215
  /** Set is internal subsolver.
216
   *
217
   * This function is called on SolverEngine objects that are created
218
   * internally.  It is used to mark that this SolverEngine should not
219
   * perform preprocessing passes that rephrase the input, such as
220
   * --sygus-rr-synth-input or
221
   * --sygus-abduct.
222
   */
223
  void setIsInternalSubsolver();
224
  /** Is this an internal subsolver? */
225
  bool isInternalSubsolver() const;
226
227
  /**
228
   * Block the current model. Can be called only if immediately preceded by
229
   * a SAT or INVALID query. Only permitted if produce-models is on, and the
230
   * block-models option is set to a mode other than "none".
231
   *
232
   * This adds an assertion to the assertion stack that blocks the current
233
   * model based on the current options configured by cvc5.
234
   *
235
   * The return value has the same meaning as that of assertFormula.
236
   */
237
  Result blockModel();
238
239
  /**
240
   * Block the current model values of (at least) the values in exprs.
241
   * Can be called only if immediately preceded by a SAT or NOT_ENTAILED query.
242
   * Only permitted if produce-models is on, and the block-models option is set
243
   * to a mode other than "none".
244
   *
245
   * This adds an assertion to the assertion stack of the form:
246
   *  (or (not (= exprs[0] M0)) ... (not (= exprs[n] Mn)))
247
   * where M0 ... Mn are the current model values of exprs[0] ... exprs[n].
248
   *
249
   * The return value has the same meaning as that of assertFormula.
250
   */
251
  Result blockModelValues(const std::vector<Node>& exprs);
252
253
  /**
254
   * Declare heap. For smt2 inputs, this is called when the command
255
   * (declare-heap (locT datat)) is invoked by the user. This sets locT as the
256
   * location type and dataT is the data type for the heap. This command should
257
   * be executed only once, and must be invoked before solving separation logic
258
   * inputs.
259
   */
260
  void declareSepHeap(TypeNode locT, TypeNode dataT);
261
262
  /**
263
   * Get the separation heap types, which extracts which types were passed to
264
   * the method above.
265
   *
266
   * @return true if the separation logic heap types have been declared.
267
   */
268
  bool getSepHeapTypes(TypeNode& locT, TypeNode& dataT);
269
270
  /** When using separation logic, obtain the expression for the heap.  */
271
  Node getSepHeapExpr();
272
273
  /** When using separation logic, obtain the expression for nil.  */
274
  Node getSepNilExpr();
275
276
  /**
277
   * Get an aspect of the current SMT execution environment.
278
   * @throw OptionException
279
   */
280
  std::string getOption(const std::string& key) const;
281
282
  /**
283
   * Define function func in the current context to be:
284
   *   (lambda (formals) formula)
285
   * This adds func to the list of defined functions, which indicates that
286
   * all occurrences of func should be expanded during expandDefinitions.
287
   *
288
   * @param func a variable of function type that expects the arguments in
289
   *             formal
290
   * @param formals a list of BOUND_VARIABLE expressions
291
   * @param formula The body of the function, must not contain func
292
   * @param global True if this definition is global (i.e. should persist when
293
   *               popping the user context)
294
   */
295
  void defineFunction(Node func,
296
                      const std::vector<Node>& formals,
297
                      Node formula,
298
                      bool global = false);
299
300
  /**
301
   * Define functions recursive
302
   *
303
   * For each i, this constrains funcs[i] in the current context to be:
304
   *   (lambda (formals[i]) formulas[i])
305
   * where formulas[i] may contain variables from funcs. Unlike defineFunction
306
   * above, we do not add funcs[i] to the set of defined functions. Instead,
307
   * we consider funcs[i] to be a free uninterpreted function, and add:
308
   *   forall formals[i]. f(formals[i]) = formulas[i]
309
   * to the set of assertions in the current context.
310
   * This method expects input such that for each i:
311
   * - func[i] : a variable of function type that expects the arguments in
312
   *             formals[i], and
313
   * - formals[i] : a list of BOUND_VARIABLE expressions.
314
   *
315
   * @param global True if this definition is global (i.e. should persist when
316
   *               popping the user context)
317
   */
318
  void defineFunctionsRec(const std::vector<Node>& funcs,
319
                          const std::vector<std::vector<Node>>& formals,
320
                          const std::vector<Node>& formulas,
321
                          bool global = false);
322
  /**
323
   * Define function recursive
324
   * Same as above, but for a single function.
325
   */
326
  void defineFunctionRec(Node func,
327
                         const std::vector<Node>& formals,
328
                         Node formula,
329
                         bool global = false);
330
  /**
331
   * Add a formula to the current context: preprocess, do per-theory
332
   * setup, use processAssertionList(), asserting to T-solver for
333
   * literals and conjunction of literals.  Returns false if
334
   * immediately determined to be inconsistent. Note this formula will
335
   * be included in the unsat core when applicable.
336
   *
337
   * @throw TypeCheckingException, LogicException, UnsafeInterruptException
338
   */
339
  Result assertFormula(const Node& formula);
340
341
  /**
342
   * Reduce an unsatisfiable core to make it minimal.
343
   */
344
  std::vector<Node> reduceUnsatCore(const std::vector<Node>& core);
345
346
  /**
347
   * Check if a given (set of) expression(s) is entailed with respect to the
348
   * current set of assertions. We check this by asserting the negation of
349
   * the (big AND over the) given (set of) expression(s).
350
   * Returns ENTAILED, NOT_ENTAILED, or ENTAILMENT_UNKNOWN result.
351
   *
352
   * @throw Exception
353
   */
354
  Result checkEntailed(const Node& assumption);
355
  Result checkEntailed(const std::vector<Node>& assumptions);
356
357
  /**
358
   * Assert a formula (if provided) to the current context and call
359
   * check().  Returns SAT, UNSAT, or SAT_UNKNOWN result.
360
   *
361
   * @throw Exception
362
   */
363
  Result checkSat();
364
  Result checkSat(const Node& assumption);
365
  Result checkSat(const std::vector<Node>& assumptions);
366
367
  /**
368
   * Returns a set of so-called "failed" assumptions.
369
   *
370
   * The returned set is a subset of the set of assumptions of a previous
371
   * (unsatisfiable) call to checkSatisfiability. Calling checkSatisfiability
372
   * with this set of failed assumptions still produces an unsat answer.
373
   *
374
   * Note that the returned set of failed assumptions is not necessarily
375
   * minimal.
376
   */
377
  std::vector<Node> getUnsatAssumptions(void);
378
379
  /*---------------------------- sygus commands  ---------------------------*/
380
381
  /**
382
   * Add sygus variable declaration.
383
   *
384
   * Declared SyGuS variables may be used in SyGuS constraints, in which they
385
   * are assumed to be universally quantified.
386
   *
387
   * In SyGuS semantics, declared functions are treated in the same manner as
388
   * declared variables, i.e. as universally quantified (function) variables
389
   * which can occur in the SyGuS constraints that compose the conjecture to
390
   * which a function is being synthesized. Thus declared functions should use
391
   * this method as well.
392
   */
393
  void declareSygusVar(Node var);
394
395
  /**
396
   * Add a function-to-synthesize declaration.
397
   *
398
   * The given sygusType may not correspond to the actual function type of func
399
   * but to a datatype encoding the syntax restrictions for the
400
   * function-to-synthesize. In this case this information is stored to be used
401
   * during solving.
402
   *
403
   * vars contains the arguments of the function-to-synthesize. These variables
404
   * are also stored to be used during solving.
405
   *
406
   * isInv determines whether the function-to-synthesize is actually an
407
   * invariant. This information is necessary if we are dumping a command
408
   * corresponding to this declaration, so that it can be properly printed.
409
   */
410
  void declareSynthFun(Node func,
411
                       TypeNode sygusType,
412
                       bool isInv,
413
                       const std::vector<Node>& vars);
414
  /**
415
   * Same as above, without a sygus type.
416
   */
417
  void declareSynthFun(Node func, bool isInv, const std::vector<Node>& vars);
418
419
  /**
420
   * Add a regular sygus constraint or assumption.
421
   * @param n The formula
422
   * @param isAssume True if n is an assumption.
423
   */
424
  void assertSygusConstraint(Node n, bool isAssume = false);
425
426
  /**
427
   * Add an invariant constraint.
428
   *
429
   * Invariant constraints are not explicitly declared: they are given in terms
430
   * of the invariant-to-synthesize, the pre condition, transition relation and
431
   * post condition. The actual constraint is built based on the inputs of these
432
   * place holder predicates :
433
   *
434
   * PRE(x) -> INV(x)
435
   * INV() ^ TRANS(x, x') -> INV(x')
436
   * INV(x) -> POST(x)
437
   *
438
   * The regular and primed variables are retrieved from the declaration of the
439
   * invariant-to-synthesize.
440
   */
441
  void assertSygusInvConstraint(Node inv, Node pre, Node trans, Node post);
442
  /**
443
   * Assert a synthesis conjecture to the current context and call
444
   * check().  Returns sat, unsat, or unknown result.
445
   *
446
   * The actual synthesis conjecture is built based on the previously
447
   * communicated information to this module (universal variables, defined
448
   * functions, functions-to-synthesize, and which constraints compose it). The
449
   * built conjecture is a higher-order formula of the form
450
   *
451
   * exists f1...fn . forall v1...vm . F
452
   *
453
   * in which f1...fn are the functions-to-synthesize, v1...vm are the declared
454
   * universal variables and F is the set of declared constraints.
455
   *
456
   * @throw Exception
457
   */
458
  Result checkSynth();
459
460
  /*------------------------- end of sygus commands ------------------------*/
461
462
  /**
463
   * Declare pool whose initial value is the terms in initValue. A pool is
464
   * a variable of type (Set T) that is used in quantifier annotations and does
465
   * not occur in constraints.
466
   *
467
   * @param p The pool to declare, which should be a variable of type (Set T)
468
   * for some type T.
469
   * @param initValue The initial value of p, which should be a vector of terms
470
   * of type T.
471
   */
472
  void declarePool(const Node& p, const std::vector<Node>& initValue);
473
  /**
474
   * Simplify a formula without doing "much" work.  Does not involve
475
   * the SAT Engine in the simplification, but uses the current
476
   * definitions, assertions, and the current partial model, if one
477
   * has been constructed.  It also involves theory normalization.
478
   *
479
   * @throw TypeCheckingException, LogicException, UnsafeInterruptException
480
   *
481
   * @todo (design) is this meant to give an equivalent or an
482
   * equisatisfiable formula?
483
   */
484
  Node simplify(const Node& e);
485
486
  /**
487
   * Expand the definitions in a term or formula.
488
   *
489
   * @param n The node to expand
490
   *
491
   * @throw TypeCheckingException, LogicException, UnsafeInterruptException
492
   */
493
  Node expandDefinitions(const Node& n);
494
495
  /**
496
   * Get the assigned value of an expr (only if immediately preceded by a SAT
497
   * or NOT_ENTAILED query).  Only permitted if the SolverEngine is set to
498
   * operate interactively and produce-models is on.
499
   *
500
   * @throw ModalException, TypeCheckingException, LogicException,
501
   *        UnsafeInterruptException
502
   */
503
  Node getValue(const Node& e) const;
504
505
  /**
506
   * Same as getValue but for a vector of expressions
507
   */
508
  std::vector<Node> getValues(const std::vector<Node>& exprs) const;
509
510
  /**
511
   * @return the domain elements for uninterpreted sort tn.
512
   */
513
  std::vector<Node> getModelDomainElements(TypeNode tn) const;
514
515
  /**
516
   * @return true if v is a model core symbol
517
   */
518
  bool isModelCoreSymbol(Node v);
519
520
  /**
521
   * Get a model (only if immediately preceded by an SAT or unknown query).
522
   * Only permitted if the model option is on.
523
   *
524
   * @param declaredSorts The sorts to print in the model
525
   * @param declaredFuns The free constants to print in the model. A subset
526
   * of these may be printed based on isModelCoreSymbol.
527
   * @return the string corresponding to the model. If the output language is
528
   * smt2, then this corresponds to a response to the get-model command.
529
   */
530
  std::string getModel(const std::vector<TypeNode>& declaredSorts,
531
                       const std::vector<Node>& declaredFuns);
532
533
  /** print instantiations
534
   *
535
   * Print all instantiations for all quantified formulas on out,
536
   * returns true if at least one instantiation was printed. The type of output
537
   * (list, num, etc.) is determined by printInstMode.
538
   */
539
  void printInstantiations(std::ostream& out);
540
  /**
541
   * Print the current proof. This method should be called after an UNSAT
542
   * response. It gets the proof of false from the PropEngine and passes
543
   * it to the ProofManager, which post-processes the proof and prints it
544
   * in the proper format.
545
   */
546
  void printProof();
547
548
  /**
549
   * Get synth solution.
550
   *
551
   * This method returns true if we are in a state immediately preceded by
552
   * a successful call to checkSynth.
553
   *
554
   * This method adds entries to solMap that map functions-to-synthesize with
555
   * their solutions, for all active conjectures. This should be called
556
   * immediately after the solver answers unsat for sygus input.
557
   *
558
   * Specifically, given a sygus conjecture of the form
559
   *   exists x1...xn. forall y1...yn. P( x1...xn, y1...yn )
560
   * where x1...xn are second order bound variables, we map each xi to
561
   * lambda term in solMap such that
562
   *    forall y1...yn. P( solMap[x1]...solMap[xn], y1...yn )
563
   * is a valid formula.
564
   */
565
  bool getSynthSolutions(std::map<Node, Node>& solMap);
566
567
  /**
568
   * Do quantifier elimination.
569
   *
570
   * This function takes as input a quantified formula q
571
   * of the form:
572
   *   Q x1...xn. P( x1...xn, y1...yn )
573
   * where P( x1...xn, y1...yn ) is a quantifier-free
574
   * formula in a logic that supports quantifier elimination.
575
   * Currently, the only logics supported by quantifier
576
   * elimination is LRA and LIA.
577
   *
578
   * This function returns a formula ret such that, given
579
   * the current set of formulas A asserted to this SolverEngine :
580
   *
581
   * If doFull = true, then
582
   *   - ( A ^ q ) and ( A ^ ret ) are equivalent
583
   *   - ret is quantifier-free formula containing
584
   *     only free variables in y1...yn.
585
   *
586
   * If doFull = false, then
587
   *   - (A ^ q) => (A ^ ret) if Q is forall or
588
   *     (A ^ ret) => (A ^ q) if Q is exists,
589
   *   - ret is quantifier-free formula containing
590
   *     only free variables in y1...yn,
591
   *   - If Q is exists, let A^Q_n be the formula
592
   *       A ^ ~ret^Q_1 ^ ... ^ ~ret^Q_n
593
   *     where for each i=1,...n, formula ret^Q_i
594
   *     is the result of calling doQuantifierElimination
595
   *     for q with the set of assertions A^Q_{i-1}.
596
   *     Similarly, if Q is forall, then let A^Q_n be
597
   *       A ^ ret^Q_1 ^ ... ^ ret^Q_n
598
   *     where ret^Q_i is the same as above.
599
   *     In either case, we have that ret^Q_j will
600
   *     eventually be true or false, for some finite j.
601
   *
602
   * The former feature is quantifier elimination, and
603
   * is run on invocations of the smt2 extended command get-qe.
604
   * The latter feature is referred to as partial quantifier
605
   * elimination, and is run on invocations of the smt2
606
   * extended command get-qe-disjunct, which can be used
607
   * for incrementally computing the result of a
608
   * quantifier elimination.
609
   *
610
   * The argument strict is whether to output
611
   * warnings, such as when an unexpected logic is used.
612
   *
613
   * throw@ Exception
614
   */
615
  Node getQuantifierElimination(Node q, bool doFull, bool strict = true);
616
617
  /**
618
   * This method asks this SMT engine to find an interpolant with respect to
619
   * the current assertion stack (call it A) and the conjecture (call it B). If
620
   * this method returns true, then interpolant is set to a formula I such that
621
   * A ^ ~I and I ^ ~B are both unsatisfiable.
622
   *
623
   * The argument grammarType is a sygus datatype type that encodes the syntax
624
   * restrictions on the shapes of possible solutions.
625
   *
626
   * This method invokes a separate copy of the SMT engine for solving the
627
   * corresponding sygus problem for generating such a solution.
628
   */
629
  bool getInterpol(const Node& conj,
630
                   const TypeNode& grammarType,
631
                   Node& interpol);
632
633
  /** Same as above, but without user-provided grammar restrictions */
634
  bool getInterpol(const Node& conj, Node& interpol);
635
636
  /**
637
   * This method asks this SMT engine to find an abduct with respect to the
638
   * current assertion stack (call it A) and the conjecture (call it B).
639
   * If this method returns true, then abd is set to a formula C such that
640
   * A ^ C is satisfiable, and A ^ ~B ^ C is unsatisfiable.
641
   *
642
   * The argument grammarType is a sygus datatype type that encodes the syntax
643
   * restrictions on the shape of possible solutions.
644
   *
645
   * This method invokes a separate copy of the SMT engine for solving the
646
   * corresponding sygus problem for generating such a solution.
647
   */
648
  bool getAbduct(const Node& conj, const TypeNode& grammarType, Node& abd);
649
650
  /** Same as above, but without user-provided grammar restrictions */
651
  bool getAbduct(const Node& conj, Node& abd);
652
653
  /**
654
   * Get list of quantified formulas that were instantiated on the last call
655
   * to check-sat.
656
   */
657
  void getInstantiatedQuantifiedFormulas(std::vector<Node>& qs);
658
659
  /**
660
   * Get instantiation term vectors for quantified formula q.
661
   *
662
   * This method is similar to above, but in the example above, we return the
663
   * (vectors of) terms t1, ..., tn instead.
664
   *
665
   * Notice that these are not guaranteed to come in the same order as the
666
   * instantiation lemmas above.
667
   */
668
  void getInstantiationTermVectors(Node q,
669
                                   std::vector<std::vector<Node>>& tvecs);
670
  /**
671
   * As above but only the instantiations that were relevant for the
672
   * refutation.
673
   */
674
  void getRelevantInstantiationTermVectors(
675
      std::map<Node, InstantiationList>& insts, bool getDebugInfo = false);
676
  /**
677
   * Get instantiation term vectors, which maps each instantiated quantified
678
   * formula to the list of instantiations for that quantified formula. This
679
   * list is minimized if proofs are enabled, and this call is immediately
680
   * preceded by an UNSAT or ENTAILED query
681
   */
682
  void getInstantiationTermVectors(
683
      std::map<Node, std::vector<std::vector<Node>>>& insts);
684
685
  /**
686
   * Get an unsatisfiable core (only if immediately preceded by an UNSAT or
687
   * ENTAILED query).  Only permitted if cvc5 was built with unsat-core support
688
   * and produce-unsat-cores is on.
689
   */
690
  UnsatCore getUnsatCore();
691
692
  /**
693
   * Get a refutation proof (only if immediately preceded by an UNSAT or
694
   * ENTAILED query). Only permitted if cvc5 was built with proof support and
695
   * the proof option is on. */
696
  std::string getProof();
697
698
  /**
699
   * Get the current set of assertions.  Only permitted if the
700
   * SolverEngine is set to operate interactively.
701
   */
702
  std::vector<Node> getAssertions();
703
704
  /**
705
   * Get difficulty map, which populates dmap, mapping input assertions
706
   * to a value that estimates their difficulty for solving the current problem.
707
   */
708
  void getDifficultyMap(std::map<Node, Node>& dmap);
709
710
  /**
711
   * Push a user-level context.
712
   * throw@ ModalException, LogicException, UnsafeInterruptException
713
   */
714
  void push();
715
716
  /**
717
   * Pop a user-level context.  Throws an exception if nothing to pop.
718
   * @throw ModalException
719
   */
720
  void pop();
721
722
  /** Reset all assertions, global declarations, etc.  */
723
  void resetAssertions();
724
725
  /**
726
   * Interrupt a running query.  This can be called from another thread
727
   * or from a signal handler.  Throws a ModalException if the SolverEngine
728
   * isn't currently in a query.
729
   *
730
   * @throw ModalException
731
   */
732
  void interrupt();
733
734
  /**
735
   * Set a resource limit for SolverEngine operations.  This is like a time
736
   * limit, but it's deterministic so that reproducible results can be
737
   * obtained.  Currently, it's based on the number of conflicts.
738
   * However, please note that the definition may change between different
739
   * versions of cvc5 (as may the number of conflicts required, anyway),
740
   * and it might even be different between instances of the same version
741
   * of cvc5 on different platforms.
742
   *
743
   * A cumulative and non-cumulative (per-call) resource limit can be
744
   * set at the same time.  A call to setResourceLimit() with
745
   * cumulative==true replaces any cumulative resource limit currently
746
   * in effect; a call with cumulative==false replaces any per-call
747
   * resource limit currently in effect.  Time limits can be set in
748
   * addition to resource limits; the SolverEngine obeys both.  That means
749
   * that up to four independent limits can control the SolverEngine
750
   * at the same time.
751
   *
752
   * When an SolverEngine is first created, it has no time or resource
753
   * limits.
754
   *
755
   * Currently, these limits only cause the SolverEngine to stop what its
756
   * doing when the limit expires (or very shortly thereafter); no
757
   * heuristics are altered by the limits or the threat of them expiring.
758
   * We reserve the right to change this in the future.
759
   *
760
   * @param units the resource limit, or 0 for no limit
761
   * @param cumulative whether this resource limit is to be a cumulative
762
   * resource limit for all remaining calls into the SolverEngine (true), or
763
   * whether it's a per-call resource limit (false); the default is false
764
   */
765
  void setResourceLimit(uint64_t units, bool cumulative = false);
766
767
  /**
768
   * Set a per-call time limit for SolverEngine operations.
769
   *
770
   * A per-call time limit can be set at the same time and replaces
771
   * any per-call time limit currently in effect.
772
   * Resource limits (either per-call or cumulative) can be set in
773
   * addition to a time limit; the SolverEngine obeys all three of them.
774
   *
775
   * Note that the per-call timer only ticks away when one of the
776
   * SolverEngine's workhorse functions (things like assertFormula(),
777
   * checkEntailed(), checkSat(), and simplify()) are running.
778
   * Between calls, the timer is still.
779
   *
780
   * When an SolverEngine is first created, it has no time or resource
781
   * limits.
782
   *
783
   * Currently, these limits only cause the SolverEngine to stop what its
784
   * doing when the limit expires (or very shortly thereafter); no
785
   * heuristics are altered by the limits or the threat of them expiring.
786
   * We reserve the right to change this in the future.
787
   *
788
   * @param millis the time limit in milliseconds, or 0 for no limit
789
   */
790
  void setTimeLimit(uint64_t millis);
791
792
  /**
793
   * Get the current resource usage count for this SolverEngine.  This
794
   * function can be used to ascertain reasonable values to pass as
795
   * resource limits to setResourceLimit().
796
   */
797
  unsigned long getResourceUsage() const;
798
799
  /** Get the current millisecond count for this SolverEngine.  */
800
  unsigned long getTimeUsage() const;
801
802
  /**
803
   * Get the remaining resources that can be consumed by this SolverEngine
804
   * according to the currently-set cumulative resource limit.  If there
805
   * is not a cumulative resource limit set, this function throws a
806
   * ModalException.
807
   *
808
   * @throw ModalException
809
   */
810
  unsigned long getResourceRemaining() const;
811
812
  /** Permit access to the underlying NodeManager. */
813
  NodeManager* getNodeManager() const;
814
815
  /**
816
   * Print statistics from the statistics registry in the env object owned by
817
   * this SolverEngine. Safe to use in a signal handler.
818
   */
819
  void printStatisticsSafe(int fd) const;
820
821
  /**
822
   * Print the changes to the statistics from the statistics registry in the
823
   * env object owned by this SolverEngine since this method was called the last
824
   * time. Internally prints the diff and then stores a snapshot for the next
825
   * call.
826
   */
827
  void printStatisticsDiff() const;
828
829
  /** Get the options object (const and non-const versions) */
830
  Options& getOptions();
831
  const Options& getOptions() const;
832
833
  /** Get a pointer to the UserContext owned by this SolverEngine. */
834
  context::UserContext* getUserContext();
835
836
  /** Get a pointer to the Context owned by this SolverEngine. */
837
  context::Context* getContext();
838
839
  /** Get a pointer to the TheoryEngine owned by this SolverEngine. */
840
  TheoryEngine* getTheoryEngine();
841
842
  /** Get a pointer to the PropEngine owned by this SolverEngine. */
843
  prop::PropEngine* getPropEngine();
844
845
  /** Get the resource manager of this SMT engine */
846
  ResourceManager* getResourceManager() const;
847
848
  /** Get the printer used by this SMT engine */
849
  const Printer& getPrinter() const;
850
851
  /** Get a pointer to the Rewriter owned by this SolverEngine. */
852
  theory::Rewriter* getRewriter();
853
  /**
854
   * Get expanded assertions.
855
   *
856
   * Return the set of assertions, after expanding definitions.
857
   */
858
  std::vector<Node> getExpandedAssertions();
859
860
  /**
861
   * !!!!! temporary, until the environment is passsed to all classes that
862
   * require it.
863
   */
864
  Env& getEnv();
865
  /* .......................................................................  */
866
 private:
867
  /* .......................................................................  */
868
869
  // disallow copy/assignment
870
  SolverEngine(const SolverEngine&) = delete;
871
  SolverEngine& operator=(const SolverEngine&) = delete;
872
873
  /** Set solver instance that owns this SolverEngine. */
874
10071
  void setSolver(api::Solver* solver) { d_solver = solver; }
875
876
  /** Get a pointer to the (new) PfManager owned by this SolverEngine. */
877
  smt::PfManager* getPfManager() { return d_pfManager.get(); };
878
879
  /** Get a pointer to the StatisticsRegistry owned by this SolverEngine. */
880
  StatisticsRegistry& getStatisticsRegistry();
881
882
  /**
883
   * Internal method to get an unsatisfiable core (only if immediately preceded
884
   * by an UNSAT or ENTAILED query). Only permitted if cvc5 was built with
885
   * unsat-core support and produce-unsat-cores is on. Does not dump the
886
   * command.
887
   */
888
  UnsatCore getUnsatCoreInternal();
889
890
  /**
891
   * Check that a generated proof checks. This method is the same as printProof,
892
   * but does not print the proof. Like that method, it should be called
893
   * after an UNSAT response. It ensures that a well-formed proof of false
894
   * can be constructed by the combination of the PropEngine and ProofManager.
895
   */
896
  void checkProof();
897
898
  /**
899
   * Check that an unsatisfiable core is indeed unsatisfiable.
900
   */
901
  void checkUnsatCore();
902
903
  /**
904
   * Check that a generated Model (via getModel()) actually satisfies
905
   * all user assertions.
906
   */
907
  void checkModel(bool hardFailure = true);
908
909
  /**
910
   * Check that a solution to an interpolation problem is indeed a solution.
911
   *
912
   * The check is made by determining that the assertions imply the solution of
913
   * the interpolation problem (interpol), and the solution implies the goal
914
   * (conj). If these criteria are not met, an internal error is thrown.
915
   */
916
  void checkInterpol(Node interpol,
917
                     const std::vector<Node>& easserts,
918
                     const Node& conj);
919
920
  /**
921
   * This is called by the destructor, just before destroying the
922
   * PropEngine, TheoryEngine, and DecisionEngine (in that order).  It
923
   * is important because there are destruction ordering issues
924
   * between PropEngine and Theory.
925
   */
926
  void shutdown();
927
928
  /**
929
   * Quick check of consistency in current context: calls
930
   * processAssertionList() then look for inconsistency (based only on
931
   * that).
932
   */
933
  Result quickCheck();
934
935
  /**
936
   * Get the (SMT-level) model pointer, if we are in SAT mode. Otherwise,
937
   * return nullptr.
938
   *
939
   * This ensures that the underlying theory model of the SmtSolver maintained
940
   * by this class is currently available, which means that cvc5 is producing
941
   * models, and is in "SAT mode", otherwise a recoverable exception is thrown.
942
   *
943
   * @param c used for giving an error message to indicate the context
944
   * this method was called.
945
   */
946
  theory::TheoryModel* getAvailableModel(const char* c) const;
947
  /**
948
   * Get available quantifiers engine, which throws a modal exception if it
949
   * does not exist. This can happen if a quantifiers-specific call (e.g.
950
   * getInstantiatedQuantifiedFormulas) is called in a non-quantified logic.
951
   *
952
   * @param c used for giving an error message to indicate the context
953
   * this method was called.
954
   */
955
  theory::QuantifiersEngine* getAvailableQuantifiersEngine(const char* c) const;
956
957
  // --------------------------------------- callbacks from the state
958
  /**
959
   * Notify push pre, which is called just before the user context of the state
960
   * pushes. This processes all pending assertions.
961
   */
962
  void notifyPushPre();
963
  /**
964
   * Notify push post, which is called just after the user context of the state
965
   * pushes. This performs a push on the underlying prop engine.
966
   */
967
  void notifyPushPost();
968
  /**
969
   * Notify pop pre, which is called just before the user context of the state
970
   * pops. This performs a pop on the underlying prop engine.
971
   */
972
  void notifyPopPre();
973
  /**
974
   * Notify post solve pre, which is called once per check-sat query. It
975
   * is triggered when the first d_state.doPendingPops() is issued after the
976
   * check-sat. This method is called before the contexts pop in the method
977
   * doPendingPops.
978
   */
979
  void notifyPostSolvePre();
980
  /**
981
   * Same as above, but after contexts are popped. This calls the postsolve
982
   * method of the underlying TheoryEngine.
983
   */
984
  void notifyPostSolvePost();
985
  // --------------------------------------- end callbacks from the state
986
987
  /**
988
   * Internally handle the setting of a logic.  This function should always
989
   * be called when d_logic is updated.
990
   */
991
  void setLogicInternal();
992
993
  /*
994
   * Check satisfiability (used to check satisfiability and entailment).
995
   */
996
  Result checkSatInternal(const std::vector<Node>& assumptions,
997
                          bool isEntailmentCheck);
998
999
  /**
1000
   * Check that all Expr in formals are of BOUND_VARIABLE kind, where func is
1001
   * the function that the formal argument list is for. This method is used
1002
   * as a helper function when defining (recursive) functions.
1003
   */
1004
  void debugCheckFormals(const std::vector<Node>& formals, Node func);
1005
1006
  /**
1007
   * Checks whether formula is a valid function body for func whose formal
1008
   * argument list is stored in formals. This method is
1009
   * used as a helper function when defining (recursive) functions.
1010
   */
1011
  void debugCheckFunctionBody(Node formula,
1012
                              const std::vector<Node>& formals,
1013
                              Node func);
1014
1015
  /**
1016
   * Helper method to obtain both the heap and nil from the solver. Returns a
1017
   * std::pair where the first element is the heap expression and the second
1018
   * element is the nil expression.
1019
   */
1020
  std::pair<Node, Node> getSepHeapAndNilExpr();
1021
  /**
1022
   * Get assertions internal, which is only called after initialization. This
1023
   * should be used internally to get the assertions instead of getAssertions
1024
   * or getExpandedAssertions, which may trigger initialization and SMT state
1025
   * changes.
1026
   */
1027
  std::vector<Node> getAssertionsInternal();
1028
  /* Members -------------------------------------------------------------- */
1029
1030
  /** Solver instance that owns this SolverEngine instance. */
1031
  api::Solver* d_solver = nullptr;
1032
1033
  /**
1034
   * The environment object, which contains all utilities that are globally
1035
   * available to internal code.
1036
   */
1037
  std::unique_ptr<Env> d_env;
1038
  /**
1039
   * The state of this SolverEngine, which is responsible for maintaining which
1040
   * SMT mode we are in, the contexts, the last result, etc.
1041
   */
1042
  std::unique_ptr<smt::SolverEngineState> d_state;
1043
1044
  /** Abstract values */
1045
  std::unique_ptr<smt::AbstractValues> d_absValues;
1046
  /** Assertions manager */
1047
  std::unique_ptr<smt::Assertions> d_asserts;
1048
  /** Resource out listener */
1049
  std::unique_ptr<smt::ResourceOutListener> d_routListener;
1050
1051
  /** The SMT solver */
1052
  std::unique_ptr<smt::SmtSolver> d_smtSolver;
1053
1054
  /**
1055
   * The utility used for checking models
1056
   */
1057
  std::unique_ptr<smt::CheckModels> d_checkModels;
1058
1059
  /**
1060
   * The proof manager, which manages all things related to checking,
1061
   * processing, and printing proofs.
1062
   */
1063
  std::unique_ptr<smt::PfManager> d_pfManager;
1064
1065
  /**
1066
   * The unsat core manager, which produces unsat cores and related information
1067
   * from refutations. */
1068
  std::unique_ptr<smt::UnsatCoreManager> d_ucManager;
1069
1070
  /** The solver for sygus queries */
1071
  std::unique_ptr<smt::SygusSolver> d_sygusSolver;
1072
1073
  /** The solver for abduction queries */
1074
  std::unique_ptr<smt::AbductionSolver> d_abductSolver;
1075
  /** The solver for interpolation queries */
1076
  std::unique_ptr<smt::InterpolationSolver> d_interpolSolver;
1077
  /** The solver for quantifier elimination queries */
1078
  std::unique_ptr<smt::QuantElimSolver> d_quantElimSolver;
1079
1080
  /**
1081
   * The logic set by the user. The actual logic, which may extend the user's
1082
   * logic, lives in the Env class.
1083
   */
1084
  LogicInfo d_userLogic;
1085
1086
  /** Whether this is an internal subsolver. */
1087
  bool d_isInternalSubsolver;
1088
1089
  /**
1090
   * Verbosity of various commands.
1091
   */
1092
  std::map<std::string, int> d_commandVerbosity;
1093
1094
  /** The statistics class */
1095
  std::unique_ptr<smt::SolverEngineStatistics> d_stats;
1096
1097
  /**
1098
   * The global scope object. Upon creation of this SolverEngine, it becomes the
1099
   * SolverEngine in scope. It says the SolverEngine in scope until it is
1100
   * destructed, or another SolverEngine is created.
1101
   */
1102
  std::unique_ptr<smt::SolverEngineScope> d_scope;
1103
}; /* class SolverEngine */
1104
1105
/* -------------------------------------------------------------------------- */
1106
1107
}  // namespace cvc5
1108
1109
#endif /* CVC5__SMT_ENGINE_H */