1 #include "satencoder.h"
5 #include "constraint.h"
9 #include "tableentry.h"
14 SATEncoder * allocSATEncoder() {
15 SATEncoder *This=ourmalloc(sizeof (SATEncoder));
20 void deleteSATEncoder(SATEncoder *This) {
24 void initializeConstraintVars(CSolver* csolver, SATEncoder* This){
25 /** We really should not walk the free list to generate constraint
26 variables...walk the constraint tree instead. Or even better
27 yet, just do this as you need to during the encodeAllSATEncoder
30 // FIXME!!!!(); // Make sure Hamed sees comment above
32 uint size = getSizeVectorElement(csolver->allElements);
33 for(uint i=0; i<size; i++){
34 Element* element = getVectorElement(csolver->allElements, i);
35 generateElementEncodingVariables(This,getElementEncoding(element));
40 Constraint * getElementValueConstraint(Element* This, uint64_t value) {
41 switch(getElementEncoding(This)->type){
52 return getElementValueBinaryIndexConstraint(This, value);
63 Constraint * getElementValueBinaryIndexConstraint(Element* This, uint64_t value) {
64 ASTNodeType type = GETELEMENTTYPE(This);
65 ASSERT(type == ELEMSET || type == ELEMFUNCRETURN);
66 ElementEncoding* elemEnc = getElementEncoding(This);
67 for(uint i=0; i<elemEnc->encArraySize; i++){
68 if( isinUseElement(elemEnc, i) && elemEnc->encodingArray[i]==value){
69 return generateBinaryConstraint(elemEnc->numVars,
70 elemEnc->variables, i);
77 void encodeAllSATEncoder(CSolver *csolver, SATEncoder * This) {
78 VectorBoolean *constraints=csolver->constraints;
79 uint size=getSizeVectorBoolean(constraints);
80 for(uint i=0;i<size;i++) {
81 Boolean *constraint=getVectorBoolean(constraints, i);
82 encodeConstraintSATEncoder(This, constraint);
85 size = getSizeVectorElement(csolver->allElements);
86 for(uint i=0; i<size; i++){
87 Element* element = getVectorElement(csolver->allElements, i);
88 switch(GETELEMENTTYPE(element)){
90 encodeFunctionElementSATEncoder(This, (ElementFunction*) element);
94 //ElementSets that aren't used in any constraints/functions
100 Constraint * encodeConstraintSATEncoder(SATEncoder *This, Boolean *constraint) {
101 switch(GETBOOLEANTYPE(constraint)) {
103 return encodeOrderSATEncoder(This, (BooleanOrder *) constraint);
105 return encodeVarSATEncoder(This, (BooleanVar *) constraint);
107 return encodeLogicSATEncoder(This, (BooleanLogic *) constraint);
109 return encodePredicateSATEncoder(This, (BooleanPredicate *) constraint);
111 model_print("Unhandled case in encodeConstraintSATEncoder %u", GETBOOLEANTYPE(constraint));
116 void getArrayNewVarsSATEncoder(SATEncoder* encoder, uint num, Constraint **carray) {
117 for(uint i=0;i<num;i++)
118 carray[i]=getNewVarSATEncoder(encoder);
121 Constraint * getNewVarSATEncoder(SATEncoder *This) {
122 Constraint * var=allocVarConstraint(VAR, This->varcount);
123 Constraint * varneg=allocVarConstraint(NOTVAR, This->varcount++);
124 setNegConstraint(var, varneg);
125 setNegConstraint(varneg, var);
129 Constraint * encodeVarSATEncoder(SATEncoder *This, BooleanVar * constraint) {
130 if (constraint->var == NULL) {
131 constraint->var=getNewVarSATEncoder(This);
133 return constraint->var;
136 Constraint * encodeLogicSATEncoder(SATEncoder *This, BooleanLogic * constraint) {
137 Constraint * array[getSizeArrayBoolean(&constraint->inputs)];
138 for(uint i=0;i<getSizeArrayBoolean(&constraint->inputs);i++)
139 array[i]=encodeConstraintSATEncoder(This, getArrayBoolean(&constraint->inputs, i));
141 switch(constraint->op) {
143 return allocArrayConstraint(AND, getSizeArrayBoolean(&constraint->inputs), array);
145 return allocArrayConstraint(OR, getSizeArrayBoolean(&constraint->inputs), array);
147 ASSERT(constraint->numArray==1);
148 return negateConstraint(array[0]);
150 ASSERT(constraint->numArray==2);
151 Constraint * nleft=negateConstraint(cloneConstraint(array[0]));
152 Constraint * nright=negateConstraint(cloneConstraint(array[1]));
153 return allocConstraint(OR,
154 allocConstraint(AND, array[0], nright),
155 allocConstraint(AND, nleft, array[1]));
158 ASSERT(constraint->numArray==2);
159 return allocConstraint(IMPLIES, array[0], array[1]);
161 model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
166 Constraint * encodeOrderSATEncoder(SATEncoder *This, BooleanOrder * constraint) {
167 switch( constraint->order->type){
169 return encodePartialOrderSATEncoder(This, constraint);
171 return encodeTotalOrderSATEncoder(This, constraint);
178 Constraint * encodeTotalOrderSATEncoder(SATEncoder *This, BooleanOrder * boolOrder){
179 ASSERT(boolOrder->order->type == TOTAL);
180 HashTableBoolConst* boolToConsts = boolOrder->order->boolsToConstraints;
181 if( containsBoolConst(boolToConsts, boolOrder) ){
182 return getBoolConst(boolToConsts, boolOrder);
184 Constraint* constraint = getNewVarSATEncoder(This);
185 putBoolConst(boolToConsts,boolOrder, constraint);
186 VectorBoolean* orderConstrs = &boolOrder->order->constraints;
187 uint size= getSizeVectorBoolean(orderConstrs);
188 for(uint i=0; i<size; i++){
189 ASSERT(GETBOOLEANTYPE( getVectorBoolean(orderConstrs, i)) == ORDERCONST );
190 BooleanOrder* tmp = (BooleanOrder*)getVectorBoolean(orderConstrs, i);
191 BooleanOrder* newBool;
192 Constraint *first, *second;
193 if(tmp->second==boolOrder->first){
194 newBool = (BooleanOrder*)allocBooleanOrder(tmp->order,tmp->first,boolOrder->second);
195 first = encodeTotalOrderSATEncoder(This, tmp);
198 }else if (boolOrder->second == tmp->first){
199 newBool = (BooleanOrder*)allocBooleanOrder(tmp->order,boolOrder->first,tmp->second);
201 second = encodeTotalOrderSATEncoder(This, tmp);
204 Constraint* transConstr= encodeTotalOrderSATEncoder(This, newBool);
205 generateTransOrderConstraintSATEncoder(This, first, second, transConstr );
213 Constraint * generateTransOrderConstraintSATEncoder(SATEncoder *This, Constraint *first,Constraint *second,Constraint *third){
214 //FIXME: first we should add the the constraint to the satsolver!
215 return allocConstraint(IMPLIES, allocConstraint(AND, first, second), third);
218 Constraint * encodePartialOrderSATEncoder(SATEncoder *This, BooleanOrder * constraint){
222 Constraint * encodePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
228 Constraint* encodeFunctionElementSATEncoder(SATEncoder* encoder, ElementFunction *This){
229 switch(GETFUNCTIONTYPE(This->function)){
231 return encodeTableElementFunctionSATEncoder(encoder, This);
233 return encodeOperatorElementFunctionSATEncoder(encoder, This);
240 Constraint* encodeTableElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
241 switch(getElementFunctionEncoding(This)->type){
242 case ENUMERATEIMPLICATIONS:
243 return encodeEnumTableElemFunctionSATEncoder(encoder, This);
254 Constraint* encodeOperatorElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
255 //FIXME: for now it just adds/substracts inputs exhustively
259 Constraint* encodeEnumTableElemFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
260 ASSERT(GETFUNCTIONTYPE(This->function)==TABLEFUNC);
261 ArrayElement* elements= &This->inputs;
262 Table* table = ((FunctionTable*) (This->function))->table;
263 uint size = getSizeVectorTableEntry(&table->entries);
264 Constraint* constraints[size]; //FIXME: should add a space for the case that didn't match any entries
265 for(uint i=0; i<size; i++){
266 TableEntry* entry = getVectorTableEntry(&table->entries, i);
267 uint inputNum =getSizeArrayElement(elements);
268 Element* el= getArrayElement(elements, i);
269 Constraint* carray[inputNum];
270 for(uint j=0; j<inputNum; j++){
271 carray[inputNum] = getElementValueConstraint(el, entry->inputs[j]);
273 Constraint* row= allocConstraint(IMPLIES, allocArrayConstraint(AND, inputNum, carray),
274 getElementValueBinaryIndexConstraint((Element*)This, entry->output));
277 Constraint* result = allocArrayConstraint(OR, size, constraints);