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