using namespace std;
-struct PropagatorLeqSetID {};
-typedef expr::Attribute<PropagatorLeqSetID, OrderedSet*, SetCleanupStrategy> PropagatorLeqSet;
-
-struct PropagatorEqSetID {};
-typedef expr::Attribute<PropagatorEqSetID, OrderedSet*, SetCleanupStrategy> PropagatorEqSet;
-
-struct PropagatorGeqSetID {};
-typedef expr::Attribute<PropagatorGeqSetID, OrderedSet*, SetCleanupStrategy> PropagatorGeqSet;
-
ArithUnatePropagator::ArithUnatePropagator(context::Context* cxt, OutputChannel& out) :
- d_arithOut(out)
+ d_arithOut(out), d_orderedListMap()
{ }
bool ArithUnatePropagator::leftIsSetup(TNode left){
- return left.hasAttribute(PropagatorEqSet());
+ return d_orderedListMap.find(left) != d_orderedListMap.end();
+}
+
+ArithUnatePropagator::OrderedSetTriple& ArithUnatePropagator::getOrderedSetTriple(TNode left){
+ Assert(leftIsSetup(left));
+ return d_orderedListMap[left];
+}
+
+OrderedSet& ArithUnatePropagator::getEqSet(TNode left){
+ Assert(leftIsSetup(left));
+ return getOrderedSetTriple(left).d_eqSet;
+}
+OrderedSet& ArithUnatePropagator::getLeqSet(TNode left){
+ Assert(leftIsSetup(left));
+ return getOrderedSetTriple(left).d_leqSet;
+}
+OrderedSet& ArithUnatePropagator::getGeqSet(TNode left){
+ Assert(leftIsSetup(left));
+ return getOrderedSetTriple(left).d_geqSet;
}
bool ArithUnatePropagator::hasAnyAtoms(TNode v){
Assert(!leftIsSetup(v)
- || !v.getAttribute(PropagatorEqSet())->empty()
- || !v.getAttribute(PropagatorLeqSet())->empty()
- || !v.getAttribute(PropagatorGeqSet())->empty());
+ || !(getEqSet(v)).empty()
+ || !(getLeqSet(v)).empty()
+ || !(getGeqSet(v)).empty());
return leftIsSetup(v);
}
void ArithUnatePropagator::setupLefthand(TNode left){
Assert(!leftIsSetup(left));
- OrderedSet* eqList = new OrderedSet();
- OrderedSet* leqList = new OrderedSet();
- OrderedSet* geqList = new OrderedSet();
-
- left.setAttribute(PropagatorEqSet(), eqList);
- left.setAttribute(PropagatorLeqSet(), geqList);
- left.setAttribute(PropagatorGeqSet(), leqList);
+ d_orderedListMap[left] = OrderedSetTriple();
}
void ArithUnatePropagator::addAtom(TNode atom){
setupLefthand(left);
}
- OrderedSet* eqSet = left.getAttribute(PropagatorEqSet());
- OrderedSet* leqSet = left.getAttribute(PropagatorLeqSet());
- OrderedSet* geqSet = left.getAttribute(PropagatorGeqSet());
+ OrderedSet& eqSet = getEqSet(left);
+ OrderedSet& leqSet = getLeqSet(left);
+ OrderedSet& geqSet = getGeqSet(left);
switch(atom.getKind()){
case EQUAL:
{
- pair<OrderedSet::iterator, bool> res = eqSet->insert(atom);
+ pair<OrderedSet::iterator, bool> res = eqSet.insert(atom);
Assert(res.second);
- addEqualityToEqualities(atom, eqSet, res.first);
- addEqualityToLeqs(atom, leqSet);
- addEqualityToGeqs(atom, geqSet);
+ addImplicationsUsingEqualityAndEqualityList(atom, eqSet);
+ addImplicationsUsingEqualityAndLeqList(atom, leqSet);
+ addImplicationsUsingEqualityAndGeqList(atom, geqSet);
break;
}
case LEQ:
{
- pair<OrderedSet::iterator, bool> res = leqSet->insert(atom);
+ pair<OrderedSet::iterator, bool> res = leqSet.insert(atom);
Assert(res.second);
- addLeqToLeqs(atom, leqSet, res.first);
- addLeqToEqualities(atom, eqSet);
- addLeqToGeqs(atom, geqSet);
+ addImplicationsUsingLeqAndEqualityList(atom, eqSet);
+ addImplicationsUsingLeqAndLeqList(atom, leqSet);
+ addImplicationsUsingLeqAndGeqList(atom, geqSet);
break;
}
case GEQ:
{
- pair<OrderedSet::iterator, bool> res = geqSet->insert(atom);
+ pair<OrderedSet::iterator, bool> res = geqSet.insert(atom);
Assert(res.second);
- addGeqToGeqs(atom, geqSet, res.first);
- addGeqToEqualities(atom, eqSet);
- addGeqToLeqs(atom, leqSet);
+ addImplicationsUsingGeqAndEqualityList(atom, eqSet);
+ addImplicationsUsingGeqAndLeqList(atom, leqSet);
+ addImplicationsUsingGeqAndGeqList(atom, geqSet);
break;
}
return qA == qB;
}
-bool rightHandRationalIsLT(TNode a, TNode b){
- TNode secondA = a[1];
- TNode secondB = b[1];
- const Rational& qA = secondA.getConst<Rational>();
- const Rational& qB = secondB.getConst<Rational>();
- return qA < qB;
+bool rightHandRationalIsLT(TNode a, TNode b){
+ //This version is sticking around because it is easier to read!
+ return RightHandRationalLT()(a,b);
}
-void ArithUnatePropagator::addEqualityToEqualities(TNode atom,
- OrderedSet* eqSet,
- OrderedSet::iterator eqPos){
+//void addImplicationsUsingEqualityAndEqualityList(TNode eq, OrderedSet* eqSet);
+
+void ArithUnatePropagator::addImplicationsUsingEqualityAndEqualityList(TNode atom, OrderedSet& eqSet){
Assert(atom.getKind() == EQUAL);
+ OrderedSet::iterator eqPos = eqSet.find(atom);
+ Assert(eqPos != eqSet.end());
+ Assert(*eqPos == atom);
+
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- for(OrderedSet::iterator eqIter = eqSet->begin();
- eqIter != eqSet->end(); ++eqIter){
+ for(OrderedSet::iterator eqIter = eqSet.begin();
+ eqIter != eqSet.end(); ++eqIter){
if(eqIter == eqPos) continue;
TNode eq = *eqIter;
Assert(!rightHandRationalIsEqual(eq, atom));
}
}
-void ArithUnatePropagator::addEqualityToLeqs(TNode atom, OrderedSet* leqSet)
-{
+void ArithUnatePropagator::addImplicationsUsingEqualityAndLeqList(TNode atom, OrderedSet& leqSet){
+
Assert(atom.getKind() == EQUAL);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- OrderedSet::iterator leqIter = leqSet->lower_bound(atom);
- if(leqIter != leqSet->end()){
+ OrderedSet::iterator leqIter = leqSet.lower_bound(atom);
+ if(leqIter != leqSet.end()){
TNode lowerBound = *leqIter;
if(rightHandRationalIsEqual(atom, lowerBound)){
addImplication(atom, lowerBound); // x=b /\ b = b' => x <= b'
- if(leqIter != leqSet->begin()){
+ if(leqIter != leqSet.begin()){
--leqIter;
Assert(rightHandRationalIsLT(*leqIter, atom));
addImplication(*leqIter, negation); // x=b /\ b > b' => x > b'
Assert(rightHandRationalIsLT(atom, lowerBound));
addImplication(atom, lowerBound);// x=b /\ b < b' => x <= b'
- if(leqIter != leqSet->begin()){
+ if(leqIter != leqSet.begin()){
--leqIter;
Assert(rightHandRationalIsLT(*leqIter, atom));
addImplication(*leqIter, negation);// x=b /\ b > b' => x > b'
}
}
- }else if(leqIter != leqSet->begin()){
+ }else if(leqIter != leqSet.begin()){
--leqIter;
TNode strictlyLessThan = *leqIter;
Assert(rightHandRationalIsLT(strictlyLessThan, atom));
addImplication(*leqIter, negation); // x=b /\ b < b' => x <= b'
}else{
- Assert(leqSet->empty());
+ Assert(leqSet.empty());
}
}
-void ArithUnatePropagator::addEqualityToGeqs(TNode atom, OrderedSet* geqSet){
+void ArithUnatePropagator::addImplicationsUsingEqualityAndGeqList(TNode atom, OrderedSet& geqSet){
Assert(atom.getKind() == EQUAL);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- OrderedSet::iterator geqIter = geqSet->lower_bound(atom);
- if(geqIter != geqSet->end()){
+ OrderedSet::iterator geqIter = geqSet.lower_bound(atom);
+ if(geqIter != geqSet.end()){
TNode lowerBound = *geqIter;
if(rightHandRationalIsEqual(atom, lowerBound)){
addImplication(atom, lowerBound); // x=b /\ b = b' => x >= b'
++geqIter;
- if(geqIter != geqSet->end()){ // x=b /\ b < b' => x < b'
+ if(geqIter != geqSet.end()){ // x=b /\ b < b' => x < b'
TNode strictlyGt = *geqIter;
Assert(rightHandRationalIsLT( atom, strictlyGt ));
addImplication(strictlyGt, negation);
}else{
Assert(rightHandRationalIsLT(atom, lowerBound));
addImplication(lowerBound, negation);// x=b /\ b < b' => x < b'
- if(geqIter != geqSet->begin()){
+ if(geqIter != geqSet.begin()){
--geqIter;
TNode strictlyLessThan = *geqIter;
Assert(rightHandRationalIsLT(strictlyLessThan, atom));
addImplication(atom, strictlyLessThan);// x=b /\ b > b' => x >= b'
}
}
- }else if(geqIter != geqSet->begin()){
+ }else if(geqIter != geqSet.begin()){
--geqIter;
TNode strictlyLT = *geqIter;
Assert(rightHandRationalIsLT(strictlyLT, atom));
addImplication(atom, strictlyLT);// x=b /\ b > b' => x >= b'
}else{
- Assert(geqSet->empty());
+ Assert(geqSet.empty());
}
}
-void ArithUnatePropagator::addLeqToLeqs
-(TNode atom,
- OrderedSet* leqSet,
- OrderedSet::iterator atomPos)
+void ArithUnatePropagator::addImplicationsUsingLeqAndLeqList(TNode atom, OrderedSet& leqSet)
{
Assert(atom.getKind() == LEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- if(atomPos != leqSet->begin()){
+ OrderedSet::iterator atomPos = leqSet.find(atom);
+ Assert(atomPos != leqSet.end());
+ Assert(*atomPos == atom);
+
+ if(atomPos != leqSet.begin()){
--atomPos;
TNode beforeLeq = *atomPos;
Assert(rightHandRationalIsLT(beforeLeq, atom));
++atomPos;
}
++atomPos;
- if(atomPos != leqSet->end()){
+ if(atomPos != leqSet.end()){
TNode afterLeq = *atomPos;
Assert(rightHandRationalIsLT(atom, afterLeq));
addImplication(atom, afterLeq);// x<=b /\ b < b' => x <= b'
}
}
-void ArithUnatePropagator::addLeqToGeqs(TNode atom, OrderedSet* geqSet) {
+void ArithUnatePropagator::addImplicationsUsingLeqAndGeqList(TNode atom, OrderedSet& geqSet) {
Assert(atom.getKind() == LEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- OrderedSet::iterator geqIter = geqSet->lower_bound(atom);
- if(geqIter != geqSet->end()){
+ OrderedSet::iterator geqIter = geqSet.lower_bound(atom);
+ if(geqIter != geqSet.end()){
TNode lowerBound = *geqIter;
if(rightHandRationalIsEqual(atom, lowerBound)){
Assert(rightHandRationalIsEqual(atom, lowerBound));
addImplication(negation, lowerBound);// (x > b) => (x >= b)
++geqIter;
- if(geqIter != geqSet->end()){
+ if(geqIter != geqSet.end()){
TNode next = *geqIter;
Assert(rightHandRationalIsLT(atom, next));
addImplication(next, negation);// x>=b' /\ b' > b => x > b
}else{
Assert(rightHandRationalIsLT(atom, lowerBound));
addImplication(lowerBound, negation);// x>=b' /\ b' > b => x > b
- if(geqIter != geqSet->begin()){
+ if(geqIter != geqSet.begin()){
--geqIter;
TNode prev = *geqIter;
Assert(rightHandRationalIsLT(prev, atom));
addImplication(negation, prev);// (x>b /\ b > b') => x >= b'
}
}
- }else if(geqIter != geqSet->begin()){
+ }else if(geqIter != geqSet.begin()){
--geqIter;
TNode strictlyLT = *geqIter;
Assert(rightHandRationalIsLT(strictlyLT, atom));
addImplication(negation, strictlyLT);// (x>b /\ b > b') => x >= b'
}else{
- Assert(geqSet->empty());
+ Assert(geqSet.empty());
}
}
-void ArithUnatePropagator::addLeqToEqualities(TNode atom, OrderedSet* eqSet) {
+void ArithUnatePropagator::addImplicationsUsingLeqAndEqualityList(TNode atom, OrderedSet& eqSet) {
Assert(atom.getKind() == LEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
//TODO Improve this later
- for(OrderedSet::iterator eqIter = eqSet->begin(); eqIter != eqSet->end(); ++eqIter){
+ for(OrderedSet::iterator eqIter = eqSet.begin(); eqIter != eqSet.end(); ++eqIter){
TNode eq = *eqIter;
if(rightHandRationalIsEqual(atom, eq)){
// (x = b' /\ b = b') => x <= b
}
-void ArithUnatePropagator::addGeqToGeqs
-(TNode atom, OrderedSet* geqSet, OrderedSet::iterator atomPos)
-{
+void ArithUnatePropagator::addImplicationsUsingGeqAndGeqList(TNode atom, OrderedSet& geqSet){
Assert(atom.getKind() == GEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- if(atomPos != geqSet->begin()){
+ OrderedSet::iterator atomPos = geqSet.find(atom);
+ Assert(atomPos != geqSet.end());
+ Assert(*atomPos == atom);
+
+ if(atomPos != geqSet.begin()){
--atomPos;
TNode beforeGeq = *atomPos;
Assert(rightHandRationalIsLT(beforeGeq, atom));
++atomPos;
}
++atomPos;
- if(atomPos != geqSet->end()){
+ if(atomPos != geqSet.end()){
TNode afterGeq = *atomPos;
Assert(rightHandRationalIsLT(atom, afterGeq));
addImplication(afterGeq, atom);// x>=b' /\ b' > b => x >= b
}
}
-void ArithUnatePropagator::addGeqToLeqs(TNode atom, OrderedSet* leqSet){
+void ArithUnatePropagator::addImplicationsUsingGeqAndLeqList(TNode atom, OrderedSet& leqSet){
Assert(atom.getKind() == GEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- OrderedSet::iterator leqIter = leqSet->lower_bound(atom);
- if(leqIter != leqSet->end()){
+ OrderedSet::iterator leqIter = leqSet.lower_bound(atom);
+ if(leqIter != leqSet.end()){
TNode lowerBound = *leqIter;
if(rightHandRationalIsEqual(atom, lowerBound)){
Assert(rightHandRationalIsEqual(atom, lowerBound));
addImplication(negation, lowerBound);// (x < b) => (x <= b)
- if(leqIter != leqSet->begin()){
+ if(leqIter != leqSet.begin()){
--leqIter;
TNode prev = *leqIter;
Assert(rightHandRationalIsLT(prev, atom));
Assert(rightHandRationalIsLT(atom, lowerBound));
addImplication(negation, lowerBound);// (x < b /\ b < b') => x <= b'
++leqIter;
- if(leqIter != leqSet->end()){
+ if(leqIter != leqSet.end()){
TNode next = *leqIter;
Assert(rightHandRationalIsLT(atom, next));
addImplication(negation, next);// (x < b /\ b < b') => x <= b'
}
}
- }else if(leqIter != leqSet->begin()){
+ }else if(leqIter != leqSet.begin()){
--leqIter;
TNode strictlyLT = *leqIter;
Assert(rightHandRationalIsLT(strictlyLT, atom));
addImplication(strictlyLT, negation);// (x <= b' /\ b' < b) => x < b
}else{
- Assert(leqSet->empty());
+ Assert(leqSet.empty());
}
}
-void ArithUnatePropagator::addGeqToEqualities(TNode atom, OrderedSet* eqSet){
+void ArithUnatePropagator::addImplicationsUsingGeqAndEqualityList(TNode atom, OrderedSet& eqSet){
Assert(atom.getKind() == GEQ);
Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
//TODO Improve this later
- for(OrderedSet::iterator eqIter = eqSet->begin(); eqIter != eqSet->end(); ++eqIter){
+ for(OrderedSet::iterator eqIter = eqSet.begin(); eqIter != eqSet.end(); ++eqIter){
TNode eq = *eqIter;
if(rightHandRationalIsEqual(atom, eq)){
// (x = b' /\ b = b') => x >= b
#define __CVC4__THEORY__ARITH__ARITH_PROPAGATOR_H
#include "expr/node.h"
-#include "context/cdlist.h"
#include "context/context.h"
-#include "context/cdo.h"
#include "theory/output_channel.h"
#include "theory/arith/ordered_set.h"
+#include <ext/hash_map>
+
namespace CVC4 {
namespace theory {
namespace arith {
*/
OutputChannel& d_arithOut;
+ struct OrderedSetTriple {
+ OrderedSet d_leqSet;
+ OrderedSet d_eqSet;
+ OrderedSet d_geqSet;
+ };
+
+ /** TODO: justify making this a TNode. */
+ typedef __gnu_cxx::hash_map<Node, OrderedSetTriple, NodeHashFunction> NodeToOrderedSetMap;
+ NodeToOrderedSetMap d_orderedListMap;
+
public:
ArithUnatePropagator(context::Context* cxt, OutputChannel& arith);
bool hasAnyAtoms(TNode v);
private:
+ OrderedSetTriple& getOrderedSetTriple(TNode left);
+ OrderedSet& getEqSet(TNode left);
+ OrderedSet& getLeqSet(TNode left);
+ OrderedSet& getGeqSet(TNode left);
+
+
/** Sends an implication (=> a b) to the PropEngine via d_arithOut. */
void addImplication(TNode a, TNode b);
/**
- * The addKtoJs(...) functions are the work horses of ArithUnatePropagator.
+ * The addImplicationsUsingKAndJList(...)
+ * functions are the work horses of ArithUnatePropagator.
* These take an atom of the kind K that has just been added
- * to its associated list, and the list of Js associated with the lhs,
+ * to its associated list, and the ordered list of Js associated with the lhs,
* and uses these to deduce unate implications.
* (K and J vary over EQUAL, LEQ, and GEQ.)
*
* Input:
- * atom - the atom being inserted
- * Kset - the list of atoms of kind K associated with the lhs.
- * atomPos - the atoms Position in its own list after being inserted.
+ * atom - the atom being inserted of kind K
+ * Jset - the list of atoms of kind J associated with the lhs.
*
* Unfortunately, these tend to be an absolute bear to read because
* of all of the special casing and C++ iterator manipulation required.
*/
- void addEqualityToEqualities(TNode eq, OrderedSet* eqSet, OrderedSet::iterator eqPos);
- void addEqualityToLeqs(TNode eq, OrderedSet* leqSet);
- void addEqualityToGeqs(TNode eq, OrderedSet* geqSet);
+ void addImplicationsUsingEqualityAndEqualityList(TNode eq, OrderedSet& eqSet);
+ void addImplicationsUsingEqualityAndLeqList(TNode eq, OrderedSet& leqSet);
+ void addImplicationsUsingEqualityAndGeqList(TNode eq, OrderedSet& geqSet);
- void addLeqToLeqs(TNode leq, OrderedSet* leqSet, OrderedSet::iterator leqPos);
- void addLeqToGeqs(TNode leq, OrderedSet* geqSet);
- void addLeqToEqualities(TNode leq, OrderedSet* eqSet);
+ void addImplicationsUsingLeqAndEqualityList(TNode leq, OrderedSet& eqSet);
+ void addImplicationsUsingLeqAndLeqList(TNode leq, OrderedSet& leqSet);
+ void addImplicationsUsingLeqAndGeqList(TNode leq, OrderedSet& geqSet);
- void addGeqToGeqs(TNode geq, OrderedSet* geqSet, OrderedSet::iterator geqPos);
- void addGeqToLeqs(TNode geq, OrderedSet* leqSet);
- void addGeqToEqualities(TNode geq, OrderedSet* eqSet);
+ void addImplicationsUsingGeqAndEqualityList(TNode geq, OrderedSet& eqSet);
+ void addImplicationsUsingGeqAndLeqList(TNode geq, OrderedSet& leqSet);
+ void addImplicationsUsingGeqAndGeqList(TNode geq, OrderedSet& geqSet);
};