Skip to content

Commit a9cbf7b

Browse files
etw33smolkaj
authored andcommitted
implement set, test, star, subseteq, and add README. add tests for star (#6)
1 parent a1ec58a commit a9cbf7b

File tree

4 files changed

+86
-7
lines changed

4 files changed

+86
-7
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Overview
2+
This package implements hash-consed binary decision diagrams (BDDs) and identity-suppressed decision diagrams (IDDs).
3+
4+
An IDD, like a BBD, can be seen as representing a transition relation R on a state space of boolean vectors. I.e. boolean vector pair (v1, v2) belongs to R if and only if evaluating the IDD-representation of R in the environment given by (v1, v2) yields true.
5+
6+
The main motivation for IDDs is that they represent the identity relation in a constant amount of space instead of in an amount of space that is linear in the size of the boolean vectors.
7+
8+
# Provided operations
9+
## BDDs
10+
* Constructors: true, false, if-then-else
11+
* Operations: equality, negation, disjunction, conjunction
12+
13+
## IDDs
14+
* Constructors: identity relation, empty relation, test, set, branch
15+
* Operations: equality, subset test, apply algorithm, union, sequential composition, transitive-reflexive closure
16+
17+

src/idd.ml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ let manager () : manager = {
2222
seq_cache = Hashtbl.create (module Pair);
2323
}
2424

25+
let test mgr i b =
26+
Dd.branch mgr.dd (Var.inp i) (if b then Dd.ctrue else Dd.cfalse)
27+
(if b then Dd.cfalse else Dd.ctrue)
28+
29+
let set mgr i b =
30+
Dd.branch mgr.dd (Var.out i) (if b then Dd.ctrue else Dd.cfalse)
31+
(if b then Dd.cfalse else Dd.ctrue)
32+
2533
let rec eval' expl (tree:t) (env:Var.t -> bool) (n:int) =
2634
match tree with
2735
| False ->
@@ -87,7 +95,6 @@ let branch (mgr : manager) (x : Var.t) (hi : t) (lo : t) : t =
8795
end
8896
(* ) *)
8997

90-
9198
let extract (d:t) (side:bool) : t =
9299
match d with
93100
| False | True -> d
@@ -173,6 +180,16 @@ let rec seq mgr (d0:t) (d1:t) =
173180
(union mgr (seq mgr d0_01 d1_10) (seq mgr d0_00 d1_00)))
174181
)
175182

183+
let star mgr (d0:t) =
184+
let rec loop curr prev =
185+
if equal curr prev then prev else
186+
loop (seq mgr curr curr) curr
187+
in
188+
loop (union mgr ident d0) ident
189+
190+
let subseteq mgr (d0:t) (d1:t) =
191+
equal (union mgr d0 d1) d1
192+
176193
(* relational operations *)
177194
module Rel = struct
178195

src/idd.mli

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ val empty : t
2121
(** For i < n,
2222
eval (test i b) env n =
2323
env (Var.inp i) = b && eval ident env n
24-
rel n (test i b) = { (x,x) | x \in B^n, x_i = b }
24+
rel n (test i b) = \{ (x,x) | x \in B^n, x_i = b \}
2525
*)
26-
val test : int -> bool -> t
26+
val test : manager -> int -> bool -> t
2727

2828
(** For i < n,
2929
eval (set i b) env n = eval ident env' n, where
3030
env' x = if x = Var.inp i then b else env x
31-
rel n (set i b) = { (x,x[i:=b]) | x \in B^n }
31+
rel n (set i b) = \{ (x,x[i:=b]) | x \in B^n \}
3232
*)
33-
val set : int -> bool -> t
33+
val set : manager -> int -> bool -> t
3434

3535
(** [branch mgr var hi lo] is the diagram that behaves like [hi] when
3636
[var = true], and like [lo] when [var = false]. *)
@@ -47,7 +47,7 @@ val seq : manager -> t -> t -> t
4747
val union : manager -> t -> t -> t
4848

4949
(** (Relational) transitive-reflexive closure *)
50-
val star : t -> t
50+
val star : manager -> t -> t
5151

5252
(** {2 Boolean operations} *)
5353

@@ -58,7 +58,7 @@ val star : t -> t
5858
val equal : t -> t -> bool
5959

6060
(** relational containment *)
61-
val subseteq : t -> t -> bool
61+
val subseteq : manager -> t -> t -> bool
6262

6363
(** {2 Semantics} *)
6464

test/idd_test.ml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,49 @@ module Basic = struct
151151
)
152152
)
153153

154+
(* Star tests *)
155+
156+
let is_transitive d0 max_idx =
157+
Idd.(
158+
let alllsts = all_lsts max_idx in
159+
List.cartesian_product alllsts alllsts |>
160+
List.cartesian_product alllsts |>
161+
List.for_all ~f:(fun (lst1, (lst2, lst3)) ->
162+
if eval d0 (env_from_lsts lst1 lst2) max_idx &&
163+
eval d0 (env_from_lsts lst2 lst3) max_idx then
164+
eval d0 (env_from_lsts lst1 lst3) max_idx
165+
else true
166+
)
167+
)
168+
169+
let%test "[star d0] contains d0 and is reflexive and transitive" =
170+
List.for_all trees ~f:(fun d0 ->
171+
Idd.(
172+
let starred = star mgr d0 in
173+
let max1, max2 = index d0 + 1, index starred + 1 in
174+
let max_idx = max max1 max2 in
175+
(* contains d0 check *)
176+
subseteq mgr d0 starred &&
177+
(* reflexive check *)
178+
subseteq mgr ident starred &&
179+
(* transitive check *)
180+
is_transitive starred max_idx
181+
)
182+
)
183+
184+
let%test "[star d0] is the smallest" =
185+
List.for_all small_trees ~f:(fun d0 ->
186+
Idd.(
187+
let starred = star mgr d0 in
188+
let max1 = index d0 + 1 in
189+
List.for_all small_trees ~f:(fun d1 ->
190+
let max2 = index d1 + 1 in
191+
let max_idx = max max1 max2 in
192+
if subseteq mgr ident d1 && subseteq mgr d0 d1 &&
193+
is_transitive d1 max_idx
194+
then subseteq mgr starred d1 else true
195+
)
196+
)
197+
)
198+
154199
end

0 commit comments

Comments
 (0)