}
if(somethingChanged) {
+
rewrite = nodeManager->mkNode(node.getKind(), newChildren);
nodeManager->setAttribute(node, IteRewriteAttr(), rewrite);
return rewrite;
case AND:
return handleAnd(node);
default:
- return handleAtom(handleNonAtomicNode(node));
+ {
+ Node atomic = handleNonAtomicNode(node);
+ AlwaysAssert(isCached(atomic) || atomic.isAtomic());
+ return toCNF(atomic);
+ }
}
}
//TODO Assert(d_x_i.getType() == REAL);
Assert(sum.getKind() == PLUS);
+ Rational zero(0,1);
for(TNode::iterator iter=sum.begin(); iter != sum.end(); ++iter){
TNode pair = *iter;
//TODO Assert(var_i.getKind() == REAL);
Assert(!has(var_i));
d_nonbasic.insert(var_i);
- d_coeffs[var_i] = coeff.getConst<Rational>();
+ Rational q = coeff.getConst<Rational>();
+ d_coeffs[var_i] = q;
+ Assert(q != zero);
+ Assert(d_coeffs[var_i] != zero);
}
}
bool has(TNode x_j){
CoefficientTable::iterator x_jPos = d_coeffs.find(x_j);
-
return x_jPos != d_coeffs.end();
}
Rational& lookup(TNode x_j){
- return d_coeffs[x_j];
+ CoefficientTable::iterator x_jPos = d_coeffs.find(x_j);
+ Assert(x_jPos != d_coeffs.end());
+ return (*x_jPos).second;
}
void pivot(TNode x_j){
TNode nb = *nonbasicIter;
d_coeffs[nb] = d_coeffs[nb] * negInverseA_rs;
}
+
}
void subsitute(Row& row_s){
TNode x_s = row_s.basicVar();
Assert(has(x_s));
+ Assert(d_nonbasic.find(x_s) != d_nonbasic.end());
Assert(x_s != d_x_i);
+ Rational zero(0,1);
Rational a_rs = lookup(x_s);
+ Assert(a_rs != zero);
d_coeffs.erase(x_s);
+ d_nonbasic.erase(x_s);
for(std::set<TNode>::iterator iter = row_s.d_nonbasic.begin();
iter != row_s.d_nonbasic.end();
Rational a_sj = a_rs * row_s.lookup(x_j);
if(has(x_j)){
d_coeffs[x_j] = d_coeffs[x_j] + a_sj;
+ if(d_coeffs[x_j] == zero){
+ d_coeffs.erase(x_j);
+ d_nonbasic.erase(x_j);
+ }
}else{
d_nonbasic.insert(x_j);
d_coeffs[x_j] = a_sj;
using namespace CVC4::theory;
using namespace CVC4::theory::arith;
+struct EagerSplittingTag {};
+typedef expr::Attribute<EagerSplittingTag, bool> EagerlySplitUpon;
+
+
TheoryArith::TheoryArith(context::Context* c, OutputChannel& out) :
Theory(c, out),
d_preprocessed(c),
}
}
+void TheoryArith::preRegisterTerm(TNode n) {
+ Debug("arith_preregister") << "arith: begin TheoryArith::preRegisterTerm("
+ << n << ")" << endl;
+
+ if(n.getKind() == EQUAL){
+ if(!n.getAttribute(EagerlySplitUpon())){
+ TNode left = n[0];
+ TNode right = n[1];
+
+ Node lt = NodeManager::currentNM()->mkNode(LT, left,right);
+ Node gt = NodeManager::currentNM()->mkNode(GT, left,right);
+ Node eagerSplit = NodeManager::currentNM()->mkNode(OR, n, lt, gt);
+
+ d_splits.push_back(eagerSplit);
+
+ n.setAttribute(EagerlySplitUpon(), true);
+ d_out->augmentingLemma(eagerSplit);
+ }
+ }
+
+ Debug("arith_preregister") << "arith: end TheoryArith::preRegisterTerm("
+ << n << ")" << endl;
+}
bool isBasicSum(TNode n){
if(n.getKind() != kind::PLUS) return false;
TNode x_j = *basicIter;
Row* row_j = d_tableau.lookup(x_j);
- Rational& a_ji = row_j->lookup(x_i);
+ if(row_j->has(x_i)){
+ Rational& a_ji = row_j->lookup(x_i);
- DeltaRational assignment = d_partialModel.getAssignment(x_j);
- DeltaRational nAssignment = assignment+(diff * a_ji);
- d_partialModel.setAssignment(x_j, nAssignment);
+ DeltaRational assignment = d_partialModel.getAssignment(x_j);
+ DeltaRational nAssignment = assignment+(diff * a_ji);
+ d_partialModel.setAssignment(x_j, nAssignment);
+ }
}
d_partialModel.setAssignment(x_i, v);
TNode x_k = *basicIter;
Row* row_k = d_tableau.lookup(x_k);
- if(x_k != x_i){
+ if(x_k != x_i && row_k->has(x_j)){
DeltaRational a_kj = row_k->lookup(x_j);
DeltaRational nextAssignment = d_partialModel.getAssignment(x_k) + theta;
d_partialModel.setAssignment(x_k, nextAssignment);
d_partialModel.beginRecordingAssignments();
while(true){
TNode x_i = selectSmallestInconsistentVar();
+ Debug("arith_update") << "selectSmallestInconsistentVar()=" << x_i << endl;
if(x_i == Node::null()){
+ Debug("arith_update") << "No inconsistent variables" << endl;
d_partialModel.stopRecordingAssignments(false);
return Node::null(); //sat
}
if(possibleConflict != Node::null()){
Debug("arith") << "Found a conflict " << possibleConflict << endl;
d_out->conflict(possibleConflict);
+ }else{
+ Debug("arith") << "No conflict found" << endl;
}
}
bool enqueuedCaseSplit = false;
typedef context::CDList<Node>::const_iterator diseq_iterator;
for(diseq_iterator i = d_diseq.begin(); i!= d_diseq.end(); ++i){
+
Node assertion = *i;
+ Debug("arith") << "splitting" << assertion << endl;
TNode eq = assertion[0];
TNode x_i = eq[0];
TNode c_i = eq[1];
DeltaRational constant = c_i.getConst<Rational>();
+ Debug("arith") << "broken apart" << endl;
if(d_partialModel.getAssignment(x_i) == constant){
+ Debug("arith") << "here" << endl;
enqueuedCaseSplit = true;
Node lt = NodeManager::currentNM()->mkNode(LT,x_i,c_i);
Node gt = NodeManager::currentNM()->mkNode(GT,x_i,c_i);
Node caseSplit = NodeManager::currentNM()->mkNode(OR, eq, lt, gt);
//d_out->enqueueCaseSplits(caseSplit);
+ Debug("arith") << "finished" << caseSplit << endl;
}
+ Debug("arith") << "end of for loop" << endl;
+
}
+ Debug("arith") << "finished" << endl;
+
if(enqueuedCaseSplit){
//d_out->caseSplit();
- Warning() << "Outstanding case split in theory arith" << endl;
+ //Warning() << "Outstanding case split in theory arith" << endl;
}
}
+ Debug("arith") << "TheoryArith::check end" << std::endl;
+
}
private:
/* Chopping block begins */
+ std::vector<Node> d_splits;
+ //This stores the eager splits sent out of the theory.
+ //TODO get rid of this.
+
context::CDList<Node> d_preprocessed;
//TODO This is currently needed to save preprocessed nodes that may not
//currently have an outisde reference. Get rid of when preprocessing is occuring
Node rewrite(TNode n);
- void preRegisterTerm(TNode n) { Unimplemented(); }
+ void preRegisterTerm(TNode n);
void registerTerm(TNode n);
void check(Effort e);
void propagate(Effort e) { Unimplemented(); }
Theory(c, out) {
}
- void preRegisterTerm(TNode n) { Unimplemented(); }
- void registerTerm(TNode n) { Unimplemented(); }
+ void preRegisterTerm(TNode n) {
+ Debug("bool") << "bool: begin preRegisterTerm(" << n << ")" << std::endl;
+ Debug("bool") << "bool: end preRegisterTerm(" << n << ")" << std::endl;
+ }
+ void registerTerm(TNode n) {
+ Debug("bool") << "bool: begin preRegisterTerm(" << n << ")" << std::endl;
+ Debug("bool") << "bool: end preRegisterTerm(" << n << ")" << std::endl;
+ }
void check(Effort e) { Unimplemented(); }
void propagate(Effort e) { Unimplemented(); }
void explain(TNode n, Effort e) { Unimplemented(); }
+
};
}/* CVC4::theory::booleans namespace */
#ifndef __CVC4__THEORY__OUTPUT_CHANNEL_H
#define __CVC4__THEORY__OUTPUT_CHANNEL_H
+#include "util/Assert.h"
#include "theory/interrupted.h"
namespace CVC4 {
* With safePoint(), the theory signals that it is at a safe point
* and can be interrupted.
*/
- virtual void safePoint() throw(Interrupted) {
+ virtual void safePoint() throw(Interrupted, AssertionException) {
}
/**
*
* @param safe - whether it is safe to be interrupted
*/
- virtual void conflict(TNode n, bool safe = false) throw(Interrupted) = 0;
+ virtual void conflict(TNode n, bool safe = false) throw(Interrupted, AssertionException) = 0;
/**
* Propagate a theory literal.
*
* @param safe - whether it is safe to be interrupted
*/
- virtual void propagate(TNode n, bool safe = false) throw(Interrupted) = 0;
+ virtual void propagate(TNode n, bool safe = false) throw(Interrupted, AssertionException) = 0;
/**
* Tell the core that a valid theory lemma at decision level 0 has
* @param n - a theory lemma valid at decision level 0
* @param safe - whether it is safe to be interrupted
*/
- virtual void lemma(TNode n, bool safe = false) throw(Interrupted) = 0;
+ virtual void lemma(TNode n, bool safe = false) throw(Interrupted, AssertionException) = 0;
+
+ /**
+ * Tell the core to add the following valid lemma as if it were a user assertion.
+ * This should NOT be called during solving, only preprocessing.
+ *
+ * @param n - a theory lemma valid to be asserted
+ * @param safe - whether it is safe to be interrupted
+ */
+ virtual void augmentingLemma(TNode n, bool safe = false) throw(Interrupted, AssertionException) = 0;
/**
* Provide an explanation in response to an explanation request.
* @param n - an explanation
* @param safe - whether it is safe to be interrupted
*/
- virtual void explanation(TNode n, bool safe = false) throw(Interrupted) = 0;
+ virtual void explanation(TNode n, bool safe = false) throw(Interrupted, AssertionException) = 0;
};/* class OutputChannel */
Node TheoryEngine::preprocess(TNode t) {
Node top = rewrite(t);
- Debug("rewrite") << "rewrote: " << t << "\nto : " << top << "\n";
- return top;
+ Debug("rewrite") << "rewrote: " << t << endl << "to : " << top << endl;
list<TNode> toReg;
toReg.push_back(top);
d_conflictNode(context) {
}
- void conflict(TNode conflictNode, bool safe) throw(theory::Interrupted) {
+ void conflict(TNode conflictNode, bool safe) throw(theory::Interrupted, AssertionException) {
Debug("theory") << "EngineOutputChannel::conflict(" << conflictNode << ")" << std::endl;
d_conflictNode = conflictNode;
if(safe) {
}
}
- void propagate(TNode, bool) throw(theory::Interrupted) {
+ void propagate(TNode, bool) throw(theory::Interrupted, AssertionException) {
}
- void lemma(TNode node, bool) throw(theory::Interrupted) {
+ void lemma(TNode node, bool) throw(theory::Interrupted, AssertionException) {
d_engine->newLemma(node);
}
-
- void explanation(TNode, bool) throw(theory::Interrupted) {
+ void augmentingLemma(TNode node, bool) throw(theory::Interrupted, AssertionException) {
+ d_engine->newAugmentingLemma(node);
+ }
+ void explanation(TNode, bool) throw(theory::Interrupted, AssertionException) {
}
};
inline void newLemma(TNode node) {
d_propEngine->assertLemma(node);
}
-
+ inline void newAugmentingLemma(TNode node) {
+ Node preprocessed = preprocess(node);
+ d_propEngine->assertFormula(preprocessed);
+ }
/**
* Returns the last conflict (if any).
*/
flet.smt \
flet2.smt \
ite_real_int_type.smt \
+ ite_real_valid.smt \
let.smt \
let2.smt \
simple2.smt \
--- /dev/null
+(benchmark ite_real_valid
+:logic QF_LRA
+:status unsat
+:extrafuns ((x Real))
+:extrapreds ((b))
+:formula
+ (not (implies (= x (ite b 0 1)) (>= x 0)))
+)
~TestOutputChannel() {}
- void safePoint() throw(Interrupted) {}
+ void safePoint() throw(Interrupted, AssertionException) {}
- void conflict(TNode n, bool safe = false) throw(Interrupted) {
+ void conflict(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(CONFLICT, n);
}
- void propagate(TNode n, bool safe = false) throw(Interrupted) {
+ void propagate(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(PROPAGATE, n);
}
- void lemma(TNode n, bool safe = false) throw(Interrupted) {
+ void lemma(TNode n, bool safe = false) throw(Interrupted, AssertionException){
push(LEMMA, n);
}
- void explanation(TNode n, bool safe = false) throw(Interrupted) {
+ void augmentingLemma(TNode n, bool safe = false) throw(Interrupted, AssertionException){
+ Unreachable();
+ }
+
+ void explanation(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(EXPLANATION, n);
}
~TestOutputChannel() {}
- void safePoint() throw(Interrupted) {}
+ void safePoint() throw(Interrupted, AssertionException) {}
- void conflict(TNode n, bool safe = false) throw(Interrupted) {
+ void conflict(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(CONFLICT, n);
}
- void propagate(TNode n, bool safe = false) throw(Interrupted) {
+ void propagate(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(PROPOGATE, n);
}
- void lemma(TNode n, bool safe = false) throw(Interrupted) {
+ void lemma(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(LEMMA, n);
}
- void explanation(TNode n, bool safe = false) throw(Interrupted) {
+ void augmentingLemma(TNode n, bool safe = false) throw(Interrupted, AssertionException){
+ Unreachable();
+ }
+ void explanation(TNode n, bool safe = false) throw(Interrupted, AssertionException) {
push(EXPLANATION, n);
}