5bd6034d223ae5b16065bf177e6f1fb7a38f817e
[cvc5.git] / src / theory / arith / simplex.h
1 /********************* */
2 /*! \file simplex.h
3 ** \verbatim
4 ** Top contributors (to current version):
5 ** Tim King, Clark Barrett
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
11 **
12 ** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
13 ** decision procedure.
14 **
15 ** This implements the Simplex module for the Simpelx for DPLL(T) decision procedure.
16 ** See the Simplex for DPLL(T) technical report for more background.(citation?)
17 ** This shares with the theory a Tableau, and a PartialModel that:
18 ** - satisfies the equalities in the Tableau, and
19 ** - the assignment for the non-basic variables satisfies their bounds.
20 ** This is required to either produce a conflict or satisifying PartialModel.
21 ** Further, we require being told when a basic variable updates its value.
22 **
23 ** During the Simplex search we maintain a queue of variables.
24 ** The queue is required to contain all of the basic variables that voilate their bounds.
25 ** As elimination from the queue is more efficient to be done lazily,
26 ** we do not maintain that the queue of variables needs to be only basic variables or only
27 ** variables that satisfy their bounds.
28 **
29 ** The simplex procedure roughly follows Alberto's thesis. (citation?)
30 ** There is one round of selecting using a heuristic pivoting rule. (See PreferenceFunction
31 ** Documentation for the available options.)
32 ** The non-basic variable is the one that appears in the fewest pivots. (Bruno says that
33 ** Leonardo invented this first.)
34 ** After this, Bland's pivot rule is invoked.
35 **
36 ** During this proccess, we periodically inspect the queue of variables to
37 ** 1) remove now extraneous extries,
38 ** 2) detect conflicts that are "waiting" on the queue but may not be detected by the
39 ** current queue heuristics, and
40 ** 3) detect multiple conflicts.
41 **
42 ** Conflicts are greedily slackened to use the weakest bounds that still produce the
43 ** conflict.
44 **
45 ** Extra things tracked atm: (Subject to change at Tim's whims)
46 ** - A superset of all of the newly pivoted variables.
47 ** - A queue of additional conflicts that were discovered by Simplex.
48 ** These are theory valid and are currently turned into lemmas
49 **/
50
51
52 #include "cvc4_private.h"
53
54 #pragma once
55
56 #include <unordered_map>
57
58 #include "theory/arith/arithvar.h"
59 #include "theory/arith/delta_rational.h"
60 #include "theory/arith/error_set.h"
61 #include "theory/arith/linear_equality.h"
62 #include "theory/arith/partial_model.h"
63 #include "theory/arith/tableau.h"
64 #include "util/dense_map.h"
65 #include "util/result.h"
66
67 namespace CVC4 {
68 namespace theory {
69 namespace arith {
70
71 class SimplexDecisionProcedure {
72 protected:
73 typedef std::vector< std::pair<ArithVar, int> > AVIntPairVec;
74
75 /** Pivot count of the current round of pivoting. */
76 uint32_t d_pivots;
77
78 /** The set of variables that are in conflict in this round. */
79 DenseSet d_conflictVariables;
80
81 /** The rule to use for heuristic selection mode. */
82 options::ErrorSelectionRule d_heuristicRule;
83
84 /** Linear equality module. */
85 LinearEqualityModule& d_linEq;
86
87 /**
88 * Manages information about the assignment and upper and lower bounds on
89 * variables.
90 * Partial model matches that in LinearEqualityModule.
91 */
92 ArithVariables& d_variables;
93
94 /**
95 * Stores the linear equalities used by Simplex.
96 * Tableau from the LinearEquality module.
97 */
98 Tableau& d_tableau;
99
100 /** Contains a superset of the basic variables in violation of their bounds. */
101 ErrorSet& d_errorSet;
102
103 /** Number of variables in the system. This is used for tuning heuristics. */
104 ArithVar d_numVariables;
105
106 /** This is the call back channel for Simplex to report conflicts. */
107 RaiseConflict d_conflictChannel;
108
109 /** This is the call back channel for Simplex to report conflicts. */
110 FarkasConflictBuilder* d_conflictBuilder;
111
112 /** Used for requesting d_opt, bound and error variables for primal.*/
113 TempVarMalloc d_arithVarMalloc;
114
115 /** The size of the error set. */
116 uint32_t d_errorSize;
117
118 /** A local copy of 0. */
119 const Rational d_zero;
120
121 /** A local copy of 1. */
122 const Rational d_posOne;
123
124 /** A local copy of -1. */
125 const Rational d_negOne;
126
127 ArithVar constructInfeasiblityFunction(TimerStat& timer);
128 ArithVar constructInfeasiblityFunction(TimerStat& timer, ArithVar e);
129 ArithVar constructInfeasiblityFunction(TimerStat& timer, const ArithVarVec& set);
130
131 void tearDownInfeasiblityFunction(TimerStat& timer, ArithVar inf);
132 void adjustInfeasFunc(TimerStat& timer, ArithVar inf, const AVIntPairVec& focusChanges);
133 void addToInfeasFunc(TimerStat& timer, ArithVar inf, ArithVar e);
134 void removeFromInfeasFunc(TimerStat& timer, ArithVar inf, ArithVar e);
135 void shrinkInfeasFunc(TimerStat& timer, ArithVar inf, const ArithVarVec& dropped);
136
137 public:
138 SimplexDecisionProcedure(LinearEqualityModule& linEq, ErrorSet& errors, RaiseConflict conflictChannel, TempVarMalloc tvmalloc);
139 virtual ~SimplexDecisionProcedure();
140
141 /**
142 * Tries to update the assignments of variables such that all of the
143 * assignments are consistent with their bounds.
144 * This is done by a simplex search through the possible bases of the tableau.
145 *
146 * If all of the variables can be made consistent with their bounds
147 * SAT is returned. Otherwise UNSAT is returned, and at least 1 conflict
148 * was reported on the conflictCallback passed to the Module.
149 *
150 * Tableau pivoting is performed so variables may switch from being basic to
151 * nonbasic and vice versa.
152 *
153 * Corresponds to the "check()" procedure in [Cav06].
154 */
155 virtual Result::Sat findModel(bool exactResult) = 0;
156
157 void increaseMax() { d_numVariables++; }
158
159
160 uint32_t getPivots() const { return d_pivots; }
161 protected:
162
163 /** Reports a conflict to on the output channel. */
164 void reportConflict(ArithVar basic);
165
166 /**
167 * Checks a basic variable, b, to see if it is in conflict.
168 * If a conflict is discovered a node summarizing the conflict is returned.
169 * Otherwise, Node::null() is returned.
170 */
171 bool maybeGenerateConflictForBasic(ArithVar basic) const;
172
173 /** Returns true if a tracked basic variable has a conflict on it. */
174 bool checkBasicForConflict(ArithVar b) const;
175
176 /**
177 * If a basic variable has a conflict on its row,
178 * this produces a minimized row on the conflict channel.
179 */
180 ConstraintCP generateConflictForBasic(ArithVar basic) const;
181
182
183 /** Gets a fresh variable from TheoryArith. */
184 ArithVar requestVariable(){
185 return d_arithVarMalloc.request();
186 }
187
188 /** Releases a requested variable from TheoryArith.*/
189 void releaseVariable(ArithVar v){
190 d_arithVarMalloc.release(v);
191 }
192
193 /** Post condition: !d_queue.moreSignals() */
194 bool standardProcessSignals(TimerStat &timer, IntStat& conflictStat);
195
196 struct ArithVarIntPairHashFunc {
197 size_t operator()(const std::pair<ArithVar, int>& p) const {
198 size_t h1 = std::hash<ArithVar>()(p.first);
199 size_t h2 = std::hash<int>()(p.second);
200 return h1 + 3389 * h2;
201 }
202 };
203
204 typedef std::unordered_map< std::pair<ArithVar, int>, ArithVarVec, ArithVarIntPairHashFunc> sgn_table;
205
206 static inline int determinizeSgn(int sgn){
207 return sgn < 0 ? -1 : (sgn == 0 ? 0 : 1);
208 }
209
210 void addSgn(sgn_table& sgns, ArithVar col, int sgn, ArithVar basic);
211 void addRowSgns(sgn_table& sgns, ArithVar basic, int norm);
212 ArithVar find_basic_in_sgns(const sgn_table& sgns, ArithVar col, int sgn, const DenseSet& m, bool inside);
213
214 sgn_table::const_iterator find_sgns(const sgn_table& sgns, ArithVar col, int sgn);
215
216 };/* class SimplexDecisionProcedure */
217
218 }/* CVC4::theory::arith namespace */
219 }/* CVC4::theory namespace */
220 }/* CVC4 namespace */