aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/rtree.ml
diff options
context:
space:
mode:
authorGravatar Maxime Dénès <mail@maximedenes.fr>2014-03-11 14:23:27 -0400
committerGravatar Maxime Dénès <mail@maximedenes.fr>2014-07-22 17:34:57 -0400
commit9c9f5a3bde48a46c8e5146093392883ee16bc9e2 (patch)
tree3ea3b2b8fe1efbbb602952361d9adfa91aae357f /lib/rtree.ml
parent286abd141d415a621cc8ea98055d8dc744c8b752 (diff)
Made intersection on regular trees less intensional.
Diffstat (limited to 'lib/rtree.ml')
-rw-r--r--lib/rtree.ml28
1 files changed, 17 insertions, 11 deletions
diff --git a/lib/rtree.ml b/lib/rtree.ml
index 3c900d0b4..efcb6aae1 100644
--- a/lib/rtree.ml
+++ b/lib/rtree.ml
@@ -11,13 +11,12 @@ open Util
(* Type of regular trees:
- Param denotes tree variables (like de Bruijn indices)
the first int is the depth of the occurrence, and the second int
- is the index in the array of trees introduced at that depth
+ is the index in the array of trees introduced at that depth.
+ Warning: Param's indices both start at 0!
- Node denotes the usual tree node, labelled with 'a
- Rec(j,v1..vn) introduces infinite tree. It denotes
v(j+1) with parameters 0..n-1 replaced by
Rec(0,v1..vn)..Rec(n-1,v1..vn) respectively.
- Parameters n and higher denote parameters global to the
- current Rec node (as usual in de Bruijn binding system)
*)
type 'a t =
Param of int * int
@@ -145,22 +144,29 @@ let equal cmp t t' =
(** Deprecated alias *)
let eq_rtree = equal
-(* Intersection of rtrees of same arity *)
-let rec inter interlbl def t t' =
+(** Intersection of rtrees of same arity *)
+let rec inter cmp interlbl def n histo t t' =
+ try
+ let (i,j) = List.assoc_f (raw_eq2 cmp) (t,t') histo in
+ Param (n-i-1,j)
+ with Not_found ->
match t, t' with
| Param (i,j), Param (i',j') ->
assert (Int.equal i i' && Int.equal j j'); t
| Node (x, a), Node (x', a') ->
(match interlbl x x' with
| None -> mk_node def [||]
- | Some x'' -> Node (x'', Array.map2 (inter interlbl def) a a'))
- | Rec (i, a), Rec (i', a') ->
- if Int.equal i i' then Rec(i, Array.map2 (inter interlbl def) a a')
- else mk_node def [||]
- | Rec _, _ -> inter interlbl def (expand t) t'
- | _ , Rec _ -> inter interlbl def t (expand t')
+ | Some x'' -> Node (x'', Array.map2 (inter cmp interlbl def n histo) a a'))
+ (* Mutually recursive trees are transformed into nested trees *)
+ | Rec _, Rec _ ->
+ let histo = ((t,t'),(n,0))::histo in
+ Rec(0, [|inter cmp interlbl def (n+1) histo (expand t) (expand t')|])
+ | Rec _, _ -> inter cmp interlbl def n histo (expand t) t'
+ | _ , Rec _ -> inter cmp interlbl def n histo t (expand t')
| _ -> assert false
+let inter cmp interlbl def t t' = inter cmp interlbl def 0 [] t t'
+
(** Tests if a given tree is infinite, i.e. has a branch of infinite length.
This corresponds to a cycle when visiting the expanded tree.
We use a specific comparison to detect already seen trees. *)