1 #include "satencoder.h"
5 #include "constraint.h"
9 #include "tableentry.h"
12 #include "predicate.h"
13 #include "orderpair.h"
16 SATEncoder * allocSATEncoder() {
17 SATEncoder *This=ourmalloc(sizeof (SATEncoder));
22 void deleteSATEncoder(SATEncoder *This) {
26 void initializeConstraintVars(CSolver* csolver, SATEncoder* This){
27 /** We really should not walk the free list to generate constraint
28 variables...walk the constraint tree instead. Or even better
29 yet, just do this as you need to during the encodeAllSATEncoder
32 // FIXME!!!!(); // Make sure Hamed sees comment above
34 uint size = getSizeVectorElement(csolver->allElements);
35 for(uint i=0; i<size; i++){
36 Element* element = getVectorElement(csolver->allElements, i);
37 generateElementEncodingVariables(This,getElementEncoding(element));
42 Constraint * getElementValueConstraint(Element* This, uint64_t value) {
43 switch(getElementEncoding(This)->type){
54 return getElementValueBinaryIndexConstraint(This, value);
65 Constraint * getElementValueBinaryIndexConstraint(Element* This, uint64_t value) {
66 ASTNodeType type = GETELEMENTTYPE(This);
67 ASSERT(type == ELEMSET || type == ELEMFUNCRETURN);
68 ElementEncoding* elemEnc = getElementEncoding(This);
69 for(uint i=0; i<elemEnc->encArraySize; i++){
70 if( isinUseElement(elemEnc, i) && elemEnc->encodingArray[i]==value){
71 return generateBinaryConstraint(elemEnc->numVars,
72 elemEnc->variables, i);
79 void encodeAllSATEncoder(CSolver *csolver, SATEncoder * This) {
80 VectorBoolean *constraints=csolver->constraints;
81 uint size=getSizeVectorBoolean(constraints);
82 for(uint i=0;i<size;i++) {
83 Boolean *constraint=getVectorBoolean(constraints, i);
84 encodeConstraintSATEncoder(This, constraint);
87 // FIXME: Following line for element!
88 // size = getSizeVectorElement(csolver->allElements);
89 // for(uint i=0; i<size; i++){
90 // Element* element = getVectorElement(csolver->allElements, i);
91 // switch(GETELEMENTTYPE(element)){
92 // case ELEMFUNCRETURN:
93 // encodeFunctionElementSATEncoder(This, (ElementFunction*) element);
97 // //ElementSets that aren't used in any constraints/functions
98 // //will be eliminated.
103 Constraint * encodeConstraintSATEncoder(SATEncoder *This, Boolean *constraint) {
104 switch(GETBOOLEANTYPE(constraint)) {
106 return encodeOrderSATEncoder(This, (BooleanOrder *) constraint);
108 return encodeVarSATEncoder(This, (BooleanVar *) constraint);
110 return encodeLogicSATEncoder(This, (BooleanLogic *) constraint);
112 return encodePredicateSATEncoder(This, (BooleanPredicate *) constraint);
114 model_print("Unhandled case in encodeConstraintSATEncoder %u", GETBOOLEANTYPE(constraint));
119 void getArrayNewVarsSATEncoder(SATEncoder* encoder, uint num, Constraint **carray) {
120 for(uint i=0;i<num;i++)
121 carray[i]=getNewVarSATEncoder(encoder);
124 Constraint * getNewVarSATEncoder(SATEncoder *This) {
125 Constraint * var=allocVarConstraint(VAR, This->varcount);
126 Constraint * varneg=allocVarConstraint(NOTVAR, This->varcount++);
127 setNegConstraint(var, varneg);
128 setNegConstraint(varneg, var);
132 Constraint * encodeVarSATEncoder(SATEncoder *This, BooleanVar * constraint) {
133 if (constraint->var == NULL) {
134 constraint->var=getNewVarSATEncoder(This);
136 return constraint->var;
139 Constraint * encodeLogicSATEncoder(SATEncoder *This, BooleanLogic * constraint) {
140 Constraint * array[getSizeArrayBoolean(&constraint->inputs)];
141 for(uint i=0;i<getSizeArrayBoolean(&constraint->inputs);i++)
142 array[i]=encodeConstraintSATEncoder(This, getArrayBoolean(&constraint->inputs, i));
144 switch(constraint->op) {
146 return allocArrayConstraint(AND, getSizeArrayBoolean(&constraint->inputs), array);
148 return allocArrayConstraint(OR, getSizeArrayBoolean(&constraint->inputs), array);
150 ASSERT(constraint->numArray==1);
151 return negateConstraint(array[0]);
153 ASSERT(constraint->numArray==2);
154 Constraint * nleft=negateConstraint(cloneConstraint(array[0]));
155 Constraint * nright=negateConstraint(cloneConstraint(array[1]));
156 return allocConstraint(OR,
157 allocConstraint(AND, array[0], nright),
158 allocConstraint(AND, nleft, array[1]));
161 ASSERT(constraint->numArray==2);
162 return allocConstraint(IMPLIES, array[0], array[1]);
164 model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
170 Constraint * encodeOrderSATEncoder(SATEncoder *This, BooleanOrder * constraint) {
171 switch( constraint->order->type){
173 return encodePartialOrderSATEncoder(This, constraint);
175 return encodeTotalOrderSATEncoder(This, constraint);
183 Constraint * encodeTotalOrderSATEncoder(SATEncoder *This, BooleanOrder * boolOrder){
184 ASSERT(boolOrder->order->type == TOTAL);
185 HashTableBoolConst* boolToConsts = boolOrder->order->boolsToConstraints;
186 OrderPair* pair = allocOrderPair(boolOrder->first, boolOrder->second);
187 if( !containsBoolConst(boolToConsts, pair) ){
188 createAllTotalOrderConstraintsSATEncoder(This, boolOrder->order);
190 Constraint* constraint = getOrderConstraint(boolToConsts, pair);
191 deleteOrderPair(pair);
195 void createAllTotalOrderConstraintsSATEncoder(SATEncoder* This, Order* order){
196 ASSERT(order->type == TOTAL);
197 VectorInt* mems = order->set->members;
198 HashTableBoolConst* table = order->boolsToConstraints;
199 uint size = getSizeVectorInt(mems);
200 for(uint i=0; i<size; i++){
201 uint64_t valueI = getVectorInt(mems, i);
202 for(uint j=i+1; j<size;j++){
203 uint64_t valueJ = getVectorInt(mems, j);
204 OrderPair* pairIJ = allocOrderPair(valueI, valueJ);
205 ASSERT(!containsBoolConst(table, pairIJ));
206 Constraint* constIJ = getNewVarSATEncoder(This);
207 putBoolConst(table, pairIJ, constIJ);
208 for(uint k=j+1; k<size; k++){
209 uint64_t valueK = getVectorInt(mems, k);
210 OrderPair* pairJK = allocOrderPair(valueJ, valueK);
211 OrderPair* pairIK = allocOrderPair(valueI, valueK);
212 Constraint* constJK, *constIK;
213 if(!containsBoolConst(table, pairJK)){
214 constJK = getNewVarSATEncoder(This);
215 putBoolConst(table, pairJK, constJK);
217 if(!containsBoolConst(table, pairIK)){
218 constIK = getNewVarSATEncoder(This);
219 putBoolConst(table, pairIK, constIK);
221 generateTransOrderConstraintSATEncoder(This, constIJ, constJK, constIK);
227 Constraint* getOrderConstraint(HashTableBoolConst *table, OrderPair *pair){
228 ASSERT(pair->first!= pair->second);
229 Constraint* constraint= getBoolConst(table, pair);
230 ASSERT(constraint!= NULL);
231 if(pair->first > pair->second)
234 return negateConstraint(constraint);
237 Constraint * generateTransOrderConstraintSATEncoder(SATEncoder *This, Constraint *constIJ,Constraint *constJK,Constraint *constIK){
238 //FIXME: first we should add the the constraint to the satsolver!
239 Constraint *carray[] = {constIJ, constJK, negateConstraint(constIK)};
240 Constraint * loop1= allocArrayConstraint(OR, 3, carray);
241 Constraint * carray2[] = {negateConstraint(constIJ), negateConstraint(constJK), constIK};
242 Constraint * loop2= allocArrayConstraint(OR, 3,carray2 );
243 return allocConstraint(AND, loop1, loop2);
246 Constraint * encodePartialOrderSATEncoder(SATEncoder *This, BooleanOrder * constraint){
247 // FIXME: we can have this implementation for partial order. Basically,
248 // we compute the transitivity between two order constraints specified by the client! (also can be used
249 // when client specify sparse constraints for the total order!)
250 ASSERT(boolOrder->order->type == PARTIAL);
252 HashTableBoolConst* boolToConsts = boolOrder->order->boolsToConstraints;
253 if( containsBoolConst(boolToConsts, boolOrder) ){
254 return getBoolConst(boolToConsts, boolOrder);
256 Constraint* constraint = getNewVarSATEncoder(This);
257 putBoolConst(boolToConsts,boolOrder, constraint);
258 VectorBoolean* orderConstrs = &boolOrder->order->constraints;
259 uint size= getSizeVectorBoolean(orderConstrs);
260 for(uint i=0; i<size; i++){
261 ASSERT(GETBOOLEANTYPE( getVectorBoolean(orderConstrs, i)) == ORDERCONST );
262 BooleanOrder* tmp = (BooleanOrder*)getVectorBoolean(orderConstrs, i);
263 BooleanOrder* newBool;
264 Constraint* first, *second;
265 if(tmp->second==boolOrder->first){
266 newBool = (BooleanOrder*)allocBooleanOrder(tmp->order,tmp->first,boolOrder->second);
267 first = encodeTotalOrderSATEncoder(This, tmp);
270 }else if (boolOrder->second == tmp->first){
271 newBool = (BooleanOrder*)allocBooleanOrder(tmp->order,boolOrder->first,tmp->second);
273 second = encodeTotalOrderSATEncoder(This, tmp);
276 Constraint* transConstr= encodeTotalOrderSATEncoder(This, newBool);
277 generateTransOrderConstraintSATEncoder(This, first, second, transConstr );
285 Constraint * encodePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
286 switch(GETPREDICATETYPE(constraint) ){
288 return encodeTablePredicateSATEncoder(This, constraint);
290 return encodeOperatorPredicateSATEncoder(This, constraint);
297 Constraint * encodeTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
298 switch(constraint->encoding.type){
299 case ENUMERATEIMPLICATIONS:
300 return encodeEnumTablePredicateSATEncoder(This, constraint);
310 Constraint * encodeEnumTablePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
311 VectorTableEntry* entries = &(((PredicateTable*)constraint->predicate)->table->entries);
312 uint size = getSizeVectorTableEntry(entries);
313 for(uint i=0; i<size; i++){
314 TableEntry* entry = getVectorTableEntry(entries, i);
320 Constraint * encodeOperatorPredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint){
321 switch(constraint->encoding.type){
322 case ENUMERATEIMPLICATIONS:
332 Constraint* encodeFunctionElementSATEncoder(SATEncoder* encoder, ElementFunction *This){
333 switch(GETFUNCTIONTYPE(This->function)){
335 return encodeTableElementFunctionSATEncoder(encoder, This);
337 return encodeOperatorElementFunctionSATEncoder(encoder, This);
344 Constraint* encodeTableElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
345 switch(getElementFunctionEncoding(This)->type){
346 case ENUMERATEIMPLICATIONS:
347 return encodeEnumTableElemFunctionSATEncoder(encoder, This);
358 Constraint* encodeOperatorElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
359 //FIXME: for now it just adds/substracts inputs exhustively
363 Constraint* encodeEnumTableElemFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
364 ASSERT(GETFUNCTIONTYPE(This->function)==TABLEFUNC);
365 ArrayElement* elements= &This->inputs;
366 Table* table = ((FunctionTable*) (This->function))->table;
367 uint size = getSizeVectorTableEntry(&table->entries);
368 Constraint* constraints[size]; //FIXME: should add a space for the case that didn't match any entries
369 for(uint i=0; i<size; i++){
370 TableEntry* entry = getVectorTableEntry(&table->entries, i);
371 uint inputNum =getSizeArrayElement(elements);
372 Element* el= getArrayElement(elements, i);
373 Constraint* carray[inputNum];
374 for(uint j=0; j<inputNum; j++){
375 carray[inputNum] = getElementValueConstraint(el, entry->inputs[j]);
377 Constraint* row= allocConstraint(IMPLIES, allocArrayConstraint(AND, inputNum, carray),
378 getElementValueBinaryIndexConstraint((Element*)This, entry->output));
381 Constraint* result = allocArrayConstraint(OR, size, constraints);