X-Git-Url: http://matita.cs.unibo.it/gitweb/?p=helm.git;a=blobdiff_plain;f=components%2Ftactics%2Fparamodulation%2Fsubst.ml;fp=components%2Ftactics%2Fparamodulation%2Fsubst.ml;h=fb8e3b78e25266a473fc3d0d9b9f5d59ce7a06e7;hp=0000000000000000000000000000000000000000;hb=f61af501fb4608cc4fb062a0864c774e677f0d76;hpb=58ae1809c352e71e7b5530dc41e2bfc834e1aef1 diff --git a/components/tactics/paramodulation/subst.ml b/components/tactics/paramodulation/subst.ml new file mode 100644 index 000000000..fb8e3b78e --- /dev/null +++ b/components/tactics/paramodulation/subst.ml @@ -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;; + +