/*****************************************************************************/ /*! * \file circuit.cpp * \brief Circuit class * *
* * License to use, copy, modify, sell and/or distribute this software * and its documentation for any purpose is hereby granted without * royalty, subject to the terms and conditions defined in the \ref * LICENSE file provided with this distribution. * *
* */ /*****************************************************************************/ #include "circuit.h" #include "search_fast.h" #include "search_rules.h" using namespace std; namespace CVC3 { Circuit::Circuit(SearchEngineFast* se, const Theorem& thm) : d_thm(thm) { const Expr& e = d_thm.getExpr(); for (int i = 0; i < e.arity(); i++) { d_lits[i] = e[i].isNot() ? Literal(Variable(se->d_vm, e[i][0]), false) : Literal(Variable(se->d_vm, e[i]), true); se->d_circuitsByExpr[e[i]].push_back(this); se->d_circuitsByExpr[e[i].negate()].push_back(this); } } #define vals3(a, b, c) ((a) + 1 + ((b) + 1) * 3 + ((c) + 1) * 9) #define vals4(a, b, c, d) (vals3(a, b, c) + ((d) + 1) * 27) bool Circuit::propagate(SearchEngineFast* se) { int v0 = d_lits[0].getValue(); int v1 = d_lits[1].getValue(); int v2 = d_lits[2].getValue(); int v3 = d_lits[3].getValue(); const Theorem& t0 = d_lits[0].getTheorem(); const Theorem& t1 = d_lits[1].getTheorem(); const Theorem& t2 = d_lits[2].getTheorem(); const Theorem& t3 = d_lits[3].getTheorem(); int values = d_thm.getExpr().arity() == 3 ? vals3(v0, v1, v2) : vals4(v0, v1, v2, v3); Theorem thm; Theorem thm2; switch (d_thm.getExpr().getKind()) { case AND_R: switch (values) { case vals3(0,0,0): case vals3(0,0,1): case vals3(0,1,0): case vals3(1,1,1): case vals3(-1,0,0): case vals3(-1,0,-1): case vals3(-1,1,-1): case vals3(-1,-1,0): case vals3(-1,-1,1): case vals3(-1,-1,-1): break; case vals3(0,0,-1): case vals3(0,1,-1): case vals3(0,-1,0): case vals3(0,-1,1): case vals3(0,-1,-1): // simp thm = se->d_rules->propAndrAF(d_thm, v1 == -1, v1 == -1 ? t1 : t2); break; case vals3(0,1,1): // simp thm = se->d_rules->propAndrAT(d_thm, t1, t2); break; case vals3(1,1,0): case vals3(1,0,1): case vals3(1,0,0): // split cases to avoid doing extra work? se->d_rules->propAndrLRT(d_thm, t0, &thm, &thm2); break; case vals3(-1,0,1): thm = se->d_rules->propAndrLF(d_thm, t0, t2); break; case vals3(-1,1,0): thm = se->d_rules->propAndrRF(d_thm, t0, t1); break; case vals3(1,0,-1): case vals3(1,1,-1): case vals3(1,-1,0): case vals3(1,-1,1): case vals3(1,-1,-1): se->d_conflictTheorem = se->d_rules->confAndrAT(d_thm, t0, v1 == -1, v1 == -1 ? t1 : t2); return false; case vals3(-1,1,1): se->d_conflictTheorem = se->d_rules->confAndrAF(d_thm, t0, t1, t2); return false; } break; case IFF_R: switch (values) { case vals3(0,0,0): case vals3(0,0,1): case vals3(0,0,-1): case vals3(0,1,0): case vals3(0,-1,0): case vals3(1,0,0): case vals3(1,1,1): case vals3(1,-1,-1): case vals3(-1,0,0): case vals3(-1,1,-1): case vals3(-1,-1,1): break; case vals3(0,1,1): case vals3(0,-1,-1): case vals3(0,1,-1): case vals3(0,-1,1): // simp thm = se->d_rules->propIffr(d_thm, 0, t1, t2); break; case vals3(1,0,1): case vals3(-1,0,-1): case vals3(1,0,-1): case vals3(-1,0,1): thm = se->d_rules->propIffr(d_thm, 1, t0, t2); break; case vals3(1,1,0): case vals3(-1,-1,0): case vals3(1,-1,0): case vals3(-1,1,0): thm = se->d_rules->propIffr(d_thm, 2, t0, t1); break; case vals3(1,1,-1): case vals3(1,-1,1): case vals3(-1,1,1): case vals3(-1,-1,-1): se->d_conflictTheorem = se->d_rules->confIffr(d_thm, t0, t1, t2); return false; } break; case ITE_R: switch (values) { case vals4(0,0,0,0): case vals4(0,0,0,1): case vals4(0,0,0,-1): case vals4(0,0,1,0): case vals4(0,0,1,1): case vals4(0,0,1,-1): case vals4(0,0,-1,0): case vals4(0,0,-1,1): case vals4(0,0,-1,-1): case vals4(0,1,0,0): case vals4(0,1,0,1): case vals4(0,1,0,-1): case vals4(0,-1,0,0): case vals4(0,-1,1,0): case vals4(0,-1,-1,0): case vals4(1,0,0,0): case vals4(1,0,0,1): case vals4(1,0,1,0): case vals4(1,0,1,1): case vals4(1,1,1,0): case vals4(1,1,1,1): case vals4(1,1,1,-1): case vals4(1,-1,0,1): case vals4(1,-1,1,1): case vals4(1,-1,-1,1): case vals4(-1,0,0,0): case vals4(-1,0,0,-1): case vals4(-1,0,-1,0): case vals4(-1,0,-1,-1): case vals4(-1,1,-1,0): case vals4(-1,1,-1,1): case vals4(-1,1,-1,-1): case vals4(-1,-1,0,-1): case vals4(-1,-1,1,-1): case vals4(-1,-1,-1,-1): break; case vals4(0,1,1,0): case vals4(0,1,1,1): case vals4(0,1,1,-1): case vals4(0,1,-1,0): case vals4(0,1,-1,1): case vals4(0,1,-1,-1): case vals4(0,-1,0,-1): case vals4(0,-1,1,-1): case vals4(0,-1,-1,-1): case vals4(0,-1,0,1): case vals4(0,-1,1,1): case vals4(0,-1,-1,1): // simp thm = se->d_rules->propIterIte(d_thm, v1 == 1, t1, v1 == 1 ? t2 : t3); break; case vals4(1,0,0,-1): case vals4(1,0,1,-1): case vals4(1,0,-1,0): case vals4(1,0,-1,1): case vals4(-1,0,0,1): case vals4(-1,0,1,0): case vals4(-1,0,1,-1): case vals4(-1,0,-1,1): se->d_rules->propIterIfThen(d_thm, v0 == -v2, t0, v0 == -v2 ? t2 : t3, &thm, &thm2); break; case vals4(1,1,0,0): case vals4(1,1,0,1): case vals4(1,1,0,-1): case vals4(1,-1,0,0): case vals4(1,-1,1,0): case vals4(1,-1,-1,0): case vals4(-1,1,0,0): case vals4(-1,1,0,1): case vals4(-1,1,0,-1): case vals4(-1,-1,0,0): case vals4(-1,-1,1,0): case vals4(-1,-1,-1,0): thm = se->d_rules->propIterThen(d_thm, t0, t1); break; case vals4(1,0,-1,-1): case vals4(-1,0,1,1): case vals4(-1,1,1,1): case vals4(1,1,-1,-1): se->d_conflictTheorem = se->d_rules->confIterThenElse(d_thm, t0, t2, t3); return false; case vals4(1,1,-1,0): case vals4(1,1,-1,1): case vals4(1,-1,0,-1): case vals4(1,-1,1,-1): case vals4(1,-1,-1,-1): case vals4(-1,1,1,0): case vals4(-1,1,1,-1): case vals4(-1,-1,0,1): case vals4(-1,-1,1,1): case vals4(-1,-1,-1,1): se->d_conflictTheorem = se->d_rules->confIterIfThen(d_thm, v1 == 1, t0, t1, v1 == 1 ? t2 : t3); return false; } break; default: DebugAssert(false, "unhandled circuit"); } if (!thm.isNull() && se->newLiteral(thm.getExpr()).getValue() == 0) { se->d_core->addFact(thm); se->recordFact(thm); se->d_literals.push_back(se->newLiteral(thm.getExpr())); se->d_circuitPropCount++; } if (!thm2.isNull() && se->newLiteral(thm2.getExpr()).getValue() == 0) { se->d_core->addFact(thm2); se->recordFact(thm2); se->d_literals.push_back(se->newLiteral(thm2.getExpr())); se->d_circuitPropCount++; } return true; } } // namespace CVC3