X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_refiner%2FnCicMetaSubst.ml;h=60abe85c37c08879ea80d01ededa27c158d0192f;hb=8049c166a37789d7a1b1ca1c3a1174712bbf87ba;hp=12fe977083ec04a2c9ee309c116e2cb22419929b;hpb=e1ffde2ba67b8a2f7d4d97898ba28afd65d96ea7;p=helm.git diff --git a/helm/software/components/ng_refiner/nCicMetaSubst.ml b/helm/software/components/ng_refiner/nCicMetaSubst.ml index 12fe97708..60abe85c3 100644 --- a/helm/software/components/ng_refiner/nCicMetaSubst.ml +++ b/helm/software/components/ng_refiner/nCicMetaSubst.ml @@ -14,155 +14,27 @@ exception MetaSubstFailure of string Lazy.t exception Uncertain of string Lazy.t -(* -(*** Functions to apply a substitution ***) - -let apply_subst_gen ~appl_fun subst term = - let rec um_aux = - let module C = Cic in - let module S = CicSubstitution in - function - C.Rel _ as t -> t - | C.Var (uri,exp_named_subst) -> - let exp_named_subst' = - List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst - in - C.Var (uri, exp_named_subst') - | C.Meta (i, l) -> - (try - let (_, t,_) = lookup_subst i subst in - um_aux (S.subst_meta l t) - with CicUtil.Subst_not_found _ -> - (* unconstrained variable, i.e. free in subst*) - let l' = - List.map (function None -> None | Some t -> Some (um_aux t)) l - in - C.Meta (i,l')) - | C.Sort _ - | C.Implicit _ as t -> t - | C.Cast (te,ty) -> C.Cast (um_aux te, um_aux ty) - | C.Prod (n,s,t) -> C.Prod (n, um_aux s, um_aux t) - | C.Lambda (n,s,t) -> C.Lambda (n, um_aux s, um_aux t) - | C.LetIn (n,s,ty,t) -> C.LetIn (n, um_aux s, um_aux ty, um_aux t) - | C.Appl (hd :: tl) -> appl_fun um_aux hd tl - | C.Appl _ -> assert false - | C.Const (uri,exp_named_subst) -> - let exp_named_subst' = - List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst - in - C.Const (uri, exp_named_subst') - | C.MutInd (uri,typeno,exp_named_subst) -> - let exp_named_subst' = - List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst - in - C.MutInd (uri,typeno,exp_named_subst') - | C.MutConstruct (uri,typeno,consno,exp_named_subst) -> - let exp_named_subst' = - List.map (fun (uri, t) -> (uri, um_aux t)) exp_named_subst - in - C.MutConstruct (uri,typeno,consno,exp_named_subst') - | C.MutCase (sp,i,outty,t,pl) -> - let pl' = List.map um_aux pl in - C.MutCase (sp, i, um_aux outty, um_aux t, pl') - | C.Fix (i, fl) -> - let fl' = - List.map (fun (name, i, ty, bo) -> (name, i, um_aux ty, um_aux bo)) fl - in - C.Fix (i, fl') - | C.CoFix (i, fl) -> - let fl' = - List.map (fun (name, ty, bo) -> (name, um_aux ty, um_aux bo)) fl - in - C.CoFix (i, fl') - in - um_aux term -;; - -let apply_subst = - let appl_fun um_aux he tl = - let tl' = List.map um_aux tl in - let t' = - match um_aux he with - Cic.Appl l -> Cic.Appl (l@tl') - | he' -> Cic.Appl (he'::tl') - in - begin - match he with - Cic.Meta (m,_) -> CicReduction.head_beta_reduce t' - | _ -> t' - end - in - fun subst t -> -(* incr apply_subst_counter; *) -match subst with - [] -> t - | _ -> apply_subst_gen ~appl_fun subst t -;; - -let profiler = HExtlib.profile "U/CicMetaSubst.apply_subst" -let apply_subst s t = - profiler.HExtlib.profile (apply_subst s) t - - -let apply_subst_context subst context = - match subst with - [] -> context - | _ -> -(* - incr apply_subst_context_counter; - context_length := !context_length + List.length context; -*) - List.fold_right - (fun item context -> - match item with - | Some (n, Cic.Decl t) -> - let t' = apply_subst subst t in - Some (n, Cic.Decl t') :: context - | Some (n, Cic.Def (t, ty)) -> - let ty' = apply_subst subst ty in - let t' = apply_subst subst t in - Some (n, Cic.Def (t', ty')) :: context - | None -> None :: context) - context [] - -let apply_subst_metasenv subst metasenv = -(* - incr apply_subst_metasenv_counter; - metasenv_length := !metasenv_length + List.length metasenv; -*) -match subst with - [] -> metasenv - | _ -> - List.map - (fun (n, context, ty) -> - (n, apply_subst_context subst context, apply_subst subst ty)) - (List.filter - (fun (i, _, _) -> not (List.mem_assoc i subst)) - metasenv) - -let tempi_type_of_aux_subst = ref 0.0;; -let tempi_subst = ref 0.0;; -let tempi_type_of_aux = ref 0.0;; -*) - -let newmeta = +let newmeta,maxmeta = let maxmeta = ref 0 in - fun () -> incr maxmeta; !maxmeta + (fun () -> incr maxmeta; !maxmeta), + (fun () -> !maxmeta) ;; exception NotInTheList;; -let position n (shift, lc) = +let position to_skip n (shift, lc) = match lc with + | NCic.Irl _ when to_skip > 0 -> assert false (* unclear to me *) | NCic.Irl len when n <= shift || n > shift + len -> raise NotInTheList | NCic.Irl _ -> n - shift | NCic.Ctx tl -> - let rec aux k = function + let rec aux to_skip k = function | [] -> raise NotInTheList + | _ :: tl when to_skip > 0 -> aux (to_skip - 1) (k+1) tl | (NCic.Rel m)::_ when m + shift = n -> k - | _::tl -> aux (k+1) tl + | _::tl -> aux to_skip (k+1) tl in - aux 1 tl + aux to_skip 1 tl ;; let pack_lc orig = @@ -200,29 +72,41 @@ let rec force_does_not_occur metasenv subst restrictions t = in if amount > 0 then ms, NCic.Rel (r - amount) else ms, orig | NCic.Meta (n, (shift,lc as l)) as orig -> - (* we ignore the subst since restrict will take care of already - * instantiated/restricted metavariabels *) - let (metasenv,subst as ms), restrictions_for_n, l' = - let l = NCicUtils.expand_local_context lc in - let ms, _, restrictions_for_n, l = - List.fold_right - (fun t (ms, i, restrictions_for_n, l) -> - try - let ms, t = aux (k-shift) ms t in - ms, i-1, restrictions_for_n, t::l - with Occur -> - ms, i-1, i::restrictions_for_n, l) - l (ms, List.length l, [], []) - in - ms, restrictions_for_n, pack_lc (shift, NCic.Ctx l) + let meta_chain = + try + Some (NCicUtils.lookup_subst n subst) + with + NCicUtils.Subst_not_found _ -> None in - if restrictions_for_n = [] then - ms, if l = l' then orig else NCic.Meta (n, l') - else - let metasenv, subst, newmeta = - restrict metasenv subst n restrictions_for_n - in - (metasenv, subst), NCic.Meta (newmeta, l') + (match meta_chain with + Some (_,_,bo,_) -> + aux k ms (NCicSubstitution.subst_meta l bo) + | None -> + (* we ignore the subst since restrict will take care of already + * instantiated/restricted metavariabels *) + let (metasenv,subst as ms), restrictions_for_n, l' = + let l = NCicUtils.expand_local_context lc in + + let ms, _, restrictions_for_n, l = + List.fold_right + (fun t (ms, i, restrictions_for_n, l) -> + try + let ms, t = aux (k-shift) ms t in + ms, i-1, restrictions_for_n, t::l + with Occur -> + ms, i-1, i::restrictions_for_n, l) + l (ms, List.length l, [], []) + in + + ms, restrictions_for_n, pack_lc (shift, NCic.Ctx l) + in + if restrictions_for_n = [] then + ms, if l = l' then orig else NCic.Meta (n, l') + else + let metasenv, subst, newmeta = + restrict metasenv subst n restrictions_for_n + in + (metasenv, subst), NCic.Meta (newmeta, l')) | t -> NCicUntrusted.map_term_fold_a (fun _ k -> k+1) k aux ms t in aux 0 (metasenv,subst) t @@ -322,37 +206,129 @@ and restrict metasenv subst i restrictions = | NCicUtils.Meta_not_found _ -> assert false ;; +let rec flexible_arg context subst = function + | NCic.Meta (i,_) | NCic.Appl (NCic.Meta (i,_) :: _)-> + (try + let _,_,t,_ = List.assoc i subst in + flexible_arg context subst t + with Not_found -> true) + (* this is a cheap whd, it only performs zeta-reduction. + * + * it works when the **omissis** disambiguation algorithm + * is run on `let x := K a b in t`, K is substituted for a + * ? and thus in t metavariables have a flexible Rel + *) + | NCic.Rel i -> + (try + match List.nth context (i-1) + with + | _,NCic.Def (bo,_) -> + flexible_arg context subst + (NCicSubstitution.lift i bo) + | _ -> false + with + | Failure _ -> assert false + | Invalid_argument _ -> assert false) + | _ -> false +;; + +let in_scope_tag = "tag:in_scope" ;; +let out_scope_tag_prefix = "tag:out_scope:" +let out_scope_tag n = out_scope_tag_prefix ^ string_of_int n ;; +let is_out_scope_tag tag = + String.length tag > String.length out_scope_tag_prefix && + String.sub tag 0 (String.length out_scope_tag_prefix) = out_scope_tag_prefix +;; +let int_of_out_scope_tag tag = + int_of_string + (String.sub tag (String.length out_scope_tag_prefix) + (String.length tag - (String.length out_scope_tag_prefix))) +;; + + +exception Found;; + (* INVARIANT: we suppose that t is not another occurrence of Meta(n,_), otherwise the occur check does not make sense in case of unification of ?n with ?n *) -let delift metasenv subst context n l t = - let rec aux k (metasenv, subst as ms) = function +let delift ~unify metasenv subst context n l t = + let is_in_scope_meta subst = function + | NCic.Meta (i,_) -> + (try + let tag, _, _, _ = NCicUtils.lookup_subst i subst in + tag = Some in_scope_tag + with NCicUtils.Subst_not_found _ -> false) + | _ -> false + in + let contains_in_scope subst t = + let rec aux _ () = function + | NCic.Meta _ as t -> + if is_in_scope_meta subst t then raise Found + else () + | t -> + if is_in_scope_meta subst t then raise Found + else NCicUtils.fold (fun _ () -> ()) () aux () t + in + try aux () () t; false with Found -> true + in + let unify_list in_scope = + match l with + | _, NCic.Irl _ -> fun _ _ _ _ _ -> None + | shift, NCic.Ctx l -> fun metasenv subst context k t -> + if flexible_arg context subst t || contains_in_scope subst t then None else + let lb = List.map (fun t -> t, flexible_arg context subst t) l in + HExtlib.list_findopt + (fun (li,flexible) i -> + if flexible || i < in_scope then None else + let li = NCicSubstitution.lift (k+shift) li in + match unify metasenv subst context li t with + | Some (metasenv,subst) -> + Some ((metasenv, subst), NCic.Rel (i+1+k)) + | None -> None) + lb + in + let rec aux (context,k,in_scope) (metasenv, subst as ms) t = + match unify_list in_scope metasenv subst context k t with + | Some x -> x + | None -> + match t with | NCic.Rel n as t when n <= k -> ms, t | NCic.Rel n -> (try match List.nth context (n-k-1) with | _,NCic.Def (bo,_) -> - (try ms, NCic.Rel ((position (n-k) l) + k) + (try ms, NCic.Rel ((position in_scope (n-k) l) + k) with NotInTheList -> (* CSC: This bit of reduction hurts performances since it is * possible to have an exponential explosion of the size of the * proof. required for nat/nth_prime.ma *) - aux k ms (NCicSubstitution.lift n bo)) - | _,NCic.Decl _ -> ms, NCic.Rel ((position (n-k) l) + k) + aux (context,k,in_scope) ms (NCicSubstitution.lift n bo)) + | _,NCic.Decl _ -> ms, NCic.Rel ((position in_scope (n-k) l) + k) with Failure _ -> assert false) (*Unbound variable found in delift*) - | NCic.Meta (_,(_,(NCic.Irl 0| NCic.Ctx []))) as orig -> ms, orig + | NCic.Meta (i,_) when i=n -> + raise (MetaSubstFailure (lazy (Printf.sprintf ( + "Cannot unify the metavariable ?%d with a term that has "^^ + "as subterm %s in which the same metavariable "^^ + "occurs (occur check)") i + (NCicPp.ppterm ~context ~metasenv ~subst t)))) | NCic.Meta (i,l1) as orig -> (try - let _,_,t,_ = NCicUtils.lookup_subst i subst in - aux k ms (NCicSubstitution.subst_meta l1 t) + let tag,c,t,ty = NCicUtils.lookup_subst i subst in + let in_scope, clear = + match tag with + | Some tag when tag = in_scope_tag -> 0, true + | Some tag when is_out_scope_tag tag->int_of_out_scope_tag tag,true + | _ -> in_scope, false + in + let ms = + if not clear then ms + else + metasenv, + (i,(None,c,t,ty)) :: List.filter (fun j,_ -> i <> j) subst + in + aux (context,k,in_scope) ms (NCicSubstitution.subst_meta l1 t) with NCicUtils.Subst_not_found _ -> - (* see the top level invariant *) - if (i = n) then - raise (MetaSubstFailure (lazy (Printf.sprintf ( - "Cannot unify the metavariable ?%d with a term that has "^^ - "as subterm %s in which the same metavariable "^^ - "occurs (occur check)") i - (NCicPp.ppterm ~context ~metasenv ~subst t)))) + if snd l1 = NCic.Irl 0 || snd l1 = NCic.Ctx [] then ms, orig else let shift1,lc1 = l1 in let shift,lc = l in @@ -366,21 +342,33 @@ let delift metasenv subst context n l t = in (metasenv, subst), NCic.Meta (newmeta, (0,NCic.Irl (max 0 (k-shift1)))) - | NCic.Irl len, NCic.Irl len1 - when shift1 < shift || len1 + shift1 > len + shift -> - (* C. Hoare. Premature optimization is the root of all evil*) - let stop = shift + len in - let stop1 = shift1 + len1 in - let low_gap = max 0 (shift - shift1) in - let high_gap = max 0 (stop1 - stop) in - let restrictions = - HExtlib.list_seq (k+1-shift1) (low_gap + 1) @ - HExtlib.list_seq (len1 - high_gap + 1) (len1 + 1) + | NCic.Irl len, NCic.Irl len1 -> + let low_restrictions, new_shift = + if k <= shift1 && shift1 < shift then + HExtlib.list_seq 1 (shift - shift1 + 1), k + else if shift1 < k (* <= shift *) then + let save_below = k - shift1 in + HExtlib.list_seq (save_below + 1) (shift - shift1 + 1), + shift1 + else [], shift1 - shift + k + in + let high_restrictions = + let last = shift + len in + let last1 = shift1 + len1 in + if last1 > last then + let high_gap = last1 - last in + HExtlib.list_seq (len1 - high_gap + 1) (len1 + 1) + else [] in + let restrictions = low_restrictions @ high_restrictions in + if restrictions = [] then + if shift = k then ms, orig + else ms, NCic.Meta (i, (new_shift, lc1)) + else let metasenv, subst, newmeta = - restrict metasenv subst i restrictions + restrict metasenv subst i restrictions in -(* +(* {{{ prerr_endline ("RESTRICTIONS FOR: " ^ NCicPp.ppterm ~metasenv ~subst ~context:[] (NCic.Meta (i,l1))^" that was part of a term unified with " @@ -389,22 +377,16 @@ let delift metasenv subst context n l t = string_of_int restrictions) ^ "\nMENV:\n" ^ NCicPp.ppmetasenv ~subst metasenv ^ "\nSUBST:\n" ^ NCicPp.ppsubst subst ~metasenv); -*) - let newlc_len = - len1 - low_gap - high_gap + max 0 (k - shift1) in - assert (if shift1 > k then - shift1 + low_gap - shift = 0 else true); - let meta = - NCic.Meta(newmeta,(shift1 + low_gap - shift, - NCic.Irl newlc_len)) - in - let _, cctx, _ = NCicUtils.lookup_meta newmeta metasenv in - assert (List.length cctx = newlc_len); +}}} *) + let newlc_len = len1 - List.length restrictions in + let meta = + NCic.Meta(newmeta,(new_shift, NCic.Irl newlc_len)) + in + assert ( + let _, cctx, _ = NCicUtils.lookup_meta newmeta metasenv in + List.length cctx = newlc_len); (metasenv, subst), meta - - | NCic.Irl _, NCic.Irl _ when shift = 0 -> ms, orig - | NCic.Irl _, NCic.Irl _ -> - ms, NCic.Meta (i, (max 0 (shift1 - shift), lc1)) + | _ -> let lc1 = NCicUtils.expand_local_context lc1 in let lc1 = List.map (NCicSubstitution.lift shift1) lc1 in @@ -413,7 +395,7 @@ let delift metasenv subst context n l t = | t::tl -> let ms, tbr, tl = deliftl tbr (j+1) ms tl in try - let ms, t = aux k ms t in + let ms, t = aux (context,k,in_scope) ms t in ms, tbr, t::tl with | NotInTheList | MetaSubstFailure _ -> ms, j::tbr, tl @@ -436,9 +418,11 @@ let delift metasenv subst context n l t = restrict metasenv subst i to_be_r in (metasenv, subst), NCic.Meta(newmeta,l1)) - | t -> NCicUntrusted.map_term_fold_a (fun _ k -> k+1) k aux ms t + | t -> + NCicUntrusted.map_term_fold_a + (fun e (c,k,s) -> (e::c,k+1,s)) (context,k,in_scope) aux ms t in - try aux 0 (metasenv,subst) t + try aux (context,0,0) (metasenv,subst) t with NotInTheList -> (* This is the case where we fail even first order unification. *) (* The reason is that our delift function is weaker than first *) @@ -455,184 +439,40 @@ let delift metasenv subst context n l t = let lc = NCicUtils.expand_local_context lc in let l = List.map (NCicSubstitution.lift shift) lc in if - List.exists - (fun t -> NCicUntrusted.metas_of_term subst context t = []) - l + List.exists (fun t-> NCicUntrusted.metas_of_term subst context t <> [])l then raise (Uncertain msg) else raise (MetaSubstFailure msg) ;; -(* -(* delifts a term t of n levels strating from k, that is changes (Rel m) - * to (Rel (m - n)) when m > (k + n). if k <= m < k + n delift fails - *) -let delift_rels_from subst metasenv k n = - let rec liftaux subst metasenv k = - let module C = Cic in - function - C.Rel m as t -> - if m < k then - t, subst, metasenv - else if m < k + n then - raise DeliftingARelWouldCaptureAFreeVariable - else - C.Rel (m - n), subst, metasenv - | C.Var (uri,exp_named_subst) -> - let exp_named_subst',subst,metasenv = - List.fold_right - (fun (uri,t) (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - (uri,t')::l,subst,metasenv) exp_named_subst ([],subst,metasenv) - in - C.Var (uri,exp_named_subst'),subst,metasenv - | C.Meta (i,l) -> - (try - let (_, t,_) = lookup_subst i subst in - liftaux subst metasenv k (CicSubstitution.subst_meta l t) - with CicUtil.Subst_not_found _ -> - let l',to_be_restricted,subst,metasenv = - let rec aux con l subst metasenv = - match l with - [] -> [],[],subst,metasenv - | he::tl -> - let tl',to_be_restricted,subst,metasenv = - aux (con + 1) tl subst metasenv in - let he',more_to_be_restricted,subst,metasenv = - match he with - None -> None,[],subst,metasenv - | Some t -> - try - let t',subst,metasenv = liftaux subst metasenv k t in - Some t',[],subst,metasenv - with - DeliftingARelWouldCaptureAFreeVariable -> - None,[i,con],subst,metasenv - in - he'::tl',more_to_be_restricted@to_be_restricted,subst,metasenv - in - aux 1 l subst metasenv in - let metasenv,subst = restrict subst to_be_restricted metasenv in - C.Meta(i,l'),subst,metasenv) - | C.Sort _ as t -> t,subst,metasenv - | C.Implicit _ as t -> t,subst,metasenv - | C.Cast (te,ty) -> - let te',subst,metasenv = liftaux subst metasenv k te in - let ty',subst,metasenv = liftaux subst metasenv k ty in - C.Cast (te',ty'),subst,metasenv - | C.Prod (n,s,t) -> - let s',subst,metasenv = liftaux subst metasenv k s in - let t',subst,metasenv = liftaux subst metasenv (k+1) t in - C.Prod (n,s',t'),subst,metasenv - | C.Lambda (n,s,t) -> - let s',subst,metasenv = liftaux subst metasenv k s in - let t',subst,metasenv = liftaux subst metasenv (k+1) t in - C.Lambda (n,s',t'),subst,metasenv - | C.LetIn (n,s,ty,t) -> - let s',subst,metasenv = liftaux subst metasenv k s in - let ty',subst,metasenv = liftaux subst metasenv k ty in - let t',subst,metasenv = liftaux subst metasenv (k+1) t in - C.LetIn (n,s',ty',t'),subst,metasenv - | C.Appl l -> - let l',subst,metasenv = - List.fold_right - (fun t (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - t'::l,subst,metasenv) l ([],subst,metasenv) in - C.Appl l',subst,metasenv - | C.Const (uri,exp_named_subst) -> - let exp_named_subst',subst,metasenv = - List.fold_right - (fun (uri,t) (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - (uri,t')::l,subst,metasenv) exp_named_subst ([],subst,metasenv) - in - C.Const (uri,exp_named_subst'),subst,metasenv - | C.MutInd (uri,tyno,exp_named_subst) -> - let exp_named_subst',subst,metasenv = - List.fold_right - (fun (uri,t) (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - (uri,t')::l,subst,metasenv) exp_named_subst ([],subst,metasenv) - in - C.MutInd (uri,tyno,exp_named_subst'),subst,metasenv - | C.MutConstruct (uri,tyno,consno,exp_named_subst) -> - let exp_named_subst',subst,metasenv = - List.fold_right - (fun (uri,t) (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - (uri,t')::l,subst,metasenv) exp_named_subst ([],subst,metasenv) - in - C.MutConstruct (uri,tyno,consno,exp_named_subst'),subst,metasenv - | C.MutCase (sp,i,outty,t,pl) -> - let outty',subst,metasenv = liftaux subst metasenv k outty in - let t',subst,metasenv = liftaux subst metasenv k t in - let pl',subst,metasenv = - List.fold_right - (fun t (l,subst,metasenv) -> - let t',subst,metasenv = liftaux subst metasenv k t in - t'::l,subst,metasenv) pl ([],subst,metasenv) - in - C.MutCase (sp,i,outty',t',pl'),subst,metasenv - | C.Fix (i, fl) -> - let len = List.length fl in - let liftedfl,subst,metasenv = - List.fold_right - (fun (name, i, ty, bo) (l,subst,metasenv) -> - let ty',subst,metasenv = liftaux subst metasenv k ty in - let bo',subst,metasenv = liftaux subst metasenv (k+len) bo in - (name,i,ty',bo')::l,subst,metasenv - ) fl ([],subst,metasenv) - in - C.Fix (i, liftedfl),subst,metasenv - | C.CoFix (i, fl) -> - let len = List.length fl in - let liftedfl,subst,metasenv = - List.fold_right - (fun (name, ty, bo) (l,subst,metasenv) -> - let ty',subst,metasenv = liftaux subst metasenv k ty in - let bo',subst,metasenv = liftaux subst metasenv (k+len) bo in - (name,ty',bo')::l,subst,metasenv - ) fl ([],subst,metasenv) - in - C.CoFix (i, liftedfl),subst,metasenv - in - liftaux subst metasenv k - -let delift_rels subst metasenv n t = - delift_rels_from subst metasenv 1 n t -*) - let mk_meta ?name metasenv context ty = - match ty with - | `Typeless -> - let n = newmeta () in - let ty = NCic.Implicit (`Typeof n) in - let menv_entry = (n, (name, context, ty)) in - menv_entry :: metasenv,NCic.Meta (n, (0,NCic.Irl (List.length context))), ty - | `Type - | `Term -> - let context_for_ty = if ty = `Type then [] else context in - let n = newmeta () in - let ty_menv_entry = (n, (name,context_for_ty, NCic.Implicit (`Typeof n))) in - let m = newmeta () in - let ty = NCic.Meta (n, (0,NCic.Irl (List.length context_for_ty))) in - let menv_entry = (m, (name, context, ty)) in - menv_entry :: ty_menv_entry :: metasenv, - NCic.Meta (m, (0,NCic.Irl (List.length context))), ty + let tyof = function Some s -> Some ("typeof_"^s) | None -> None in + let rec mk_meta name n metasenv context = function | `WithType ty -> - let n = newmeta () in let len = List.length context in let menv_entry = (n, (name, context, ty)) in - menv_entry :: metasenv, NCic.Meta (n, (0,NCic.Irl len)), ty + menv_entry :: metasenv, n, NCic.Meta (n, (0,NCic.Irl len)), ty + | `Sort -> + let ty = NCic.Implicit (`Typeof n) in + mk_meta (tyof name) n metasenv [] (`WithType ty) + | `Type -> + let metasenv, _, ty, _ = + mk_meta (tyof name) (newmeta ()) metasenv context `Sort in + mk_meta name n metasenv context (`WithType ty) + | `Term -> + let metasenv, _, ty, _ = + mk_meta (tyof name) (newmeta ()) metasenv context `Type in + mk_meta name n metasenv context (`WithType ty) + in + mk_meta name (newmeta ()) metasenv context ty ;; -let saturate ?(delta=0) metasenv context ty goal_arity = +let saturate ?(delta=0) metasenv subst context ty goal_arity = assert (goal_arity >= 0); let rec aux metasenv = function - | NCic.Prod (name,s,t) -> - let metasenv1, arg,_ = + | NCic.Prod (name,s,t) as ty -> + let metasenv1, _, arg,_ = mk_meta ~name:name metasenv context (`WithType s) in let t, metasenv1, args, pno = aux metasenv1 (NCicSubstitution.subst arg t) @@ -642,7 +482,7 @@ let saturate ?(delta=0) metasenv context ty goal_arity = else t, metasenv1, arg::args, pno+1 | ty -> - match NCicReduction.whd context ty ~delta with + match NCicReduction.whd ~subst context ty ~delta with | NCic.Prod _ as ty -> aux metasenv ty | ty -> ty, metasenv, [], 0 in