From 55ce117e8083477593cf1ff2e51a3641c7973830 Mon Sep 17 00:00:00 2001 From: Samuel Mimram Date: Tue, 13 Feb 2007 13:48:12 +0000 Subject: Imported Upstream version 8.1+dfsg --- pretyping/evarutil.ml | 136 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 30 deletions(-) (limited to 'pretyping/evarutil.ml') diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml index 307c9886..b545bd38 100644 --- a/pretyping/evarutil.ml +++ b/pretyping/evarutil.ml @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(* $Id: evarutil.ml 9154 2006-09-20 17:18:18Z corbinea $ *) +(* $Id: evarutil.ml 9573 2007-01-31 20:18:18Z notin $ *) open Util open Pp @@ -57,8 +57,8 @@ let tj_nf_evar = Pretype_errors.tj_nf_evar let nf_evar_info evc info = { info with - evar_concl = Reductionops.nf_evar evc info.evar_concl; - evar_hyps = map_named_val (Reductionops.nf_evar evc) info.evar_hyps} + evar_concl = Reductionops.nf_evar evc info.evar_concl; + evar_hyps = map_named_val (Reductionops.nf_evar evc) info.evar_hyps} let nf_evars evm = Evd.fold (fun ev evi evm' -> Evd.add evm' ev (nf_evar_info evm evi)) evm Evd.empty @@ -99,7 +99,7 @@ let push_dependent_evars sigma emap = (Evd.add sigma' ev (Evd.find emap' ev),Evd.remove emap' ev)) (sigma',emap') (collect_evars emap' ccl)) emap (sigma,emap) - + (* replaces a mapping of existentials into a mapping of metas. Problem if an evar appears in the type of another one (pops anomaly) *) let evars_to_metas sigma (emap, c) = @@ -165,12 +165,12 @@ let new_untyped_evar = (* All ids of sign must be distincts! *) let new_evar_instance sign evd typ ?(src=(dummy_loc,InternalHole)) instance = let ctxt = named_context_of_val sign in - assert (List.length instance = named_context_length ctxt); - if not (list_distinct (ids_of_named_context ctxt)) then - anomaly "new_evar_instance: two vars have the same name"; - let newev = new_untyped_evar() in - (evar_declare sign newev typ ~src:src evd, - mkEvar (newev,Array.of_list instance)) + assert (List.length instance = named_context_length ctxt); + if not (list_distinct (ids_of_named_context ctxt)) then + anomaly "new_evar_instance: two vars have the same name"; + let newev = new_untyped_evar() in + (evar_declare sign newev typ ~src:src evd, + mkEvar (newev,Array.of_list instance)) let make_evar_instance_with_rel env = let n = rel_context_length (rel_context env) in @@ -199,7 +199,6 @@ let push_rel_context_to_named_context env = let (subst,_,env) = Sign.fold_rel_context (fun (na,c,t) (subst,avoid,env) -> - let na = if na = Anonymous then Name(id_of_string"_") else na in let id = next_name_away na avoid in ((mkVar id)::subst, id::avoid, @@ -215,11 +214,11 @@ let new_evar evd env ?(src=(dummy_loc,InternalHole)) typ = let instance = make_evar_instance_with_rel env in new_evar_instance sign evd typ' ~src:src instance -(* The same using side-effect *) + (* The same using side-effect *) let e_new_evar evd env ?(src=(dummy_loc,InternalHole)) ty = let (evd',ev) = new_evar !evd env ~src:src ty in - evd := evd'; - ev + evd := evd'; + ev (*------------------------------------* * operations on the evar constraints * @@ -315,33 +314,110 @@ let do_restrict_hyps env k evd ev args = let evi = Evd.find (evars_of !evd) ev in let hyps = evar_context evi in let (hyps',ncargs) = list_filter2 (fun _ a -> closedn k a) (hyps,args) in - (* No care is taken in case the evar type uses vars filtered out! - Assuming that the restriction comes from a well-typed Flex/Flex - unification problem (see real_clean), the type of the evar cannot - depend on variables that are not in the scope of the other evar, - since this other evar has the same type (up to unification). + (* No care is taken in case the evar type uses vars filtered out! + Assuming that the restriction comes from a well-typed Flex/Flex + unification problem (see real_clean), the type of the evar cannot + depend on variables that are not in the scope of the other evar, + since this other evar has the same type (up to unification). Since moreover, the evar contexts uses names only, the - restriction raise no de Bruijn reallocation problem *) + restriction raise no de Bruijn reallocation problem *) let env' = Sign.fold_named_context push_named hyps' ~init:(reset_context env) in let nc = e_new_evar evd env' ~src:(evar_source ev !evd) evi.evar_concl in - evd := Evd.evar_define ev nc !evd; - let (evn,_) = destEvar nc in - mkEvar(evn,Array.of_list ncargs) + evd := Evd.evar_define ev nc !evd; + let (evn,_) = destEvar nc in + mkEvar(evn,Array.of_list ncargs) + + +exception Dependency_error of identifier + +let rec check_and_clear_in_constr evd c ids = + (* returns a new constr where all the evars have been 'cleaned' + (ie the hypotheses ids have been removed from the contexts of + evars *) + let check id' = + if List.mem id' ids then + raise (Dependency_error id') + in + match kind_of_term c with + | ( Rel _ | Meta _ | Sort _ ) -> c + | ( Const _ | Ind _ | Construct _ ) -> + let vars = Environ.vars_of_global (Global.env()) c in + List.iter check vars; c + | Var id' -> + check id'; mkVar id' + | Evar (e,l) -> + if Evd.is_defined_evar !evd (e,l) then + (* If e is already defined we replace it by its definition *) + let nc = nf_evar (evars_of !evd) c in + (check_and_clear_in_constr evd nc ids) + else + (* We check for dependencies to elements of ids in the + evar_info corresponding to e and in the instance of + arguments. Concurrently, we build a new evar + corresponding to e where hypotheses of ids have been + removed *) + let evi = Evd.find (evars_of !evd) e in + let nconcl = check_and_clear_in_constr evd (evar_concl evi) ids in + let (nhyps,nargs) = + List.fold_right2 + (fun (id,ob,c) i (hy,ar) -> + if List.mem id ids then + (hy,ar) + else + let d' = (id, + (match ob with + None -> None + | Some b -> Some (check_and_clear_in_constr evd b ids)), + check_and_clear_in_constr evd c ids) in + let i' = check_and_clear_in_constr evd i ids in + (d'::hy, i'::ar) + ) + (evar_context evi) (Array.to_list l) ([],[]) in + let env = Sign.fold_named_context push_named nhyps ~init:(empty_env) in + let ev'= e_new_evar evd env ~src:(evar_source e !evd) nconcl in + evd := Evd.evar_define e ev' !evd; + let (e',_) = destEvar ev' in + mkEvar(e', Array.of_list nargs) + | _ -> map_constr (fun c -> check_and_clear_in_constr evd c ids) c + +and clear_hyps_in_evi evd evi ids = + (* clear_evar_hyps erases hypotheses ids in evi, checking if some + hypothesis does not depend on a element of ids, and erases ids in + the contexts of the evars occuring in evi *) + let nconcl = try check_and_clear_in_constr evd (evar_concl evi) ids + with Dependency_error id' -> error (string_of_id id' ^ " is used in conclusion") in + let (nhyps,_) = + let aux (id,ob,c) = + try + (id, + (match ob with + None -> None + | Some b -> Some (check_and_clear_in_constr evd b ids)), + check_and_clear_in_constr evd c ids) + with Dependency_error id' -> error (string_of_id id' ^ " is used in hypothesis " + ^ string_of_id id) + in + remove_hyps ids aux (evar_hyps evi) + in + { evi with + evar_concl = nconcl; + evar_hyps = nhyps} + let need_restriction k args = not (array_for_all (closedn k) args) (* We try to instantiate the evar assuming the body won't depend * on arguments that are not Rels or Vars, or appearing several times - (i.e. we tackle only Miller-Pfenning patterns unification) + * (i.e. we tackle only Miller-Pfenning patterns unification) - 1) Let a unification problem "env |- ev[hyps:=args] = rhs" - 2) We limit it to a patterns unification problem "env |- ev[subst] = rhs" - where only Rel's and Var's are relevant in subst - 3) We recur on rhs, "imitating" the term failing if some Rel/Var not in scope + * 1) Let a unification problem "env |- ev[hyps:=args] = rhs" + * 2) We limit it to a patterns unification problem "env |- ev[subst] = rhs" + * where only Rel's and Var's are relevant in subst + * 3) We recur on rhs, "imitating" the term failing if some Rel/Var not in scope - Note: we don't assume rhs in normal form, it may fail while it would - have succeeded after some reductions + * Note: we don't assume rhs in normal form, it may fail while it would + * have succeeded after some reductions *) (* Note: error_not_clean should not be an error: it simply means that the * conversion test that lead to the faulty call to [real_clean] should return -- cgit v1.2.3