]> matita.cs.unibo.it Git - helm.git/commitdiff
path indexing working!
authorAlberto Griggio <griggio@fbk.eu>
Sun, 19 Jun 2005 10:08:05 +0000 (10:08 +0000)
committerAlberto Griggio <griggio@fbk.eu>
Sun, 19 Jun 2005 10:08:05 +0000 (10:08 +0000)
helm/ocaml/paramodulation/path_indexing.ml [new file with mode: 0644]
helm/ocaml/paramodulation/test_path_indexing.ml [new file with mode: 0644]

diff --git a/helm/ocaml/paramodulation/path_indexing.ml b/helm/ocaml/paramodulation/path_indexing.ml
new file mode 100644 (file)
index 0000000..87e917f
--- /dev/null
@@ -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 (file)
index 0000000..0514f9a
--- /dev/null
@@ -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 ();;