GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/theory_arith_private.h Lines: 28 33 84.8 %
Date: 2021-09-16 Branches: 15 42 35.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Tim King, Andrew Reynolds, Alex Ozdemir
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
 * [[ Add one-line brief description here ]]
14
 *
15
 * [[ Add lengthier description here ]]
16
 * \todo document this file
17
 */
18
19
#pragma once
20
21
#include <map>
22
#include <vector>
23
24
#include "context/cdhashset.h"
25
#include "context/cdinsert_hashmap.h"
26
#include "context/cdlist.h"
27
#include "context/cdqueue.h"
28
#include "expr/kind.h"
29
#include "expr/node.h"
30
#include "expr/node_builder.h"
31
#include "proof/trust_node.h"
32
#include "theory/arith/arith_static_learner.h"
33
#include "theory/arith/arith_utilities.h"
34
#include "theory/arith/arithvar.h"
35
#include "theory/arith/attempt_solution_simplex.h"
36
#include "theory/arith/branch_and_bound.h"
37
#include "theory/arith/congruence_manager.h"
38
#include "theory/arith/constraint.h"
39
#include "theory/arith/delta_rational.h"
40
#include "theory/arith/dio_solver.h"
41
#include "theory/arith/dual_simplex.h"
42
#include "theory/arith/error_set.h"
43
#include "theory/arith/fc_simplex.h"
44
#include "theory/arith/infer_bounds.h"
45
#include "theory/arith/linear_equality.h"
46
#include "theory/arith/matrix.h"
47
#include "theory/arith/normal_form.h"
48
#include "theory/arith/partial_model.h"
49
#include "theory/arith/proof_checker.h"
50
#include "theory/arith/soi_simplex.h"
51
#include "theory/arith/theory_arith.h"
52
#include "theory/valuation.h"
53
#include "util/dense_map.h"
54
#include "util/integer.h"
55
#include "util/rational.h"
56
#include "util/result.h"
57
#include "util/statistics_stats.h"
58
59
namespace cvc5 {
60
61
class EagerProofGenerator;
62
63
namespace theory {
64
65
class TheoryModel;
66
67
namespace arith {
68
69
class BranchCutInfo;
70
class TreeLog;
71
class ApproximateStatistics;
72
73
class ArithEntailmentCheckParameters;
74
class ArithEntailmentCheckSideEffects;
75
namespace inferbounds {
76
  class InferBoundAlgorithm;
77
}
78
class InferBoundsResult;
79
80
/**
81
 * Implementation of QF_LRA.
82
 * Based upon:
83
 * http://research.microsoft.com/en-us/um/people/leonardo/cav06.pdf
84
 */
85
class TheoryArithPrivate : protected EnvObj
86
{
87
 private:
88
  static const uint32_t RESET_START = 2;
89
90
  TheoryArith& d_containing;
91
92
33612172
  const Options& options() const { return d_env.getOptions(); }
93
94
  /**
95
   * Whether we encountered non-linear arithmetic at any time during solving.
96
   */
97
  bool d_foundNl;
98
99
  BoundInfoMap d_rowTracking;
100
  /** Branch and bound utility */
101
  BranchAndBound& d_bab;
102
  // For proofs
103
  /** Manages the proof nodes of this theory. */
104
  ProofNodeManager* d_pnm;
105
  /** Checks the proof rules of this theory. */
106
  ArithProofRuleChecker d_checker;
107
  /** Stores proposition(node)/proof pairs. */
108
  std::unique_ptr<EagerProofGenerator> d_pfGen;
109
110
  /**
111
   * The constraint database associated with the theory.
112
   * This must be declared before ArithPartialModel.
113
   */
114
  ConstraintDatabase d_constraintDatabase;
115
116
  enum Result::Sat d_qflraStatus;
117
  // check()
118
  //   !done() -> d_qflraStatus = Unknown
119
  //   fullEffort(e) -> simplex returns either sat or unsat
120
  //   !fullEffort(e) -> simplex returns either sat, unsat or unknown
121
  //                     if unknown, save the assignment
122
  //                     if unknown, the simplex priority queue cannot be emptied
123
  int d_unknownsInARow;
124
125
  bool d_replayedLemmas;
126
127
  /**
128
   * This counter is false if nothing has been done since the last cut.
129
   * This is used to break an infinite loop.
130
   */
131
  bool d_hasDoneWorkSinceCut;
132
133
  /** Static learner. */
134
  ArithStaticLearner d_learner;
135
136
  //std::vector<ArithVar> d_pool;
137
public:
138
  void releaseArithVar(ArithVar v);
139
6423505
  void signal(ArithVar v){ d_errorSet.signalVariable(v); }
140
141
142
private:
143
  // t does not contain constants
144
  void entailmentCheckBoundLookup(std::pair<Node, DeltaRational>& tmp, int sgn, TNode tp) const;
145
  void entailmentCheckRowSum(std::pair<Node, DeltaRational>& tmp, int sgn, TNode tp) const;
146
147
  /**
148
   * Infers either a new upper/lower bound on term in the real relaxation.
149
   * Either:
150
   * - term is malformed (see below)
151
   * - a maximum/minimum is found with the result being a pair
152
   * -- <dr, exp> where
153
   * -- term <?> dr is implies by exp
154
   * -- <?> is <= if inferring an upper bound, >= otherwise
155
   * -- exp is in terms of the assertions to the theory.
156
   * - No upper or lower bound is inferrable in the real relaxation.
157
   * -- Returns <0, Null()>
158
   * - the maximum number of rounds was exhausted:
159
   * -- Returns <v, term> where v is the current feasible value of term
160
   * - Threshold reached:
161
   * -- If theshold != NULL, and a feasible value is found to exceed threshold
162
   * -- Simplex stops and returns <threshold, term>
163
   */
164
  //std::pair<DeltaRational, Node> inferBound(TNode term, bool lb, int maxRounds = -1, const DeltaRational* threshold = NULL);
165
166
private:
167
  static bool decomposeTerm(Node term, Rational& m, Node& p, Rational& c);
168
  static bool decomposeLiteral(Node lit, Kind& k, int& dir, Rational& lm,  Node& lp, Rational& rm, Node& rp, Rational& dm, Node& dp, DeltaRational& sep);
169
  static void setToMin(int sgn, std::pair<Node, DeltaRational>& min, const std::pair<Node, DeltaRational>& e);
170
171
  /**
172
   * The map between arith variables to nodes.
173
   */
174
  //ArithVarNodeMap d_arithvarNodeMap;
175
176
  typedef ArithVariables::var_iterator var_iterator;
177
1910217
  var_iterator var_begin() const { return d_partialModel.var_begin(); }
178
1910217
  var_iterator var_end() const { return d_partialModel.var_end(); }
179
180
  NodeSet d_setupNodes;
181
public:
182
5258626
  bool isSetup(Node n) const {
183
5258626
    return d_setupNodes.find(n) != d_setupNodes.end();
184
  }
185
437145
  void markSetup(Node n){
186
437145
    Assert(!isSetup(n));
187
437145
    d_setupNodes.insert(n);
188
437145
  }
189
private:
190
  void setupVariable(const Variable& x);
191
  void setupVariableList(const VarList& vl);
192
  void setupPolynomial(const Polynomial& poly);
193
public:
194
  void setupAtom(TNode atom);
195
private:
196
  void cautiousSetupPolynomial(const Polynomial& p);
197
198
  /**
199
   * A superset of all of the assertions that currently are not the literal for
200
   * their constraint do not match constraint literals. Not just the witnesses.
201
   */
202
  context::CDInsertHashMap<Node, ConstraintP>
203
      d_assertionsThatDoNotMatchTheirLiterals;
204
205
  /** Returns true if x is of type Integer. */
206
20545631
  inline bool isInteger(ArithVar x) const {
207
20545631
    return d_partialModel.isInteger(x);
208
  }
209
210
211
  /** Returns true if the variable was initially introduced as an auxiliary variable. */
212
2458062
  inline bool isAuxiliaryVariable(ArithVar x) const{
213
2458062
    return d_partialModel.isAuxiliary(x);
214
  }
215
216
766455424
  inline bool isIntegerInput(ArithVar x) const
217
  {
218
766455424
    return d_partialModel.isIntegerInput(x)
219
1532910848
           && d_preregisteredNodes.contains(d_partialModel.asNode(x));
220
  }
221
222
  /**
223
   * On full effort checks (after determining LA(Q) satisfiability), we
224
   * consider integer vars, but we make sure to do so fairly to avoid
225
   * nontermination (although this isn't a guarantee).  To do it fairly,
226
   * we consider variables in round-robin fashion.  This is the
227
   * round-robin index.
228
   */
229
  ArithVar d_nextIntegerCheckVar;
230
231
  /**
232
   * Queue of Integer variables that are known to be equal to a constant.
233
   */
234
  context::CDQueue<ArithVar> d_constantIntegerVariables;
235
236
  Node callDioSolver();
237
  /**
238
   * Produces lemmas of the form (or (>= f 0) (<= f 0)),
239
   * where f is a plane that the diophantine solver is interested in.
240
   *
241
   * More precisely, produces lemmas of the form (or (>= lc -c) (<= lc -c))
242
   * where lc is a linear combination of variables, c is a constant, and lc + c
243
   * is the plane.
244
   */
245
  TrustNode dioCutting();
246
247
  Comparison mkIntegerEqualityFromAssignment(ArithVar v);
248
249
  /**
250
   * List of all of the disequalities asserted in the current context that are not known
251
   * to be satisfied.
252
   */
253
  context::CDQueue<ConstraintP> d_diseqQueue;
254
255
  /**
256
   * Constraints that have yet to be processed by proagation work list.
257
   * All of the elements have type of LowerBound, UpperBound, or
258
   * Equality.
259
   *
260
   * This is empty at the beginning of every check call.
261
   *
262
   * If head()->getType() == LowerBound or UpperBound,
263
   * then d_cPL[1] is the previous constraint in d_partialModel for the
264
   * corresponding bound.
265
   * If head()->getType() == Equality,
266
   * then d_cPL[1] is the previous lowerBound in d_partialModel,
267
   * and d_cPL[2] is the previous upperBound in d_partialModel.
268
   */
269
  std::deque<ConstraintP> d_currentPropagationList;
270
271
  context::CDQueue<ConstraintP> d_learnedBounds;
272
273
  /**
274
   * Contains all nodes that have been preregistered
275
   */
276
  context::CDHashSet<Node> d_preregisteredNodes;
277
278
  /**
279
   * Manages information about the assignment and upper and lower bounds on
280
   * variables.
281
   */
282
  ArithVariables d_partialModel;
283
284
  /** The set of variables in error in the partial model. */
285
  ErrorSet d_errorSet;
286
287
  /**
288
   * The tableau for all of the constraints seen thus far in the system.
289
   */
290
  Tableau d_tableau;
291
292
  /**
293
   * Maintains the relationship between the PartialModel and the Tableau.
294
   */
295
  LinearEqualityModule d_linEq;
296
297
  /**
298
   * A Diophantine equation solver.  Accesses the tableau and partial
299
   * model (each in a read-only fashion).
300
   */
301
  DioSolver d_diosolver;
302
303
  /** Counts the number of notifyRestart() calls to the theory. */
304
  uint32_t d_restartsCounter;
305
306
  /**
307
   * Every number of restarts equal to s_TABLEAU_RESET_PERIOD,
308
   * the density of the tableau, d, is computed.
309
   * If d >= s_TABLEAU_RESET_DENSITY * d_initialDensity, the tableau
310
   * is set to d_initialTableau.
311
   */
312
  bool d_tableauSizeHasBeenModified;
313
  double d_tableauResetDensity;
314
  uint32_t d_tableauResetPeriod;
315
  static const uint32_t s_TABLEAU_RESET_INCREMENT = 5;
316
317
318
  /** This is only used by simplex at the moment. */
319
  context::CDList<std::pair<ConstraintCP, InferenceId>> d_conflicts;
320
321
  /** This is only used by simplex at the moment. */
322
  context::CDO<Node> d_blackBoxConflict;
323
  /** For holding the proof of the above conflict node. */
324
  context::CDO<std::shared_ptr<ProofNode>> d_blackBoxConflictPf;
325
326
  bool isProofEnabled() const;
327
328
 public:
329
  /**
330
   * This adds the constraint a to the queue of conflicts in d_conflicts.
331
   * Both a and ~a must have a proof.
332
   */
333
  void raiseConflict(ConstraintCP a, InferenceId id);
334
335
  // inline void raiseConflict(const ConstraintCPVec& cv){
336
  //   d_conflicts.push_back(cv);
337
  // }
338
339
  // void raiseConflict(ConstraintCP a, ConstraintCP b);
340
  // void raiseConflict(ConstraintCP a, ConstraintCP b, ConstraintCP c);
341
342
  /** This is a conflict that is magically known to hold. */
343
  void raiseBlackBoxConflict(Node bb, std::shared_ptr<ProofNode> pf = nullptr);
344
  /**
345
   * Returns true iff a conflict has been raised. This method is public since
346
   * it is needed by the ArithState class to know whether we are in conflict.
347
   */
348
  bool anyConflict() const;
349
350
 private:
351
18700195
  inline bool conflictQueueEmpty() const {
352
18700195
    return d_conflicts.empty();
353
  }
354
355
  /**
356
   * Outputs the contents of d_conflicts onto d_out.
357
   * The conditions of anyConflict() must hold.
358
   */
359
  void outputConflicts();
360
361
  /**
362
   * A copy of the tableau.
363
   * This is equivalent  to the original tableau if d_tableauSizeHasBeenModified
364
   * is false.
365
   * The set of basic and non-basic variables may differ from d_tableau.
366
   */
367
  Tableau d_smallTableauCopy;
368
369
  /**
370
   * Returns true if all of the basic variables in the simplex queue of
371
   * basic variables that violate their bounds in the current tableau
372
   * are basic in d_smallTableauCopy.
373
   *
374
   * d_tableauSizeHasBeenModified must be false when calling this.
375
   * Simplex's priority queue must be in collection mode.
376
   */
377
  bool safeToReset() const;
378
379
  /** This keeps track of difference equalities. Mostly for sharing. */
380
  ArithCongruenceManager d_congruenceManager;
381
  context::CDO<bool> d_cmEnabled;
382
383
  /** This implements the Simplex decision procedure. */
384
  DualSimplexDecisionProcedure d_dualSimplex;
385
  FCSimplexDecisionProcedure d_fcSimplex;
386
  SumOfInfeasibilitiesSPD d_soiSimplex;
387
  AttemptSolutionSDP d_attemptSolSimplex;
388
389
  bool solveRealRelaxation(Theory::Effort effortLevel);
390
391
  /* Returns true if this is heuristically a good time to try
392
   * to solve the integers.
393
   */
394
  bool attemptSolveInteger(Theory::Effort effortLevel, bool emmmittedLemmaOrSplit);
395
  bool replayLemmas(ApproximateSimplex* approx);
396
  void solveInteger(Theory::Effort effortLevel);
397
  bool safeToCallApprox() const;
398
  SimplexDecisionProcedure& selectSimplex(bool pass1);
399
  SimplexDecisionProcedure* d_pass1SDP;
400
  SimplexDecisionProcedure* d_otherSDP;
401
  /* Sets d_qflraStatus */
402
  void importSolution(const ApproximateSimplex::Solution& solution);
403
  bool solveRelaxationOrPanic(Theory::Effort effortLevel);
404
  context::CDO<int> d_lastContextIntegerAttempted;
405
  bool replayLog(ApproximateSimplex* approx);
406
407
  class ModelException : public Exception {
408
   public:
409
    ModelException(TNode n, const char* msg);
410
    ~ModelException() override;
411
  };
412
413
  /**
414
   * Computes the delta rational value of a term from the current partial
415
   * model. This returns the delta value assignment to the term if it is in the
416
   * partial model. Otherwise, this is computed recursively for arithmetic terms
417
   * from each subterm.
418
   *
419
   * This throws a DeltaRationalException if the value cannot be represented as
420
   * a DeltaRational. This throws a ModelException if there is a term is not in
421
   * the partial model and is not a theory of arithmetic term.
422
   *
423
   * precondition: The linear abstraction of the nodes must be satisfiable.
424
   */
425
  DeltaRational getDeltaValue(TNode term) const
426
      /* throw(DeltaRationalException, ModelException) */;
427
 public:
428
  TheoryArithPrivate(TheoryArith& containing, Env& env, BranchAndBound& bab);
429
  ~TheoryArithPrivate();
430
431
  //--------------------------------- initialization
432
  /**
433
   * Returns true if we need an equality engine, see
434
   * Theory::needsEqualityEngine.
435
   */
436
  bool needsEqualityEngine(EeSetupInfo& esi);
437
  /** finish initialize */
438
  void finishInit();
439
  //--------------------------------- end initialization
440
441
  /**
442
   * Does non-context dependent setup for a node connected to a theory.
443
   */
444
  void preRegisterTerm(TNode n);
445
446
  void propagate(Theory::Effort e);
447
  TrustNode explain(TNode n);
448
449
  Rational deltaValueForTotalOrder() const;
450
451
  bool collectModelInfo(TheoryModel* m);
452
  /**
453
   * Collect model values. This is the main method for extracting information
454
   * about how to construct the model. This method relies on the caller for
455
   * processing the map, which is done so that other modules (e.g. the
456
   * non-linear extension) can modify arithModel before it is sent to the model.
457
   *
458
   * @param termSet The set of relevant terms
459
   * @param arithModel Mapping from terms (of real type) to their values. The
460
   * caller should assert equalities to the model for each entry in this map.
461
   */
462
  void collectModelValues(const std::set<Node>& termSet,
463
                          std::map<Node, Node>& arithModel);
464
465
  void shutdown(){ }
466
467
  void presolve();
468
  void notifyRestart();
469
  Theory::PPAssertStatus ppAssert(TrustNode tin,
470
                                  TrustSubstitutionMap& outSubstitutions);
471
  void ppStaticLearn(TNode in, NodeBuilder& learned);
472
473
  std::string identify() const { return std::string("TheoryArith"); }
474
475
  EqualityStatus getEqualityStatus(TNode a, TNode b);
476
477
  /** Called when n is notified as being a shared term with TheoryArith. */
478
  void notifySharedTerm(TNode n);
479
480
  Node getModelValue(TNode var);
481
482
483
  std::pair<bool, Node> entailmentCheck(TNode lit, const ArithEntailmentCheckParameters& params, ArithEntailmentCheckSideEffects& out);
484
485
  //--------------------------------- standard check
486
  /** Pre-check, called before the fact queue of the theory is processed. */
487
  bool preCheck(Theory::Effort level);
488
  /** Pre-notify fact. */
489
  void preNotifyFact(TNode atom, bool pol, TNode fact);
490
  /**
491
   * Post-check, called after the fact queue of the theory is processed. Returns
492
   * true if a conflict or lemma was emitted.
493
   */
494
  bool postCheck(Theory::Effort level);
495
  //--------------------------------- end standard check
496
  /**
497
   * Found non-linear? This returns true if this solver ever encountered
498
   * any non-linear terms that were unhandled. Note that this class is not
499
   * responsible for handling non-linear arithmetic. If the owner of this
500
   * class does not handle non-linear arithmetic in another way, then
501
   * setIncomplete should be called on the output channel of TheoryArith.
502
   */
503
  bool foundNonlinear() const;
504
505
  /** get the proof checker of this theory */
506
  ArithProofRuleChecker* getProofChecker();
507
508
 private:
509
  /** The constant zero. */
510
  DeltaRational d_DELTA_ZERO;
511
512
  /** propagates an arithvar */
513
  void propagateArithVar(bool upperbound, ArithVar var );
514
515
  /**
516
   * Using the simpleKind return the ArithVar associated with the assertion.
517
   */
518
  ArithVar determineArithVar(const Polynomial& p) const;
519
  ArithVar determineArithVar(TNode assertion) const;
520
521
  /**
522
   * Splits the disequalities in d_diseq that are violated using lemmas on demand.
523
   * returns true if any lemmas were issued.
524
   * returns false if all disequalities are satisfied in the current model.
525
   */
526
  bool splitDisequalities();
527
528
  /** A Difference variable is known to be 0.*/
529
  void zeroDifferenceDetected(ArithVar x);
530
531
532
  /**
533
   * Looks for the next integer variable without an integer assignment in a
534
   * round-robin fashion. Changes the value of d_nextIntegerCheckVar.
535
   *
536
   * This returns true if all integer variables have integer assignments.
537
   * If this returns false, d_nextIntegerCheckVar does not have an integer
538
   * assignment.
539
   */
540
  bool hasIntegerModel();
541
542
  /**
543
   * Looks for through the variables starting at d_nextIntegerCheckVar
544
   * for the first integer variable that is between its upper and lower bounds
545
   * that has a non-integer assignment.
546
   *
547
   * If assumeBounds is true, skip the check that the variable is in bounds.
548
   *
549
   * If there is no such variable, returns ARITHVAR_SENTINEL;
550
   */
551
  ArithVar nextIntegerViolation(bool assumeBounds) const;
552
553
  /**
554
   * Issues branches for non-auxiliary integer variables with non-integer assignments.
555
   * Returns a cut for a lemma.
556
   * If there is an integer model, this returns Node::null().
557
   */
558
  TrustNode roundRobinBranch();
559
560
1463
  bool proofsEnabled() const { return d_pnm; }
561
562
 public:
563
  /**
564
   * This requests a new unique ArithVar value for x.
565
   * This also does initial (not context dependent) set up for a variable,
566
   * except for setting up the initial.
567
   *
568
   * If aux is true, this is an auxiliary variable.
569
   * If internal is true, x might not be unique up to a constant multiple.
570
   */
571
  ArithVar requestArithVar(TNode x, bool aux, bool internal);
572
573
public:
574
  const BoundsInfo& boundsInfo(ArithVar basic) const;
575
576
577
private:
578
  /** Initial (not context dependent) sets up for a variable.*/
579
  void setupBasicValue(ArithVar x);
580
581
  /** Initial (not context dependent) sets up for a new auxiliary variable.*/
582
  void setupAuxiliary(TNode left);
583
584
585
  /**
586
   * Assert*(n, orig) takes an bound n that is implied by orig.
587
   * and asserts that as a new bound if it is tighter than the current bound
588
   * and updates the value of a basic variable if needed.
589
   *
590
   * orig must be a literal in the SAT solver so that it can be used for
591
   * conflict analysis.
592
   *
593
   * x is the variable getting the new bound,
594
   * c is the value of the new bound.
595
   *
596
   * If this new bound is in conflict with the other bound,
597
   * a node describing this conflict is returned.
598
   * If this new bound is not in conflict, Node::null() is returned.
599
   */
600
  bool AssertLower(ConstraintP constraint);
601
  bool AssertUpper(ConstraintP constraint);
602
  bool AssertEquality(ConstraintP constraint);
603
  bool AssertDisequality(ConstraintP constraint);
604
605
  /** Tracks the bounds that were updated in the current round. */
606
  DenseSet d_updatedBounds;
607
608
  /** Tracks the basic variables where propagation might be possible. */
609
  DenseSet d_candidateBasics;
610
  DenseSet d_candidateRows;
611
612
2905675
  bool hasAnyUpdates() { return !d_updatedBounds.empty(); }
613
  void clearUpdates();
614
615
  void revertOutOfConflict();
616
617
  void propagateCandidatesNew();
618
  void dumpUpdatedBoundsToRows();
619
  bool propagateCandidateRow(RowIndex rid);
620
  bool propagateMightSucceed(ArithVar v, bool ub) const;
621
  /** Attempt to perform a row propagation where there is at most 1 possible variable.*/
622
  bool attemptSingleton(RowIndex ridx, bool rowUp);
623
  /** Attempt to perform a row propagation where every variable is a potential candidate.*/
624
  bool attemptFull(RowIndex ridx, bool rowUp);
625
  bool tryToPropagate(RowIndex ridx, bool rowUp, ArithVar v, bool vUp, const DeltaRational& bound);
626
  bool rowImplicationCanBeApplied(RowIndex ridx, bool rowUp, ConstraintP bestImplied);
627
  //void enqueueConstraints(std::vector<ConstraintCP>& out, Node n) const;
628
  //ConstraintCPVec resolveOutPropagated(const ConstraintCPVec& v, const std::set<ConstraintCP>& propagated) const;
629
  void resolveOutPropagated(std::vector<ConstraintCPVec>& confs, const std::set<ConstraintCP>& propagated) const;
630
  void subsumption(std::vector<ConstraintCPVec>& confs) const;
631
632
  Node cutToLiteral(ApproximateSimplex*  approx, const CutInfo& cut) const;
633
  Node branchToNode(ApproximateSimplex* approx, const NodeLog& cut) const;
634
635
  void propagateCandidates();
636
  void propagateCandidate(ArithVar basic);
637
  bool propagateCandidateBound(ArithVar basic, bool upperBound);
638
639
1020
  inline bool propagateCandidateLowerBound(ArithVar basic){
640
1020
    return propagateCandidateBound(basic, false);
641
  }
642
726
  inline bool propagateCandidateUpperBound(ArithVar basic){
643
726
    return propagateCandidateBound(basic, true);
644
  }
645
646
  /**
647
   * Performs a check to see if it is definitely true that setup can be avoided.
648
   */
649
  bool canSafelyAvoidEqualitySetup(TNode equality);
650
651
  /**
652
   * Handles the case splitting for check() for a new assertion.
653
   * Returns a conflict if one was found.
654
   * Returns Node::null if no conflict was found.
655
   *
656
   * @param assertion The assertion that was just popped from the fact queue
657
   * of TheoryArith and given to this class via preNotifyFact.
658
   */
659
  ConstraintP constraintFromFactQueue(TNode assertion);
660
  bool assertionCases(ConstraintP c);
661
662
  /**
663
   * Returns the basic variable with the shorted row containing a non-basic variable.
664
   * If no such row exists, return ARITHVAR_SENTINEL.
665
   */
666
  ArithVar findShortestBasicRow(ArithVar variable);
667
668
  /**
669
   * Debugging only routine!
670
   * Returns true iff every variable is consistent in the partial model.
671
   */
672
  bool entireStateIsConsistent(const std::string& locationHint);
673
  bool unenqueuedVariablesAreConsistent();
674
675
  bool isImpliedUpperBound(ArithVar var, Node exp);
676
  bool isImpliedLowerBound(ArithVar var, Node exp);
677
678
  void internalExplain(TNode n, NodeBuilder& explainBuilder);
679
680
  void asVectors(const Polynomial& p,
681
                 std::vector<Rational>& coeffs,
682
                 std::vector<ArithVar>& variables);
683
684
  /** Routine for debugging. Print the assertions the theory is aware of. */
685
  void debugPrintAssertions(std::ostream& out) const;
686
  /** Debugging only routine. Prints the model. */
687
  void debugPrintModel(std::ostream& out) const;
688
689
1916022
  inline bool done() const { return d_containing.done(); }
690
  inline TNode get() { return d_containing.get(); }
691
385579
  inline bool isLeaf(TNode x) const { return d_containing.isLeaf(x); }
692
1226370
  inline TheoryId theoryOf(TNode x) const { return d_containing.theoryOf(x); }
693
  inline void debugPrintFacts() const { d_containing.debugPrintFacts(); }
694
  bool outputTrustedLemma(TrustNode lem, InferenceId id);
695
  bool outputLemma(TNode lem, InferenceId id);
696
  void outputTrustedConflict(TrustNode conf, InferenceId id);
697
  void outputConflict(TNode lit, InferenceId id);
698
  void outputPropagate(TNode lit);
699
  void outputRestart();
700
701
  inline bool isSatLiteral(TNode l) const {
702
    return (d_containing.d_valuation).isSatLiteral(l);
703
  }
704
  inline Node getSatValue(TNode n) const {
705
    return (d_containing.d_valuation).getSatValue(n);
706
  }
707
708
  /** Used for replaying approximate simplex */
709
  context::CDQueue<TrustNode> d_approxCuts;
710
  /** Also used for replaying approximate simplex. "approximate cuts temporary storage" */
711
  std::vector<TrustNode> d_acTmp;
712
713
  /** Counts the number of fullCheck calls to arithmetic. */
714
  uint32_t d_fullCheckCounter;
715
  std::vector<ArithVar> cutAllBounded() const;
716
  TrustNode branchIntegerVariable(ArithVar x) const;
717
  void branchVector(const std::vector<ArithVar>& lemmas);
718
719
  context::CDO<unsigned> d_cutCount;
720
  context::CDHashSet<ArithVar, std::hash<ArithVar> > d_cutInContext;
721
722
  context::CDO<bool> d_likelyIntegerInfeasible;
723
724
725
  context::CDO<bool> d_guessedCoeffSet;
726
  ArithRatPairVec d_guessedCoeffs;
727
728
729
  TreeLog* d_treeLog;
730
  TreeLog& getTreeLog();
731
732
733
  ArithVarVec d_replayVariables;
734
  std::vector<ConstraintP> d_replayConstraints;
735
  DenseMap<Rational> d_lhsTmp;
736
737
  /* Approximate simpplex solvers are given a copy of their stats */
738
  ApproximateStatistics* d_approxStats;
739
  ApproximateStatistics& getApproxStats();
740
  context::CDO<int32_t> d_attemptSolveIntTurnedOff;
741
  void turnOffApproxFor(int32_t rounds);
742
  bool getSolveIntegerResource();
743
744
  void tryBranchCut(ApproximateSimplex* approx, int nid, BranchCutInfo& bl);
745
  std::vector<ConstraintCPVec> replayLogRec(ApproximateSimplex* approx, int nid, ConstraintP bc, int depth);
746
747
  std::pair<ConstraintP, ArithVar> replayGetConstraint(const CutInfo& info);
748
  std::pair<ConstraintP, ArithVar> replayGetConstraint(
749
      ApproximateSimplex* approx, const NodeLog& nl);
750
  std::pair<ConstraintP, ArithVar> replayGetConstraint(const DenseMap<Rational>& lhs, Kind k, const Rational& rhs, bool branch);
751
752
  void replayAssert(ConstraintP c);
753
754
  static ConstraintCP vectorToIntHoleConflict(const ConstraintCPVec& conflict);
755
  static void intHoleConflictToVector(ConstraintCP conflicting, ConstraintCPVec& conflict);
756
757
  // Returns true if the node contains a literal
758
  // that is an arithmetic literal and is not a sat literal
759
  // No caching is done so this should likely only
760
  // be called carefully!
761
  bool hasFreshArithLiteral(Node n) const;
762
763
  int32_t d_dioSolveResources;
764
  bool getDioCuttingResource();
765
766
  uint32_t d_solveIntMaybeHelp, d_solveIntAttempts;
767
768
  RationalVector d_farkasBuffer;
769
770
  //---------------- during check
771
  /** Whether there were new facts during preCheck */
772
  bool d_newFacts;
773
  /** The previous status, computed during preCheck */
774
  Result::Sat d_previousStatus;
775
  //---------------- end during check
776
777
  /** These fields are designed to be accessible to TheoryArith methods. */
778
  class Statistics {
779
  public:
780
    IntStat d_statAssertUpperConflicts, d_statAssertLowerConflicts;
781
782
    IntStat d_statUserVariables, d_statAuxiliaryVariables;
783
    IntStat d_statDisequalitySplits;
784
    IntStat d_statDisequalityConflicts;
785
    TimerStat d_simplifyTimer;
786
    TimerStat d_staticLearningTimer;
787
788
    TimerStat d_presolveTime;
789
790
    TimerStat d_newPropTime;
791
792
    IntStat d_externalBranchAndBounds;
793
794
    IntStat d_initialTableauSize;
795
    IntStat d_currSetToSmaller;
796
    IntStat d_smallerSetToCurr;
797
    TimerStat d_restartTimer;
798
799
    TimerStat d_boundComputationTime;
800
    IntStat d_boundComputations, d_boundPropagations;
801
802
    IntStat d_unknownChecks;
803
    IntStat d_maxUnknownsInARow;
804
    AverageStat d_avgUnknownsInARow;
805
806
    IntStat d_revertsOnConflicts;
807
    IntStat d_commitsOnConflicts;
808
    IntStat d_nontrivialSatChecks;
809
810
    IntStat d_replayLogRecCount,
811
      d_replayLogRecConflictEscalation,
812
      d_replayLogRecEarlyExit,
813
      d_replayBranchCloseFailures,
814
      d_replayLeafCloseFailures,
815
      d_replayBranchSkips,
816
      d_mirCutsAttempted,
817
      d_gmiCutsAttempted,
818
      d_branchCutsAttempted,
819
      d_cutsReconstructed,
820
      d_cutsReconstructionFailed,
821
      d_cutsProven,
822
      d_cutsProofFailed,
823
      d_mipReplayLemmaCalls,
824
      d_mipExternalCuts,
825
      d_mipExternalBranch;
826
827
    IntStat d_inSolveInteger,
828
      d_branchesExhausted,
829
      d_execExhausted,
830
      d_pivotsExhausted,
831
      d_panicBranches,
832
      d_relaxCalls,
833
      d_relaxLinFeas,
834
      d_relaxLinFeasFailures,
835
      d_relaxLinInfeas,
836
      d_relaxLinInfeasFailures,
837
      d_relaxLinExhausted,
838
      d_relaxOthers;
839
840
    IntStat d_applyRowsDeleted;
841
    TimerStat d_replaySimplexTimer;
842
843
    TimerStat d_replayLogTimer,
844
      d_solveIntTimer,
845
      d_solveRealRelaxTimer;
846
847
    IntStat d_solveIntCalls,
848
      d_solveStandardEffort;
849
850
    IntStat d_approxDisabled;
851
    IntStat d_replayAttemptFailed;
852
853
    IntStat d_cutsRejectedDuringReplay;
854
    IntStat d_cutsRejectedDuringLemmas;
855
856
    HistogramStat<uint32_t> d_satPivots;
857
    HistogramStat<uint32_t> d_unsatPivots;
858
    HistogramStat<uint32_t> d_unknownPivots;
859
860
    IntStat d_solveIntModelsAttempts;
861
    IntStat d_solveIntModelsSuccessful;
862
    TimerStat d_mipTimer;
863
    TimerStat d_lpTimer;
864
865
    IntStat d_mipProofsAttempted;
866
    IntStat d_mipProofsSuccessful;
867
868
    IntStat d_numBranchesFailed;
869
870
    Statistics(StatisticsRegistry& reg, const std::string& name);
871
  };
872
873
874
  Statistics d_statistics;
875
}; /* class TheoryArithPrivate */
876
877
}  // namespace arith
878
}  // namespace theory
879
}  // namespace cvc5