1 #include "satencoder.h"
8 #include "tableentry.h"
13 Edge SATEncoder::encodeEnumEntriesTablePredicateSATEncoder(BooleanPredicate *constraint) {
14 ASSERT(constraint->predicate->type == TABLEPRED);
15 UndefinedBehavior undefStatus = ((PredicateTable *)constraint->predicate)->undefinedbehavior;
16 ASSERT(undefStatus == SATC_IGNOREBEHAVIOR || undefStatus == SATC_FLAGFORCEUNDEFINED);
17 Table *table = ((PredicateTable *)constraint->predicate)->table;
18 FunctionEncodingType encType = constraint->encoding.type;
19 Array<Element *> *inputs = &constraint->inputs;
20 uint inputNum = inputs->getSize();
21 uint size = table->getSize();
22 Polarity polarity = constraint->polarity;
23 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
25 polarity = negatePolarity(polarity);
26 if (undefStatus ==SATC_FLAGFORCEUNDEFINED)
27 polarity = P_BOTHTRUEFALSE;
29 Edge constraints[size];
31 SetIteratorTableEntry *iterator = table->getEntries();
33 while (iterator->hasNext()) {
34 TableEntry *entry = iterator->next();
35 if (generateNegation == (entry->output != 0) && undefStatus == SATC_IGNOREBEHAVIOR) {
36 //Skip the irrelevant entries
39 Edge carray[inputNum];
40 for (uint j = 0; j < inputNum; j++) {
41 Element *el = inputs->get(j);
42 carray[j] = getElementValueConstraint(el, polarity, entry->inputs[j]);
45 switch (undefStatus) {
46 case SATC_IGNOREBEHAVIOR:
47 row = constraintAND(cnf, inputNum, carray);
49 case SATC_FLAGFORCEUNDEFINED: {
50 Edge proxy = constraintNewVar(cnf);
51 generateProxy(cnf, constraintAND(cnf, inputNum, carray), proxy, P_BOTHTRUEFALSE);
52 Edge undefConst = encodeConstraintSATEncoder(constraint->undefStatus);
53 addConstraintCNF(cnf, constraintIMPLIES(cnf, proxy, constraintNegate(undefConst)));
54 if (generateNegation == (entry->output != 0)) {
63 constraints[i++] = row;
67 Edge result = generateNegation ? constraintNegate(constraintOR(cnf, i, constraints))
68 : constraintOR(cnf, i, constraints);
72 Edge SATEncoder::encodeEnumTablePredicateSATEncoder(BooleanPredicate *constraint) {
74 model_print("Enumeration Table Predicate ...\n");
76 ASSERT(constraint->predicate->type == TABLEPRED);
77 Polarity polarity = constraint->polarity;
79 //First encode children
80 Array<Element *> *inputs = &constraint->inputs;
81 uint inputNum = inputs->getSize();
82 //Encode all the inputs first ...
83 for (uint i = 0; i < inputNum; i++) {
84 encodeElementSATEncoder(inputs->get(i));
86 PredicateTable *predicate = (PredicateTable *)constraint->predicate;
87 switch (predicate->undefinedbehavior) {
88 case SATC_IGNOREBEHAVIOR:
89 case SATC_FLAGFORCEUNDEFINED:
90 return encodeEnumEntriesTablePredicateSATEncoder(constraint);
94 bool generateNegation = constraint->encoding.type == ENUMERATEIMPLICATIONSNEGATE;
95 uint numDomains = predicate->table->numDomains();
98 polarity = negatePolarity(polarity);
100 VectorEdge *clauses = allocDefVectorEdge();
102 uint indices[numDomains]; //setup indices
103 bzero(indices, sizeof(uint) * numDomains);
105 uint64_t vals[numDomains];//setup value array
106 for (uint i = 0; i < numDomains; i++) {
107 Set *set = predicate->table->getDomain(i);
108 vals[i] = set->getElement(indices[i]);
110 bool hasOverflow = false;
112 bool notfinished = true;
113 while (notfinished) {
114 Edge carray[numDomains];
115 TableEntry *tableEntry = predicate->table->getTableEntry(vals, numDomains);
116 bool isInRange = tableEntry != NULL;
117 if (!isInRange && !hasOverflow) {
121 for (uint i = 0; i < numDomains; i++) {
122 Element *elem = constraint->inputs.get(i);
123 carray[i] = getElementValueConstraint(elem, polarity, vals[i]);
126 switch (predicate->undefinedbehavior) {
127 case SATC_UNDEFINEDSETSFLAG:
129 clause = constraintAND(cnf, numDomains, carray);
131 Edge undefConstraint = encodeConstraintSATEncoder(constraint->undefStatus);
132 addConstraintCNF(cnf, constraintIMPLIES(cnf,constraintAND(cnf, numDomains, carray), undefConstraint) );
135 case SATC_FLAGIFFUNDEFINED: {
136 Edge undefConstraint = encodeConstraintSATEncoder(constraint->undefStatus);
138 clause = constraintAND(cnf, numDomains, carray);
139 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), constraintNegate(undefConstraint)));
141 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), undefConstraint) );
151 model_print("added clause in predicate table enumeration ...\n");
155 pushVectorEdge(clauses, clause);
159 for (uint i = 0; i < numDomains; i++) {
160 uint index = ++indices[i];
161 Set *set = predicate->table->getDomain(i);
163 if (index < set->getSize()) {
164 vals[i] = set->getElement(index);
169 vals[i] = set->getElement(0);
173 Edge result = E_NULL;
174 ASSERT(getSizeVectorEdge(clauses) != 0);
175 result = constraintOR(cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
177 Edge undefConstraint = encodeConstraintSATEncoder(constraint->undefStatus);
178 result = constraintOR2(cnf, result, undefConstraint);
180 if (generateNegation) {
181 ASSERT(!hasOverflow);
182 result = constraintNegate(result);
184 deleteVectorEdge(clauses);
188 void SATEncoder::encodeEnumEntriesTableElemFuncSATEncoder(ElementFunction *func) {
189 UndefinedBehavior undefStatus = ((FunctionTable *) func->getFunction())->undefBehavior;
190 ASSERT(undefStatus == SATC_IGNOREBEHAVIOR || undefStatus == SATC_FLAGFORCEUNDEFINED);
191 Array<Element *> *elements = &func->inputs;
193 Table *table = ((FunctionTable *) (func->getFunction()))->table;
194 uint size = table->getSize();
195 Edge constraints[size];
196 SetIteratorTableEntry *iterator = table->getEntries();
198 while (iterator->hasNext()) {
199 TableEntry *entry = iterator->next();
200 ASSERT(entry != NULL);
201 uint inputNum = elements->getSize();
202 Edge carray[inputNum];
203 for (uint j = 0; j < inputNum; j++) {
204 Element *el = elements->get(j);
205 carray[j] = getElementValueConstraint(el, P_FALSE, entry->inputs[j]);
207 Edge output = getElementValueConstraint(func, P_TRUE, entry->output);
208 switch (undefStatus ) {
209 case SATC_IGNOREBEHAVIOR: {
210 addConstraintCNF(cnf, constraintIMPLIES(cnf,constraintAND(cnf, inputNum, carray), output));
213 case SATC_FLAGFORCEUNDEFINED: {
214 Edge undefConst = encodeConstraintSATEncoder(func->overflowstatus);
215 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, inputNum, carray), constraintAND2(cnf, output, constraintNegate(undefConst))));
226 void SATEncoder::encodeEnumTableElemFunctionSATEncoder(ElementFunction *elemFunc) {
228 model_print("Enumeration Table functions ...\n");
230 ASSERT(elemFunc->getFunction()->type == TABLEFUNC);
232 //First encode children
233 Array<Element *> *elements = &elemFunc->inputs;
234 for (uint i = 0; i < elements->getSize(); i++) {
235 Element *elem = elements->get(i);
236 encodeElementSATEncoder(elem);
239 FunctionTable *function = (FunctionTable *)elemFunc->getFunction();
240 switch (function->undefBehavior) {
241 case SATC_IGNOREBEHAVIOR:
242 case SATC_FLAGFORCEUNDEFINED:
243 return encodeEnumEntriesTableElemFuncSATEncoder(elemFunc);
248 uint numDomains = function->table->numDomains();
250 uint indices[numDomains]; //setup indices
251 bzero(indices, sizeof(uint) * numDomains);
253 uint64_t vals[numDomains];//setup value array
254 for (uint i = 0; i < numDomains; i++) {
255 Set *set = function->table->getDomain(i);
256 vals[i] = set->getElement(indices[i]);
259 bool notfinished = true;
260 while (notfinished) {
261 Edge carray[numDomains + 1];
262 TableEntry *tableEntry = function->table->getTableEntry(vals, numDomains);
263 bool isInRange = tableEntry != NULL;
264 ASSERT(function->undefBehavior == SATC_UNDEFINEDSETSFLAG || function->undefBehavior == SATC_FLAGIFFUNDEFINED);
265 for (uint i = 0; i < numDomains; i++) {
266 Element *elem = elemFunc->inputs.get(i);
267 carray[i] = getElementValueConstraint(elem, P_FALSE, vals[i]);
270 carray[numDomains] = getElementValueConstraint(elemFunc, P_TRUE, tableEntry->output);
273 switch (function->undefBehavior) {
274 case SATC_UNDEFINEDSETSFLAG: {
276 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), carray[numDomains]));
278 Edge undefConstraint = encodeConstraintSATEncoder(elemFunc->overflowstatus);
279 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), undefConstraint));
283 case SATC_FLAGIFFUNDEFINED: {
284 Edge undefConstraint = encodeConstraintSATEncoder(elemFunc->overflowstatus);
286 Edge freshvar = constraintNewVar(cnf);
287 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), freshvar ));
288 addConstraintCNF(cnf, constraintIMPLIES(cnf, freshvar, constraintNegate(undefConstraint) ));
289 addConstraintCNF(cnf, constraintIMPLIES(cnf, freshvar, carray[numDomains]));
291 addConstraintCNF(cnf, constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), undefConstraint));
300 model_print("added clause in function table enumeration ...\n");
307 for (uint i = 0; i < numDomains; i++) {
308 uint index = ++indices[i];
309 Set *set = function->table->getDomain(i);
311 if (index < set->getSize()) {
312 vals[i] = set->getElement(index);
317 vals[i] = set->getElement(0);