1 #include "satencoder.h"
8 #include "tableentry.h"
13 Edge encodeEnumEntriesTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
14 Table* table = ((PredicateTable*)constraint->predicate)->table;
15 FunctionEncodingType encType = constraint->encoding.type;
16 ArrayElement* inputs = &constraint->inputs;
17 uint inputNum =getSizeArrayElement(inputs);
18 //Encode all the inputs first ...
19 for(uint i=0; i<inputNum; i++){
20 encodeElementSATEncoder(This, getArrayElement(inputs, i));
22 uint size = getSizeHashSetTableEntry(table->entries);
23 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
24 Edge constraints[size];
25 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
27 while(hasNextTableEntry(iterator)){
28 TableEntry* entry = nextTableEntry(iterator);
29 if(generateNegation == entry->output) {
30 //Skip the irrelevant entries
33 Edge carray[inputNum];
34 for(uint j=0; j<inputNum; j++){
35 Element* el = getArrayElement(inputs, j);
36 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
38 constraints[i++]=constraintAND(This->cnf, inputNum, carray);
40 Edge result=constraintOR(This->cnf, size, constraints);
42 return generateNegation ? constraintNegate(result) : result;
44 Edge encodeEnumTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
49 void encodeEnumEntriesTableElemFuncSATEncoder(SATEncoder* This, ElementFunction* func){
50 UndefinedBehavior undefStatus = ((FunctionTable*) func->function)->undefBehavior;
51 ASSERT(undefStatus == IGNOREBEHAVIOR || undefStatus == FLAGFORCEUNDEFINED);
52 ArrayElement* elements= &func->inputs;
53 Table* table = ((FunctionTable*) (func->function))->table;
54 uint size = getSizeHashSetTableEntry(table->entries);
55 Edge constraints[size];
56 HSIteratorTableEntry* iterator = iteratorTableEntry(table->entries);
58 while(hasNextTableEntry(iterator)) {
59 TableEntry* entry = nextTableEntry(iterator);
61 uint inputNum = getSizeArrayElement(elements);
62 Edge carray[inputNum];
63 for(uint j=0; j<inputNum; j++){
64 Element* el= getArrayElement(elements, j);
65 carray[j] = getElementValueConstraint(This, el, entry->inputs[j]);
67 Edge output = getElementValueConstraint(This, (Element*)func, entry->output);
70 case IGNOREBEHAVIOR: {
71 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), output);
74 case FLAGFORCEUNDEFINED: {
75 Edge undefConst = ((BooleanVar*)func->overflowstatus)->var;
76 row=constraintIMPLIES(This->cnf,constraintAND(This->cnf, inputNum, carray), constraintAND2(This->cnf, output, constraintNegate(undefConst)));
85 deleteIterTableEntry(iterator);
86 addConstraintCNF(This->cnf, constraintAND(This->cnf, size, constraints));
89 void encodeEnumTableElemFunctionSATEncoder(SATEncoder* This, ElementFunction* elemFunc){
91 model_print("Enumeration Table functions ...\n");
93 ASSERT(GETFUNCTIONTYPE(elemFunc->function)==TABLEFUNC);
94 //First encode children
95 ArrayElement* elements= &elemFunc->inputs;
96 for(uint i=0; i<getSizeArrayElement(elements); i++){
97 Element *elem = getArrayElement( elements, i);
98 encodeElementSATEncoder(This, elem);
101 FunctionTable* function =(FunctionTable*)elemFunc;
102 switch(function->undefBehavior){
104 case FLAGFORCEUNDEFINED:
105 return encodeEnumEntriesTableElemFuncSATEncoder(This, elemFunc);
110 uint numDomains=getSizeArraySet(&function->table->domains);
112 VectorEdge * clauses=allocDefVectorEdge(); // Setup array of clauses
114 uint indices[numDomains]; //setup indices
115 bzero(indices, sizeof(uint)*numDomains);
117 uint64_t vals[numDomains]; //setup value array
118 for(uint i=0;i<numDomains; i++) {
119 Set * set=getArraySet(&function->table->domains, i);
120 vals[i]=getSetElement(set, indices[i]);
123 Edge undefConstraint = ((BooleanVar*) elemFunc->overflowstatus)->var;
125 bool notfinished=true;
127 Edge carray[numDomains+1];
128 TableEntry* tableEntry = getTableEntryFromTable(function->table, vals, numDomains);
129 bool isInRange = tableEntry!=NULL;
130 bool needClause = isInRange;
131 if (function->undefBehavior == UNDEFINEDSETSFLAG || function->undefBehavior == FLAGIFFUNDEFINED) {
136 //Include this in the set of terms
137 for(uint i=0;i<numDomains;i++) {
138 Element * elem = getArrayElement(&elemFunc->inputs, i);
139 carray[i] = getElementValueConstraint(This, elem, vals[i]);
142 carray[numDomains] = getElementValueConstraint(This, (Element*)elemFunc, tableEntry->output);
146 switch(function->undefBehavior) {
147 case UNDEFINEDSETSFLAG: {
149 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), carray[numDomains]);
151 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
155 case FLAGIFFUNDEFINED: {
157 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), constraintAND2(This->cnf, carray[numDomains], constraintNegate(undefConstraint)));
159 clause=constraintIMPLIES(This->cnf,constraintAND(This->cnf, numDomains, carray), undefConstraint);
167 model_print("added clause in table enumeration ...\n");
171 pushVectorEdge(clauses, clause);
175 for(uint i=0;i<numDomains; i++) {
176 uint index=++indices[i];
177 Set * set=getArraySet(&function->table->domains, i);
179 if (index < getSetSize(set)) {
180 vals[i]=getSetElement(set, index);
185 vals[i]=getSetElement(set, 0);
190 Edge cor=constraintAND(This->cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
191 addConstraintCNF(This->cnf, cor);
192 deleteVectorEdge(clauses);