1 #include "satencoder.h"
8 #include "tableentry.h"
13 Edge SATEncoder::encodeOperatorPredicateSATEncoder(BooleanPredicate *constraint) {
14 switch (constraint->encoding.type) {
15 case ENUMERATEIMPLICATIONS:
16 return encodeEnumOperatorPredicateSATEncoder(constraint);
18 return encodeCircuitOperatorPredicateEncoder(constraint);
25 Edge SATEncoder::encodeEnumOperatorPredicateSATEncoder(BooleanPredicate *constraint) {
26 PredicateOperator *predicate = (PredicateOperator *)constraint->predicate;
27 uint numDomains = predicate->domains.getSize();
29 FunctionEncodingType encType = constraint->encoding.type;
30 bool generateNegation = encType == ENUMERATEIMPLICATIONSNEGATE;
32 /* Call base encoders for children */
33 for (uint i = 0; i < numDomains; i++) {
34 Element *elem = constraint->inputs.get(i);
35 encodeElementSATEncoder(elem);
37 VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
39 uint indices[numDomains]; //setup indices
40 bzero(indices, sizeof(uint) * numDomains);
42 uint64_t vals[numDomains];//setup value array
43 for (uint i = 0; i < numDomains; i++) {
44 Set *set = predicate->domains.get(i);
45 vals[i] = set->getElement(indices[i]);
48 bool notfinished = true;
50 Edge carray[numDomains];
52 if (predicate->evalPredicateOperator(vals) != generateNegation) {
53 //Include this in the set of terms
54 for (uint i = 0; i < numDomains; i++) {
55 Element *elem = constraint->inputs.get(i);
56 carray[i] = getElementValueConstraint(elem, vals[i]);
58 Edge term = constraintAND(cnf, numDomains, carray);
59 pushVectorEdge(clauses, term);
63 for (uint i = 0; i < numDomains; i++) {
64 uint index = ++indices[i];
65 Set *set = predicate->domains.get(i);
67 if (index < set->getSize()) {
68 vals[i] = set->getElement(index);
73 vals[i] = set->getElement(0);
77 if (getSizeVectorEdge(clauses) == 0) {
78 deleteVectorEdge(clauses);
81 Edge cor = constraintOR(cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
82 deleteVectorEdge(clauses);
83 return generateNegation ? constraintNegate(cor) : cor;
87 void SATEncoder::encodeOperatorElementFunctionSATEncoder(ElementFunction *func) {
89 model_print("Operator Function ...\n");
91 FunctionOperator *function = (FunctionOperator *) func->function;
92 uint numDomains = func->inputs.getSize();
94 /* Call base encoders for children */
95 for (uint i = 0; i < numDomains; i++) {
96 Element *elem = func->inputs.get(i);
97 encodeElementSATEncoder(elem);
100 VectorEdge *clauses = allocDefVectorEdge(); // Setup array of clauses
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 = getElementSet(func->inputs.get(i));
108 vals[i] = set->getElement(indices[i]);
111 Edge overFlowConstraint = ((BooleanVar *) func->overflowstatus)->var;
113 bool notfinished = true;
114 while (notfinished) {
115 Edge carray[numDomains + 1];
117 uint64_t result = function->applyFunctionOperator(numDomains, vals);
118 bool isInRange = ((FunctionOperator *)func->function)->isInRangeFunction(result);
119 bool needClause = isInRange;
120 if (function->overflowbehavior == OVERFLOWSETSFLAG || function->overflowbehavior == FLAGIFFOVERFLOW) {
125 //Include this in the set of terms
126 for (uint i = 0; i < numDomains; i++) {
127 Element *elem = func->inputs.get(i);
128 carray[i] = getElementValueConstraint(elem, vals[i]);
131 carray[numDomains] = getElementValueConstraint(func, result);
135 switch (function->overflowbehavior) {
139 clause = constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), carray[numDomains]);
142 case FLAGFORCESOVERFLOW: {
143 clause = constraintIMPLIES(cnf,constraintAND(cnf, numDomains, carray), constraintAND2(cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
146 case OVERFLOWSETSFLAG: {
148 clause = constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), carray[numDomains]);
150 clause = constraintIMPLIES(cnf,constraintAND(cnf, numDomains, carray), overFlowConstraint);
154 case FLAGIFFOVERFLOW: {
156 clause = constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), constraintAND2(cnf, carray[numDomains], constraintNegate(overFlowConstraint)));
158 clause = constraintIMPLIES(cnf, constraintAND(cnf, numDomains, carray), overFlowConstraint);
166 model_print("added clause in operator function\n");
170 pushVectorEdge(clauses, clause);
174 for (uint i = 0; i < numDomains; i++) {
175 uint index = ++indices[i];
176 Set *set = getElementSet(func->inputs.get(i));
178 if (index < set->getSize()) {
179 vals[i] = set->getElement(index);
184 vals[i] = set->getElement(0);
188 if (getSizeVectorEdge(clauses) == 0) {
189 deleteVectorEdge(clauses);
192 Edge cor = constraintAND(cnf, getSizeVectorEdge(clauses), exposeArrayEdge(clauses));
193 addConstraintCNF(cnf, cor);
194 deleteVectorEdge(clauses);
197 Edge SATEncoder::encodeCircuitOperatorPredicateEncoder(BooleanPredicate *constraint) {
198 PredicateOperator *predicate = (PredicateOperator *) constraint->predicate;
199 Element *elem0 = constraint->inputs.get(0);
200 encodeElementSATEncoder(elem0);
201 Element *elem1 = constraint->inputs.get(1);
202 encodeElementSATEncoder(elem1);
203 ElementEncoding *ee0 = getElementEncoding(elem0);
204 ElementEncoding *ee1 = getElementEncoding(elem1);
205 ASSERT(ee0->numVars == ee1->numVars);
206 uint numVars = ee0->numVars;
207 switch (predicate->op) {
209 return generateEquivNVConstraint(cnf, numVars, ee0->variables, ee1->variables);
211 return generateLTConstraint(cnf, numVars, ee0->variables, ee1->variables);
213 return generateLTConstraint(cnf, numVars, ee1->variables, ee0->variables);