1 #include "satencoder.h"
8 #include "tableentry.h"
13 Edge encodeEnumEntriesTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
14 ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
15 UndefinedBehavior undefStatus = ((PredicateTable*)constraint->predicate)->undefinedbehavior;
16 ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
17 Table* table = ((PredicateTable*)constraint->predicate)->table;
18 FunctionEncodingType encType = constraint->encoding.type;
19 ArrayElement* inputs = &constraint->inputs;
20 uint inputNum =getSizeArrayElement(inputs);
21 uint size = getSizeHashSetTableEntry(table->entries);
22 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
23 Edge constraints[size];
24 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
26 while(hasNextTableEntry(iterator)){
27 TableEntry* entry = nextTableEntry(iterator);
28 if(generateNegation == entry->output) {
29 //Skip the irrelevant entries
32 Edge carray[inputNum];
33 for(uint j=0; j<inputNum; j++){
34 Element* el = getArrayElement(inputs, j);
35 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
40 row=constraintAND(This->cnf, inputNum, carray);
42 case FLAGFORCEUNDEFINED:{
43 Edge undefConst = encodeConstraintSATEncoder(This, constraint->undefStatus);
44 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintNegate(undefConst));
50 constraints[i++] = row;
53 Edge result=constraintOR(This->cnf, size, constraints);
55 return generateNegation ? constraintNegate(result) : result;
57 Edge encodeEnumTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
59 model_print("Enumeration Table Predicate ...\n");
61 ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
62 //First encode children
63 ArrayElement* inputs = &constraint->inputs;
64 uint inputNum =getSizeArrayElement(inputs);
65 //Encode all the inputs first ...
66 for(uint i=0; i<inputNum; i++){
67 encodeElementSATEncoder(This, getArrayElement(inputs, i));
69 PredicateTable* predicate = (PredicateTable*)constraint->predicate;
70 switch(predicate->undefinedbehavior){
72 case FLAGFORCEUNDEFINED:
73 return encodeEnumEntriesTablePredicateSATEncoder(This, constraint);
77 bool generateNegation = constraint->encoding.type == ENUMERATEIMPLICATIONSNEGATE;
78 uint numDomains=getSizeArraySet(&predicate->table->domains);
80 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
82 uint indices[numDomains]; //setup indices
83 bzero(indices, sizeof(uint)*numDomains);
85 uint64_t vals[numDomains]; //setup value array
86 for(uint i=0;i<numDomains; i++) {
87 Set * set=getArraySet(&predicate->table->domains, i);
88 vals[i]=getSetElement(set, indices[i]);
91 Edge undefConstraint = encodeConstraintSATEncoder (This, constraint->undefStatus);
93 bool notfinished=true;
95 Edge carray[numDomains];
96 TableEntry* tableEntry = getTableEntryFromTable(predicate->table, vals, numDomains);
97 bool isInRange = tableEntry!=NULL;
98 bool ignoreEntry = generateNegation == tableEntry->output;
99 ASSERT(predicate->undefinedbehavior == UNDEFINEDSETSFLAG || predicate->undefinedbehavior == FLAGIFFUNDEFINED);
100 //Include this in the set of terms
101 for(uint i=0;i<numDomains;i++) {
102 Element * elem = getArrayElement(&constraint->inputs, i);
103 carray[i] = getElementValueConstraint(This, elem, vals[i]);
107 switch(predicate->undefinedbehavior) {
108 case UNDEFINEDSETSFLAG: {
109 if (isInRange && !ignoreEntry) {
110 clause=constraintAND(This->cnf, numDomains, carray);
111 } else if(!isInRange) {
112 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
116 case FLAGIFFUNDEFINED: {
117 if (isInRange && !ignoreEntry) {
118 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(undefConstraint)));
119 } else if(!isInRange) {
120 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
128 model_print("added clause in predicate table enumeration ...\n");
132 pushVectorEdge(clauses, clause);
136 for(uint i=0;i<numDomains; i++) {
137 uint index=++indices[i];
138 Set * set=getArraySet(&predicate->table->domains, i);
140 if (index < getSetSize(set)) {
141 vals[i]=getSetElement(set, index);
146 vals[i]=getSetElement(set, 0);
151 Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
152 deleteVectorEdge(clauses);
153 return generateNegation ? constraintNegate(cor) : cor;
156 void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder* This, ElementFunction* func){
157 UndefinedBehavior undefStatus = ((FunctionTable*) func->function)->undefBehavior;
158 ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
159 ArrayElement* elements= &func->inputs;
160 Table* table = ((FunctionTable*) (func->function))->table;
161 uint size = getSizeHashSetTableEntry(table->entries);
162 Edge constraints[size];
163 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
165 while(hasNextTableEntry(iterator)) {
166 TableEntry* entry = nextTableEntry(iterator);
168 uint inputNum = getSizeArrayElement(elements);
169 Edge carray[inputNum];
170 for(uint j=0; j<inputNum; j++){
171 Element* el= getArrayElement(elements, j);
172 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
174 Edge output = getElementValueConstraint(This, (Element*)func, entry->output);
176 switch(undefStatus ){
177 case IGNOREBEHAVIOR: {
178 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
181 case FLAGFORCEUNDEFINED: {
182 Edge undefConst = encodeConstraintSATEncoder(This, func->overflowstatus);
183 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
190 constraints[i++]=row;
192 deleteIterTableEntry(iterator);
193 addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
196 void encodeEnumTableElemFunctionSATEncoder(SATEncoder* This, ElementFunction* elemFunc){
198 model_print("Enumeration Table functions ...\n");
200 ASSERT(GETFUNCTIONTYPE(elemFunc->function)==TABLEFUNC);
201 //First encode children
202 ArrayElement* elements= &elemFunc->inputs;
203 for(uint i=0; i<getSizeArrayElement(elements); i++){
204 Element *elem = getArrayElement( elements, i);
205 encodeElementSATEncoder(This, elem);
208 FunctionTable* function =(FunctionTable*)elemFunc->function;
209 switch(function->undefBehavior){
211 case FLAGFORCEUNDEFINED:
212 return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
217 uint numDomains=getSizeArraySet(&function->table->domains);
219 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
221 uint indices[numDomains]; //setup indices
222 bzero(indices, sizeof(uint)*numDomains);
224 uint64_t vals[numDomains]; //setup value array
225 for(uint i=0;i<numDomains; i++) {
226 Set * set=getArraySet(&function->table->domains, i);
227 vals[i]=getSetElement(set, indices[i]);
230 Edge undefConstraint = encodeConstraintSATEncoder(This, elemFunc->overflowstatus);
231 bool notfinished=true;
233 Edge carray[numDomains+1];
234 TableEntry* tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
235 bool isInRange = tableEntry!=NULL;
236 ASSERT(function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED);
237 //Include this in the set of terms
238 for(uint i=0;i<numDomains;i++) {
239 Element * elem = getArrayElement(&elemFunc->inputs, i);
240 carray[i] = getElementValueConstraint(This, elem, vals[i]);
243 carray[numDomains] = getElementValueConstraint(This, (Element*)elemFunc, tableEntry->output);
247 switch(function->undefBehavior) {
248 case UNDEFINEDSETSFLAG: {
250 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
252 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
256 case FLAGIFFUNDEFINED: {
258 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(undefConstraint)));
260 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
268 model_print("added clause in function table enumeration ...\n");
272 pushVectorEdge(clauses, clause);
276 for(uint i=0;i<numDomains; i++) {
277 uint index=++indices[i];
278 Set * set=getArraySet(&function->table->domains, i);
280 if (index < getSetSize(set)) {
281 vals[i]=getSetElement(set, index);
286 vals[i]=getSetElement(set, 0);
291 Edge cor=constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
292 addConstraintCNF(This->cnf, cor);
293 deleteVectorEdge(clauses);