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);
69 void dumpConstraint(Constraint * This, IncrementalSolver *solver) {
70 if (This->type==VAR) {
71 addClauseLiteral(solver, This->numoperandsorvar);
72 addClauseLiteral(solver, 0);
73 } else if (This->type==NOTVAR) {
74 addClauseLiteral(solver, -This->numoperandsorvar);
75 addClauseLiteral(solver, 0);
77 ASSERT(This->type==OR);
78 for(uint i=0;i<This->numoperandsorvar;i++) {
79 Constraint *c=This->operands[i];
81 addClauseLiteral(solver, c->numoperandsorvar);
82 } else if (c->type==NOTVAR) {
83 addClauseLiteral(solver, -c->numoperandsorvar);
86 addClauseLiteral(solver, 0);
90 void internalfreeConstraint(Constraint * This) {
101 deleteConstraint(This);
105 void freerecConstraint(Constraint *This) {
115 if (This->operands!=NULL) {
116 for(uint i=0;i<This->numoperandsorvar;i++)
117 freerecConstraint(This->operands[i]);
120 deleteConstraint(This);
125 void printConstraint(Constraint * This) {
131 model_print("false");
135 printConstraint(This->operands[0]);
139 printConstraint(This->operands[1]);
145 for(uint i=0;i<This->numoperandsorvar;i++) {
152 printConstraint(This->operands[i]);
157 model_print("t%u",This->numoperandsorvar);
160 model_print("!t%u",This->numoperandsorvar);
163 model_print("In printingConstraint: %d", This->type);
168 Constraint * cloneConstraint(Constraint * This) {
176 return allocConstraint(IMPLIES, cloneConstraint(This->operands[0]), cloneConstraint(This->operands[1]));
179 Constraint *array[This->numoperandsorvar];
180 for(uint i=0;i<This->numoperandsorvar;i++) {
181 array[i]=cloneConstraint(This->operands[i]);
183 return allocArrayConstraint(This->type, This->numoperandsorvar, array);
191 Constraint * generateBinaryConstraint(uint numvars, Constraint ** vars, uint value) {
192 Constraint *carray[numvars];
193 for(uint j=0;j<numvars;j++) {
194 carray[j]=((value&1)==1) ? vars[j] : negateConstraint(vars[j]);
198 return allocArrayConstraint(AND, numvars, carray);
201 /** Generates a constraint to ensure that all encodings are less than value */
202 Constraint * generateLTConstraint(uint numvars, Constraint ** vars, uint value) {
203 Constraint *orarray[numvars];
204 Constraint *andarray[numvars];
210 for(uint j=0;j<numvars;j++) {
212 orarray[ori++]=negateConstraint(vars[j]);
215 //no ones to flip, so bail now...
217 return allocArrayConstraint(AND, andi, andarray);
219 andarray[andi++]=allocArrayConstraint(OR, ori, orarray);
221 value=value+(1<<(__builtin_ctz(value)));
226 Constraint * generateEquivNVConstraint(uint numvars, Constraint **var1, Constraint **var2) {
229 Constraint *array[numvars*2];
230 for(uint i=0;i<numvars;i++) {
231 array[i*2]=allocConstraint(OR, negateConstraint(cloneConstraint(var1[i])), var2[i]);
232 array[i*2+1]=allocConstraint(OR, var1[i], negateConstraint(cloneConstraint(var2[i])));
234 return allocArrayConstraint(AND, numvars*2, array);
237 Constraint * generateEquivConstraint(Constraint *var1, Constraint *var2) {
238 Constraint * imp1=allocConstraint(OR, negateConstraint(cloneConstraint(var1)), var2);
239 Constraint * imp2=allocConstraint(OR, var1, negateConstraint(cloneConstraint(var2)));
241 return allocConstraint(AND, imp1, imp2);
244 bool mergeandfree(VectorConstraint * to, VectorConstraint * from) {
245 for(uint i=0;i<getSizeVectorConstraint(from);i++) {
246 Constraint *c=getVectorConstraint(from, i);
249 if (c->type==FALSE) {
250 for(uint j=i+1;j<getSizeVectorConstraint(from);j++)
251 freerecConstraint(getVectorConstraint(from,j));
252 for(uint j=0;j<getSizeVectorConstraint(to);j++)
253 freerecConstraint(getVectorConstraint(to, j));
254 clearVectorConstraint(to);
255 pushVectorConstraint(to, &ctrue);
256 deleteVectorConstraint(from);
259 pushVectorConstraint(to, c);
261 deleteVectorConstraint(from);
265 VectorConstraint * simplifyConstraint(Constraint * This) {
271 VectorConstraint * vec=allocDefVectorConstraint();
272 pushVectorConstraint(vec, This);
276 VectorConstraint *vec=allocDefVectorConstraint();
277 for(uint i=0;i<This->numoperandsorvar;i++) {
278 VectorConstraint * subvec=simplifyConstraint(This->operands[i]);
279 if (mergeandfree(vec, subvec)) {
280 for(uint j=i+1;j<This->numoperandsorvar;j++) {
281 freerecConstraint(This->operands[j]);
283 internalfreeConstraint(This);
287 internalfreeConstraint(This);
291 for(uint i=0;i<This->numoperandsorvar;i++) {
292 Constraint *c=This->operands[i];
295 VectorConstraint * vec=allocDefVectorConstraint();
296 pushVectorConstraint(vec, c);
297 freerecConstraint(This);
301 Constraint *array[This->numoperandsorvar-1];
303 for(uint j=0;j<This->numoperandsorvar;j++) {
305 array[index++]=This->operands[j];
307 Constraint *cn=allocArrayConstraint(OR, index, array);
308 VectorConstraint *vec=simplifyConstraint(cn);
309 internalfreeConstraint(This);
316 uint nsize=This->numoperandsorvar+c->numoperandsorvar-1;
317 Constraint *array[nsize];
319 for(uint j=0;j<This->numoperandsorvar;j++)
321 array[index++]=This->operands[j];
322 for(uint j=0;j<c->numoperandsorvar;j++)
323 array[index++]=c->operands[j];
324 Constraint *cn=allocArrayConstraint(OR, nsize, array);
325 VectorConstraint *vec=simplifyConstraint(cn);
326 internalfreeConstraint(This);
327 internalfreeConstraint(c);
331 uint nsize=This->numoperandsorvar+1;
332 Constraint *array[nsize];
334 for(uint j=0;j<This->numoperandsorvar;j++)
336 array[index++]=This->operands[j];
337 array[index++]=negateConstraint(c->operands[0]);
338 array[index++]=c->operands[1];
339 Constraint *cn=allocArrayConstraint(OR, nsize, array);
340 VectorConstraint *vec=simplifyConstraint(cn);
341 internalfreeConstraint(This);
342 internalfreeConstraint(c);
346 Constraint *array[This->numoperandsorvar];
348 VectorConstraint *vec=allocDefVectorConstraint();
349 for(uint j=0;j<c->numoperandsorvar;j++) {
350 //copy other elements
351 for(uint k=0;k<This->numoperandsorvar;k++) {
353 array[k]=cloneConstraint(This->operands[k]);
357 array[i]=cloneConstraint(c->operands[j]);
358 Constraint *cn=allocArrayConstraint(OR, This->numoperandsorvar, array);
359 VectorConstraint * newvec=simplifyConstraint(cn);
360 if (mergeandfree(vec, newvec)) {
361 freerecConstraint(This);
365 freerecConstraint(This);
371 //continue on to next item
373 VectorConstraint * vec=allocDefVectorConstraint();
374 if (This->numoperandsorvar==1) {
375 Constraint *c=This->operands[0];
376 freerecConstraint(This);
377 pushVectorConstraint(vec, c);
379 pushVectorConstraint(vec, This);
383 Constraint *cn=allocConstraint(OR, negateConstraint(This->operands[0]), This->operands[1]);
384 VectorConstraint * vec=simplifyConstraint(cn);
385 internalfreeConstraint(This);
394 Constraint * negateConstraint(Constraint * This) {
404 Constraint *l=This->operands[0];
405 Constraint *r=This->operands[1];
412 for(uint i=0;i<This->numoperandsorvar;i++) {
413 This->operands[i]=negateConstraint(This->operands[i]);
415 This->type=(This->type==AND) ? OR : AND;