using namespace CVC4::theory::arith;
ArithPriorityQueue::ArithPriorityQueue(ArithPartialModel& pm, const Tableau& tableau):
- d_partialModel(pm), d_tableau(tableau), d_usingGriggioRule(true)
+ d_partialModel(pm), d_tableau(tableau), d_usingGriggioRule(true), d_ZERO_DELTA(0,0)
{}
ArithVar ArithPriorityQueue::popInconsistentBasicVariable(){
if(usingGriggioRule()){
while(!d_griggioRuleQueue.empty()){
- ArithVar var = d_griggioRuleQueue.top().first;
- d_griggioRuleQueue.pop();
+ ArithVar var = d_griggioRuleQueue.front().variable();
+ pop_heap(d_griggioRuleQueue.begin(), d_griggioRuleQueue.end());
+ d_griggioRuleQueue.pop_back();
Debug("arith_update") << "possiblyInconsistentGriggio var" << var << endl;
if(basicAndInconsistent(var)){
return var;
<< d_possiblyInconsistent.size() << endl;
while(!d_possiblyInconsistent.empty()){
- ArithVar var = d_possiblyInconsistent.top();
- d_possiblyInconsistent.pop();
+ ArithVar var = d_possiblyInconsistent.front();
+ pop_heap(d_possiblyInconsistent.begin(), d_possiblyInconsistent.end(), std::greater<ArithVar>());
+ d_possiblyInconsistent.pop_back();
+
Debug("arith_update") << "possiblyInconsistent var" << var << endl;
if(basicAndInconsistent(var)){
return var;
DeltaRational diff = d_partialModel.belowLowerBound(basic,beta,true) ?
d_partialModel.getLowerBound(basic) - beta:
beta - d_partialModel.getUpperBound(basic);
- d_griggioRuleQueue.push(make_pair(basic,diff));
+
+ Assert(d_ZERO_DELTA < diff);
+ d_griggioRuleQueue.push_back(VarDRatPair(basic,diff));
+ push_heap(d_griggioRuleQueue.begin(), d_griggioRuleQueue.end());
+
}else{
- d_possiblyInconsistent.push(basic);
+ d_possiblyInconsistent.push_back(basic);
+ push_heap(d_possiblyInconsistent.begin(), d_possiblyInconsistent.end(), std::greater<ArithVar>());
}
}
}
-
-void ArithPriorityQueue::enqueueTrustedVector(const vector<VarDRatPair>& trusted){
+ArithPriorityQueue::GriggioPQueue::const_iterator ArithPriorityQueue::queueAsListBegin() const{
Assert(usingGriggioRule());
- Assert(empty());
-
- d_griggioRuleQueue = GriggioPQueue(trusted.begin(), trusted.end());
- Assert(size() == trusted.size());
+ return d_griggioRuleQueue.begin();
}
-
-
-void ArithPriorityQueue::dumpQueueIntoVector(vector<VarDRatPair>& target){
+ArithPriorityQueue::GriggioPQueue::const_iterator ArithPriorityQueue::queueAsListEnd() const{
Assert(usingGriggioRule());
- while( !d_griggioRuleQueue.empty()){
- ArithVar var = d_griggioRuleQueue.top().first;
- if(basicAndInconsistent(var)){
- target.push_back( d_griggioRuleQueue.top());
- }
- d_griggioRuleQueue.pop();
- }
+ return d_griggioRuleQueue.end();
}
void ArithPriorityQueue::useBlandQueue(){
Assert(usingGriggioRule());
- while(!d_griggioRuleQueue.empty()){
- ArithVar var = d_griggioRuleQueue.top().first;
+ Assert(d_possiblyInconsistent.empty());
+ for(GriggioPQueue::const_iterator i = d_griggioRuleQueue.begin(), end = d_griggioRuleQueue.end(); i != end; ++i){
+ ArithVar var = (*i).variable();
if(basicAndInconsistent(var)){
- d_possiblyInconsistent.push(var);
+ d_possiblyInconsistent.push_back(var);
}
- d_griggioRuleQueue.pop();
}
+ d_griggioRuleQueue.clear();
+ make_heap(d_possiblyInconsistent.begin(), d_possiblyInconsistent.end(), std::greater<ArithVar>());
d_usingGriggioRule = false;
Assert(d_griggioRuleQueue.empty());
void ArithPriorityQueue::clear(){
if(usingGriggioRule() && !d_griggioRuleQueue.empty()){
- d_griggioRuleQueue = GriggioPQueue();
+ d_griggioRuleQueue.clear();
}else if(!d_possiblyInconsistent.empty()) {
- d_possiblyInconsistent = PQueue();
+ d_possiblyInconsistent.clear();
}
Assert(d_possiblyInconsistent.empty());
Assert(d_griggioRuleQueue.empty());
#include "theory/arith/tableau.h"
#include "theory/arith/partial_model.h"
-#include <queue>
+
+#include <vector>
+#include <algorithm>
namespace CVC4 {
namespace theory {
namespace arith {
-typedef std::pair<ArithVar, DeltaRational> VarDRatPair;
-
-struct VarDRatPairCompare{
- inline bool operator()(const VarDRatPair& a, const VarDRatPair& b){
- return a.second > b.second;
- }
-};
-
-typedef std::priority_queue<VarDRatPair, std::vector<VarDRatPair>, VarDRatPairCompare> GriggioPQueue;
-typedef std::priority_queue<ArithVar, vector<ArithVar>, std::greater<ArithVar> > PQueue;
+class ArithPriorityQueue {
+private:
+ class VarDRatPair {
+ ArithVar d_variable;
+ DeltaRational d_orderBy;
+ public:
+ VarDRatPair(ArithVar var, const DeltaRational& dr):
+ d_variable(var), d_orderBy(dr)
+ { }
+
+ ArithVar variable() const {
+ return d_variable;
+ }
+ bool operator<(const VarDRatPair& other){
+ return d_orderBy > other.d_orderBy;
+ }
+ };
-class ArithPriorityQueue {
+public:
+ typedef std::vector<VarDRatPair> GriggioPQueue;
private:
+ typedef std::vector<ArithVar> PQueue;
+
/**
* Priority Queue of the basic variables that may be inconsistent.
* Variables are ordered according to which violates its bound the most.
*/
bool d_usingGriggioRule;
+ /** Storage of Delta Rational 0 */
+ DeltaRational d_ZERO_DELTA;
+
public:
+
ArithPriorityQueue(ArithPartialModel& pm, const Tableau& tableau);
ArithVar popInconsistentBasicVariable();
void enqueueIfInconsistent(ArithVar basic);
- void enqueueTrustedVector(const vector<VarDRatPair>& trusted);
-
- void dumpQueueIntoVector(vector<VarDRatPair>& target);
+ GriggioPQueue::const_iterator queueAsListBegin() const;
+ GriggioPQueue::const_iterator queueAsListEnd() const;
inline bool basicAndInconsistent(ArithVar var) const{
return d_tableau.isBasic(var)
}
}else{
d_queue.enqueueIfInconsistent(x_i);
- //checkBasicVariable(x_i);
}
return false;
ArithVarSet::iterator basicIter = d_tableau.beginColumn(x_j);
ArithVarSet::iterator endIter = d_tableau.endColumn(x_j);
for(; basicIter != endIter; ++basicIter){
-
- //ArithVarSet::iterator basicIter = d_tableau.begin(), end = d_tableau.end();
- //for(; basicIter != end; ++basicIter){
ArithVar x_k = *basicIter;
ReducedRowVector& row_k = d_tableau.lookup(x_k);
Assert(row_k.has(x_j));
-
- //if(x_k != x_i && row_k.has(x_j)){
if(x_k != x_i ){
const Rational& a_kj = row_k.lookup(x_j);
DeltaRational nextAssignment = d_partialModel.getAssignment(x_k) + (theta * a_kj);
TimerStat::CodeTimer codeTimer(d_statistics.d_selectInitialConflictTime);
- vector<VarDRatPair> init;
- d_queue.dumpQueueIntoVector(init);
-
int conflictChanges = 0;
- vector<VarDRatPair>::iterator i=init.begin(), end=init.end();
+ ArithPriorityQueue::GriggioPQueue::const_iterator i = d_queue.queueAsListBegin();
+ ArithPriorityQueue::GriggioPQueue::const_iterator end = d_queue.queueAsListEnd();
for(; i != end; ++i){
- ArithVar x_i = (*i).first;
+ ArithVar x_i = (*i).variable();
- Node possibleConflict = checkBasicForConflict(x_i);
- if(!possibleConflict.isNull()){
- Node better = betterConflict(bestConflict, possibleConflict);
+ if(d_tableau.isBasic(x_i)){
+ Node possibleConflict = checkBasicForConflict(x_i);
+ if(!possibleConflict.isNull()){
+ Node better = betterConflict(bestConflict, possibleConflict);
- if(better != bestConflict){
- ++conflictChanges;
+ if(better != bestConflict){
+ ++conflictChanges;
+ }
+ bestConflict = better;
+ ++(d_statistics.d_statEarlyConflicts);
}
- bestConflict = better;
- ++(d_statistics.d_statEarlyConflicts);
}
}
- if(bestConflict.isNull()){
- d_queue.enqueueTrustedVector(init);
- }
if(conflictChanges > 1) ++(d_statistics.d_statEarlyConflictImprovements);
return bestConflict;
possibleConflict = searchForFeasibleSolution<true>(d_numVariables + 1);
}
- if(possibleConflict.isNull()){
+ if(!d_queue.empty() && possibleConflict.isNull()){
d_queue.useBlandQueue();
possibleConflict = searchForFeasibleSolution<false>(0);
}
//corresponds to Check() in dM06
template <bool limitIterations>
Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingIterations){
-
Debug("arith") << "updateInconsistentVars" << endl;
- //uint32_t iteratationNum = 0;
-
while(!limitIterations || remainingIterations > 0){
if(Debug.isOn("paranoid:check_tableau")){ checkTableau(); }
ArithVar x_i = d_queue.popInconsistentBasicVariable();
- //selectSmallestInconsistentVar<useGriggioQueue>();
Debug("arith::update::select") << "selectSmallestInconsistentVar()=" << x_i << endl;
if(x_i == ARITHVAR_SENTINEL){
Debug("arith_update") << "No inconsistent variables" << endl;
return earlyConflict;
}
}
- if(remainingIterations == 0 && limitIterations){
- return Node::null();
- }
+ AlwaysAssert(limitIterations && remainingIterations == 0);
- Unreachable();
+ return Node::null();
}