1 /********************* */
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
12 ** \brief This is an implementation of the Simplex Module for the Simplex for DPLL(T)
13 ** decision procedure.
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.
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.
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.
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.
42 ** Conflicts are greedily slackened to use the weakest bounds that still produce the
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
52 #include "cvc4_private.h"
56 #include <unordered_map>
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"
71 class SimplexDecisionProcedure
{
73 typedef std::vector
< std::pair
<ArithVar
, int> > AVIntPairVec
;
75 /** Pivot count of the current round of pivoting. */
78 /** The set of variables that are in conflict in this round. */
79 DenseSet d_conflictVariables
;
81 /** The rule to use for heuristic selection mode. */
82 options::ErrorSelectionRule d_heuristicRule
;
84 /** Linear equality module. */
85 LinearEqualityModule
& d_linEq
;
88 * Manages information about the assignment and upper and lower bounds on
90 * Partial model matches that in LinearEqualityModule.
92 ArithVariables
& d_variables
;
95 * Stores the linear equalities used by Simplex.
96 * Tableau from the LinearEquality module.
100 /** Contains a superset of the basic variables in violation of their bounds. */
101 ErrorSet
& d_errorSet
;
103 /** Number of variables in the system. This is used for tuning heuristics. */
104 ArithVar d_numVariables
;
106 /** This is the call back channel for Simplex to report conflicts. */
107 RaiseConflict d_conflictChannel
;
109 /** This is the call back channel for Simplex to report conflicts. */
110 FarkasConflictBuilder
* d_conflictBuilder
;
112 /** Used for requesting d_opt, bound and error variables for primal.*/
113 TempVarMalloc d_arithVarMalloc
;
115 /** The size of the error set. */
116 uint32_t d_errorSize
;
118 /** A local copy of 0. */
119 const Rational d_zero
;
121 /** A local copy of 1. */
122 const Rational d_posOne
;
124 /** A local copy of -1. */
125 const Rational d_negOne
;
127 ArithVar
constructInfeasiblityFunction(TimerStat
& timer
);
128 ArithVar
constructInfeasiblityFunction(TimerStat
& timer
, ArithVar e
);
129 ArithVar
constructInfeasiblityFunction(TimerStat
& timer
, const ArithVarVec
& set
);
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
);
138 SimplexDecisionProcedure(LinearEqualityModule
& linEq
, ErrorSet
& errors
, RaiseConflict conflictChannel
, TempVarMalloc tvmalloc
);
139 virtual ~SimplexDecisionProcedure();
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.
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.
150 * Tableau pivoting is performed so variables may switch from being basic to
151 * nonbasic and vice versa.
153 * Corresponds to the "check()" procedure in [Cav06].
155 virtual Result::Sat
findModel(bool exactResult
) = 0;
157 void increaseMax() { d_numVariables
++; }
160 uint32_t getPivots() const { return d_pivots
; }
163 /** Reports a conflict to on the output channel. */
164 void reportConflict(ArithVar basic
);
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.
171 bool maybeGenerateConflictForBasic(ArithVar basic
) const;
173 /** Returns true if a tracked basic variable has a conflict on it. */
174 bool checkBasicForConflict(ArithVar b
) const;
177 * If a basic variable has a conflict on its row,
178 * this produces a minimized row on the conflict channel.
180 ConstraintCP
generateConflictForBasic(ArithVar basic
) const;
183 /** Gets a fresh variable from TheoryArith. */
184 ArithVar
requestVariable(){
185 return d_arithVarMalloc
.request();
188 /** Releases a requested variable from TheoryArith.*/
189 void releaseVariable(ArithVar v
){
190 d_arithVarMalloc
.release(v
);
193 /** Post condition: !d_queue.moreSignals() */
194 bool standardProcessSignals(TimerStat
&timer
, IntStat
& conflictStat
);
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
;
204 typedef std::unordered_map
< std::pair
<ArithVar
, int>, ArithVarVec
, ArithVarIntPairHashFunc
> sgn_table
;
206 static inline int determinizeSgn(int sgn
){
207 return sgn
< 0 ? -1 : (sgn
== 0 ? 0 : 1);
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
);
214 sgn_table::const_iterator
find_sgns(const sgn_table
& sgns
, ArithVar col
, int sgn
);
216 };/* class SimplexDecisionProcedure */
218 }/* CVC4::theory::arith namespace */
219 }/* CVC4::theory namespace */
220 }/* CVC4 namespace */