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 uint size = getSizeVectorElement(csolver->allElements);
26 for(uint i=0; i<size; i++){
27 Element* element = getVectorElement(csolver->allElements, i);
28 generateElementEncodingVariables(This,getElementEncoding(element));
32 void encodeAllSATEncoder(CSolver *csolver, SATEncoder * This) {
33 VectorBoolean *constraints=csolver->constraints;
34 uint size=getSizeVectorBoolean(constraints);
35 for(uint i=0;i<size;i++) {
36 Boolean *constraint=getVectorBoolean(constraints, i);
37 encodeConstraintSATEncoder(This, constraint);
40 size = getSizeVectorElement(csolver->allElements);
41 for(uint i=0; i<size; i++){
42 Element* element = getVectorElement(csolver->allElements, i);
43 switch(GETELEMENTTYPE(element)){
45 encodeFunctionElementSATEncoder(This, (ElementFunction*) element);
49 //ElementSets that aren't used in any constraints/functions
55 Constraint * encodeConstraintSATEncoder(SATEncoder *This, Boolean *constraint) {
56 switch(GETBOOLEANTYPE(constraint)) {
58 return encodeOrderSATEncoder(This, (BooleanOrder *) constraint);
60 return encodeVarSATEncoder(This, (BooleanVar *) constraint);
62 return encodeLogicSATEncoder(This, (BooleanLogic *) constraint);
64 return encodePredicateSATEncoder(This, (BooleanPredicate *) constraint);
66 model_print("Unhandled case in encodeConstraintSATEncoder %u", GETBOOLEANTYPE(constraint));
71 void getArrayNewVarsSATEncoder(SATEncoder* encoder, uint num, Constraint **carray) {
72 for(uint i=0;i<num;i++)
73 carray[i]=getNewVarSATEncoder(encoder);
76 Constraint * getNewVarSATEncoder(SATEncoder *This) {
77 Constraint * var=allocVarConstraint(VAR, This->varcount);
78 Constraint * varneg=allocVarConstraint(NOTVAR, This->varcount++);
79 setNegConstraint(var, varneg);
80 setNegConstraint(varneg, var);
84 Constraint * encodeVarSATEncoder(SATEncoder *This, BooleanVar * constraint) {
85 if (constraint->var == NULL) {
86 constraint->var=getNewVarSATEncoder(This);
88 return constraint->var;
91 Constraint * encodeLogicSATEncoder(SATEncoder *This, BooleanLogic * constraint) {
92 Constraint * array[getSizeArrayBoolean(&constraint->inputs)];
93 for(uint i=0;i<getSizeArrayBoolean(&constraint->inputs);i++)
94 array[i]=encodeConstraintSATEncoder(This, getArrayBoolean(&constraint->inputs, i));
96 switch(constraint->op) {
98 return allocArrayConstraint(AND, getSizeArrayBoolean(&constraint->inputs), array);
100 return allocArrayConstraint(OR, getSizeArrayBoolean(&constraint->inputs), array);
102 ASSERT(constraint->numArray==1);
103 return negateConstraint(array[0]);
105 ASSERT(constraint->numArray==2);
106 Constraint * nleft=negateConstraint(cloneConstraint(array[0]));
107 Constraint * nright=negateConstraint(cloneConstraint(array[1]));
108 return allocConstraint(OR,
109 allocConstraint(AND, array[0], nright),
110 allocConstraint(AND, nleft, array[1]));
113 ASSERT(constraint->numArray==2);
114 return allocConstraint(IMPLIES, array[0], array[1]);
116 model_print("Unhandled case in encodeLogicSATEncoder %u", constraint->op);
121 Constraint * encodeOrderSATEncoder(SATEncoder *This, BooleanOrder * constraint) {
122 if(constraint->var== NULL){
123 constraint->var = getNewVarSATEncoder(This);
125 return constraint->var;
128 Constraint * encodePredicateSATEncoder(SATEncoder * This, BooleanPredicate * constraint) {
134 Constraint* encodeFunctionElementSATEncoder(SATEncoder* encoder, ElementFunction *This){
135 switch(GETFUNCTIONTYPE(This->function)){
137 return encodeTableElementFunctionSATEncoder(encoder, This);
139 return encodeOperatorElementFunctionSATEncoder(encoder, This);
146 Constraint* encodeTableElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
147 switch(getElementFunctionEncoding(This)->type){
148 case ENUMERATEIMPLICATIONS:
149 return encodeEnumTableElemFunctionSATEncoder(encoder, This);
160 Constraint* encodeOperatorElementFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
161 //FIXME: for now it just adds/substracts inputs exhustively
165 Constraint* encodeEnumTableElemFunctionSATEncoder(SATEncoder* encoder, ElementFunction* This){
166 ASSERT(GETFUNCTIONTYPE(This->function)==TABLEFUNC);
167 ArrayElement* elements= &This->inputs;
168 Table* table = ((FunctionTable*) (This->function))->table;
169 uint size = getSizeVectorTableEntry(&table->entries);
170 Constraint* constraints[size]; //FIXME: should add a space for the case that didn't match any entries
171 for(uint i=0; i<size; i++){
172 TableEntry* entry = getVectorTableEntry(&table->entries, i);
173 uint inputNum =getSizeArrayElement(elements);
174 Element* el= getArrayElement(elements, i);
175 Constraint* carray[inputNum];
176 for(uint j=0; j<inputNum; j++){
177 carray[inputNum] = getElementValueBinaryIndexConstraint(el, entry->inputs[j]);
179 Constraint* row= allocConstraint(IMPLIES, allocArrayConstraint(AND, inputNum, carray),
180 getElementValueBinaryIndexConstraint((Element*)This, entry->output));
183 Constraint* result = allocArrayConstraint(OR, size, constraints);