]> matita.cs.unibo.it Git - helm.git/blobdiff - components/tactics/paramodulation/subst.ml
branch for universe
[helm.git] / components / tactics / paramodulation / subst.ml
diff --git a/components/tactics/paramodulation/subst.ml b/components/tactics/paramodulation/subst.ml
new file mode 100644 (file)
index 0000000..fb8e3b7
--- /dev/null
@@ -0,0 +1,217 @@
+(* cOpyright (C) 2005, HELM Team.
+ * 
+ * This file is part of HELM, an Hypertextual, Electronic
+ * Library of Mathematics, developed at the Computer Science
+ * Department, University of Bologna, Italy.
+ * 
+ * HELM is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * HELM is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HELM; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ * 
+ * For details, see the HELM World-Wide-Web page,
+ * http://cs.unibo.it/helm/.
+ *)
+
+(* $Id: inference.ml 6245 2006-04-05 12:07:51Z tassi $ *)
+
+
+(******* CIC substitution ***************************************************)
+
+type cic_substitution = Cic.substitution
+let cic_apply_subst = CicMetaSubst.apply_subst
+let cic_apply_subst_metasenv = CicMetaSubst.apply_subst_metasenv
+let cic_ppsubst = CicMetaSubst.ppsubst
+let cic_buildsubst n context t ty tail = (n,(context,t,ty)) :: tail
+let cic_flatten_subst subst =
+    List.map
+      (fun (i, (context, term, ty)) ->
+         let context = (* cic_apply_subst_context subst*) context in
+         let term = cic_apply_subst subst term in
+         let ty = cic_apply_subst subst ty in  
+         (i, (context, term, ty))) subst
+let rec cic_lookup_subst meta subst =
+  match meta with
+  | Cic.Meta (i, _) -> (
+      try let _, (_, t, _) = List.find (fun (m, _) -> m = i) subst 
+      in cic_lookup_subst t subst 
+      with Not_found -> meta
+    )
+  | _ -> meta
+;;
+
+let cic_merge_subst_if_possible s1 s2 =
+  let already_in = Hashtbl.create 13 in
+  let rec aux acc = function
+    | ((i,_,x) as s)::tl ->
+        (try 
+          let x' = Hashtbl.find already_in i in
+          if x = x' then aux acc tl else None
+        with
+        | Not_found -> 
+            Hashtbl.add already_in i x;
+            aux (s::acc) tl)
+    | [] -> Some acc 
+  in  
+    aux [] (s1@s2)
+;;
+
+(******** NAIF substitution **************************************************)
+(* 
+ * naif version of apply subst; the local context of metas is ignored;
+ * we assume the substituted term must be lifted according to the nesting
+ * depth of the meta. 
+ * Alternatively, we could used implicit instead of metas 
+ *)
+
+type naif_substitution = (int * Cic.term) list 
+
+let naif_apply_subst lift subst term =
+ let rec aux k t =
+   match t with
+       Cic.Rel _ -> t
+     | Cic.Var (uri,exp_named_subst) -> 
+         let exp_named_subst' =
+           List.map (fun (uri, t) -> (uri, aux k t)) exp_named_subst
+         in
+           Cic.Var (uri, exp_named_subst')
+    | Cic.Meta (i, l) -> 
+        (try
+          aux k (CicSubstitution.lift (k+lift) (List.assoc i subst)) 
+         with Not_found -> t)
+    | Cic.Sort _
+    | Cic.Implicit _ -> t
+    | Cic.Cast (te,ty) -> Cic.Cast (aux k te, aux k ty)
+    | Cic.Prod (n,s,t) -> Cic.Prod (n, aux k s, aux (k+1) t)
+    | Cic.Lambda (n,s,t) -> Cic.Lambda (n, aux k s, aux (k+1) t)
+    | Cic.LetIn (n,s,ty,t) -> Cic.LetIn (n, aux k s, aux k ty, aux (k+1) t)
+    | Cic.Appl [] -> assert false
+    | Cic.Appl l -> Cic.Appl (List.map (aux k) l)
+    | Cic.Const (uri,exp_named_subst) ->
+        let exp_named_subst' =
+          List.map (fun (uri, t) -> (uri, aux k t)) exp_named_subst
+        in
+          if exp_named_subst' != exp_named_subst then
+            Cic.Const (uri, exp_named_subst')
+          else
+            t (* TODO: provare a mantenere il piu' possibile sharing *)
+    | Cic.MutInd (uri,typeno,exp_named_subst) ->
+        let exp_named_subst' =
+          List.map (fun (uri, t) -> (uri, aux k t)) exp_named_subst
+        in
+          Cic.MutInd (uri,typeno,exp_named_subst')
+    | Cic.MutConstruct (uri,typeno,consno,exp_named_subst) ->
+        let exp_named_subst' =
+          List.map (fun (uri, t) -> (uri, aux k t)) exp_named_subst
+        in
+          Cic.MutConstruct (uri,typeno,consno,exp_named_subst')
+    | Cic.MutCase (sp,i,outty,t,pl) ->
+        let pl' = List.map (aux k) pl in
+          Cic.MutCase (sp, i, aux k outty, aux k t, pl')
+    | Cic.Fix (i, fl) ->
+        let len = List.length fl in
+        let fl' =
+         List.map 
+           (fun (name, i, ty, bo) -> (name, i, aux k ty, aux (k+len) bo)) fl
+        in
+          Cic.Fix (i, fl')
+    | Cic.CoFix (i, fl) ->
+        let len = List.length fl in
+        let fl' =
+          List.map (fun (name, ty, bo) -> (name, aux k ty, aux (k+len) bo)) fl
+        in
+          Cic.CoFix (i, fl')
+in
+  aux 0 term
+;;
+
+(* naif version of apply_subst_metasenv: we do not apply the 
+substitution to the context *)
+
+let naif_apply_subst_metasenv subst metasenv =
+  List.map
+    (fun (n, context, ty) ->
+      (n, context, naif_apply_subst 0 subst ty))
+    (List.filter
+      (fun (i, _, _) -> not (List.mem_assoc i subst))
+      metasenv)
+
+let naif_ppsubst names subst =
+  "{" ^ String.concat "; "
+    (List.map
+      (fun (idx, t) ->
+         Printf.sprintf "%d:= %s" idx (CicPp.pp t names))
+    subst) ^ "}"
+;;
+
+let naif_buildsubst n context t ty tail = (n,t) :: tail ;;
+
+let naif_flatten_subst subst = 
+  List.map (fun (i,t) -> i, naif_apply_subst 0 subst t ) subst
+;;
+
+let rec naif_lookup_subst meta subst =
+  match meta with
+    | Cic.Meta (i, _) ->
+        (try
+          naif_lookup_subst (List.assoc i subst) subst
+        with
+            Not_found -> meta)
+    | _ -> meta
+;;
+
+let naif_merge_subst_if_possible s1 s2 =
+  let already_in = Hashtbl.create 13 in
+  let rec aux acc = function
+    | ((i,x) as s)::tl ->
+        (try 
+          let x' = Hashtbl.find already_in i in
+          if x = x' then aux acc tl else None
+        with
+        | Not_found -> 
+            Hashtbl.add already_in i x;
+            aux (s::acc) tl)
+    | [] -> Some acc 
+  in  
+    aux [] (s1@s2)
+;;
+
+(********** ACTUAL SUBSTITUTION IMPLEMENTATION *******************************)
+
+type substitution = naif_substitution
+let apply_subst = naif_apply_subst 0
+let apply_subst_lift = naif_apply_subst
+let apply_subst_metasenv = naif_apply_subst_metasenv
+let ppsubst ?(names=[]) l = naif_ppsubst names l
+let buildsubst = naif_buildsubst
+let flatten_subst = naif_flatten_subst
+let lookup_subst = naif_lookup_subst
+
+(* filter out from metasenv the variables in substs *)
+let filter subst metasenv =
+  List.filter
+    (fun (m, _, _) ->
+         try let _ = List.find (fun (i, _) -> m = i) subst in false
+         with Not_found -> true)
+    metasenv
+;;
+
+let is_in_subst i subst = List.mem_assoc i subst;;
+  
+let merge_subst_if_possible = naif_merge_subst_if_possible;;
+
+let empty_subst = [];;
+
+let concat x y = x @ y;;
+
+