Edits
[satune.git] / src / Backend / satencoder.cc
1 #include "satencoder.h"
2 #include "structs.h"
3 #include "csolver.h"
4 #include "boolean.h"
5 #include "constraint.h"
6 #include "common.h"
7 #include "element.h"
8 #include "function.h"
9 #include "tableentry.h"
10 #include "table.h"
11 #include "order.h"
12 #include "predicate.h"
13 #include "set.h"
14
15 SATEncoder::SATEncoder(CSolver *_solver) :
16         cnf(createCNF()),
17         solver(_solver),
18   vector(allocDefVectorEdge()) {
19 }
20
21 SATEncoder::~SATEncoder() {
22         deleteCNF(cnf);
23         deleteVectorEdge(vector);
24 }
25
26 void SATEncoder::resetSATEncoder() {
27         resetCNF(cnf);
28         booledgeMap.reset();
29 }
30
31 int SATEncoder::solve() {
32         return solveCNF(cnf);
33 }
34
35 void SATEncoder::encodeAllSATEncoder(CSolver *csolver) {
36         SetIteratorBooleanEdge *iterator = csolver->getConstraints();
37         while (iterator->hasNext()) {
38                 BooleanEdge constraint = iterator->next();
39                 Edge c = encodeConstraintSATEncoder(constraint);
40                 addConstraintCNF(cnf, c);
41         }
42         delete iterator;
43 }
44
45 Edge SATEncoder::encodeConstraintSATEncoder(BooleanEdge c) {
46         Edge result;
47         Boolean *constraint = c.getBoolean();
48
49         if (booledgeMap.contains(constraint)) {
50                 Edge e = {(Node *) booledgeMap.get(constraint)};
51                 return c.isNegated() ? constraintNegate(e) : e;
52         }
53
54         switch (constraint->type) {
55         case ORDERCONST:
56                 result = encodeOrderSATEncoder((BooleanOrder *) constraint);
57                 break;
58         case BOOLEANVAR:
59                 result = encodeVarSATEncoder((BooleanVar *) constraint);
60                 break;
61         case LOGICOP:
62                 result = encodeLogicSATEncoder((BooleanLogic *) constraint);
63                 break;
64         case PREDICATEOP:
65                 result = encodePredicateSATEncoder((BooleanPredicate *) constraint);
66                 break;
67         default:
68                 model_print("Unhandled case in encodeConstraintSATEncoder %u", constraint->type);
69                 exit(-1);
70         }
71         Polarity p = constraint->polarity;
72         uint pSize = constraint->parents.getSize();
73         if ((pSize > 1 && p != P_BOTHTRUEFALSE ) || pSize > 2) {
74                 Edge e = getNewVarSATEncoder();
75                 generateProxy(cnf, result, e, p);
76                 booledgeMap.put(constraint, e.node_ptr);
77                 result = e;
78         }
79
80         return c.isNegated() ? constraintNegate(result) : result;
81 }
82
83 void SATEncoder::getArrayNewVarsSATEncoder(uint num, Edge *carray) {
84         for (uint i = 0; i < num; i++)
85                 carray[i] = getNewVarSATEncoder();
86 }
87
88 Edge SATEncoder::getNewVarSATEncoder() {
89         return constraintNewVar(cnf);
90 }
91
92 Edge SATEncoder::encodeVarSATEncoder(BooleanVar *constraint) {
93         if (edgeIsNull(constraint->var)) {
94                 constraint->var = getNewVarSATEncoder();
95         }
96         return constraint->var;
97 }
98
99 Edge SATEncoder::encodeLogicSATEncoder(BooleanLogic *constraint) {
100         Edge array[constraint->inputs.getSize()];
101         for (uint i = 0; i < constraint->inputs.getSize(); i++)
102                 array[i] = encodeConstraintSATEncoder(constraint->inputs.get(i));
103
104         switch (constraint->op) {
105         case SATC_AND:
106                 return constraintAND(cnf, constraint->inputs.getSize(), array);
107         case SATC_NOT:
108                 return constraintNegate(array[0]);
109         case SATC_IFF:
110                 ASSERT(constraint->inputs.getSize() == 2);
111                 return constraintIFF(cnf, array[0], array[1]);
112         case SATC_OR:
113         case SATC_XOR:
114         case SATC_IMPLIES:
115         //Don't handle, translate these away...
116         default:
117                 model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
118                 exit(-1);
119         }
120 }
121
122 Edge SATEncoder::encodePredicateSATEncoder(BooleanPredicate *constraint) {
123         switch (constraint->predicate->type) {
124         case TABLEPRED:
125                 return encodeTablePredicateSATEncoder(constraint);
126         case OPERATORPRED:
127                 return encodeOperatorPredicateSATEncoder(constraint);
128         default:
129                 ASSERT(0);
130         }
131         return E_BOGUS;
132 }
133
134 Edge SATEncoder::encodeTablePredicateSATEncoder(BooleanPredicate *constraint) {
135         switch (constraint->encoding.type) {
136         case ENUMERATEIMPLICATIONS:
137         case ENUMERATEIMPLICATIONSNEGATE:
138                 return encodeEnumTablePredicateSATEncoder(constraint);
139         case CIRCUIT:
140                 ASSERT(0);
141                 break;
142         default:
143                 ASSERT(0);
144         }
145         return E_BOGUS;
146 }
147
148 void SATEncoder::encodeElementSATEncoder(Element *element) {
149         /* Check to see if we have already encoded this element. */
150         if (element->getElementEncoding()->variables != NULL)
151                 return;
152
153         /* Need to encode. */
154         switch ( element->type) {
155         case ELEMFUNCRETURN:
156                 generateElementEncoding(element);
157                 encodeElementFunctionSATEncoder((ElementFunction *) element);
158                 break;
159         case ELEMSET:
160                 generateElementEncoding(element);
161                 return;
162         case ELEMCONST:
163                 return;
164         default:
165                 ASSERT(0);
166         }
167 }
168
169 void SATEncoder::encodeElementFunctionSATEncoder(ElementFunction *function) {
170         switch (function->getFunction()->type) {
171         case TABLEFUNC:
172                 encodeTableElementFunctionSATEncoder(function);
173                 break;
174         case OPERATORFUNC:
175                 encodeOperatorElementFunctionSATEncoder(function);
176                 break;
177         default:
178                 ASSERT(0);
179         }
180 }
181
182 void SATEncoder::encodeTableElementFunctionSATEncoder(ElementFunction *function) {
183         switch (function->getElementFunctionEncoding()->type) {
184         case ENUMERATEIMPLICATIONS:
185                 encodeEnumTableElemFunctionSATEncoder(function);
186                 break;
187         case CIRCUIT:
188                 ASSERT(0);
189                 break;
190         default:
191                 ASSERT(0);
192         }
193 }