1 /* Copyright (c) 2015 Regents of the University of California
3 * Author: Brian Demsky <bdemsky@uci.edu>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
10 #include "constraint.h"
12 #include "inc_solver.h"
14 Constraint ctrue={TRUE, 0xffffffff, NULL, NULL};
15 Constraint cfalse={FALSE, 0xffffffff, NULL, NULL};
17 Constraint * allocConstraint(CType t, Constraint *l, Constraint *r) {
18 Constraint *this=(Constraint *) ourmalloc(sizeof(Constraint));
20 this->numoperandsorvar=2;
21 this->operands=(Constraint **)ourmalloc(2*sizeof(Constraint *));
24 //if (type==IMPLIES) {
26 // operands[0]=l->negate();
34 Constraint * allocUnaryConstraint(CType t, Constraint *l) {
35 Constraint *this=(Constraint *) ourmalloc(sizeof(Constraint));
37 this->numoperandsorvar=1;
38 this->operands=(Constraint **) ourmalloc(sizeof(Constraint *));
44 Constraint * allocArrayConstraint(CType t, uint num, Constraint **array) {
45 Constraint *this=(Constraint *) ourmalloc(sizeof(Constraint));
47 this->numoperandsorvar=num;
48 this->operands=(Constraint **) ourmalloc(num*sizeof(Constraint *));
50 memcpy(this->operands, array, num*sizeof(Constraint *));
54 Constraint * allocVarConstraint(CType t, uint v) {
55 Constraint *this=(Constraint *) ourmalloc(sizeof(Constraint));
57 this->numoperandsorvar=v;
63 void deleteConstraint(Constraint *this) {
64 if (this->operands!=NULL)
65 ourfree(this->operands);
68 void dumpConstraint(Constraint * this, IncrementalSolver *solver) {
69 if (this->type==VAR) {
70 addClauseLiteral(solver, this->numoperandsorvar);
71 addClauseLiteral(solver, 0);
72 } else if (this->type==NOTVAR) {
73 addClauseLiteral(solver, -this->numoperandsorvar);
74 addClauseLiteral(solver, 0);
76 ASSERT(this->type==OR);
77 for(uint i=0;i<this->numoperandsorvar;i++) {
78 Constraint *c=this->operands[i];
80 addClauseLiteral(solver, c->numoperandsorvar);
81 } else if (c->type==NOTVAR) {
82 addClauseLiteral(solver, -c->numoperandsorvar);
85 addClauseLiteral(solver, 0);
89 void internalfreeConstraint(Constraint * this) {
104 void freerecConstraint(Constraint *this) {
114 if (this->operands!=NULL) {
115 for(uint i=0;i<this->numoperandsorvar;i++)
116 freerecConstraint(this->operands[i]);
119 deleteConstraint(this);
124 void printConstraint(Constraint * this) {
130 model_print("false");
134 printConstraint(this->operands[0]);
138 printConstraint(this->operands[1]);
144 for(uint i=0;i<this->numoperandsorvar;i++) {
151 printConstraint(this->operands[i]);
156 model_print("t%u",this->numoperandsorvar);
159 model_print("!t%u",this->numoperandsorvar);
166 Constraint * cloneConstraint(Constraint * this) {
174 return allocConstraint(IMPLIES, cloneConstraint(this->operands[0]), cloneConstraint(this->operands[1]));
177 Constraint *array[this->numoperandsorvar];
178 for(uint i=0;i<this->numoperandsorvar;i++) {
179 array[i]=cloneConstraint(this->operands[i]);
181 return allocArrayConstraint(this->type, this->numoperandsorvar, array);
189 Constraint * generateConstraint(uint numvars, Constraint ** vars, uint value) {
190 Constraint *carray[numvars];
191 for(uint j=0;j<numvars;j++) {
192 carray[j]=((value&1)==1) ? vars[j] : negateConstraint(vars[j]);
196 return allocArrayConstraint(AND, numvars, carray);
199 /** Generates a constraint to ensure that all encodings are less than value */
200 Constraint * generateLTConstraint(uint numvars, Constraint ** vars, uint value) {
201 Constraint *orarray[numvars];
202 Constraint *andarray[numvars];
208 for(uint j=0;j<numvars;j++) {
210 orarray[ori++]=negateConstraint(vars[j]);
213 //no ones to flip, so bail now...
215 return allocArrayConstraint(AND, andi, andarray);
217 andarray[andi++]=allocArrayConstraint(OR, ori, orarray);
219 value=value+(1<<(__builtin_ctz(value)));
224 Constraint * generateEquivNVConstraint(uint numvars, Constraint **var1, Constraint **var2) {
227 Constraint *array[numvars*2];
228 for(uint i=0;i<numvars;i++) {
229 array[i*2]=allocConstraint(OR, negateConstraint(cloneConstraint(var1[i])), var2[i]);
230 array[i*2+1]=allocConstraint(OR, var1[i], negateConstraint(cloneConstraint(var2[i])));
232 return allocArrayConstraint(AND, numvars*2, array);
235 Constraint * generateEquivConstraint(Constraint *var1, Constraint *var2) {
236 Constraint * imp1=allocConstraint(OR, negateConstraint(cloneConstraint(var1)), var2);
237 Constraint * imp2=allocConstraint(OR, var1, negateConstraint(cloneConstraint(var2)));
239 return allocConstraint(AND, imp1, imp2);
242 bool mergeandfree(VectorConstraint * to, VectorConstraint * from) {
243 for(uint i=0;i<getSizeVectorConstraint(from);i++) {
244 Constraint *c=getVectorConstraint(from, i);
247 if (c->type==FALSE) {
248 for(uint j=i+1;j<getSizeVectorConstraint(from);j++)
249 freerecConstraint(getVectorConstraint(from,j));
250 for(uint j=0;j<getSizeVectorConstraint(to);j++)
251 freerecConstraint(getVectorConstraint(to, j));
252 clearVectorConstraint(to);
253 pushVectorConstraint(to, &ctrue);
254 deleteVectorConstraint(from);
257 pushVectorConstraint(to, c);
259 deleteVectorConstraint(from);
263 VectorConstraint * simplifyConstraint(Constraint * this) {
269 VectorConstraint * vec=allocDefVectorConstraint();
270 pushVectorConstraint(vec, this);
274 VectorConstraint *vec=allocDefVectorConstraint();
275 for(uint i=0;i<this->numoperandsorvar;i++) {
276 VectorConstraint * subvec=simplifyConstraint(this->operands[i]);
277 if (mergeandfree(vec, subvec)) {
278 for(uint j=i+1;j<this->numoperandsorvar;j++) {
279 freerecConstraint(this->operands[j]);
281 internalfreeConstraint(this);
285 internalfreeConstraint(this);
289 for(uint i=0;i<this->numoperandsorvar;i++) {
290 Constraint *c=this->operands[i];
293 VectorConstraint * vec=allocDefVectorConstraint();
294 pushVectorConstraint(vec, c);
295 freerecConstraint(this);
299 Constraint *array[this->numoperandsorvar-1];
301 for(uint j=0;j<this->numoperandsorvar;j++) {
303 array[index++]=this->operands[j];
305 Constraint *cn=allocArrayConstraint(OR, index, array);
306 VectorConstraint *vec=simplifyConstraint(cn);
307 internalfreeConstraint(this);
314 uint nsize=this->numoperandsorvar+c->numoperandsorvar-1;
315 Constraint *array[nsize];
317 for(uint j=0;j<this->numoperandsorvar;j++)
319 array[index++]=this->operands[j];
320 for(uint j=0;j<c->numoperandsorvar;j++)
321 array[index++]=c->operands[j];
322 Constraint *cn=allocArrayConstraint(OR, nsize, array);
323 VectorConstraint *vec=simplifyConstraint(cn);
324 internalfreeConstraint(this);
325 internalfreeConstraint(c);
329 uint nsize=this->numoperandsorvar+1;
330 Constraint *array[nsize];
332 for(uint j=0;j<this->numoperandsorvar;j++)
334 array[index++]=this->operands[j];
335 array[index++]=negateConstraint(c->operands[0]);
336 array[index++]=c->operands[1];
337 Constraint *cn=allocArrayConstraint(OR, nsize, array);
338 VectorConstraint *vec=simplifyConstraint(cn);
339 internalfreeConstraint(this);
340 internalfreeConstraint(c);
344 Constraint *array[this->numoperandsorvar];
346 VectorConstraint *vec=allocDefVectorConstraint();
347 for(uint j=0;j<c->numoperandsorvar;j++) {
348 //copy other elements
349 for(uint k=0;k<this->numoperandsorvar;k++) {
351 array[k]=cloneConstraint(this->operands[k]);
355 array[i]=cloneConstraint(c->operands[j]);
356 Constraint *cn=allocArrayConstraint(OR, this->numoperandsorvar, array);
357 VectorConstraint * newvec=simplifyConstraint(cn);
358 if (mergeandfree(vec, newvec)) {
359 freerecConstraint(this);
363 freerecConstraint(this);
369 //continue on to next item
371 VectorConstraint * vec=allocDefVectorConstraint();
372 if (this->numoperandsorvar==1) {
373 Constraint *c=this->operands[0];
374 freerecConstraint(this);
375 pushVectorConstraint(vec, c);
377 pushVectorConstraint(vec, this);
381 Constraint *cn=allocConstraint(OR, negateConstraint(this->operands[0]), this->operands[1]);
382 VectorConstraint * vec=simplifyConstraint(cn);
383 internalfreeConstraint(this);
392 Constraint * negateConstraint(Constraint * this) {
402 Constraint *l=this->operands[0];
403 Constraint *r=this->operands[1];
410 for(uint i=0;i<this->numoperandsorvar;i++) {
411 this->operands[i]=negateConstraint(this->operands[i]);
413 this->type=(this->type==AND) ? OR : AND;