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 VectorEdge * undefClauses=allocDefVectorEdge();
25 Edge undefConst = encodeConstraintSATEncoder(This, constraint->undefStatus);
28 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
30 while(hasNextTableEntry(iterator)){
31 TableEntry* entry = nextTableEntry(iterator);
32 if(generateNegation == entry->output) {
33 //Skip the irrelevant entries
36 Edge carray[inputNum];
37 for(uint j=0; j<inputNum; j++){
38 Element* el = getArrayElement(inputs, j);
39 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
46 row=constraintAND(This->cnf, inputNum, carray);
48 case FLAGFORCEUNDEFINED:{
49 row=constraintAND(This->cnf, inputNum, carray);
50 pushVectorEdge(undefClauses, constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintNegate(undefConst)));
56 constraints[i++] = row;
61 Edge result= generateNegation?constraintNegate(constraintOR(This->cnf, i, constraints))
62 :constraintOR(This->cnf, i, constraints);
64 if(getSizeVectorEdge(undefClauses) != 0)
65 tmp= constraintAND(This->cnf, getSizeVectorEdge(undefClauses), exposeArrayEdge(undefClauses));
66 deleteVectorEdge(undefClauses);
68 return edgeIsNull(tmp)? result: constraintAND2(This->cnf, tmp, result);
70 Edge encodeEnumTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
72 model_print("Enumeration Table Predicate ...\n");
74 ASSERT(GETPREDICATETYPE(constraint->predicate) == TABLEPRED);
75 //First encode children
76 ArrayElement* inputs = &constraint->inputs;
77 uint inputNum =getSizeArrayElement(inputs);
78 //Encode all the inputs first ...
79 for(uint i=0; i<inputNum; i++){
80 encodeElementSATEncoder(This, getArrayElement(inputs, i));
82 PredicateTable* predicate = (PredicateTable*)constraint->predicate;
83 switch(predicate->undefinedbehavior){
85 case FLAGFORCEUNDEFINED:
86 return encodeEnumEntriesTablePredicateSATEncoder(This, constraint);
90 bool generateNegation = constraint->encoding.type == ENUMERATEIMPLICATIONSNEGATE;
91 uint numDomains=getSizeArraySet(&predicate->table->domains);
93 VectorEdge * clauses=allocDefVectorEdge();
94 VectorEdge * undefClauses=allocDefVectorEdge();
96 uint indices[numDomains]; //setup indices
97 bzero(indices, sizeof(uint)*numDomains);
99 uint64_t vals[numDomains]; //setup value array
100 for(uint i=0;i<numDomains; i++) {
101 Set * set=getArraySet(&predicate->table->domains, i);
102 vals[i]=getSetElement(set, indices[i]);
105 Edge undefConstraint = encodeConstraintSATEncoder (This, constraint->undefStatus);
106 printCNF(undefConstraint);
107 bool notfinished=true;
109 Edge carray[numDomains];
110 TableEntry* tableEntry = getTableEntryFromTable(predicate->table, vals, numDomains);
111 bool isInRange = tableEntry!=NULL;
112 if(isInRange && generateNegation == tableEntry->output)
115 for(uint i=0;i<numDomains;i++) {
116 Element * elem = getArrayElement(&constraint->inputs, i);
117 carray[i] = getElementValueConstraint(This, elem, vals[i]);
120 switch(predicate->undefinedbehavior) {
121 case UNDEFINEDSETSFLAG:
123 clause=constraintAND(This->cnf, numDomains, carray);
125 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
128 case FLAGIFFUNDEFINED:
130 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintNegate(undefConstraint));
132 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
140 model_print("added clause in predicate table enumeration ...\n");
145 pushVectorEdge(clauses, clause);
147 pushVectorEdge(undefClauses, clause);
150 for(uint i=0;i<numDomains; i++) {
151 uint index=++indices[i];
152 Set * set=getArraySet(&predicate->table->domains, i);
154 if (index < getSetSize(set)) {
155 vals[i]=getSetElement(set, index);
160 vals[i]=getSetElement(set, 0);
164 Edge result = E_NULL;
165 if(getSizeVectorEdge(clauses) != 0){
166 result=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
167 if(generateNegation){
168 ASSERT(getSizeVectorEdge(undefClauses) == 0);
169 result = constraintNegate(result);
172 if(getSizeVectorEdge(undefClauses)!= 0){
173 ASSERT(!generateNegation);
174 Edge tmp = constraintAND(This->cnf, getSizeVectorEdge(undefClauses), exposeArrayEdge(undefClauses));
175 result= edgeIsNull(result)? tmp : constraintAND2(This->cnf, tmp, result);
177 deleteVectorEdge(clauses);
178 deleteVectorEdge(undefClauses);
182 void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder* This, ElementFunction* func){
183 UndefinedBehavior undefStatus = ((FunctionTable*) func->function)->undefBehavior;
184 ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
185 ArrayElement* elements= &func->inputs;
186 Table* table = ((FunctionTable*) (func->function))->table;
187 uint size = getSizeHashSetTableEntry(table->entries);
188 Edge constraints[size];
189 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
191 while(hasNextTableEntry(iterator)) {
192 TableEntry* entry = nextTableEntry(iterator);
194 uint inputNum = getSizeArrayElement(elements);
195 Edge carray[inputNum];
196 for(uint j=0; j<inputNum; j++){
197 Element* el= getArrayElement(elements, j);
198 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
200 Edge output = getElementValueConstraint(This, (Element*)func, entry->output);
202 switch(undefStatus ){
203 case IGNOREBEHAVIOR: {
204 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
207 case FLAGFORCEUNDEFINED: {
208 Edge undefConst = encodeConstraintSATEncoder(This, func->overflowstatus);
209 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
216 constraints[i++]=row;
218 deleteIterTableEntry(iterator);
219 addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
222 void encodeEnumTableElemFunctionSATEncoder(SATEncoder* This, ElementFunction* elemFunc){
224 model_print("Enumeration Table functions ...\n");
226 ASSERT(GETFUNCTIONTYPE(elemFunc->function)==TABLEFUNC);
227 //First encode children
228 ArrayElement* elements= &elemFunc->inputs;
229 for(uint i=0; i<getSizeArrayElement(elements); i++){
230 Element *elem = getArrayElement( elements, i);
231 encodeElementSATEncoder(This, elem);
234 FunctionTable* function =(FunctionTable*)elemFunc->function;
235 switch(function->undefBehavior){
237 case FLAGFORCEUNDEFINED:
238 return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
243 uint numDomains=getSizeArraySet(&function->table->domains);
245 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
247 uint indices[numDomains]; //setup indices
248 bzero(indices, sizeof(uint)*numDomains);
250 uint64_t vals[numDomains]; //setup value array
251 for(uint i=0;i<numDomains; i++) {
252 Set * set=getArraySet(&function->table->domains, i);
253 vals[i]=getSetElement(set, indices[i]);
256 Edge undefConstraint = encodeConstraintSATEncoder(This, elemFunc->overflowstatus);
257 bool notfinished=true;
259 Edge carray[numDomains+1];
260 TableEntry* tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
261 bool isInRange = tableEntry!=NULL;
262 ASSERT(function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED);
263 for(uint i=0;i<numDomains;i++) {
264 Element * elem = getArrayElement(&elemFunc->inputs, i);
265 carray[i] = getElementValueConstraint(This, elem, vals[i]);
268 carray[numDomains] = getElementValueConstraint(This, (Element*)elemFunc, tableEntry->output);
272 switch(function->undefBehavior) {
273 case UNDEFINEDSETSFLAG: {
275 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
277 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
281 case FLAGIFFUNDEFINED: {
283 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(undefConstraint)));
285 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
293 model_print("added clause in function table enumeration ...\n");
297 pushVectorEdge(clauses, clause);
301 for(uint i=0;i<numDomains; i++) {
302 uint index=++indices[i];
303 Set * set=getArraySet(&function->table->domains, i);
305 if (index < getSetSize(set)) {
306 vals[i]=getSetElement(set, index);
311 vals[i]=getSetElement(set, 0);
315 if(getSizeVectorEdge(clauses) == 0){
316 deleteVectorEdge(clauses);
319 Edge cor=constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
320 addConstraintCNF(This->cnf, cor);
321 deleteVectorEdge(clauses);