1
2
3
4 package net.sf.javabdd;
5
6 import java.util.Collection;
7 import java.math.BigInteger;
8
9 /***
10 * <p>An implementation of BDDFactory that relies on the CUDD library through a
11 * native interface. You can use this by calling the "CUDDFactory.init()"
12 * method with the desired arguments. This will return you an instance of the
13 * BDDFactory class that you can use. Call "done()" on that instance when you
14 * are finished.</p>
15 *
16 * <p>CUDD does not have much of the functionality that BuDDy has, and it has
17 * not been well-tested. Furthermore, it is slower than BuDDy. Therefore, it
18 * is recommended that you use the BuDDy library instead.</p>
19 *
20 * <p>This class (and the CUDD library) do NOT support multithreading.
21 * Furthermore, there can be only one instance active at a time. You can only
22 * call "init()" again after you have called "done()" on the original instance.
23 * It is not recommended to call "init()" again after calling "done()" unless
24 * you are _completely_ sure that all BDD objects that reference the old
25 * factory have been freed.</p>
26 *
27 * <p>If you really need multiple BDD factories, consider using the JavaFactory
28 * class for the additional BDD factories --- JavaFactory can have multiple
29 * factory instances active at a time.</p>
30 *
31 * @see net.sf.javabdd.BDDFactory
32 * @see net.sf.javabdd.BuDDyFactory
33 *
34 * @author John Whaley
35 * @version $Id: CUDDFactory.java 454 2006-07-17 03:45:42Z joewhaley $
36 */
37 public class CUDDFactory extends BDDFactory {
38
39 public static BDDFactory init(int nodenum, int cachesize) {
40 CUDDFactory f = new CUDDFactory();
41 f.initialize(nodenum/256, cachesize);
42 return f;
43 }
44
45 private static CUDDFactory INSTANCE;
46
47 static {
48 String libname = "cudd";
49 try {
50 System.loadLibrary(libname);
51 } catch (java.lang.UnsatisfiedLinkError x) {
52
53 libname = System.mapLibraryName(libname);
54 String currentdir = getProperty("user.dir", ".");
55 String sep = getProperty("file.separator", "/");
56 System.load(currentdir+sep+libname);
57 }
58 registerNatives();
59 }
60
61 private static native void registerNatives();
62
63 private CUDDFactory() {}
64
65 private static long zero;
66 private static long one;
67
68
69
70
71 public BDD zero() {
72 return new CUDDBDD(zero);
73 }
74
75
76
77
78 public BDD one() {
79 return new CUDDBDD(one);
80 }
81
82
83
84
85 protected void initialize(int nodenum, int cachesize) {
86 if (INSTANCE != null) {
87 throw new InternalError("Error: CUDDFactory already initialized.");
88 }
89 INSTANCE = this;
90 initialize0(nodenum, cachesize);
91 }
92 private static native void initialize0(int nodenum, int cachesize);
93
94
95
96
97 public boolean isInitialized() {
98 return isInitialized0();
99 }
100 private static native boolean isInitialized0();
101
102
103
104
105 public void done() {
106 INSTANCE = null;
107 done0();
108 }
109 private static native void done0();
110
111
112
113
114 public void setError(int code) {
115
116 }
117
118
119
120
121 public void clearError() {
122
123 }
124
125
126
127
128 public int setMaxNodeNum(int size) {
129
130 System.err.println("Warning: setMaxNodeNum() not yet implemented");
131 return 1000000;
132 }
133
134
135
136
137 public int setNodeTableSize(int size) {
138
139 System.err.println("Warning: setNodeTableSize() not yet implemented");
140 return getNodeTableSize();
141 }
142
143
144
145
146 public int setCacheSize(int size) {
147
148 System.err.println("Warning: setCacheSize() not yet implemented");
149 return 0;
150 }
151
152
153
154
155 public double setMinFreeNodes(double x) {
156
157 System.err.println("Warning: setMinFreeNodes() not yet implemented");
158 return 0;
159 }
160
161
162
163
164 public int setMaxIncrease(int x) {
165
166 System.err.println("Warning: setMaxIncrease() not yet implemented");
167 return 50000;
168 }
169
170
171
172
173 public double setCacheRatio(double x) {
174
175 System.err.println("Warning: setCacheRatio() not yet implemented");
176 return 0;
177 }
178
179
180
181
182 public double setIncreaseFactor(double x) {
183
184 System.err.println("Warning: setIncreaseFactor() not yet implemented");
185 return 0;
186 }
187
188
189
190
191 public int varNum() {
192 return varNum0();
193 }
194 private static native int varNum0();
195
196
197
198
199 public int setVarNum(int num) {
200 return setVarNum0(num);
201 }
202 private static native int setVarNum0(int num);
203
204
205
206
207 public int duplicateVar(int var) {
208
209 throw new UnsupportedOperationException();
210 }
211
212
213
214
215 public BDD ithVar(int var) {
216 long id = ithVar0(var);
217 return new CUDDBDD(id);
218 }
219 private static native long ithVar0(int var);
220
221
222
223
224 public BDD nithVar(int var) {
225 BDD b = ithVar(var);
226 BDD c = b.not(); b.free();
227 return c;
228 }
229
230
231
232
233 public void swapVar(int v1, int v2) {
234
235 throw new UnsupportedOperationException();
236 }
237
238
239
240
241 public BDDPairing makePair() {
242 return new CUDDBDDPairing();
243 }
244
245
246
247
248 public void printAll() {
249
250 throw new UnsupportedOperationException();
251 }
252
253
254
255
256 public void printTable(BDD b) {
257
258 throw new UnsupportedOperationException();
259 }
260
261
262
263
264 public int level2Var(int level) {
265 return level2Var0(level);
266 }
267 private static native int level2Var0(int level);
268
269
270
271
272 public int var2Level(int var) {
273 return var2Level0(var);
274 }
275 private static native int var2Level0(int var);
276
277
278
279
280 public void reorder(ReorderMethod m) {
281
282 throw new UnsupportedOperationException();
283 }
284
285
286
287
288 public void autoReorder(ReorderMethod method) {
289
290 throw new UnsupportedOperationException();
291 }
292
293
294
295
296 public void autoReorder(ReorderMethod method, int max) {
297
298 throw new UnsupportedOperationException();
299 }
300
301
302
303
304 public ReorderMethod getReorderMethod() {
305
306 throw new UnsupportedOperationException();
307 }
308
309
310
311
312 public int getReorderTimes() {
313
314 throw new UnsupportedOperationException();
315 }
316
317
318
319
320 public void disableReorder() {
321
322 System.err.println("Warning: disableReorder() not yet implemented");
323 }
324
325
326
327
328 public void enableReorder() {
329
330 System.err.println("Warning: enableReorder() not yet implemented");
331 }
332
333
334
335
336 public int reorderVerbose(int v) {
337
338 throw new UnsupportedOperationException();
339 }
340
341
342
343
344 public void setVarOrder(int[] neworder) {
345 setVarOrder0(neworder);
346 }
347 private static native void setVarOrder0(int[] neworder);
348
349
350
351
352 public void addVarBlock(BDD var, boolean fixed) {
353
354 throw new UnsupportedOperationException();
355 }
356
357
358
359
360 public void addVarBlock(int first, int last, boolean fixed) {
361
362 throw new UnsupportedOperationException();
363 }
364
365
366
367
368 public void varBlockAll() {
369
370 throw new UnsupportedOperationException();
371 }
372
373
374
375
376 public void clearVarBlocks() {
377
378 throw new UnsupportedOperationException();
379 }
380
381
382
383
384 public void printOrder() {
385
386 throw new UnsupportedOperationException();
387 }
388
389
390
391
392 public int nodeCount(Collection r) {
393
394 throw new UnsupportedOperationException();
395 }
396
397
398
399
400 public int getNodeTableSize() {
401 return getAllocNum0();
402 }
403 private static native int getAllocNum0();
404
405
406
407
408 public int getNodeNum() {
409 return getNodeNum0();
410 }
411 private static native int getNodeNum0();
412
413
414
415
416 public int getCacheSize() {
417 return getCacheSize0();
418 }
419 private static native int getCacheSize0();
420
421
422
423
424 public int reorderGain() {
425
426 throw new UnsupportedOperationException();
427 }
428
429
430
431
432 public void printStat() {
433
434 throw new UnsupportedOperationException();
435 }
436
437
438
439
440 protected BDDDomain createDomain(int a, BigInteger b) {
441 return new CUDDBDDDomain(a, b);
442 }
443
444
445
446
447 private static class CUDDBDD extends BDD {
448
449 /*** The pointer used by the BDD library. */
450 private long _ddnode_ptr;
451
452 /*** An invalid id, for use in invalidating BDDs. */
453 static final long INVALID_BDD = -1;
454
455 private CUDDBDD(long ddnode) {
456 this._ddnode_ptr = ddnode;
457 addRef(ddnode);
458 }
459
460
461
462
463 public BDDFactory getFactory() {
464 return INSTANCE;
465 }
466
467
468
469
470 public boolean isZero() {
471 return this._ddnode_ptr == zero;
472 }
473
474
475
476
477 public boolean isOne() {
478 return this._ddnode_ptr == one;
479 }
480
481
482
483
484 public int var() {
485 if (isZero() || isOne())
486 throw new BDDException("cannot get var of terminal");
487 return var0(_ddnode_ptr);
488 }
489 private static native int var0(long b);
490
491
492
493
494 public BDD high() {
495 long b = high0(_ddnode_ptr);
496 return new CUDDBDD(b);
497 }
498 private static native long high0(long b);
499
500
501
502
503 public BDD low() {
504 long b = low0(_ddnode_ptr);
505 return new CUDDBDD(b);
506 }
507 private static native long low0(long b);
508
509
510
511
512 public BDD id() {
513 return new CUDDBDD(_ddnode_ptr);
514 }
515
516
517
518
519 public BDD not() {
520 long b = not0(_ddnode_ptr);
521 return new CUDDBDD(b);
522 }
523 private static native long not0(long b);
524
525
526
527
528 public BDD ite(BDD thenBDD, BDD elseBDD) {
529 CUDDBDD c = (CUDDBDD) thenBDD;
530 CUDDBDD d = (CUDDBDD) elseBDD;
531 long b = ite0(_ddnode_ptr, c._ddnode_ptr, d._ddnode_ptr);
532 return new CUDDBDD(b);
533 }
534 private static native long ite0(long b, long c, long d);
535
536
537
538
539 public BDD relprod(BDD that, BDDVarSet var) {
540 CUDDBDD c = (CUDDBDD) that;
541 CUDDBDD d = (CUDDBDD) ((BDDVarSet.DefaultImpl) var).b;
542 long b = relprod0(_ddnode_ptr, c._ddnode_ptr, d._ddnode_ptr);
543 return new CUDDBDD(b);
544 }
545 private static native long relprod0(long b, long c, long d);
546
547
548
549
550 public BDD compose(BDD that, int var) {
551 CUDDBDD c = (CUDDBDD) that;
552 long b = compose0(_ddnode_ptr, c._ddnode_ptr, var);
553 return new CUDDBDD(b);
554 }
555 private static native long compose0(long b, long c, int var);
556
557
558
559
560 public BDD constrain(BDD that) {
561
562 throw new UnsupportedOperationException();
563 }
564
565
566
567
568 public BDD exist(BDDVarSet var) {
569 CUDDBDD c = (CUDDBDD) ((BDDVarSet.DefaultImpl) var).b;
570 long b = exist0(_ddnode_ptr, c._ddnode_ptr);
571 return new CUDDBDD(b);
572 }
573 private static native long exist0(long b, long c);
574
575
576
577
578 public BDD forAll(BDDVarSet var) {
579 CUDDBDD c = (CUDDBDD) ((BDDVarSet.DefaultImpl) var).b;
580 long b = forAll0(_ddnode_ptr, c._ddnode_ptr);
581 return new CUDDBDD(b);
582 }
583 private static native long forAll0(long b, long c);
584
585
586
587
588 public BDD unique(BDDVarSet var) {
589
590 throw new UnsupportedOperationException();
591 }
592
593
594
595
596 public BDD restrict(BDD var) {
597 CUDDBDD c = (CUDDBDD) var;
598 long b = restrict0(_ddnode_ptr, c._ddnode_ptr);
599 return new CUDDBDD(b);
600 }
601 private static native long restrict0(long b, long var);
602
603
604
605
606 public BDD restrictWith(BDD var) {
607 CUDDBDD c = (CUDDBDD) var;
608 long b = restrict0(_ddnode_ptr, c._ddnode_ptr);
609 addRef(b);
610 delRef(_ddnode_ptr);
611 if (this != c) {
612 delRef(c._ddnode_ptr);
613 c._ddnode_ptr = INVALID_BDD;
614 }
615 _ddnode_ptr = b;
616 return this;
617 }
618
619
620
621
622 public BDD simplify(BDDVarSet d) {
623
624 throw new UnsupportedOperationException();
625 }
626
627
628
629
630 public BDDVarSet support() {
631 long b = support0(_ddnode_ptr);
632 return new BDDVarSet.DefaultImpl(new CUDDBDD(b));
633 }
634 private static native long support0(long b);
635
636
637
638
639 public BDD apply(BDD that, BDDFactory.BDDOp opr) {
640 CUDDBDD c = (CUDDBDD) that;
641 long b = apply0(_ddnode_ptr, c._ddnode_ptr, opr.id);
642 return new CUDDBDD(b);
643 }
644 private static native long apply0(long b, long c, int opr);
645
646
647
648
649 public BDD applyWith(BDD that, BDDFactory.BDDOp opr) {
650 CUDDBDD c = (CUDDBDD) that;
651 long b = apply0(_ddnode_ptr, c._ddnode_ptr, opr.id);
652 addRef(b);
653 delRef(_ddnode_ptr);
654 if (this != c) {
655 delRef(c._ddnode_ptr);
656 c._ddnode_ptr = INVALID_BDD;
657 }
658 _ddnode_ptr = b;
659 return this;
660 }
661
662
663
664
665 public BDD applyAll(BDD that, BDDOp opr, BDDVarSet var) {
666
667 throw new UnsupportedOperationException();
668 }
669
670
671
672
673 public BDD applyEx(BDD that, BDDOp opr, BDDVarSet var) {
674
675 throw new UnsupportedOperationException();
676 }
677
678
679
680
681 public BDD applyUni(BDD that, BDDOp opr, BDDVarSet var) {
682
683 throw new UnsupportedOperationException();
684 }
685
686
687
688
689 public BDD satOne() {
690 long b = satOne0(_ddnode_ptr);
691 return new CUDDBDD(b);
692 }
693 private static native long satOne0(long b);
694
695
696
697
698 public BDD fullSatOne() {
699
700 throw new UnsupportedOperationException();
701 }
702
703
704
705
706 public BDD satOne(BDDVarSet var, boolean pol) {
707
708 throw new UnsupportedOperationException();
709 }
710
711
712
713
714 public int nodeCount() {
715 return nodeCount0(_ddnode_ptr);
716 }
717 private static native int nodeCount0(long b);
718
719
720
721
722 public double pathCount() {
723 return pathCount0(_ddnode_ptr);
724 }
725 private static native double pathCount0(long b);
726
727
728
729
730 public double satCount() {
731 return satCount0(_ddnode_ptr);
732 }
733 private static native double satCount0(long b);
734
735
736
737
738 public int[] varProfile() {
739
740 throw new UnsupportedOperationException();
741 }
742
743 private static native void addRef(long p);
744
745 private static native void delRef(long p);
746
747 static final boolean USE_FINALIZER = false;
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771 public void free() {
772 delRef(_ddnode_ptr);
773 _ddnode_ptr = INVALID_BDD;
774 }
775
776
777
778
779 public BDD veccompose(BDDPairing pair) {
780 CUDDBDDPairing p = (CUDDBDDPairing) pair;
781 long b = veccompose0(_ddnode_ptr, p._ptr);
782 return new CUDDBDD(b);
783 }
784 private static native long veccompose0(long b, long p);
785
786
787
788
789 public BDD replace(BDDPairing pair) {
790 CUDDBDDPairing p = (CUDDBDDPairing) pair;
791 long b = replace0(_ddnode_ptr, p._ptr);
792 return new CUDDBDD(b);
793 }
794 private static native long replace0(long b, long p);
795
796
797
798
799 public BDD replaceWith(BDDPairing pair) {
800 CUDDBDDPairing p = (CUDDBDDPairing) pair;
801 long b = replace0(_ddnode_ptr, p._ptr);
802 addRef(b);
803 delRef(_ddnode_ptr);
804 _ddnode_ptr = b;
805 return this;
806 }
807
808
809
810
811 public boolean equals(BDD that) {
812 return this._ddnode_ptr == ((CUDDBDD) that)._ddnode_ptr;
813 }
814
815
816
817
818 public int hashCode() {
819 return (int) this._ddnode_ptr;
820 }
821
822
823
824
825 public BDDVarSet toVarSet() {
826 return new BDDVarSet.DefaultImpl(new CUDDBDD(this._ddnode_ptr));
827 }
828
829 }
830
831
832
833
834 private static class CUDDBDDDomain extends BDDDomain {
835
836 private CUDDBDDDomain(int index, BigInteger range) {
837 super(index, range);
838 }
839
840
841
842
843 public BDDFactory getFactory() {
844 return INSTANCE;
845 }
846
847 }
848
849
850
851
852 private static class CUDDBDDPairing extends BDDPairing {
853
854 long _ptr;
855
856 private CUDDBDDPairing() {
857 _ptr = alloc();
858 }
859
860 private static native long alloc();
861
862
863
864
865 public void set(int oldvar, int newvar) {
866 set0(_ptr, oldvar, newvar);
867 }
868 private static native void set0(long p, int oldvar, int newvar);
869
870
871
872
873 public void set(int oldvar, BDD newvar) {
874 CUDDBDD c = (CUDDBDD) newvar;
875 set2(_ptr, oldvar, c._ddnode_ptr);
876 }
877 private static native void set2(long p, int oldvar, long newbdd);
878
879
880
881
882 public void reset() {
883 reset0(_ptr);
884 }
885 private static native void reset0(long ptr);
886
887 /***
888 * Free the memory allocated for this pair.
889 */
890 private static native void free0(long ptr);
891 }
892
893
894
895
896 protected BDDBitVector createBitVector(int a) {
897 return new CUDDBDDBitVector(a);
898 }
899
900
901
902
903 private static class CUDDBDDBitVector extends BDDBitVector {
904
905 private CUDDBDDBitVector(int a) {
906 super(a);
907 }
908
909 public BDDFactory getFactory() { return INSTANCE; }
910
911 }
912
913 public static void main(String[] args) {
914 BDDFactory bdd = init(1000000, 100000);
915
916 System.out.println("One: "+CUDDFactory.one);
917 System.out.println("Zero: "+CUDDFactory.zero);
918
919 BDDDomain[] doms = bdd.extDomain(new int[] {50, 10, 15, 20, 15});
920
921 BDD b = bdd.one();
922 for (int i=0; i<doms.length-1; ++i) {
923 b.andWith(doms[i].ithVar(i));
924 }
925
926 for (int i=0; i<bdd.numberOfDomains(); ++i) {
927 BDDDomain d = bdd.getDomain(i);
928 int[] ivar = d.vars();
929 System.out.print("Domain #"+i+":");
930 for (int j=0; j<ivar.length; ++j) {
931 System.out.print(' ');
932 System.out.print(j);
933 System.out.print(':');
934 System.out.print(ivar[j]);
935 }
936 System.out.println();
937 }
938
939 BDDPairing p = bdd.makePair(doms[2], doms[doms.length-1]);
940 System.out.println("Pairing: "+p);
941
942 System.out.println("Before replace(): "+b);
943 BDD c = b.replace(p);
944 System.out.println("After replace(): "+c);
945
946 c.printDot();
947 }
948
949 public static final String REVISION = "$Revision: 454 $";
950
951
952
953
954 public String getVersion() {
955 return "CUDD "+REVISION.substring(11, REVISION.length()-2);
956 }
957
958 }