From: Alberto Griggio Date: Sun, 19 Jun 2005 10:08:05 +0000 (+0000) Subject: path indexing working! X-Git-Tag: INDEXING_NO_PROOFS~115 X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=commitdiff_plain;h=b9599336a7e5b19b3cf37d73a9d14f9899e2b82f;p=helm.git path indexing working! --- diff --git a/helm/ocaml/paramodulation/path_indexing.ml b/helm/ocaml/paramodulation/path_indexing.ml new file mode 100644 index 000000000..87e917fff --- /dev/null +++ b/helm/ocaml/paramodulation/path_indexing.ml @@ -0,0 +1,308 @@ +(* path indexing implementation *) + +(* position of the subterm, subterm (Appl are not stored...) *) +type path_string_elem = Index of int | Term of Cic.term;; +type path_string = path_string_elem list;; + + +let rec path_strings_of_term index = + let module C = Cic in function + | C.Meta _ -> [ [Index index; Term (C.Implicit None)] ] + | C.Appl (hd::tl) -> + let p = if index > 0 then [Index index; Term hd] else [Term hd] in + let _, res = + List.fold_left + (fun (i, r) t -> + let rr = path_strings_of_term i t in + (i+1, r @ (List.map (fun ps -> p @ ps) rr))) + (1, []) tl + in + res + | term -> [ [Index index; Term term] ] +;; + + +let string_of_path_string ps = + String.concat "." + (List.map + (fun e -> + let s = + match e with + | Index i -> "Index " ^ (string_of_int i) + | Term t -> "Term " ^ (CicPp.ppterm t) + in + "(" ^ s ^ ")") + ps) +;; + + +module OrderedPathStringElement = struct + type t = path_string_elem + + let compare t1 t2 = + match t1, t2 with + | Index i, Index j -> Pervasives.compare i j + | Term t1, Term t2 -> if t1 = t2 then 0 else Pervasives.compare t1 t2 + | Index _, Term _ -> -1 + | Term _, Index _ -> 1 +end + +module PSMap = Map.Make(OrderedPathStringElement);; + +(* module PSTrie = Trie.Make(PathStringElementMap);; *) + +module OrderedPosEquality = struct + type t = Utils.pos * Inference.equality + + let compare = Pervasives.compare +end + +module PosEqSet = Set.Make(OrderedPosEquality);; + +(* + * Trie: maps over lists. + * Copyright (C) 2000 Jean-Christophe FILLIATRE + *) +module PSTrie = struct + type key = path_string + type t = Node of PosEqSet.t option * (t PSMap.t) + + let empty = Node (None, PSMap.empty) + + let rec find l t = + match (l, t) with + | [], Node (None, _) -> raise Not_found + | [], Node (Some v, _) -> v + | x::r, Node (_, m) -> find r (PSMap.find x m) + + let rec mem l t = + match (l, t) with + | [], Node (None, _) -> false + | [], Node (Some _, _) -> true + | x::r, Node (_, m) -> try mem r (PSMap.find x m) with Not_found -> false + + let add l v t = + let rec ins = function + | [], Node (_, m) -> Node (Some v, m) + | x::r, Node (v, m) -> + let t' = try PSMap.find x m with Not_found -> empty in + let t'' = ins (r, t') in + Node (v, PSMap.add x t'' m) + in + ins (l, t) + + let rec remove l t = + match (l, t) with + | [], Node (_, m) -> Node (None, m) + | x::r, Node (v, m) -> + try + let t' = remove r (PSMap.find x m) in + Node (v, if t' = empty then PSMap.remove x m else PSMap.add x t' m) + with Not_found -> + t + + let rec fold f t acc = + let rec traverse revp t acc = match t with + | Node (None, m) -> + PSMap.fold (fun x -> traverse (x::revp)) m acc + | Node (Some v, m) -> + f (List.rev revp) v (PSMap.fold (fun x -> traverse (x::revp)) m acc) + in + traverse [] t acc + +end + + +let index trie equality = + let _, (_, l, r, ordering), _, _ = equality in + let psl = path_strings_of_term 0 l + and psr = path_strings_of_term 0 r in + let index pos trie ps = + let ps_set = try PSTrie.find ps trie with Not_found -> PosEqSet.empty in + let trie = PSTrie.add ps (PosEqSet.add (pos, equality) ps_set) trie in +(* if PosEqSet.mem (pos, equality) (PSTrie.find ps trie) then *) +(* Printf.printf "OK: %s, %s indexed\n" (Utils.string_of_pos pos) *) +(* (Inference.string_of_equality equality); *) + trie + in + match ordering with + | Utils.Gt -> List.fold_left (index Utils.Left) trie psl + | Utils.Lt -> List.fold_left (index Utils.Right) trie psr + | _ -> + let trie = List.fold_left (index Utils.Left) trie psl in + List.fold_left (index Utils.Right) trie psr +;; + + +let remove_index trie equality = + let _, (_, l, r, ordering), _, _ = equality in + let psl = path_strings_of_term 0 l + and psr = path_strings_of_term 0 r in + let remove_index pos trie ps = + try + let ps_set = PosEqSet.remove (pos, equality) (PSTrie.find ps trie) in + if PosEqSet.is_empty ps_set then + PSTrie.remove ps trie + else + PSTrie.add ps ps_set trie + with Not_found -> +(* Printf.printf "NOT_FOUND: %s, %s\n" (Utils.string_of_pos pos) *) +(* (Inference.string_of_equality equality); *) + trie +(* raise Not_found *) + in + match ordering with + | Utils.Gt -> List.fold_left (remove_index Utils.Left) trie psl + | Utils.Lt -> List.fold_left (remove_index Utils.Right) trie psr + | _ -> + let trie = List.fold_left (remove_index Utils.Left) trie psl in + List.fold_left (remove_index Utils.Right) trie psr +;; + + +let head_of_term = function + | Cic.Appl (hd::tl) -> hd + | term -> term +;; + + +let subterm_at_pos index term = + if index = 0 then + term + else + match term with + | Cic.Appl l -> + (try List.nth l index with Failure _ -> raise Not_found) + | _ -> raise Not_found +;; + + +let rec retrieve_generalizations trie term = + match trie with + | PSTrie.Node (value, map) -> + let res = + match term with + | Cic.Meta _ -> PosEqSet.empty + | term -> + let hd_term = head_of_term term in + try + let n = PSMap.find (Term hd_term) map in + match n with + | PSTrie.Node (Some s, _) -> s + | PSTrie.Node (None, m) -> + let l = + PSMap.fold + (fun k v res -> + match k with + | Index i -> + let t = subterm_at_pos i term in + let s = retrieve_generalizations v t in + s::res + | _ -> res) + m [] + in + match l with + | hd::tl -> + List.fold_left (fun r s -> PosEqSet.inter r s) hd tl + | _ -> PosEqSet.empty + with Not_found -> + PosEqSet.empty + in + try + let n = PSMap.find (Term (Cic.Implicit None)) map in + match n with + | PSTrie.Node (Some s, _) -> PosEqSet.union res s + | _ -> res + with Not_found -> + res +;; + + +let rec retrieve_unifiables trie term = + match trie with + | PSTrie.Node (value, map) -> + let res = + match term with + | Cic.Meta _ -> + PSTrie.fold + (fun ps v res -> PosEqSet.union res v) + (PSTrie.Node (None, map)) + PosEqSet.empty + | _ -> + let hd_term = head_of_term term in + try + let n = PSMap.find (Term hd_term) map in + match n with + | PSTrie.Node (Some v, _) -> v + | PSTrie.Node (None, m) -> + let l = + PSMap.fold + (fun k v res -> + match k with + | Index i -> + let t = subterm_at_pos i term in + let s = retrieve_unifiables v t in + s::res + | _ -> res) + m [] + in + match l with + | hd::tl -> + List.fold_left (fun r s -> PosEqSet.inter r s) hd tl + | _ -> PosEqSet.empty + with Not_found -> +(* Printf.printf "Not_found: %s, term was: %s\n" *) +(* (CicPp.ppterm hd_term) (CicPp.ppterm term); *) +(* Printf.printf "map is:\n %s\n\n" *) +(* (String.concat "\n" *) +(* (PSMap.fold *) +(* (fun k v l -> *) +(* match k with *) +(* | Index i -> ("Index " ^ (string_of_int i))::l *) +(* | Term t -> ("Term " ^ (CicPp.ppterm t))::l) *) +(* map [])); *) + PosEqSet.empty + in + try + let n = PSMap.find (Term (Cic.Implicit None)) map in + match n with + | PSTrie.Node (Some s, _) -> PosEqSet.union res s + | _ -> res + with Not_found -> + res +;; + + +let string_of_pstrie trie = + let rec to_string level = function + | PSTrie.Node (v, map) -> + let s = + match v with + | Some v -> + (String.make (2 * level) ' ') ^ + "{" ^ (String.concat "; " + (List.map + (fun (p, e) -> + "(" ^ (Utils.string_of_pos p) ^ ", " ^ + (Inference.string_of_equality e) ^ ")") + (PosEqSet.elements v))) ^ "}" + | None -> "" + in + let rest = + String.concat "\n" + (PSMap.fold + (fun k v s -> + let ks = + match k with + | Index i -> "Index " ^ (string_of_int i) + | Term t -> "Term " ^ (CicPp.ppterm t) + in + let rs = to_string (level+1) v in + ((String.make (2 * level) ' ') ^ ks ^ "\n" ^ rs)::s) + map []) + in + s ^ rest + in + to_string 0 trie +;; + diff --git a/helm/ocaml/paramodulation/test_path_indexing.ml b/helm/ocaml/paramodulation/test_path_indexing.ml new file mode 100644 index 000000000..0514f9ab9 --- /dev/null +++ b/helm/ocaml/paramodulation/test_path_indexing.ml @@ -0,0 +1,56 @@ +open Path_indexing + + +let build_equality term = + let module C = Cic in + C.Implicit None, (C.Implicit None, term, C.Rel 1, Utils.Gt), [], [] +;; + + +(* + f = Rel 1 + g = Rel 2 + a = Rel 3 + b = Rel 4 + c = Rel 5 +*) +let main_test () = + let module C = Cic in + let terms = [ + C.Appl [C.Rel 1; C.Appl [C.Rel 2; C.Rel 3; C.Meta (1, [])]; C.Rel 5]; + C.Appl [C.Rel 1; C.Appl [C.Rel 2; C.Meta (1, []); C.Rel 4]; C.Meta (1, [])]; + C.Appl [C.Rel 1; C.Appl [C.Rel 2; C.Rel 3; C.Rel 4]; C.Rel 5]; + C.Appl [C.Rel 1; C.Appl [C.Rel 2; C.Meta (1, []); C.Rel 5]; C.Rel 4]; + C.Appl [C.Rel 1; C.Meta (1, []); C.Meta (1, [])] + ] in + let path_strings = List.map (path_strings_of_term 0) terms in + let table = + List.fold_left index PSTrie.empty (List.map build_equality terms) in + let query = + C.Appl [C.Rel 1; C.Appl [C.Rel 2; C.Meta (1, []); C.Rel 4]; C.Rel 5] in + let matches = retrieve_generalizations table query in + let unifications = retrieve_unifiables table query in + let print_results res = + String.concat "\n" + (PosEqSet.fold + (fun (p, e) l -> + let s = + "(" ^ (Utils.string_of_pos p) ^ ", " ^ + (Inference.string_of_equality e) ^ ")" + in + s::l) + res []) + in + Printf.printf "path_strings:\n%s\n\n" + (String.concat "\n" + (List.map + (fun l -> + "{" ^ (String.concat "; " (List.map string_of_path_string l)) ^ "}" + ) path_strings)); + Printf.printf "table:\n%s\n\n" (string_of_pstrie table); + Printf.printf "matches:\n%s\n\n" (print_results matches); + Printf.printf "unifications:\n%s\n" (print_results unifications) +;; + + +main_test ();;