1 // Constantinos Bartzis bar@cs.uscb.edu
17 int i
, ir
; //state index
18 int s
, sr
; //status: 0=not yet processed
21 //ir and sr are for the rejecting clone
24 int *corresP
; //used by dfaEquivalence
26 //returns the gcd of integers x and y
27 int gcd(int x
, int y
){
38 //returns the sum of the coefficients for the non-zero bits up to the k-th
39 //ith coefficient corresponds to the ith least-significant bit
40 int count_ones(long n
, int k
, int *coeffs
){
43 if(n
&1) ones
+=coeffs
[k
];
49 //Returns a string of length k containing the binary representation of i
50 char *bintostr(unsigned long n
, int k
){
52 str
=(char *)malloc(k
+1);
63 //reduces the coefficients by dividing them with their gcd
64 //kind: 0 for = , 1 for <
65 //returns 1 for contradictions
66 int preprocess(int vars
, int *coef
, int *cons
, int kind
){
68 int temp
=abs(coef
[0]);
69 for (i
=1; i
<vars
; i
++)
70 temp
=gcd(abs(coef
[i
]),temp
);
71 for (i
=0; i
<vars
; i
++)
82 if (*cons
>=0) *cons
=*cons
/temp
;
83 else *cons
=(*cons
+1)/temp
-1;
90 //Constructs a DFA for the equation coeffs*variables+constant=0
91 DFA
*build_DFA_eq(int vars
, int *coeffs
, int constant
, int *indices
){
92 int min
, max
, states
, next_index
, next_label
, result
, target
,
95 unsigned long j
, transitions
;
101 if (preprocess(vars
, coeffs
, &constant
, 0)) return dfaFalse();
107 for (i
=0; i
<vars
; i
++)
108 if (coeffs
[i
]>0) max
+=coeffs
[i
];
112 if (constant
>max
) max
=constant
;
113 else if(constant
<min
) min
=constant
;
115 if(states
>range
*(log_2(constant
)+1)+1)
116 states
=range
*(log_2(constant
)+1)+1;
118 rev_map
=(int *)malloc((states
+1)*sizeof(int));
119 for(i
=0;i
<=states
;i
++)
123 //This array maps state labels (carries) to state indices
124 map
= (struct map_ent
*)malloc((max
-min
+2)*sizeof(struct map_ent
)) -min
;
125 for(i
=min
; i
<max
+2; i
++){
129 map
[constant
].s
=1; //the first state to be expanded
130 next_index
=0; //the next available state index
131 next_label
=constant
; //the next available state label
136 transitions
=1<<vars
; //number of transitions from each state
139 dfaSetup(states
, vars
, indices
);
142 while(next_label
<max
+1){ //there is a state to expand (excuding sink)
144 dfaAllocExceptions(transitions
/2);
145 for(j
=0; j
<transitions
; j
++){
146 result
=next_label
+count_ones(j
,vars
,coeffs
);
149 if(map
[target
].s
==0){
152 map
[target
].i
=next_index
;
153 rev_map
[next_index
]=target
;
155 dfaStoreException(map
[target
].i
,bintostr(j
,vars
));
158 dfaStoreState(states
-1);
160 // for(next_label=min; (next_label<=max) &&
161 //(map[next_label].i!=count); next_label++);
162 //find next state to expand
163 next_label
=rev_map
[count
];
165 for(;count
<states
;count
++){
166 dfaAllocExceptions(0);
167 dfaStoreState(states
-1);
170 //define accepting and rejecting states
171 statuces
=(char *)malloc(states
+1);
172 for(i
=0;i
<states
;i
++)
174 if (map
[0].s
==2) statuces
[map
[0].i
]='+';
175 statuces
[states
]='\0';
176 temp
=dfaBuild(statuces
);
177 equality
=dfaMinimize(temp
);
184 // Constructs a DFA for the equation coeffs*variables+constant=0
185 // in two's complement arithmetic
186 DFA
*build_DFA_eq_2sc(int vars
, int *coeffs
, int constant
, int *indices
){
187 int min
, max
, states
, next_index
, next_label
, result
, target
, count
;
189 unsigned long j
, transitions
;
192 DFA
*equality
, *temp
;
194 if (preprocess(vars
, coeffs
, &constant
, 0)) return dfaFalse();
200 for (i
=0; i
<vars
; i
++)
201 if (coeffs
[i
]>0) max
+=coeffs
[i
];
204 if (constant
>max
) max
=constant
;
205 else if(constant
<min
) min
=constant
;
206 states
=2*max
-2*min
+3;
209 //This array maps state labels (carries) to state indices
210 map
= (struct map_ent
*)malloc(states
*sizeof(struct map_ent
)) -min
;
211 for(i
=min
; i
<max
+2; i
++){
218 map
[constant
].sr
=1; //the first state to be expanded
219 next_index
=0; //the next available state index
220 next_label
=constant
; //the next available state label
225 transitions
=1<<vars
; //number of transitions from each state
228 dfaSetup(states
, vars
, indices
);
231 while(next_label
<max
+1){ //there is a state to expand (excuding sink)
232 if(map
[next_label
].i
==count
)
235 map
[next_label
].sr
=2;
236 dfaAllocExceptions(transitions
/2);
237 for(j
=0; j
<transitions
; j
++){
238 result
=next_label
+count_ones(j
,vars
,coeffs
);
241 if (target
==next_label
){
242 if(map
[target
].s
==0){
245 map
[target
].i
=next_index
;
247 dfaStoreException(map
[target
].i
,bintostr(j
,vars
));
250 if(map
[target
].sr
==0){
253 map
[target
].ir
=next_index
;
255 dfaStoreException(map
[target
].ir
,bintostr(j
,vars
));
259 dfaStoreState(states
-1);
261 for(next_label
=min
; (next_label
<=max
) &&
262 (map
[next_label
].i
!=count
)&&(map
[next_label
].ir
!=count
); next_label
++);
263 //find next state to expand
265 for(;count
<states
;count
++){
266 dfaAllocExceptions(0);
267 dfaStoreState(states
-1);
270 //define accepting and rejecting states
271 statuces
=(char *)malloc(states
+1);
272 for(i
=0;i
<states
;i
++)
274 for(next_label
=min
;next_label
<=max
;next_label
++)
275 if (map
[next_label
].s
==2) statuces
[map
[next_label
].i
]='+';
276 statuces
[states
]='\0';
277 temp
=dfaBuild(statuces
);
278 equality
=dfaMinimize(temp
);
283 //Constructs a DFA for the inequation coeffs*variables+constant<0
284 DFA
*build_DFA_ineq(int vars
, int *coeffs
, int constant
, int *indices
){
285 int min
, max
, states
, next_index
, next_label
, result
, target
, count
, range
;
286 long i
, transitions
, k
;
290 DFA
*inequality
, *temp
;
293 preprocess(vars
, coeffs
, &constant
, 1);
299 for (i
=0; i
<vars
; i
++)
300 if (coeffs
[i
]>0) max
+=coeffs
[i
];
304 if (constant
>max
) max
=constant
;
305 else if(constant
<min
) min
=constant
;
307 if(states
>range
*(log_2(constant
)+1))
308 states
=range
*(log_2(constant
)+1);
310 rev_map
=(int *)malloc((states
+1)*sizeof(int));
311 for(i
=0;i
<=states
;i
++)
314 //This array maps state labels (carries) to state indices
315 map
= (struct map_ent
*)malloc((max
-min
+1)*sizeof(struct map_ent
)) -min
;
316 for(i
=min
; i
<max
+1; i
++){
321 map
[constant
].s
=1; //the first state to be expanded
322 next_index
=0; //the next available state index
323 next_label
=constant
; //the next available state label
328 transitions
=1<<vars
; //number of transitions from each state
331 dfaSetup(states
, vars
, indices
);
334 while(next_label
<max
+1){ //there is a state to expand
336 dfaAllocExceptions(transitions
);
337 for(j
=0; j
<transitions
; j
++){
338 result
=next_label
+count_ones(j
,vars
,coeffs
);
339 if (result
>=0) target
=result
/2;
340 else target
=(result
-1)/2;
341 if(map
[target
].s
==0){
344 map
[target
].i
=next_index
;
345 rev_map
[next_index
]=target
;
347 dfaStoreException(map
[target
].i
,bintostr(j
,vars
));
349 dfaStoreState(count
);
351 // for(next_label=min; (next_label<=max) &&
352 //(map[next_label].i!=count); next_label++);
353 //find next state to expand
354 next_label
=rev_map
[count
];
356 for(i
=count
;i
<states
;i
++){
357 dfaAllocExceptions(0);
361 //define accepting and rejecting states
362 statuces
=(char *)malloc(states
+1);
363 for(i
=0;i
<count
;i
++){
365 if((k
<0)&&(map
[k
].s
==2))
372 statuces
[states
]='\0';
373 temp
=dfaBuild(statuces
);
374 temp
->ns
-=states
-count
;
375 inequality
=dfaMinimize(temp
);
381 // Constructs a DFA for the inequation coeffs*variables+constant<0
382 // in two's complement arithmetic
383 DFA
*build_DFA_ineq_2sc(int vars
, int *coeffs
, int constant
, int *indices
){
384 int min
, max
, states
, next_index
, next_label
, result
, target
, count
;
386 unsigned long j
, transitions
;
389 DFA
*inequality
, *temp
;
390 int write1
, overbits
, label1
, label2
, co
;
392 preprocess(vars
, coeffs
, &constant
, 1);
398 for (i
=0; i
<vars
; i
++)
399 if (coeffs
[i
]>0) max
+=coeffs
[i
];
402 if (constant
>max
) max
=constant
;
403 else if(constant
<min
) min
=constant
;
405 overbits
=ceil(log(states
)/log(2));
408 //This array maps state labels (carries) to state indices
409 map
= (struct map_ent
*)malloc(states
*sizeof(struct map_ent
)) -min
;
410 for(i
=min
; i
<max
+1; i
++){
417 map
[constant
].sr
=1; //the first state to be expanded
418 next_index
=0; //the next available state index
419 next_label
=constant
; //the next available state label
424 transitions
=1<<vars
; //number of transitions from each state
427 dfaSetup(states
, vars
, indices
);
430 while(next_label
<max
+1){ //there is a state to expand (excuding sink)
431 if(map
[next_label
].i
==count
)
434 map
[next_label
].sr
=2;
435 dfaAllocExceptions(transitions
);
436 for(j
=0; j
<transitions
; j
++){
437 co
=count_ones(j
,vars
,coeffs
);
438 result
=next_label
+co
;
439 if (result
>=0) target
=result
/2;
440 else target
=(result
-1)/2;
445 while(label1
!=label2
){
448 if (result
>=0) label2
=result
/2;
449 else label2
=(result
-1)/2;
454 if(map
[target
].s
==0){
457 map
[target
].i
=next_index
;
459 dfaStoreException(map
[target
].i
,bintostr(j
,vars
));
462 if(map
[target
].sr
==0){
465 map
[target
].ir
=next_index
;
467 dfaStoreException(map
[target
].ir
,bintostr(j
,vars
));
470 dfaStoreState(count
);
472 for(next_label
=min
; (next_label
<=max
) &&
473 (map
[next_label
].i
!=count
)&&(map
[next_label
].ir
!=count
); next_label
++);
474 //find next state to expand
476 for(i
=count
;i
<states
;i
++){
477 dfaAllocExceptions(0);
481 //define accepting and rejecting states
482 statuces
=(char *)malloc(states
+1);
483 for(i
=0;i
<states
;i
++)
485 for(next_label
=min
;next_label
<=max
;next_label
++)
486 if (map
[next_label
].s
==2) statuces
[map
[next_label
].i
]='+';
487 statuces
[states
]='\0';
488 temp
=dfaBuild(statuces
);
489 temp
->ns
-=states
-count
;
490 inequality
=dfaMinimize(temp
);
494 //recursively checks if state sa of a is equivalent to state sb of b
495 int check(DFA
*a
, DFA
*b
, bdd_ptr sa
, bdd_ptr sb
){
496 int leafa
, leafb
, nexta
, nextb
;
497 bdd_manager
*abddm
, *bbddm
;
498 unsigned indexa
, indexb
;
503 leafa
=bdd_is_leaf(abddm
, sa
);
504 leafb
=bdd_is_leaf(bbddm
, sb
);
506 if (leafa
&& leafb
) { //both are leaf BDD nodes poining to next state
507 nexta
=bdd_leaf_value(abddm
,sa
);
508 nextb
=bdd_leaf_value(bbddm
,sb
);
509 if (corresP
[nexta
]==-1){
510 if (a
->f
[nexta
]!=b
->f
[nextb
]) return 0;
511 corresP
[nexta
]=nextb
;
512 if (!check(a
,b
,a
->q
[nexta
],b
->q
[nextb
])) return 0;
514 else return corresP
[nexta
]==nextb
;
516 else if (leafa
|| leafb
){ //one is a leaf but the other is not
519 else { //both are internal BDD nodes
520 LOAD_index(&abddm
->node_table
[sa
], indexa
);
521 LOAD_index(&bbddm
->node_table
[sb
], indexb
);
522 if(indexa
!=indexb
) return 0;
523 return check(a
,b
,bdd_then(abddm
,sa
),bdd_then(bbddm
,sb
)) &&
524 check(a
,b
,bdd_else(abddm
,sa
),bdd_else(bbddm
,sb
));
530 // A DFA that accepts everything except for the null (empty) string
531 DFA
*dfaNotNullString(){
535 dfaAllocExceptions(0);
537 dfaAllocExceptions(0);
540 return dfaBuild("-+");
544 //checks if L(A)=L(B)
545 int dfaEquivalence(DFA
*A
, DFA
*B
){
547 DFA
*a
, *b
, *temp
, *t
;
550 if ((A
->f
[A
->s
]==1)&&(B
->f
[B
->s
]==-1)){
551 t
=dfaNotNullString();
552 temp
=dfaProduct(A
,t
,dfaAND
);
558 else if ((A
->f
[A
->s
]==-1)&&(B
->f
[B
->s
]==1)){
559 t
=dfaNotNullString();
560 temp
=dfaProduct(B
,t
,dfaAND
);
575 corresP
=(int *)malloc(nsa
*sizeof(int));
579 i
= check(a
, b
, a
->q
[a
->s
], b
->q
[b
->s
]);