Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / sun4-solaris / Cudd.pm
CommitLineData
86530b38
AT
1package Cudd;
2
3use strict;
4use Carp;
5use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
6
7require Exporter;
8require DynaLoader;
9require AutoLoader;
10
11@ISA = qw(Exporter DynaLoader);
12# Items to export into callers namespace by default. Note: do not export
13# names by default without a very good reason. Use EXPORT_OK instead.
14# Do not simply export all your public functions/methods/constants.
15@EXPORT = qw(
16 APA_BASE
17 APA_BITS
18 APA_MASK
19 CACHE_SLOTS
20 MAXINDEX
21 MTR_DEFAULT
22 MTR_FIXED
23 OUT_OF_MEM
24 REORDER_SAME
25 REORDER_NONE
26 REORDER_RANDOM
27 REORDER_RANDOM_PIVOT
28 REORDER_SIFT
29 REORDER_SIFT_CONVERGE
30 REORDER_SYMM_SIFT
31 REORDER_SYMM_SIFT_CONV
32 REORDER_WINDOW2
33 REORDER_WINDOW3
34 REORDER_WINDOW4
35 REORDER_WINDOW2_CONV
36 REORDER_WINDOW3_CONV
37 REORDER_WINDOW4_CONV
38 REORDER_GROUP_SIFT
39 REORDER_GROUP_SIFT_CONV
40 REORDER_ANNEALING
41 REORDER_GENETIC
42 REORDER_LINEAR
43 REORDER_LINEAR_CONVERGE
44 REORDER_EXACT
45 RESIDUE_DEFAULT
46 RESIDUE_MSB
47 RESIDUE_TC
48 SIZEOF_INT
49 SIZEOF_LONG
50 SIZEOF_VOID_P
51 UNIQUE_SLOTS
52);
53$VERSION = '0.06';
54
55sub AUTOLOAD {
56 # This AUTOLOAD is used to 'autoload' constants from the constant()
57 # XS function. If a constant is not found then control is passed
58 # to the AUTOLOAD in AutoLoader.
59
60 my $constname;
61 ($constname = $AUTOLOAD) =~ s/.*:://;
62 my $val = constant($constname, @_ ? $_[0] : 0);
63 if ($! != 0) {
64 if ($! =~ /Invalid/) {
65 $AutoLoader::AUTOLOAD = $AUTOLOAD;
66 goto &AutoLoader::AUTOLOAD;
67 }
68 else {
69 croak "Your vendor has not defined Cudd macro $constname";
70 }
71 }
72 eval "sub $AUTOLOAD { $val }";
73 goto &$AUTOLOAD;
74}
75
76bootstrap Cudd $VERSION;
77
78# Preloaded methods go here.
79
80=head1 NAME
81
82Cudd - Perl extension for BDDs
83
84=head1 SYNOPSIS
85
86C<use Cudd;>
87
88C<my $manager = new Cudd;>
89
90and so on
91
92=head1 DESCRIPTION
93
94Cudd extends Perl so that it manipulates Binary Decision Diagrams
95(BDDs) by providing an object-oriented encapsulation of the CUDD
96package. The CUDD package is written in C and contains a large
97collection of efficient BDD manipulation functions. Only a small
98fraction of those functions are currently made available by the Cudd
99module. Those that are available, however, allow one to accomplish
100most tasks.
101
102=head2
103
104The methods defined by Cudd are divided into two packages. The first
105package, Cudd, defines methods that create and manipulate BDD managers
106and BDD variables. These are the methods defined in package Cudd:
107
108=over 4
109=cut
110
111=item new
112
113Creates a new BDD manager.
114
115=cut
116
117sub new {
118 my $class = shift;
119 my $numVars = shift || 0;
120 my $numVarsZ = shift || 0;
121 my $numSlots = shift || &Cudd::UNIQUE_SLOTS;
122 my $cacheSize = shift || &Cudd::CACHE_SLOTS;
123 my $maxMemory = shift || 0;
124 my $manager = Init($numVars,$numVarsZ,$numSlots,$cacheSize,$maxMemory);
125 bless \$manager, $class;
126 return \$manager;
127}
128
129sub DESTROY {
130 my $manager = shift;
131 my $retval = CheckZeroRef($$manager);
132 if ($retval != 0) {
133 print "In Cudd::DESTROY $retval non-zero references\n";
134 }
135 Quit($$manager);
136}
137
138=item BddVar
139
140Creates a new variable in a BDD manager.
141
142=cut
143
144sub BddVar {
145 my $manager = shift;
146 croak "Invalid reference" unless ref $manager;
147 my $node = bddNewVar($$manager);
148 Ref($node);
149 my $BDD = Cudd::BDD->new($manager,$node);
150 return $BDD;
151}
152
153=item BddOne
154
155Returns the constant 1 of a BDD manager.
156
157=cut
158
159sub BddOne {
160 my $manager = shift;
161 croak "Invalid reference" unless ref $manager;
162 my $node = ReadOne($$manager);
163 Ref($node);
164 my $BDD = Cudd::BDD->new($manager,$node);
165 return $BDD;
166}
167
168=item Reorder
169
170Reorders the BDDs of a manager.
171
172=cut
173
174sub Reorder {
175 my $manager = shift;
176 my $method = shift || &Cudd::REORDER_SAME;
177 my $minsize = shift || 1;
178 croak "Invalid reference" unless ref $manager;
179 Cudd::ReduceHeap($$manager,$method,$minsize);
180}
181
182=item EnableDyn
183
184Enables dynamic reordering for a BDD manager.
185
186=cut
187
188sub EnableDyn {
189 my $manager = shift;
190 my $method = shift || &Cudd::REORDER_SAME;
191 croak "Invalid reference" unless ref $manager;
192 Cudd::AutodynEnable($$manager,$method);
193}
194
195=item DisableDyn
196
197Disables dynamic reordering for a BDD manager.
198
199=cut
200
201sub DisableDyn {
202 my $manager = shift;
203 croak "Invalid reference" unless ref $manager;
204 Cudd::AutodynDisable($$manager);
205}
206
207=item ReportReordering
208
209Enables reporting of dynamic reordering.
210
211=cut
212
213sub ReportReordering {
214 my $manager = shift;
215 croak "Invalid reference" unless ref $manager;
216 Cudd::EnableReorderingReporting($$manager);
217}
218
219
220=item DoNotReportReordering
221
222Disables reporting of dynamic reordering.
223
224=cut
225
226sub DoNotReportReordering {
227 my $manager = shift;
228 croak "Invalid reference" unless ref $manager;
229 Cudd::DisableReorderingReporting($$manager);
230}
231
232=item Info
233
234Prints statistical information on a BDD manager.
235
236=cut
237
238sub Info {
239 my $manager = shift;
240 croak "Invalid reference" unless ref $manager;
241 my $retval = Cudd::PrintInfo($$manager);
242 croak "Error while printing manager info" if ($retval != 1);
243}
244
245=item PeakLiveNodes
246
247Returns the peak number of live nodes in the manager.
248
249=cut
250
251sub PeakLiveNodes {
252 my $manager = shift;
253 croak "Invalid reference" unless ref $manager;
254 my $retval = Cudd::ReadPeakLiveNodeCount($$manager);
255 return $retval;
256}
257
258=item LiveNodes
259
260Returns the number of live nodes in the manager.
261
262=cut
263
264sub LiveNodes {
265 my $manager = shift;
266 croak "Invalid reference" unless ref $manager;
267 my $retval = Cudd::ReadNodeCount($$manager);
268 return $retval;
269}
270
271=item DynReorderingStatus
272
273Returns a list with two elements. The first is 1 if reordering is
274currently enabled and 0 otherwise; the second is the reordering method
275currently selected.
276
277=cut
278
279sub DynReorderingStatus {
280 my $manager = shift;
281 croak "Invalid reference" unless ref $manager;
282 my @retval = Cudd::ReorderingStatus($$manager);
283 return @retval;
284}
285
286=back 4
287
288=cut
289
290package Cudd::BDD;
291
292use Carp;
293use overload
294 '+' => "Or",
295 '*' => "And",
296 '/' => "Cofactor",
297 '^' => "Xor",
298 '!' => "Not",
299 '==' => "Equal",
300 '!=' => "Unequal",
301 '<=' => "Leq",
302 '>=' => "Geq",
303 '""' => sub { return "OK"; },
304 'bool' => sub { my $self = shift; return $self->Unequal($self->Zero); }
305;
306
307=head2
308
309The second package in module Cudd is Cudd::BDD. It defines methods
310that manipulate BDDs. Starting with a set of variables belonging to a
311manager, the functions in this package allow one to create BDDs for
312arbitrary functions over those variables. These are the methods
313defined by Cudd::BDD:
314
315=over 4
316
317=cut
318
319sub new {
320 my ($class,$manager,$node) = @_;
321 croak "Invalid reference" unless ref $manager;
322 # carp "In Cudd::BDD::new: creating $node\n";
323 bless { manager => $manager,
324 node => $node
325 }, $class;
326}
327
328sub DESTROY {
329 my $self = shift;
330 my $manager = $self->{manager};
331 croak "Invalid reference" unless ref $manager;
332 # carp "In Cudd::BDD::DESTROY: dereferencing $self->{node}\n";
333 Cudd::IterDerefBdd($$manager,$self->{node});
334}
335
336=item One
337
338Returns the constant 1 BDD from the manager of $f.
339
340=cut
341
342sub One {
343 my $f = shift;
344 my $manager = $f->{'manager'};
345 croak "Invalid reference" unless ref $manager;
346 return $manager->BddOne;
347}
348
349=item Zero
350
351Returns the constant 0 BDD from the manager of $f.
352
353=cut
354
355sub Zero {
356 my $f = shift;
357 my $manager = $f->{'manager'};
358 croak "Invalid reference" unless ref $manager;
359 return !$manager->BddOne;
360}
361
362=item And
363
364Computes the conjunction of two BDDs. Overloads '*'.
365
366=cut
367
368sub And {
369 my ($f,$g) = @_;
370 my $manager = $f->{'manager'};
371 croak "Invalid reference" unless ref $manager;
372 my $node = Cudd::bddAnd($$manager,$f->{'node'},$g->{'node'});
373 Cudd::Ref($node);
374 my $BDD = new Cudd::BDD($manager,$node);
375 return $BDD;
376}
377
378=item Or
379
380Computes the disjunction of two BDDs. Overloads '+'.
381
382=cut
383
384sub Or {
385 my ($f,$g) = @_;
386 my $manager = $f->{'manager'};
387 croak "Invalid reference" unless ref $manager;
388 my $node = Cudd::bddOr($$manager,$f->{'node'},$g->{'node'});
389 Cudd::Ref($node);
390 my $BDD = new Cudd::BDD($manager,$node);
391 return $BDD;
392}
393
394=item Xor
395
396Computes the exclusive or of two BDDs. Overloads '^'.
397
398=cut
399
400sub Xor {
401 my ($f,$g) = @_;
402 my $manager = $f->{'manager'};
403 croak "Invalid reference" unless ref $manager;
404 my $node = Cudd::bddXor($$manager,$f->{'node'},$g->{'node'});
405 Cudd::Ref($node);
406 my $BDD = new Cudd::BDD($manager,$node);
407 return $BDD;
408}
409
410sub Xnor {
411 my ($f,$g) = @_;
412 my $manager = $f->{'manager'};
413 croak "Invalid reference" unless ref $manager;
414 my $node = Cudd::bddXnor($$manager,$f->{'node'},$g->{'node'});
415 Cudd::Ref($node);
416 my $BDD = new Cudd::BDD($manager,$node);
417 return $BDD;
418}
419
420=item Nand
421
422Computes the NAND of two BDDs.
423
424=cut
425
426sub Nand {
427 my ($f,$g) = @_;
428 my $manager = $f->{'manager'};
429 croak "Invalid reference" unless ref $manager;
430 my $node = Cudd::bddNand($$manager,$f->{'node'},$g->{'node'});
431 Cudd::Ref($node);
432 my $BDD = new Cudd::BDD($manager,$node);
433 return $BDD;
434}
435
436=item Nor
437
438Computes the NOR of two BDDs.
439
440=cut
441
442sub Nor {
443 my ($f,$g) = @_;
444 my $manager = $f->{'manager'};
445 croak "Invalid reference" unless ref $manager;
446 my $node = Cudd::bddNor($$manager,$f->{'node'},$g->{'node'});
447 Cudd::Ref($node);
448 my $BDD = new Cudd::BDD($manager,$node);
449 return $BDD;
450}
451
452=item Cofactor
453
454Computes the cofactor of a BDD with respect to another. Uses the constrain
455algorithm. Overloads '/'.
456
457=cut
458
459sub Cofactor {
460 my ($f,$c) = @_;
461 my $manager = $f->{'manager'};
462 my $node = Cudd::bddConstrain($$manager,$f->{'node'},$c->{'node'});
463 Cudd::Ref($node);
464 my $BDD = new Cudd::BDD($manager,$node);
465 return $BDD;
466}
467
468=item Restrict
469
470Computes the cofactor of a BDD with respect to another. Uses the restrict
471algorithm.
472
473=cut
474
475sub Restrict {
476 my ($f,$c) = @_;
477 my $manager = $f->{'manager'};
478 my $node = Cudd::bddRestrict($$manager,$f->{'node'},$c->{'node'});
479 Cudd::Ref($node);
480 my $BDD = new Cudd::BDD($manager,$node);
481 return $BDD;
482}
483
484=item Squeeze
485
486Finds a small BDD in an interval.
487
488=cut
489
490sub Squeeze {
491 my ($l,$u) = @_;
492 my $manager = $l->{'manager'};
493 my $node = Cudd::bddSqueeze($$manager,$l->{'node'},$u->{'node'});
494 Cudd::Ref($node);
495 my $BDD = new Cudd::BDD($manager,$node);
496 return $BDD;
497}
498
499=item Exists
500
501Existentially quantifies the variables in a cube from a BDD.
502
503=cut
504
505sub Exists {
506 my ($cube,$f) = @_;
507 my $manager = $f->{'manager'};
508 croak "Invalid reference" unless ref $manager;
509 my $node = Cudd::bddExistAbstract($$manager,$f->{'node'},$cube->{'node'});
510 Cudd::Ref($node);
511 my $BDD = new Cudd::BDD($manager,$node);
512 return $BDD;
513}
514
515=item Forall
516
517Universally quantifies the variables in a cube from a BDD.
518
519=cut
520
521sub Forall {
522 my ($cube,$f) = @_;
523 my $manager = $f->{'manager'};
524 croak "Invalid reference" unless ref $manager;
525 my $node = Cudd::bddUnivAbstract($$manager,$f->{'node'},$cube->{'node'});
526 Cudd::Ref($node);
527 my $BDD = new Cudd::BDD($manager,$node);
528 return $BDD;
529}
530
531=item AndExists
532
533Existentially quantifies the variables in a cube from the conjunction of
534two BDDs.
535
536=cut
537
538sub AndExists {
539 my ($cube,$f,$g) = @_;
540 my $manager = $f->{'manager'};
541 croak "Invalid reference" unless ref $manager;
542 my $node = Cudd::bddAndAbstract($$manager,$f->{'node'},$g->{'node'},
543 $cube->{'node'});
544 Cudd::Ref($node);
545 my $BDD = new Cudd::BDD($manager,$node);
546 return $BDD;
547}
548
549=item Compose
550
551Composes a BDD $g into a BDD $f substituting variable $var.
552
553=cut
554
555sub Compose {
556 my ($f,$var,$g) = @_;
557 my $manager = $f->{'manager'};
558 croak "Invalid reference" unless ref $manager;
559 my $index = Cudd::NodeReadIndex($var->{'node'});
560 my $node = Cudd::bddCompose($$manager,$f->{'node'},$g->{'node'},$index);
561 Cudd::Ref($node);
562 my $BDD = new Cudd::BDD($manager,$node);
563 return $BDD;
564}
565
566=item BooleanDiff
567
568Computes the boolean difference of a BDD with respect to one variable.
569
570=cut
571
572sub BooleanDiff {
573 my ($f,$var) = @_;
574 my $manager = $f->{'manager'};
575 croak "Invalid reference" unless ref $manager;
576 my $index = Cudd::NodeReadIndex($var->{'node'});
577 my $node = Cudd::bddBooleanDiff($$manager,$f->{'node'},$index);
578 Cudd::Ref($node);
579 my $BDD = new Cudd::BDD($manager,$node);
580 return $BDD;
581}
582
583=item Correlation
584
585Computes the correlation of two BDDs. The result is a number between 0
586and 1. A value of 1 indicates that the functions $f and $g are
587identical. A value of 0 indicates that they are complementary.
588
589=cut
590
591sub Correlation {
592 my ($f,$g) = @_;
593 my $manager = $f->{'manager'};
594 croak "Invalid reference" unless ref $manager;
595 my $correl = Cudd::bddCorrelation($$manager,$f->{'node'},$g->{'node'});
596 return $correl;
597}
598
599=item Decreasing
600
601Returns 1 if the BDD $f is monotonic decreasing (negative unate) in
602variable $var; 0 otherwise.
603
604=cut
605
606sub Decreasing {
607 my ($f,$var) = @_;
608 my $manager = $f->{'manager'};
609 croak "Invalid reference" unless ref $manager;
610 my $index = Cudd::NodeReadIndex($var->{'node'});
611 my $retval = Cudd::Decreasing($$manager,$f->{'node'},$index);
612 return $retval;
613}
614
615=item Increasing
616
617Returns 1 if the BDD $f is monotonic increasing (positive unate) in
618variable $var; 0 otherwise.
619
620=cut
621
622sub Increasing {
623 my ($f,$var) = @_;
624 my $manager = $f->{'manager'};
625 croak "Invalid reference" unless ref $manager;
626 my $index = Cudd::NodeReadIndex($var->{'node'});
627 my $retval = Cudd::Increasing($$manager,$f->{'node'},$index);
628 return $retval;
629}
630
631=item Essentials
632
633Finds the essential variables of a BDD. Returns an array of all essentials.
634Negative essentials correspond to negative literals.
635
636=cut
637
638sub Essentials {
639 my ($f) = @_;
640 my $manager = $f->{'manager'};
641 croak "Invalid reference" unless ref $manager;
642 my $essref = Cudd::FindEssential($$manager,$f->{'node'});
643 my @essentials = ();
644 foreach (@$essref) {
645 my $ess = $_;
646 Cudd::Ref($ess);
647 my $BDD = new Cudd::BDD($manager,$ess);
648 push(@essentials,$BDD);
649 }
650 return \@essentials;
651}
652
653=item Support
654
655Returns a cube of all the variables in the support of $f.
656
657=cut
658
659sub Support {
660 my ($f) = @_;
661 my $manager = $f->{'manager'};
662 croak "Invalid reference" unless ref $manager;
663 my $support = Cudd::Support($$manager,$f->{'node'});
664 Cudd::Ref($support);
665 my $BDD = new Cudd::BDD($manager,$support);
666 return $BDD;
667}
668
669=item LiteralSetIntersection
670
671Computes the intersection of two literal sets represented by cube BDDs.
672
673=cut
674
675sub LiteralSetIntersection {
676 my ($f,$g) = @_;
677 my $manager = $f->{'manager'};
678 croak "Invalid reference" unless ref $manager;
679 my $node = Cudd::bddLiteralSetIntersection($$manager,$f->{'node'},$g->{'node'});
680 Cudd::Ref($node);
681 my $BDD = new Cudd::BDD($manager,$node);
682 return $BDD;
683}
684
685=item SwapVariables
686
687Swaps two sets of variables in a BDD.
688
689=cut
690
691sub SwapVariables {
692 my ($f,$xref,$yref) = @_;
693 my $manager = $f->{'manager'};
694 croak "Invalid reference" unless ref $manager;
695 my @xvars = map $_->{'node'}, (@$xref);
696 my @yvars = map $_->{'node'}, (@$yref);
697 my $node = Cudd::bddSwapVariables($$manager,$f->{'node'},\@xvars,\@yvars);
698 Cudd::Ref($node);
699 my $BDD = new Cudd::BDD($manager,$node);
700 return $BDD;
701}
702
703=item SolveEqn
704
705Solves a boolean equation. The first argument $f is the left-hand side
706of the equation $f = 0. The second argument is a reference to the
707array of the unknowns. The variables that are not unknowns are
708parameters.
709
710=cut
711
712sub SolveEqn {
713 my ($f,$varref) = @_;
714 my $manager = $f->{'manager'};
715 croak "Invalid reference" unless ref $manager;
716 my $cube = $manager->BddOne;
717 foreach (@$varref) {
718 my $var = $_;
719 $cube *= $var;
720 }
721 my $numvar = @$varref;
722 my ($consist,$solref) = Cudd::SolveEqn($$manager,$f->{'node'},
723 $cube->{'node'},$numvar);
724 Cudd::Ref($consist);
725 my $BDD;
726 $BDD = new Cudd::BDD($manager,$consist);
727 my @solutions = ();
728 foreach (@$solref) {
729 my $sol = $_;
730 my $BDD = new Cudd::BDD($manager,$sol);
731 push(@solutions,$BDD);
732 }
733 return((\@solutions,$BDD));
734}
735
736=item Signatures
737
738Computes the variable signatures in a BDD. The signature of a variable
739is the fraction of minterms in the on-set of the cofactor w.r.t. to
740that variable. The function returns an array of as many signatures as
741there are variables plus one. The last element of the array is the
742fraction of minterms in the ON-set of the BDD, and can be used to
743normalize the variable signatures.
744
745=cut
746
747sub Signatures {
748 my $f = shift;
749 my $manager = $f->{'manager'};
750 croak "Invalid reference" unless ref $manager;
751 return Cudd::CofMinterm($$manager,$f->{'node'});
752}
753
754=item NormSignatures
755
756Returns signatures normalized between 0 and 2. See also Signatures.
757
758=cut
759
760sub NormSignatures {
761 my $f = shift;
762 my $raw = Cudd::BDD::Signatures($f);
763 my $size = @$raw;
764 my $result = [map {$$raw[$_] / $$raw[$size-1]} (0..$size-2)];
765}
766
767=item SubsetHB
768
769Computes a subset of a BDD with a maximum number of nodes. Uses the
770heavy branch approach.
771
772=cut
773
774sub SubsetHB {
775 my ($f,$th) = @_;
776 my $manager = $f->{'manager'};
777 croak "Invalid reference" unless ref $manager;
778 my $numVars = Cudd::ReadSize($$manager);
779 my $node = Cudd::SubsetHeavyBranch($$manager,$f->{'node'},$numVars,$th);
780 Cudd::Ref($node);
781 my $BDD = new Cudd::BDD($manager,$node);
782}
783
784=item SubsetSP
785
786Computes a subset of a BDD with a maximum number of nodes. Uses the
787short paths approach.
788
789=cut
790
791sub SubsetSP {
792 my ($f,$th) = @_;
793 my $manager = $f->{'manager'};
794 croak "Invalid reference" unless ref $manager;
795 my $numVars = Cudd::ReadSize($$manager);
796 my $node = Cudd::SubsetShortPaths($$manager,$f->{'node'},$numVars,$th,0);
797 Cudd::Ref($node);
798 my $BDD = new Cudd::BDD($manager,$node);
799}
800
801=item SupersetHB
802
803Computes a superset of a BDD with a maximum number of nodes. Uses the
804heavy branch approach.
805
806=cut
807
808sub SupersetHB {
809 my ($f,$th) = @_;
810 my $manager = $f->{'manager'};
811 croak "Invalid reference" unless ref $manager;
812 my $numVars = Cudd::ReadSize($$manager);
813 my $node = Cudd::SupersetHeavyBranch($$manager,$f->{'node'},$numVars,$th);
814 Cudd::Ref($node);
815 my $BDD = new Cudd::BDD($manager,$node);
816}
817
818=item SupersetSP
819
820Computes a superset of a BDD with a maximum number of nodes. Uses the
821short paths approach.
822
823=cut
824
825sub SupersetSP {
826 my ($f,$th) = @_;
827 my $manager = $f->{'manager'};
828 croak "Invalid reference" unless ref $manager;
829 my $numVars = Cudd::ReadSize($$manager);
830 my $node = Cudd::SupersetShortPaths($$manager,$f->{'node'},$numVars,$th,0);
831 Cudd::Ref($node);
832 my $BDD = new Cudd::BDD($manager,$node);
833}
834
835=item NewAdjVar
836
837Creates a new variable adjacent to the given variable. Useful in creating the next state variables of FSMs.
838
839=cut
840
841sub NewAdjVar {
842 my $var = shift;
843 my $manager = $var->{manager};
844 croak "Invalid reference" unless ref $manager;
845 my $index = Cudd::NodeReadIndex($var->{node});
846 my $level = Cudd::ReadPerm($$manager,$index);
847 my $node = Cudd::bddNewVarAtLevel($$manager,$level);
848 Cudd::Ref($node);
849 my $BDD = new Cudd::BDD($manager,$node);
850 return $BDD;
851}
852
853=item GroupVars
854
855Creates a group of variables to be kept adjacent during reordering.
856
857=cut
858
859sub GroupVars {
860 my $self = shift;
861 my $size = shift || 2;
862 my $method = shift || &Cudd::MTR_DEFAULT;
863 my $manager = $self->{manager};
864 croak "Invalid reference" unless ref $manager;
865 my $index = Cudd::NodeReadIndex($self->{node});
866 my $retval = Cudd::MakeTreeNode($$manager,$index,$size,$method);
867 return $retval;
868}
869
870=item Not
871
872Returns the complement of a BDD. Overloads '!'.
873
874=cut
875
876sub Not {
877 my ($f) = @_;
878 my $manager = $f->{'manager'};
879 croak "Invalid reference" unless ref $manager;
880 my $node = Cudd::Not($f->{'node'});
881 Cudd::Ref($node);
882 my $BDD = new Cudd::BDD($manager,$node);
883 return $BDD;
884}
885
886=item Equal
887
888Returns 1 if the two arguments are equivalent; 0 otherwise. Overloads '=='.
889
890=cut
891
892sub Equal {
893 my ($f,$g) = @_;
894 my $manager = $f->{'manager'};
895 croak "Invalid reference" unless ref $manager;
896 return (${$f->{'node'}} == ${$g->{'node'}}) ? 1 : 0;
897}
898
899=item Unequal
900
901Returns 1 if the two arguments are not equivalent; 0 otherwise. Overloads '!='.
902
903=cut
904
905sub Unequal {
906 my ($f,$g) = @_;
907 my $manager = $f->{'manager'};
908 croak "Invalid reference" unless ref $manager;
909 return (${$f->{'node'}} != ${$g->{'node'}}) ? 1 : 0;
910}
911
912=item Leq
913
914Compares two BDDs $f and $g and returns 1 if $f is less than or equal to $g.
915Overloads '<='.
916
917=cut
918
919sub Leq {
920 my ($f,$g) = @_;
921 my $manager = $f->{'manager'};
922 croak "Invalid reference" unless ref $manager;
923 return Cudd::bddLeq($$manager, $f->{'node'}, $g->{'node'});
924}
925
926=item Geq
927
928Compares two BDDs $f and $g and returns 1 if $f is greater than or equal to $g.
929Overloads '>='.
930
931=cut
932
933sub Geq {
934 my ($f,$g) = @_;
935 my $manager = $f->{'manager'};
936 croak "Invalid reference" unless ref $manager;
937 return Cudd::bddLeq($$manager, $g->{'node'}, $f->{'node'});
938}
939
940=item IsComplement
941
942Returns 1 if the BDD node is complemented, that is, if the BDD evaluates to 0 when all variables are assigned 1.
943
944=cut
945
946sub IsComplement {
947 my $f = shift;
948 return Cudd::IsComplement($f->{'node'});
949}
950
951=item ShortestPath
952
953Computes a shortest path in a BDD.
954
955=cut
956
957sub ShortestPath {
958 my ($f) = @_;
959 my $manager = $f->{'manager'};
960 croak "Invalid reference" unless ref $manager;
961 my $length = 0;
962 my $node = Cudd::ShortestPath($$manager, $f->{'node'}, $length);
963 Cudd::Ref($node);
964 my $BDD = new Cudd::BDD($manager,$node);
965 return $BDD;
966}
967
968=item Size
969
970Returns the number of nodes in the BDD or BDDs passed as arguments.
971
972=cut
973
974sub Size {
975 my ($f) = @_;
976 if (ref($f) eq "Cudd::BDD") {
977 $f = [$f->{'node'}];
978 } elsif (ref($f) eq "ARRAY") {
979 $f = [map $_->{'node'}, (@$f)];
980 } elsif (ref($f) eq "HASH") {
981 $f = [map $_->{'node'}, values(%$f)];
982 }
983 my $size = Cudd::SharingSize($f);
984 return $size;
985}
986
987=item Minterms
988
989Returns the number of minterms of the BDD. The function of the BDD is
990supposed to depend on C<$n> variables.
991
992=cut
993
994sub Minterms {
995 my ($f,$n) = @_;
996 my $manager = $f->{'manager'};
997 croak "Invalid reference" unless ref $manager;
998 my $retval = Cudd::CountMinterm($$manager, $f->{'node'}, $n);
999 return $retval;
1000}
1001
1002=item Print
1003
1004Prints information about a BDD $f. The $pr parameter controls how much
1005information is printed. The $n parameter specifies how many inputs $f depends
1006on. This information is necessary to compute the number of minterms.
1007
1008=cut
1009
1010sub Print {
1011 my ($f,$n,$pr) = @_;
1012 my $manager = $f->{'manager'};
1013 croak "Invalid reference" unless ref $manager;
1014 my $retval = Cudd::PrintDebug($$manager,$f->{'node'},$n,$pr);
1015 return $retval;
1016}
1017
1018=item Dot
1019
1020Prints a description of a set of BDDs in dot format. The function has
1021one mandatory parameter, the list of BDDs for which the dot
1022description is desired, and two optional parameters, the array of
1023input names and the array of output names. All parameters are array
1024references. If the input names are omitted but the output names are
1025not, a reference to an empty array ([]) should be passed for the input
1026names.
1027
1028=cut
1029
1030sub Dot {
1031 my $fref = shift;
1032 my ($inameref,$onameref);
1033 if (@_) {
1034 $inameref = shift;
1035 } else {
1036 $inameref = [];
1037 }
1038 if (@_) {
1039 $onameref = shift;
1040 } else {
1041 $onameref = [];
1042 }
1043 my $first = $$fref[0];
1044 my $manager = $first->{'manager'};
1045 croak "Invalid reference" unless ref $manager;
1046 my @f = ();
1047 foreach (@$fref) {
1048 my $f = $_;
1049 push(@f,$f->{'node'});
1050 }
1051 my $retval = Cudd::DumpDot($$manager,\@f,$onameref,$inameref);
1052 warn "Error while writing dot file" if ($retval != 1);
1053 return $retval;
1054}
1055
1056=item Intersect
1057
1058Computes a function included in the intersection of $f and $g. (That
1059is, a witness that the intersection is not empty.) Intersect tries to
1060build as few new nodes as possible.
1061
1062=cut
1063
1064sub Intersect {
1065 my ($f,$g) = @_;
1066 my $manager = $f->{'manager'};
1067 croak "Invalid reference" unless ref $manager;
1068 my $node = Cudd::bddIntersect($$manager,$f->{'node'},$g->{'node'});
1069 Cudd::Ref($node);
1070 my $BDD = new Cudd::BDD($manager,$node);
1071 return $BDD;
1072}
1073
1074=item ConstrainDecomp
1075
1076BDD conjunctive decomposition as in the CAV96 paper by McMillan. The
1077decomposition is canonical only for a given variable order. If
1078canonicity is required, variable ordering must be disabled after the
1079decomposition has been computed. Returns an array with one entry for
1080each BDD variable.
1081
1082=cut
1083
1084sub ConstrainDecomp {
1085 my ($f) = @_;
1086 my $manager = $f->{'manager'};
1087 croak "Invalid reference" unless ref $manager;
1088 my $decref = Cudd::bddConstrainDecomp($$manager,$f->{'node'});
1089 my @decomp = ();
1090 foreach (@$decref) {
1091 my $dec = $_;
1092 my $BDD = new Cudd::BDD($manager,$dec);
1093 push(@decomp,$BDD);
1094 }
1095 return \@decomp;
1096}
1097
1098=item CharToVect
1099
1100Computes a vector of functions such that their image equals a non-zero
1101function. Returns an array with one entry for each BDD variable.
1102
1103=cut
1104
1105sub CharToVect {
1106 my ($f) = @_;
1107 my $manager = $f->{'manager'};
1108 croak "Invalid reference" unless ref $manager;
1109 my $vecref = Cudd::bddCharToVect($$manager,$f->{'node'});
1110 my @vect = ();
1111 foreach (@$vecref) {
1112 my $vec = $_;
1113 my $BDD = new Cudd::BDD($manager,$vec);
1114 push(@vect,$BDD);
1115 }
1116 return \@vect;
1117}
1118
1119=item PrioritySelect
1120
1121Selects pairs from a relation C<R(x,y)> (given as a BDD)
1122in such a way that a given x appears in one pair only. Uses a
1123priority function to determine which y should be paired to a given x.
1124
1125=cut
1126
1127sub PrioritySelect {
1128 my ($f,$Pi,$xref,$yref,$zref) = @_;
1129 my $manager = $f->{'manager'};
1130 croak "Invalid reference" unless ref $manager;
1131 my @xvars = map $_->{'node'}, (@$xref);
1132 my @yvars = map $_->{'node'}, (@$yref);
1133 my @zvars = map $_->{'node'}, (@$zref);
1134 my $node = Cudd::PrioritySelect($$manager,$f->{'node'},$Pi->{'node'},
1135 \@xvars,\@yvars,\@zvars);
1136 Cudd::Ref($node);
1137 my $BDD = new Cudd::BDD($manager,$node);
1138 return $BDD;
1139}
1140
1141=item PiDxygtdxz
1142
1143Returns the priority function that is 1 if the distance of x from y is greater than the distance of x from z.
1144
1145=cut
1146
1147sub PiDxygtdxz {
1148 my ($xref,$yref,$zref) = @_;
1149 my $first = $$xref[0];
1150 my $manager = $first->{'manager'};
1151 croak "Invalid reference" unless ref $manager;
1152 my @xvars = map $_->{'node'}, (@$xref);
1153 my @yvars = map $_->{'node'}, (@$yref);
1154 my @zvars = map $_->{'node'}, (@$zref);
1155 my $node = Cudd::Dxygtdxz($$manager,\@xvars,\@yvars,\@zvars);
1156 Cudd::Ref($node);
1157 my $BDD = new Cudd::BDD($manager,$node);
1158 return $BDD;
1159}
1160
1161=item PiDxygtdyz
1162
1163Returns the priority function that is 1 if the distance of x from y is greater than the distance of y from z.
1164
1165=cut
1166
1167sub PiDxygtdyz {
1168 my ($xref,$yref,$zref) = @_;
1169 my $first = $$xref[0];
1170 my $manager = $first->{'manager'};
1171 croak "Invalid reference" unless ref $manager;
1172 my @xvars = map $_->{'node'}, (@$xref);
1173 my @yvars = map $_->{'node'}, (@$yref);
1174 my @zvars = map $_->{'node'}, (@$zref);
1175 my $node = Cudd::Dxygtdyz($$manager,\@xvars,\@yvars,\@zvars);
1176 Cudd::Ref($node);
1177 my $BDD = new Cudd::BDD($manager,$node);
1178 return $BDD;
1179}
1180
1181=item PiXgty
1182
1183Returns the priority function that is 1 if x is greater than y.
1184
1185=cut
1186
1187sub PiXgty {
1188 my ($zref,$xref,$yref) = @_;
1189 my $first = $$xref[0];
1190 my $manager = $first->{'manager'};
1191 croak "Invalid reference" unless ref $manager;
1192 my @zvars = map $_->{'node'}, (@$zref);
1193 my @xvars = map $_->{'node'}, (@$xref);
1194 my @yvars = map $_->{'node'}, (@$yref);
1195 my $node = Cudd::Xgty($$manager,\@zvars,\@xvars,\@yvars);
1196 Cudd::Ref($node);
1197 my $BDD = new Cudd::BDD($manager,$node);
1198 return $BDD;
1199}
1200
1201=item CProjection
1202
1203Applies the C-Projection to a relation R.
1204
1205=cut
1206
1207sub CProjection {
1208 my ($R,$Y) = @_;
1209 my $manager = $R->{'manager'};
1210 croak "Invalid reference" unless ref $manager;
1211 my $node = Cudd::CProjection($$manager,$R->{'node'},$Y->{'node'});
1212 Cudd::Ref($node);
1213 my $BDD = new Cudd::BDD($manager,$node);
1214 return $BDD;
1215}
1216
1217=item Shuffle
1218
1219Imposes a given order.
1220
1221=cut
1222
1223sub Shuffle {
1224 my $varref = shift;
1225 my $first = $$varref[0];
1226 my $manager = $first->{'manager'};
1227 croak "Invalid reference" unless ref $manager;
1228 my @permutation = ();
1229 foreach (@$varref) {
1230 my $var = $_;
1231 my $index = Cudd::NodeReadIndex($var->{node});
1232 push(@permutation,$index);
1233 }
1234 return Cudd::ShuffleHeap($$manager,\@permutation);
1235}
1236
1237package Cudd;
1238
1239# Autoload methods go after =cut, and are processed by the autosplit program.
1240
12411;
1242__END__
1243# Documentation.
1244
1245
1246=back 4
1247
1248Package Cudd:BDD overloads common operators as follows:
1249
1250C<+ > -> Or
1251
1252C<* > -> And
1253
1254C<^ > -> Xor
1255
1256C<! > -> Not
1257
1258C</ > -> Cofactor
1259
1260C<==> -> Equal
1261
1262C<!=> -> Unequal
1263
1264C<E<lt>=> -> Leq
1265
1266C<E<gt>=> -> Geq
1267
1268=head1 EXAMPLE
1269
1270The following code fragment creates a manager, two variables C<$x> and
1271C<$y> in it, and then builds and prints the conjunction of the two
1272variables.
1273
1274 my $manager = new Cudd;
1275 my $x = $manager->BddVar;
1276 my $y = $manager->BddVar;
1277 my $z = $x * $y;
1278 $z->Print(2,1); # (2 variables, verbosity 1)
1279
1280=head1 AUTHOR
1281
1282Fabio Somenzi, Fabio@Colorado.EDU
1283
1284=head1 SEE ALSO
1285
1286perl(1).
1287
1288=cut