aboutsummaryrefslogtreecommitdiff
path: root/lib/trie.ml
diff options
context:
space:
mode:
authorppedrot2013-05-09 21:53:44 +0000
committerppedrot2013-05-09 21:53:44 +0000
commit3b005bfdb2d595f5b8e094f940ae26f072780faf (patch)
tree15e7099f22d401561960de753c06add75cf53989 /lib/trie.ml
parent9f3ccbf420eec91410dea100b217a60f7defa5f2 (diff)
Documenting the Tries module, uniformizing the names according to
Map/Set style and renaming the file accordingly as Trie. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@16504 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'lib/trie.ml')
-rw-r--r--lib/trie.ml91
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/trie.ml b/lib/trie.ml
new file mode 100644
index 0000000000..d0bcc01554
--- /dev/null
+++ b/lib/trie.ml
@@ -0,0 +1,91 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+module type S =
+sig
+ type label
+ type data
+ type t
+ val empty : t
+ val get : t -> data list
+ val next : t -> label -> t
+ val labels : t -> label list
+ val add : label list -> data -> t -> t
+ val remove : label list -> data -> t -> t
+ val iter : (label list -> data -> unit) -> t -> unit
+end
+
+module Make (Y : Map.OrderedType) (X : Set.OrderedType) =
+struct
+
+module T_dom = Fset.Make(X)
+module T_codom = Fmap.Make(Y)
+
+type data = X.t
+type label = Y.t
+type t = Node of T_dom.t * t T_codom.t
+
+let codom_to_list m = T_codom.fold (fun x y l -> (x,y)::l) m []
+
+let codom_rng m = T_codom.fold (fun _ y acc -> y::acc) m []
+
+let codom_dom m = T_codom.fold (fun x _ acc -> x::acc) m []
+
+let empty = Node (T_dom.empty, T_codom.empty)
+
+let next (Node (_,m)) lbl = T_codom.find lbl m
+
+let get (Node (hereset,_)) = T_dom.elements hereset
+
+let labels (Node (_,m)) = codom_dom m
+
+let in_dom (Node (_,m)) lbl = T_codom.mem lbl m
+
+let is_empty_node (Node(a,b)) = (T_dom.elements a = []) && (codom_to_list b = [])
+
+let assure_arc m lbl =
+ if T_codom.mem lbl m then
+ m
+ else
+ T_codom.add lbl (Node (T_dom.empty,T_codom.empty)) m
+
+let cleanse_arcs (Node (hereset,m)) =
+ let l = codom_rng m in
+ Node(hereset, if List.for_all is_empty_node l then T_codom.empty else m)
+
+let rec at_path f (Node (hereset,m)) = function
+ | [] ->
+ cleanse_arcs (Node(f hereset,m))
+ | h::t ->
+ let m = assure_arc m h in
+ cleanse_arcs (Node(hereset,
+ T_codom.add h (at_path f (T_codom.find h m) t) m))
+
+let add path v tm =
+ at_path (fun hereset -> T_dom.add v hereset) tm path
+
+let remove path v tm =
+ at_path (fun hereset -> T_dom.remove v hereset) tm path
+
+let iter f tlm =
+ let rec apprec pfx (Node(hereset,m)) =
+ let path = List.rev pfx in
+ T_dom.iter (fun v -> f path v) hereset;
+ T_codom.iter (fun l tm -> apprec (l::pfx) tm) m
+ in
+ apprec [] tlm
+
+let to_list tlm =
+ let rec torec pfx (Node(hereset,m)) =
+ let path = List.rev pfx in
+ List.flatten((List.map (fun v -> (path,v)) (T_dom.elements hereset))::
+ (List.map (fun (l,tm) -> torec (l::pfx) tm) (codom_to_list m)))
+ in
+ torec [] tlm
+
+end