--- /dev/null
+(* 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;;
+
+