return &This->base;
}
-// BRIAN: REVISIT
-void getEqualitySetIntersection(PredicateOperator* This, uint* size, uint64_t* result){
- ASSERT( This->op == EQUALS);
- //make sure equality has 2 operands
- ASSERT(getSizeArraySet( &This->domains) == 2);
- *size=0;
- VectorInt* mems1 = getArraySet(&This->domains, 0)->members;
- uint size1 = getSizeVectorInt(mems1);
- VectorInt* mems2 = getArraySet(&This->domains, 1)->members;
- uint size2 = getSizeVectorInt(mems2);
- //FIXME:This isn't efficient, if we a hashset datastructure for Set, we
- // can reduce it to O(n), but for now .... HG
- for(uint i=0; i<size1; i++){
- uint64_t tmp= getVectorInt(mems1, i);
- for(uint j=0; j<size2; j++){
- if(tmp == getVectorInt(mems2, j)){
- result[(*size)++]=tmp;
- break;
- }
- }
- }
-}
-
void deletePredicate(Predicate* This){
switch(GETPREDICATETYPE(This)) {
case OPERATORPRED: {
ourfree(This);
}
+bool evalPredicateOperator(PredicateOperator * This, uint64_t * inputs) {
+ switch(This->op) {
+ case EQUALS:
+ return inputs[0]==inputs[1];
+ case LT:
+ return inputs[0]<inputs[1];
+ case GT:
+ return inputs[0]>inputs[1];
+ case LTE:
+ return inputs[0]<=inputs[1];
+ case GTE:
+ return inputs[0]>=inputs[1];
+ }
+ ASSERT(0);
+ return false;
+}
bool existsInSet(Set* This, uint64_t element){
if(This->isRange){
return element >= This->low && element <= This->high;
- }else {
+ } else {
uint size = getSizeVectorInt(This->members);
for(uint i=0; i< size; i++){
if(element == getVectorInt(This->members, i))
}
}
+uint64_t getSetElement(Set * This, uint index) {
+ if (This->isRange)
+ return This->low+index;
+ else
+ return getVectorInt(This->members, index);
+}
+
uint getSetSize(Set* This){
if(This->isRange){
- return This->high- This->low+1;
+ return This->high - This->low+1;
}else{
return getSizeVectorInt(This->members);
}
return generateNegation ? result: constraintNegate(result);
}
-Edge encodeOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
+Edge encodeOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
switch(constraint->encoding.type){
case ENUMERATEIMPLICATIONS:
return encodeEnumOperatorPredicateSATEncoder(This, constraint);
}
Edge encodeEnumOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
- ASSERT(GETPREDICATETYPE(constraint->predicate)==OPERATORPRED);
PredicateOperator* predicate = (PredicateOperator*)constraint->predicate;
- ASSERT(predicate->op == EQUALS); //For now, we just only support equals
- //getting maximum size of in common elements between two sets!
- uint size=getSizeVectorInt( getArraySet( &predicate->domains, 0)->members);
- uint64_t commonElements [size];
- getEqualitySetIntersection(predicate, &size, commonElements);
- Edge carray[size];
- Element* elem1 = getArrayElement( &constraint->inputs, 0);
- Element* elem2 = getArrayElement( &constraint->inputs, 1);
- encodeElementSATEncoder(This,elem1);
- encodeElementSATEncoder(This, elem2);
+ uint numDomains=getSizeArraySet(&predicate->domains);
+
+ FunctionEncodingType encType = constraint->encoding.type;
+ bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
+
+ /* Call base encoders for children */
+ for(uint i=0;i<numDomains;i++) {
+ Element *elem = getArrayElement( &constraint->inputs, i);
+ encodeElementSATEncoder(This, elem);
+ }
+ VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
- for(uint i=0; i<size; i++){
- Edge arg1 = getElementValueConstraint(This, elem1, commonElements[i]);
- Edge arg2 = getElementValueConstraint(This, elem2, commonElements[i]);
- carray[i] = constraintAND2(This->cnf, arg1, arg2);
+ uint indices[numDomains]; //setup indices
+ bzero(indices, sizeof(uint)*numDomains);
+
+ uint64_t vals[numDomains]; //setup value array
+ for(uint i=0;i<numDomains; i++) {
+ Set * set=getArraySet(&predicate->domains, i);
+ vals[i]=getSetElement(set, indices[i]);
+ }
+
+ bool notfinished=true;
+ while(notfinished) {
+ Edge carray[numDomains];
+
+ if (evalPredicateOperator(predicate, vals) ^ generateNegation) {
+ //Include this in the set of terms
+ for(uint i=0;i<numDomains;i++) {
+ Element * elem = getArrayElement(&constraint->inputs, i);
+ carray[i] = getElementValueConstraint(This, elem, vals[i]);
+ }
+ pushVectorEdge(clauses, constraintAND(This->cnf, numDomains, carray));
+ }
+
+ notfinished=false;
+ for(uint i=0;i<numDomains; i++) {
+ uint index=++indices[i];
+ Set * set=getArraySet(&predicate->domains, i);
+
+ if (index < getSetSize(set)) {
+ vals[i]=getSetElement(set, index);
+ notfinished=true;
+ break;
+ } else {
+ indices[i]=0;
+ vals[i]=getSetElement(set, 0);
+ }
+ }
}
- //FIXME: the case when there is no intersection ....
- return constraintOR(This->cnf, size, carray);
+
+ Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
+ deleteVectorEdge(clauses);
+ return generateNegation ? cor : constraintNegate(cor);
}
void encodeElementSATEncoder(SATEncoder* encoder, Element *This){