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);
150 if(getSizeVectorEdge(clauses) == 0){
151 deleteVectorEdge(clauses);
154 Edge cor=constraintOR(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
155 deleteVectorEdge(clauses);
156 return generateNegation ? constraintNegate(cor) : cor;
159 void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder* This, ElementFunction* func){
160 UndefinedBehavior undefStatus = ((FunctionTable*) func->function)->undefBehavior;
161 ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
162 ArrayElement* elements= &func->inputs;
163 Table* table = ((FunctionTable*) (func->function))->table;
164 uint size = getSizeHashSetTableEntry(table->entries);
165 Edge constraints[size];
166 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
168 while(hasNextTableEntry(iterator)) {
169 TableEntry* entry = nextTableEntry(iterator);
171 uint inputNum = getSizeArrayElement(elements);
172 Edge carray[inputNum];
173 for(uint j=0; j<inputNum; j++){
174 Element* el= getArrayElement(elements, j);
175 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
177 Edge output = getElementValueConstraint(This, (Element*)func, entry->output);
179 switch(undefStatus ){
180 case IGNOREBEHAVIOR: {
181 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
184 case FLAGFORCEUNDEFINED: {
185 Edge undefConst = encodeConstraintSATEncoder(This, func->overflowstatus);
186 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
193 constraints[i++]=row;
195 deleteIterTableEntry(iterator);
196 addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
199 void encodeEnumTableElemFunctionSATEncoder(SATEncoder* This, ElementFunction* elemFunc){
201 model_print("Enumeration Table functions ...\n");
203 ASSERT(GETFUNCTIONTYPE(elemFunc->function)==TABLEFUNC);
204 //First encode children
205 ArrayElement* elements= &elemFunc->inputs;
206 for(uint i=0; i<getSizeArrayElement(elements); i++){
207 Element *elem = getArrayElement( elements, i);
208 encodeElementSATEncoder(This, elem);
211 FunctionTable* function =(FunctionTable*)elemFunc->function;
212 switch(function->undefBehavior){
214 case FLAGFORCEUNDEFINED:
215 return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
220 uint numDomains=getSizeArraySet(&function->table->domains);
222 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
224 uint indices[numDomains]; //setup indices
225 bzero(indices, sizeof(uint)*numDomains);
227 uint64_t vals[numDomains]; //setup value array
228 for(uint i=0;i<numDomains; i++) {
229 Set * set=getArraySet(&function->table->domains, i);
230 vals[i]=getSetElement(set, indices[i]);
233 Edge undefConstraint = encodeConstraintSATEncoder(This, elemFunc->overflowstatus);
234 bool notfinished=true;
236 Edge carray[numDomains+1];
237 TableEntry* tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
238 bool isInRange = tableEntry!=NULL;
239 ASSERT(function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED);
240 //Include this in the set of terms
241 for(uint i=0;i<numDomains;i++) {
242 Element * elem = getArrayElement(&elemFunc->inputs, i);
243 carray[i] = getElementValueConstraint(This, elem, vals[i]);
246 carray[numDomains] = getElementValueConstraint(This, (Element*)elemFunc, tableEntry->output);
250 switch(function->undefBehavior) {
251 case UNDEFINEDSETSFLAG: {
253 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
255 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
259 case FLAGIFFUNDEFINED: {
261 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(undefConstraint)));
263 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
271 model_print("added clause in function table enumeration ...\n");
275 pushVectorEdge(clauses, clause);
279 for(uint i=0;i<numDomains; i++) {
280 uint index=++indices[i];
281 Set * set=getArraySet(&function->table->domains, i);
283 if (index < getSetSize(set)) {
284 vals[i]=getSetElement(set, index);
289 vals[i]=getSetElement(set, 0);
293 if(getSizeVectorEdge(clauses) == 0){
294 deleteVectorEdge(clauses);
297 Edge cor=constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
298 addConstraintCNF(This->cnf, cor);
299 deleteVectorEdge(clauses);