5 VectorImpl(Edge, Edge, 16)
8 CNF * cnf=ourmalloc(sizeof(CNF));
10 cnf->capacity=DEFAULT_CNF_ARRAY_SIZE;
11 cnf->mask=cnf->capacity-1;
12 cnf->node_array=ourcalloc(1, sizeof(Node *)*cnf->capacity);
14 cnf->maxsize=(uint)(((double)cnf->capacity)*LOAD_FACTOR);
15 allocInlineDefVectorEdge(& cnf->constraints);
19 void deleteCNF(CNF * cnf) {
20 for(uint i=0;i<cnf->capacity;i++) {
21 Node *n=cnf->node_array[i];
25 deleteVectorArrayEdge(& cnf->constraints);
26 ourfree(cnf->node_array);
30 void resizeCNF(CNF *cnf, uint newCapacity) {
31 Node **old_array=cnf->node_array;
32 Node **new_array=ourcalloc(1, sizeof(Node *)*newCapacity);
33 uint oldCapacity=cnf->capacity;
34 uint newMask=newCapacity-1;
35 for(uint i=0;i<oldCapacity;i++) {
37 uint hashCode=n->hashCode;
38 uint newindex=hashCode & newMask;
39 for(;;newindex=(newindex+1) & newMask) {
40 if (new_array[newindex] == NULL) {
41 new_array[newindex]=n;
47 cnf->node_array=new_array;
48 cnf->capacity=newCapacity;
49 cnf->maxsize=(uint)(((double)cnf->capacity)*LOAD_FACTOR);
53 Node * allocNode(NodeType type, uint numEdges, Edge * edges, uint hashcode) {
54 Node *n=(Node *)ourmalloc(sizeof(Node)+sizeof(Edge)*numEdges);
55 memcpy(n->edges, edges, sizeof(Edge)*numEdges);
57 n->flags.wasExpanded=0;
60 n->intAnnot[0]=0;n->intAnnot[1]=0;
61 n->ptrAnnot[0]=NULL;n->ptrAnnot[1]=NULL;
65 Edge createNode(CNF *cnf, NodeType type, uint numEdges, Edge * edges) {
66 if (cnf->size > cnf->maxsize) {
67 resizeCNF(cnf, cnf->capacity << 1);
69 uint hashvalue=hashNode(type, numEdges, edges);
71 uint index=hashvalue & mask;
73 for(;;index=(index+1)&mask) {
74 n_ptr=&cnf->node_array[index];
76 if ((*n_ptr)->hashCode==hashvalue) {
77 if (compareNodes(*n_ptr, type, numEdges, edges)) {
86 *n_ptr=allocNode(type, numEdges, edges, hashvalue);
91 uint hashNode(NodeType type, uint numEdges, Edge * edges) {
92 uint hashvalue=type ^ numEdges;
93 for(uint i=0;i<numEdges;i++) {
94 hashvalue ^= (uint) edges[i].node_ptr;
95 hashvalue = (hashvalue << 3) | (hashvalue >> 29); //rotate left by 3 bits
97 return (uint) hashvalue;
100 bool compareNodes(Node * node, NodeType type, uint numEdges, Edge *edges) {
101 if (node->flags.type!=type || node->numEdges != numEdges)
103 Edge *nodeedges=node->edges;
104 for(uint i=0;i<numEdges;i++) {
105 if (!equalsEdge(nodeedges[i], edges[i]))
111 Edge constraintOR(CNF * cnf, uint numEdges, Edge *edges) {
112 Edge edgearray[numEdges];
114 for(uint i=0; i<numEdges; i++) {
115 edgearray[i]=constraintNegate(edges[i]);
117 Edge eand=constraintAND(cnf, numEdges, edgearray);
118 return constraintNegate(eand);
121 Edge constraintOR2(CNF * cnf, Edge left, Edge right) {
122 Edge lneg=constraintNegate(left);
123 Edge rneg=constraintNegate(right);
124 Edge eand=constraintAND2(cnf, left, right);
125 return constraintNegate(eand);
128 int comparefunction(const Edge * e1, const Edge * e2) {
129 return ((uintptr_t)e1->node_ptr)-((uintptr_t)e2->node_ptr);
132 Edge constraintAND(CNF * cnf, uint numEdges, Edge * edges) {
133 qsort(edges, numEdges, sizeof(Edge), (int (*)(const void *, const void *)) comparefunction);
135 while(initindex<numEdges && equalsEdge(edges[initindex], E_True))
138 uint remainSize=numEdges-initindex;
142 else if (remainSize == 1)
143 return edges[initindex];
144 else if (equalsEdge(edges[initindex], E_False))
147 /** De-duplicate array */
149 edges[lowindex++]=edges[initindex++];
151 for(;initindex<numEdges;initindex++) {
152 Edge e1=edges[lowindex];
153 Edge e2=edges[initindex];
154 if (sameNodeVarEdge(e1, e2)) {
155 if (!sameSignEdge(e1, e2)) {
159 edges[lowindex++]=edges[initindex];
164 if (enableMatching && lowindex==2 &&
165 isNegNodeEdge(edges[0]) && isNegNodeEdge(edges[1]) &&
166 getNodeType(edges[0]) == NodeType_AND &&
167 getNodeType(edges[1]) == NodeType_AND &&
168 getNodeSize(edges[0]) == 2 &&
169 getNodeSize(edges[1]) == 2) {
170 Edge * e0edges=getEdgeArray(edges[0]);
171 Edge * e1edges=getEdgeArray(edges[1]);
172 if (sameNodeOppSign(e0edges[0], e1edges[0])) {
173 return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[1]));
174 } else if (sameNodeOppSign(e0edges[0], e1edges[1])) {
175 return constraintNegate(constraintITE(cnf, e0edges[0], e0edges[1], e1edges[0]));
176 } else if (sameNodeOppSign(e0edges[1], e1edges[0])) {
177 return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[1]));
178 } else if (sameNodeOppSign(e0edges[1], e1edges[1])) {
179 return constraintNegate(constraintITE(cnf, e0edges[1], e0edges[0], e1edges[0]));
183 return createNode(cnf, NodeType_AND, numEdges, edges);
186 Edge constraintAND2(CNF * cnf, Edge left, Edge right) {
187 Edge edges[2]={left, right};
188 return constraintAND(cnf, 2, edges);
191 Edge constraintIMPLIES(CNF * cnf, Edge left, Edge right) {
194 array[1]=constraintNegate(right);
195 Edge eand=constraintAND(cnf, 2, array);
196 return constraintNegate(eand);
199 Edge constraintIFF(CNF * cnf, Edge left, Edge right) {
200 bool negate=sameSignEdge(left, right);
201 Edge lpos=getNonNeg(left);
202 Edge rpos=getNonNeg(right);
205 if (equalsEdge(lpos, rpos)) {
207 } else if (ltEdge(lpos, rpos)) {
208 Edge edges[]={lpos, rpos};
209 e=(edgeIsConst(lpos)) ? rpos : createNode(cnf, NodeType_IFF, 2, edges);
211 Edge edges[]={rpos, lpos};
212 e=(edgeIsConst(rpos)) ? lpos : createNode(cnf, NodeType_IFF, 2, edges);
215 e=constraintNegate(e);
219 Edge constraintITE(CNF * cnf, Edge cond, Edge thenedge, Edge elseedge) {
220 if (isNegEdge(cond)) {
221 cond=constraintNegate(cond);
227 bool negate = isNegEdge(thenedge);
229 thenedge=constraintNegate(thenedge);
230 elseedge=constraintNegate(elseedge);
234 if (equalsEdge(cond, E_True)) {
236 } else if (equalsEdge(thenedge, E_True) || equalsEdge(cond, thenedge)) {
237 result=constraintOR(cnf, 2, (Edge[]) {cond, elseedge});
238 } else if (equalsEdge(elseedge, E_True) || sameNodeOppSign(cond, elseedge)) {
239 result=constraintIMPLIES(cnf, cond, thenedge);
240 } else if (equalsEdge(thenedge, E_False) || equalsEdge(cond, elseedge)) {
241 result=constraintAND(cnf, 2, (Edge[]) {cond, thenedge});
242 } else if (equalsEdge(thenedge, elseedge)) {
244 } else if (sameNodeOppSign(thenedge, elseedge)) {
245 if (ltEdge(cond, thenedge)) {
246 result=createNode(cnf, NodeType_IFF, 2, (Edge[]) {cond, thenedge});
248 result=createNode(cnf, NodeType_IFF, 2, (Edge[]) {thenedge, cond});
251 Edge edges[]={cond, thenedge, elseedge};
252 result=createNode(cnf, NodeType_ITE, 3, edges);
255 result=constraintNegate(result);
259 void addConstraint(CNF *cnf, Edge constraint) {
260 pushVectorEdge(&cnf->constraints, constraint);
263 Edge constraintNewVar(CNF *cnf) {
264 uint varnum=cnf->varcount++;
265 Edge e={(Node *) ((((uintptr_t)varnum) << VAR_SHIFT) | EDGE_IS_VAR_CONSTANT) };
269 void countPass(CNF *cnf) {
270 uint numConstraints=getSizeVectorEdge(&cnf->constraints);
271 VectorEdge *ve=allocDefVectorEdge();
272 for(uint i=0; i<numConstraints;i++) {
273 countConstraint(cnf, ve, getVectorEdge(&cnf->constraints, i));
275 deleteVectorEdge(ve);
278 void countConstraint(CNF *cnf, VectorEdge *stack, Edge e) {
279 //Skip constants and variables...
280 if (edgeIsVarConst(e))
283 clearVectorEdge(stack);pushVectorEdge(stack, e);
285 while(getSizeVectorEdge(stack) != 0) {
286 Edge e=lastVectorEdge(stack); popVectorEdge(stack);
287 bool polarity=isNegEdge(e);
288 Node *n=getNodePtrFromEdge(e);
289 if (getExpanded(n, polarity)) {
290 if (n->flags.type == NodeType_IFF ||
291 n->flags.type == NodeType_ITE) {
292 Edge pExp={n->ptrAnnot[polarity]};
293 getNodePtrFromEdge(pExp)->intAnnot[0]++;
295 n->intAnnot[polarity]++;
298 setExpanded(n, polarity); n->intAnnot[polarity]=1;
300 if (n->flags.type == NodeType_ITE||
301 n->flags.type == NodeType_IFF) {
302 n->intAnnot[polarity]=0;
303 Edge tst=n->edges[0];
304 Edge thenedge=n->edges[1];
305 Edge elseedge=n->flags.type == NodeType_IFF? constraintNegate(thenedge): n->edges[2];