1 #include "satencoder.h"
8 #include "tableentry.h"
12 #include "satfuncopencoder.h"
14 Edge encodeOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
15 switch(constraint->encoding.type){
16 case ENUMERATEIMPLICATIONS:
17 return encodeEnumOperatorPredicateSATEncoder(This, constraint);
19 return encodeCircuitOperatorPredicateEncoder(This, constraint);
26 Edge encodeEnumOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
27 PredicateOperator* predicate = (PredicateOperator*)constraint->predicate;
28 uint numDomains=getSizeArraySet(&predicate->domains);
30 FunctionEncodingType encType = constraint->encoding.type;
31 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
33 /* Call base encoders for children */
34 for(uint i=0;i<numDomains;i++) {
35 Element *elem = getArrayElement( &constraint->inputs, i);
36 encodeElementSATEncoder(This, elem);
38 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
40 uint indices[numDomains]; //setup indices
41 bzero(indices, sizeof(uint)*numDomains);
43 uint64_t vals[numDomains]; //setup value array
44 for(uint i=0;i<numDomains; i++) {
45 Set * set=getArraySet(&predicate->domains, i);
46 vals[i]=getSetElement(set, indices[i]);
49 bool notfinished=true;
51 Edge carray[numDomains];
53 if (evalPredicateOperator(predicate, vals) ^ generateNegation) {
54 //Include this in the set of terms
55 for(uint i=0;i<numDomains;i++) {
56 Element * elem = getArrayElement(&constraint->inputs, i);
57 carray[i] = getElementValueConstraint(This, elem, vals[i]);
59 Edge term=constraintAND(This->cnf, numDomains, carray);
60 pushVectorEdge(clauses, term);
64 for(uint i=0;i<numDomains; i++) {
65 uint index=++indices[i];
66 Set * set=getArraySet(&predicate->domains, i);
68 if (index < getSetSize(set)) {
69 vals[i]=getSetElement(set, index);
74 vals[i]=getSetElement(set, 0);
78 if(getSizeVectorEdge(clauses) == 0)
80 Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
81 deleteVectorEdge(clauses);
82 return generateNegation ? constraintNegate(cor) : cor;
86 void encodeOperatorElementFunctionSATEncoder(SATEncoder* This, ElementFunction* func) {
88 model_print("Operator Function ...\n");
90 FunctionOperator * function = (FunctionOperator *) func->function;
91 uint numDomains=getSizeArrayElement(&func->inputs);
93 /* Call base encoders for children */
94 for(uint i=0;i<numDomains;i++) {
95 Element *elem = getArrayElement( &func->inputs, i);
96 encodeElementSATEncoder(This, elem);
99 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
101 uint indices[numDomains]; //setup indices
102 bzero(indices, sizeof(uint)*numDomains);
104 uint64_t vals[numDomains]; //setup value array
105 for(uint i=0;i<numDomains; i++) {
106 Set * set=getElementSet(getArrayElement(&func->inputs, i));
107 vals[i]=getSetElement(set, indices[i]);
110 Edge overFlowConstraint = ((BooleanVar*) func->overflowstatus)->var;
112 bool notfinished=true;
114 Edge carray[numDomains+1];
116 uint64_t result=applyFunctionOperator(function, numDomains, vals);
117 bool isInRange = isInRangeFunction((FunctionOperator*)func->function, result);
118 bool needClause = isInRange;
119 if (function->overflowbehavior == OVERFLOWSETSFLAG || function->overflowbehavior == FLAGIFFOVERFLOW) {
124 //Include this in the set of terms
125 for(uint i=0;i<numDomains;i++) {
126 Element * elem = getArrayElement(&func->inputs, i);
127 carray[i] = getElementValueConstraint(This, elem, vals[i]);
130 carray[numDomains] = getElementValueConstraint(This, &func->base, result);
134 switch(function->overflowbehavior) {
138 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
141 case FLAGFORCESOVERFLOW: {
142 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
145 case OVERFLOWSETSFLAG: {
147 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
149 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
153 case FLAGIFFOVERFLOW: {
155 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
157 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), overFlowConstraint);
165 model_print("added clause in operator function\n");
169 pushVectorEdge(clauses, clause);
173 for(uint i=0;i<numDomains; i++) {
174 uint index=++indices[i];
175 Set * set=getElementSet(getArrayElement(&func->inputs, i));
177 if (index < getSetSize(set)) {
178 vals[i]=getSetElement(set, index);
183 vals[i]=getSetElement(set, 0);
188 Edge cor=constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
189 addConstraintCNF(This->cnf, cor);
190 deleteVectorEdge(clauses);
193 Edge encodeCircuitOperatorPredicateEncoder(SATEncoder *This, BooleanPredicate * constraint) {
194 PredicateOperator * predicate = (PredicateOperator*) constraint->predicate;
196 switch(predicate->op) {
198 return encodeCircuitEquals(This, constraint);
206 Edge encodeCircuitEquals(SATEncoder * This, BooleanPredicate * constraint) {
207 PredicateOperator * predicate = (PredicateOperator*) constraint->predicate;
208 ASSERT(getSizeArraySet(&predicate->domains) == 2);
209 Element *elem0 = getArrayElement( &constraint->inputs, 0);
210 Element *elem1 = getArrayElement( &constraint->inputs, 1);
211 ElementEncoding *ee0=getElementEncoding(elem0);
212 ElementEncoding *ee1=getElementEncoding(elem1);
213 ASSERT(ee0->numVars==ee1->numVars);
214 uint numVars=ee0->numVars;
215 Edge carray[numVars];
216 for (uint i=0; i<numVars; i++) {
217 carray[i]=constraintIFF(This->cnf, ee0->variables[i], ee1->variables[i]);
219 return constraintAND(This->cnf, numVars, carray);