case kind::UMINUS:
typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n);
break;
+ case kind::DIVISION:
+ typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n);
+ break;
case kind::CONST_RATIONAL:
typeNode = CVC4::theory::arith::ArithConstantTypeRule::computeType(this, n);
break;
return iteLit;
}
-Node TseitinCnfStream::handleNonAtomicNode(TNode node) {
- Debug("cnf") << "handleNonAtomicNode(" << node << ")" << endl;
-
- /* Our main goal here is to tease out any ITE's sitting under a theory operator. */
- Node rewrite;
- NodeManager *nodeManager = NodeManager::currentNM();
- if(nodeManager->getAttribute(node, IteRewriteAttr(), rewrite)) {
- return rewrite.isNull() ? Node(node) : rewrite;
- }
-
- if(node.getKind() == ITE) {
- Assert( node.getNumChildren() == 3 );
- //TODO should this be a skolem?
- Node skolem = nodeManager->mkVar(node.getType());
- Node newAssertion =
- nodeManager->mkNode(
- ITE,
- node[0],
- nodeManager->mkNode(EQUAL, skolem, node[1]),
- nodeManager->mkNode(EQUAL, skolem, node[2]));
- nodeManager->setAttribute(node, IteRewriteAttr(), skolem);
- convertAndAssert(newAssertion, d_assertingLemma);
- return skolem;
- } else {
- std::vector<Node> newChildren;
- bool somethingChanged = false;
- for(TNode::const_iterator it = node.begin(), end = node.end(); it != end; ++it) {
- Node newChild = handleNonAtomicNode(*it);
- somethingChanged |= (newChild != *it);
- newChildren.push_back(newChild);
- }
-
- if(somethingChanged) {
-
- rewrite = nodeManager->mkNode(node.getKind(), newChildren);
- nodeManager->setAttribute(node, IteRewriteAttr(), rewrite);
- return rewrite;
- } else {
- nodeManager->setAttribute(node, IteRewriteAttr(), Node::null());
- return node;
- }
- }
-}
SatLiteral TseitinCnfStream::toCNF(TNode node) {
Debug("cnf") << "toCNF(" << node << ")" << endl;
return handleAnd(node);
default:
{
- Node atomic = handleNonAtomicNode(node);
- return isCached(atomic) ? lookupInCache(atomic) : handleAtom(atomic);
+ //TODO make sure this does not contain any boolean substructure
+ return handleAtom(node);
+ //Unreachable();
+ //Node atomic = handleNonAtomicNode(node);
+ //return isCached(atomic) ? lookupInCache(atomic) : handleAtom(atomic);
}
}
}
SatLiteral handleAnd(TNode node);
SatLiteral handleOr(TNode node);
- struct IteRewriteTag {};
- typedef expr::Attribute<IteRewriteTag, Node> IteRewriteAttr;
- Node handleNonAtomicNode(TNode node);
/**
* Transforms the node into CNF recursively.
struct PreRegisteredTag {};
typedef expr::Attribute<PreRegisteredTag, bool> PreRegistered;
+struct IteRewriteTag {};
+typedef expr::Attribute<IteRewriteTag, Node> IteRewriteAttr;
+
}/* CVC4::theory namespace */
Node TheoryEngine::preprocess(TNode t) {
}
return top;
+}
+ /* Our goal is to tease out any ITE's sitting under a theory operator. */
+Node TheoryEngine::removeITEs(TNode node) {
+ Debug("ite") << "handleNonAtomicNode(" << node << ")" << endl;
+
+ /* The result may be cached already */
+ Node rewrite;
+ NodeManager *nodeManager = NodeManager::currentNM();
+ if(nodeManager->getAttribute(node, theory::IteRewriteAttr(), rewrite)) {
+ return rewrite.isNull() ? Node(node) : rewrite;
+ }
+
+ if(node.getKind() == kind::ITE){
+ if(theoryOf(node[1]) != &d_bool && node[1].getKind() != kind::EQUAL) {
+ Assert( node.getNumChildren() == 3 );
+
+ Debug("ite") << theoryOf(node[1]) << " " << &d_bool <<endl;
+
+ Node skolem = nodeManager->mkVar(node.getType());
+ Node newAssertion =
+ nodeManager->mkNode(
+ kind::ITE,
+ node[0],
+ nodeManager->mkNode(kind::EQUAL, skolem, node[1]),
+ nodeManager->mkNode(kind::EQUAL, skolem, node[2]));
+ nodeManager->setAttribute(node, theory::IteRewriteAttr(), skolem);
+
+ Node preprocessed = preprocess(newAssertion);
+ d_propEngine->assertFormula(preprocessed);
+
+ return skolem;
+ }
+ }
+ std::vector<Node> newChildren;
+ bool somethingChanged = false;
+ for(TNode::const_iterator it = node.begin(), end = node.end(); it != end; ++it) {
+ Node newChild = removeITEs(*it);
+ somethingChanged |= (newChild != *it);
+ newChildren.push_back(newChild);
+ }
+
+ if(somethingChanged) {
+
+ rewrite = nodeManager->mkNode(node.getKind(), newChildren);
+ nodeManager->setAttribute(node, theory::IteRewriteAttr(), rewrite);
+ return rewrite;
+ } else {
+ nodeManager->setAttribute(node, theory::IteRewriteAttr(), Node::null());
+ return node;
+ }
+
}
Node TheoryEngine::rewrite(TNode in) {
return in;
}
- /*
- theory::Theory* thy = theoryOf(in);
- if(thy == NULL) {
- Node out = rewriteBuiltins(in);
- setRewriteCache(in, out);
- return in;
- } else {
- Node out = thy->rewrite(in);
- setRewriteCache(in, out);
- return out;
- }
- */
+ in = removeITEs(in);
// these special cases should go away when theory rewriting comes online
- if(in.getKind() == kind::EQUAL) {
- Assert(in.getNumChildren() == 2);
- if(in[0] == in[1]) {
- Node out = NodeManager::currentNM()->mkConst(true);
- //setRewriteCache(in, out);
- return out;
- }
- } else if(in.getKind() == kind::DISTINCT) {
+ if(in.getKind() == kind::DISTINCT) {
vector<Node> diseqs;
for(TNode::iterator i = in.begin(); i != in.end(); ++i) {
TNode::iterator j = i;
: NodeManager::currentNM()->mkNode(CVC4::kind::AND, diseqs);
//setRewriteCache(in, out);
return out;
- } else {
- Node out = rewriteChildren(in);
+ }
+
+ theory::Theory* thy = theoryOf(in);
+ if(thy == NULL) {
+ Node out = rewriteBuiltins(in);
+ //setRewriteCache(in, out);
+ return in;
+ } else if(thy != &d_bool){
+ Node out = thy->rewrite(in);
//setRewriteCache(in, out);
return out;
+ }else{
+ Node out = rewriteChildren(in);
+ setRewriteCache(in, out);
+ return out;
}
- //setRewriteCache(in, in);
- return in;
+ Unreachable();
}
}/* CVC4 namespace */
}
NodeBuilder<> b(in.getKind());
+ if(in.getMetaKind() == kind::metakind::PARAMETERIZED){
+ Assert(in.hasOperator());
+ b << in.getOperator();
+ }
for(TNode::iterator c = in.begin(); c != in.end(); ++c) {
b << rewrite(*c);
}
}
}
+ Node removeITEs(TNode t);
+
public:
/**
Assert(k >= 0 && k < kind::LAST_KIND);
if(k == kind::VARIABLE) {
- return &d_uf;
+ TypeNode t = n.getType();
+ if(t.isBoolean()){
+ return &d_bool;
+ }else if(t.isReal()){
+ return &d_arith;
+ }else{
+ return &d_uf;
+ }
//Unimplemented();
} else if(k == kind::EQUAL) {
// if LHS is a VARIABLE, use theoryOf(LHS.getType())
TheoryUF::~TheoryUF() {
}
+Node TheoryUF::rewrite(TNode n){
+ Debug("uf") << "uf: begin rewrite(" << n << ")" << std::endl;
+ Node ret(n);
+ if(n.getKind() == EQUAL){
+ Assert(n.getNumChildren() == 2);
+ if(n[0] == n[1]) {
+ ret = NodeManager::currentNM()->mkConst(true);
+ }
+ }
+ Debug("uf") << "uf: end rewrite(" << n << ") : " << ret << std::endl;
+ return ret;
+}
void TheoryUF::preRegisterTerm(TNode n) {
Debug("uf") << "uf: begin preRegisterTerm(" << n << ")" << std::endl;
Debug("uf") << "uf: end preRegisterTerm(" << n << ")" << std::endl;
*/
void check(Effort level);
+
+ /**
+ * Rewrites a node in the theory of uninterpreted functions.
+ * This is fairly basic and only ensures that atoms that are
+ * unsatisfiable or a valid are rewritten to false or true respectively.
+ */
+ Node rewrite(TNode n);
+
/**
* Propagates theory literals. Currently does nothing.
*