1 #include "satencoder.h"
8 #include "tableentry.h"
12 Edge encodeEnumTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
13 VectorTableEntry* entries = &(((PredicateTable*)constraint->predicate)->table->entries);
14 FunctionEncodingType encType = constraint->encoding.type;
15 ArrayElement* inputs = &constraint->inputs;
16 uint inputNum =getSizeArrayElement(inputs);
17 //Encode all the inputs first ...
18 for(uint i=0; i<inputNum; i++){
19 encodeElementSATEncoder(This, getArrayElement(inputs, i));
22 //WARNING: THIS ASSUMES PREDICATE TABLE IS COMPLETE...SEEMS UNLIKELY TO BE SAFE IN MANY CASES...
23 //WONDER WHAT BEST WAY TO HANDLE THIS IS...
25 uint size = getSizeVectorTableEntry(entries);
26 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
27 Edge constraints[size];
28 for(uint i=0; i<size; i++){
29 TableEntry* entry = getVectorTableEntry(entries, i);
30 if(generateNegation == entry->output) {
31 //Skip the irrelevant entries
34 Edge carray[inputNum];
35 for(uint j=0; j<inputNum; j++){
36 Element* el = getArrayElement(inputs, j);
37 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
39 constraints[i]=constraintAND(This->cnf, inputNum, carray);
41 Edge result=constraintOR(This->cnf, size, constraints);
43 return generateNegation ? result: constraintNegate(result);
46 Edge encodeOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
47 switch(constraint->encoding.type){
48 case ENUMERATEIMPLICATIONS:
49 return encodeEnumOperatorPredicateSATEncoder(This, constraint);
59 Edge encodeEnumOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
60 PredicateOperator* predicate = (PredicateOperator*)constraint->predicate;
61 uint numDomains=getSizeArraySet(&predicate->domains);
63 FunctionEncodingType encType = constraint->encoding.type;
64 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
66 /* Call base encoders for children */
67 for(uint i=0;i<numDomains;i++) {
68 Element *elem = getArrayElement( &constraint->inputs, i);
69 encodeElementSATEncoder(This, elem);
71 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
73 uint indices[numDomains]; //setup indices
74 bzero(indices, sizeof(uint)*numDomains);
76 uint64_t vals[numDomains]; //setup value array
77 for(uint i=0;i<numDomains; i++) {
78 Set * set=getArraySet(&predicate->domains, i);
79 vals[i]=getSetElement(set, indices[i]);
82 bool notfinished=true;
84 Edge carray[numDomains];
86 if (evalPredicateOperator(predicate, vals) ^ generateNegation) {
87 //Include this in the set of terms
88 for(uint i=0;i<numDomains;i++) {
89 Element * elem = getArrayElement(&constraint->inputs, i);
90 carray[i] = getElementValueConstraint(This, elem, vals[i]);
92 pushVectorEdge(clauses, constraintAND(This->cnf, numDomains, carray));
96 for(uint i=0;i<numDomains; i++) {
97 uint index=++indices[i];
98 Set * set=getArraySet(&predicate->domains, i);
100 if (index < getSetSize(set)) {
101 vals[i]=getSetElement(set, index);
106 vals[i]=getSetElement(set, 0);
111 Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
112 deleteVectorEdge(clauses);
113 return generateNegation ? cor : constraintNegate(cor);
117 Edge encodeOperatorElementFunctionSATEncoder(SATEncoder* This, ElementFunction* func) {
118 FunctionOperator * function = (FunctionOperator *) func->function;
119 uint numDomains=getSizeArrayElement(&func->inputs);
121 /* Call base encoders for children */
122 for(uint i=0;i<numDomains;i++) {
123 Element *elem = getArrayElement( &func->inputs, i);
124 encodeElementSATEncoder(This, elem);
127 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
129 uint indices[numDomains]; //setup indices
130 bzero(indices, sizeof(uint)*numDomains);
132 uint64_t vals[numDomains]; //setup value array
133 for(uint i=0;i<numDomains; i++) {
134 Set * set=getElementSet(getArrayElement(&func->inputs, i));
135 vals[i]=getSetElement(set, indices[i]);
138 Edge overFlowConstraint = ((BooleanVar*) func->overflowstatus)->var;
140 bool notfinished=true;
142 Edge carray[numDomains+2];
144 uint64_t result=applyFunctionOperator(function, numDomains, vals);
145 bool isInRange = isInRangeFunction((FunctionOperator*)func->function, result);
146 bool needClause = isInRange;
147 if (function->overflowbehavior == OVERFLOWSETSFLAG || function->overflowbehavior == FLAGIFFOVERFLOW) {
152 //Include this in the set of terms
153 for(uint i=0;i<numDomains;i++) {
154 Element * elem = getArrayElement(&func->inputs, i);
155 carray[i] = getElementValueConstraint(This, elem, vals[i]);
158 carray[numDomains] = getElementValueConstraint(This, &func->base, result);
162 switch(function->overflowbehavior) {
166 clause=constraintAND(This->cnf, numDomains+1, carray);
169 case FLAGFORCESOVERFLOW: {
170 carray[numDomains+1]=constraintNegate(overFlowConstraint);
171 clause=constraintAND(This->cnf, numDomains+2, carray);
174 case OVERFLOWSETSFLAG: {
176 clause=constraintAND(This->cnf, numDomains+1, carray);
178 carray[numDomains+1]=overFlowConstraint;
179 clause=constraintAND(This->cnf, numDomains+1, carray);
183 case FLAGIFFOVERFLOW: {
185 carray[numDomains+1]=constraintNegate(overFlowConstraint);
186 clause=constraintAND(This->cnf, numDomains+2, carray);
188 carray[numDomains+1]=overFlowConstraint;
189 clause=constraintAND(This->cnf, numDomains+1, carray);
196 pushVectorEdge(clauses, clause);
200 for(uint i=0;i<numDomains; i++) {
201 uint index=++indices[i];
202 Set * set=getElementSet(getArrayElement(&func->inputs, i));
204 if (index < getSetSize(set)) {
205 vals[i]=getSetElement(set, index);
210 vals[i]=getSetElement(set, 0);
215 Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
216 deleteVectorEdge(clauses);
220 Edge encodeEnumTableElemFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
221 //FIXME: HANDLE UNDEFINED BEHAVIORS
222 ASSERT(GETFUNCTIONTYPE(This->function)==TABLEFUNC);
223 ArrayElement* elements= &This->inputs;
224 Table* table = ((FunctionTable*) (This->function))->table;
225 uint size = getSizeVectorTableEntry(&table->entries);
226 Edge constraints[size]; //FIXME: should add a space for the case that didn't match any entries
227 for(uint i=0; i<size; i++) {
228 TableEntry* entry = getVectorTableEntry(&table->entries, i);
229 uint inputNum = getSizeArrayElement(elements);
230 Edge carray[inputNum];
231 for(uint j=0; j<inputNum; j++){
232 Element* el= getArrayElement(elements, j);
233 carray[j] = getElementValueConstraint(encoder, el, entry->inputs[j]);
235 Edge output = getElementValueConstraint(encoder, (Element*)This, entry->output);
236 Edge row= constraintIMPLIES(encoder->cnf, constraintAND(encoder->cnf, inputNum, carray), output);
239 return constraintOR(encoder->cnf, size, constraints);