1 type path_string_elem = Cic.term;;
2 type path_string = path_string_elem list;;
5 (* needed by the retrieve_* functions, to know the arities of the "functions" *)
6 let arities = Hashtbl.create 11;;
9 let rec path_string_of_term = function
10 | Cic.Meta _ -> [Cic.Implicit None]
11 | Cic.Appl ((hd::tl) as l) ->
12 if not (Hashtbl.mem arities hd) then
13 Hashtbl.add arities hd (List.length tl);
14 List.concat (List.map path_string_of_term l)
19 module OrderedPathStringElement = struct
20 type t = path_string_elem
22 let compare = Pervasives.compare
25 module PSMap = Map.Make(OrderedPathStringElement);;
28 module DiscriminationTree = struct
29 type key = path_string
30 type t = Node of (Utils.pos * Inference.equality) option * (t PSMap.t)
32 let empty = Node (None, PSMap.empty)
36 | [], Node (None, _) -> raise Not_found
37 | [], Node (Some v, _) -> v
38 | x::r, Node (_, m) -> find r (PSMap.find x m)
42 | [], Node (None, _) -> false
43 | [], Node (Some _, _) -> true
44 | x::r, Node (_, m) -> try mem r (PSMap.find x m) with Not_found -> false
47 let rec ins = function
48 | [], Node (_, m) -> Node (Some v, m)
49 | x::r, Node (v, m) ->
50 let t' = try PSMap.find x m with Not_found -> empty in
51 let t'' = ins (r, t') in
52 Node (v, PSMap.add x t'' m)
58 | [], Node (_, m) -> Node (None, m)
59 | x::r, Node (v, m) ->
61 let t' = remove r (PSMap.find x m) in
62 Node (v, if t' = empty then PSMap.remove x m else PSMap.add x t' m)
66 let rec fold f t acc =
67 let rec traverse revp t acc = match t with
69 PSMap.fold (fun x -> traverse (x::revp)) m acc
71 f (List.rev revp) v (PSMap.fold (fun x -> traverse (x::revp)) m acc)
78 let index tree equality =
79 let _, (_, l, r, ordering), _, _ = equality in
80 let psl = path_string_of_term l
81 and psr = path_string_of_term r in
83 | Utils.Gt -> DiscriminationTree.add psl (Utils.Left, equality) tree
84 | Utils.Lt -> DiscriminationTree.add psr (Utils.Right, equality) tree
86 let tree = DiscriminationTree.add psl (Utils.Left, equality) tree in
87 DiscriminationTree.add psr (Utils.Right, equality) tree
91 let remove_index tree equality =
92 let _, (_, l, r, ordering), _, _ = equality in
93 let psl = path_string_of_term l
94 and psr = path_string_of_term r in
96 | Utils.Gt -> DiscriminationTree.remove psl tree
97 | Utils.Lt -> DiscriminationTree.remove psr tree
99 let tree = DiscriminationTree.remove psl tree in
100 DiscriminationTree.remove psr tree
104 let in_index tree equality =
105 let _, (_, l, r, ordering), _, _ = equality in
106 let psl = path_string_of_term l
107 and psr = path_string_of_term r in
108 let meta_convertibility = Inference.meta_convertibility_eq equality in
110 try let _, eq = DiscriminationTree.find ps tree in meta_convertibility eq
111 with Not_found -> false
117 let head_of_term = function
118 | Cic.Appl (hd::tl) -> hd
123 let rec subterm_at_pos pos term =
129 (try subterm_at_pos pos (List.nth l index) with _ -> raise Not_found)
130 | _ -> raise Not_found
134 let next_t pos term =
135 let t = subterm_at_pos pos term in
137 let t2 = subterm_at_pos [1] t in
142 | pos -> List.fold_right (fun i r -> if r = [] then [i+1] else i::r) pos []
146 let rec after_t pos term =
149 | [] -> raise Not_found
150 | pos -> List.fold_right (fun i r -> if r = [] then [i+1] else i::r) pos []
153 let t = subterm_at_pos pos' term in pos'
157 (fun i (r, b) -> if b then (i::r, true) else (r, true)) pos ([], false)
163 let retrieve_generalizations tree term =
164 let rec retrieve tree term pos =
166 | DiscriminationTree.Node (value, map) ->
169 let hd_term = head_of_term (subterm_at_pos pos term) in
170 let n = PSMap.find hd_term map in
172 | DiscriminationTree.Node (Some s, _) -> [s]
173 | DiscriminationTree.Node (None, _) ->
174 retrieve n term (next_t pos term)
179 let n = PSMap.find (Cic.Implicit None) map in
180 res @ (retrieve n term (after_t pos term))
184 retrieve tree term []
188 let jump_list = function
189 | DiscriminationTree.Node (value, map) ->
192 | DiscriminationTree.Node (v, m) ->
198 let a = try Hashtbl.find arities k with Not_found -> 0 in
199 (get (n-1 + a) v) @ res) m []
203 let arity = try Hashtbl.find arities k with Not_found -> 0 in
209 let retrieve_unifiables tree term =
210 let rec retrieve tree term pos =
212 | DiscriminationTree.Node (value, map) ->
215 match subterm_at_pos pos term with
219 (fun t -> retrieve t term (next_t pos term))
222 let hd_term = head_of_term subterm in
223 let n = PSMap.find hd_term map in
225 | DiscriminationTree.Node (Some s, _) -> [s]
226 | DiscriminationTree.Node (None, _) ->
227 retrieve n term (next_t pos term)
232 let n = PSMap.find (Cic.Implicit None) map in
233 res @ (retrieve n term (after_t pos term))
237 retrieve tree term []