d_cutInContext(c),
d_statistics()
{
+ srand(79);
}
TheoryArithPrivate::~TheoryArithPrivate(){ }
}
// I think this can be skipped if canBePropagated is true
//d_learnedBounds.push(bestImplied);
- cout << "success " << bestImplied << endl;
- d_partialModel.printModel(basic, cout);
-
+ if(Debug.isOn("arith::prop")){
+ Debug("arith::prop") << "success " << bestImplied << endl;
+ d_partialModel.printModel(basic, Debug("arith::prop"));
+ }
return true;
}
- cout << "failed " << basic << " " << bound << assertedToTheTheory << " " <<
- canBePropagated << " " << hasProof << endl;
- d_partialModel.printModel(basic, cout);
+ if(Debug.isOn("arith::prop")){
+ Debug("arith::prop") << "failed " << basic << " " << bound << assertedToTheTheory << " " <<
+ canBePropagated << " " << hasProof << endl;
+ d_partialModel.printModel(basic, Debug("arith::prop"));
+ }
}
- }else{
- cout << "false " << bound << " ";
- d_partialModel.printModel(basic, cout);
+ }else if(Debug.isOn("arith::prop")){
+ Debug("arith::prop") << "false " << bound << " ";
+ d_partialModel.printModel(basic, Debug("arith::prop"));
}
return false;
}
void TheoryArithPrivate::propagateCandidates(){
TimerStat::CodeTimer codeTimer(d_statistics.d_boundComputationTime);
- cout << "propagateCandidates begin" << endl;
+ Debug("arith::prop") << "propagateCandidates begin" << endl;
Assert(d_candidateBasics.empty());
Assert(d_tableau.isBasic(candidate));
propagateCandidate(candidate);
}
- cout << "propagateCandidates end" << endl << endl << endl;
+ Debug("arith::prop") << "propagateCandidates end" << endl << endl << endl;
}
void TheoryArithPrivate::propagateCandidatesNew(){
*/
TimerStat::CodeTimer codeTimer(d_statistics.d_boundComputationTime);
- cout << "propagateCandidatesNew begin" << endl;
+ Debug("arith::prop") << "propagateCandidatesNew begin" << endl;
Assert(d_qflraStatus == Result::SAT);
if(d_updatedBounds.empty()){ return; }
d_candidateRows.pop_back();
propagateCandidateRow(candidate);
}
- cout << "propagateCandidatesNew end" << endl << endl << endl;
+ Debug("arith::prop") << "propagateCandidatesNew end" << endl << endl << endl;
}
bool TheoryArithPrivate::propagateMightSucceed(ArithVar v, bool ub) const{
}
bool TheoryArithPrivate::attemptSingleton(RowIndex ridx, bool rowUp){
- cout << " attemptSingleton" << ridx;
+ Debug("arith::prop") << " attemptSingleton" << ridx;
const Tableau::Entry* ep;
ep = d_linEq.rowLacksBound(ridx, rowUp, ARITHVAR_SENTINEL);
// if c < 0, v \geq -D/c so !vUp
bool vUp = (rowUp == ( coeff.sgn() < 0));
- cout << " " << rowUp << " " << v << " " << coeff << " " << vUp << endl;
- cout << " " << propagateMightSucceed(v, vUp) << endl;
+ Debug("arith::prop") << " " << rowUp << " " << v << " " << coeff << " " << vUp << endl;
+ Debug("arith::prop") << " " << propagateMightSucceed(v, vUp) << endl;
if(propagateMightSucceed(v, vUp)){
DeltaRational dr = d_linEq.computeRowBound(ridx, rowUp, v);
}
bool TheoryArithPrivate::attemptFull(RowIndex ridx, bool rowUp){
- cout << " attemptFull" << ridx << endl;
+ Debug("arith::prop") << " attemptFull" << ridx << endl;
vector<const Tableau::Entry*> candidates;
DeltaRational impliedBound = (slack - contribution)/(-c);
bool success = tryToPropagate(ridx, rowUp, v, vUb, impliedBound);
- if(success){
- cout << " success " << v << endl;
- }else{
- cout << " fail " << v << endl;
- }
any |= success;
}
return any;
return false;
}
+Node flattenImplication(Node imp){
+ NodeBuilder<> nb(kind::OR);
+ Node left = imp[0];
+ Node right = imp[1];
+
+ if(left.getKind() == kind::AND){
+ for(Node::iterator i = left.begin(), iend = left.end(); i != iend; ++i) {
+ nb << (*i).negate();
+ }
+ }else{
+ nb << left.negate();
+ }
+
+ if(right.getKind() == kind::OR){
+ for(Node::iterator i = right.begin(), iend = right.end(); i != iend; ++i) {
+ nb << *i;
+ }
+ }else{
+ nb << right;
+ }
+
+ return nb;
+}
+
bool TheoryArithPrivate::rowImplicationCanBeApplied(RowIndex ridx, bool rowUp, Constraint implied){
Assert(implied != NullConstraint);
ArithVar v = implied->getVariable();
}
if(!assertedToTheTheory && canBePropagated && !hasProof ){
- d_linEq.propagateRow(ridx, rowUp, implied);
+ vector<Constraint> explain;
+ d_linEq.propagateRow(explain, ridx, rowUp, implied);
+ if(d_tableau.getRowLength(ridx) <= options::arithPropAsLemmaLength()){
+ Node implication = implied->makeImplication(explain);
+ Node clause = flattenImplication(implication);
+ outputLemma(clause);
+ }else{
+ implied->impliedBy(explain);
+ }
return true;
}
- cout << "failed " << v << " " << assertedToTheTheory << " " <<
- canBePropagated << " " << hasProof << " " << implied << endl;
- d_partialModel.printModel(v, cout);
+
+ if(Debug.isOn("arith::prop")){
+ Debug("arith::prop")
+ << "failed " << v << " " << assertedToTheTheory << " "
+ << canBePropagated << " " << hasProof << " " << implied << endl;
+ d_partialModel.printModel(v, Debug("arith::prop"));
+ }
return false;
}
+double fRand(double fMin, double fMax)
+{
+ double f = (double)rand() / RAND_MAX;
+ return fMin + f * (fMax - fMin);
+}
+
bool TheoryArithPrivate::propagateCandidateRow(RowIndex ridx){
BoundCounts hasCount = d_linEq.hasBoundCount(ridx);
uint32_t rowLength = d_tableau.getRowLength(ridx);
bool success = false;
static int instance = 0;
++instance;
- cout << "propagateCandidateRow " << instance << " attempt " << rowLength << " " << hasCount << endl;
+
+ Debug("arith::prop")
+ << "propagateCandidateRow " << instance << " attempt " << rowLength << " " << hasCount << endl;
if(rowLength >= options::arithPropagateMaxLength()){
- return false;
+ if(fRand(0.0,1.0) >= double(options::arithPropagateMaxLength())/rowLength){
+ return false;
+ }
}
if(hasCount.lowerBoundCount() == rowLength){