diff options
| author | herbelin | 2007-05-23 10:29:01 +0000 |
|---|---|---|
| committer | herbelin | 2007-05-23 10:29:01 +0000 |
| commit | b483e1732682bd1b8cec8d5d3a600c93d90f44ab (patch) | |
| tree | 73061a8da273c859530bbf90b61e8f9ad01ccb34 | |
| parent | 500aaf4e5ab37550efc0e0493b0afa45eaf250d3 (diff) | |
Suite restructuration unification et division des problèmes
d'unification des types des with-bindings en deux: les problèmes
d'unification susceptibles d'introduire une coercion sont retardés
(comme dans le commit r9850) et ceux susceptibles de fournir d'autres
instances restent faits au plus tôt (comme avant le commit r9850).
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@9851 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | kernel/term.ml | 4 | ||||
| -rw-r--r-- | kernel/term.mli | 1 | ||||
| -rw-r--r-- | pretyping/clenv.ml | 40 | ||||
| -rw-r--r-- | pretyping/evd.ml | 9 | ||||
| -rw-r--r-- | pretyping/evd.mli | 5 | ||||
| -rw-r--r-- | pretyping/reductionops.ml | 51 | ||||
| -rw-r--r-- | pretyping/unification.ml | 14 |
7 files changed, 83 insertions, 41 deletions
diff --git a/kernel/term.ml b/kernel/term.ml index 3386f45f51..5f9a3ff93d 100644 --- a/kernel/term.ml +++ b/kernel/term.ml @@ -388,7 +388,9 @@ let destApplication = destApp let isApp c = match kind_of_term c with App _ -> true | _ -> false -let isProd c = match kind_of_term c with | Prod(_) -> true | _ -> false +let isProd c = match kind_of_term c with | Prod _ -> true | _ -> false + +let isLambda c = match kind_of_term c with | Lambda _ -> true | _ -> false (* Destructs a constant *) let destConst c = match kind_of_term c with diff --git a/kernel/term.mli b/kernel/term.mli index 4133ca8920..fcae3341e4 100644 --- a/kernel/term.mli +++ b/kernel/term.mli @@ -234,6 +234,7 @@ val isMeta : constr -> bool val isSort : constr -> bool val isCast : constr -> bool val isApp : constr -> bool +val isLambda : constr -> bool val isProd : constr -> bool val isConst : constr -> bool val isConstruct : constr -> bool diff --git a/pretyping/clenv.ml b/pretyping/clenv.ml index 96facdef2a..cfecbf3191 100644 --- a/pretyping/clenv.ml +++ b/pretyping/clenv.ml @@ -383,6 +383,32 @@ let error_already_defined b = anomalylabstrm "" (str "Position " ++ int n ++ str" already defined") +let rec similar_type_shapes t u = + let t,_ = decompose_app t and u,_ = decompose_app u in + match kind_of_term t, kind_of_term u with + | Prod (_,t1,t2), Prod (_,u1,u2) -> similar_type_shapes t2 u2 + | Const cst, Const cst' -> cst = cst' + | Var id, Var id' -> id = id' + | Ind ind, Ind ind' -> ind = ind' + | Rel n, Rel n' -> n = n' + | Sort s, Sort s' -> family_of_sort s = family_of_sort s' + | Case (_,_,c,_), Case (_,_,c',_) -> similar_type_shapes c c' + | _ -> false + +let clenv_unify_similar_types clenv t u = + if similar_type_shapes t u then + try Processed, clenv_unify true CUMUL t u clenv + with e when precatchable_exception e -> Coercible t, clenv + else Coercible t, clenv + +let clenv_assign_binding clenv k (sigma,c) = + let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in + let clenv' = { clenv with evd = evar_merge clenv.evd sigma} in + let c_typ = clenv_hnf_constr clenv' (clenv_get_type_of clenv' c) in + let status,clenv'' = clenv_unify_similar_types clenv' c_typ k_typ in +(* let evd,c' = w_coerce (cl_env clenv') c c_typ k_typ clenv'.evd in*) + { clenv'' with evd = meta_assign k (c,status) clenv''.evd } + let clenv_match_args bl clenv = if bl = [] then clenv @@ -390,25 +416,15 @@ let clenv_match_args bl clenv = let mvs = clenv_independent clenv in check_bindings bl; List.fold_left - (fun clenv (loc,b,(sigma,c)) -> + (fun clenv (loc,b,(sigma,c as sc)) -> let k = meta_of_binder clenv loc mvs b in if meta_defined clenv.evd k then if eq_constr (fst (meta_fvalue clenv.evd k)).rebus c then clenv else error_already_defined b else - let c_typ = nf_betaiota (clenv_get_type_of clenv c) in - let c_typ = clenv_hnf_constr clenv c_typ in - let clenv = { clenv with evd = evar_merge clenv.evd sigma} in - {clenv with evd = meta_assign k (c,Coercible c_typ) clenv.evd}) + clenv_assign_binding clenv k sc) clenv bl -let clenv_assign_binding clenv k (sigma,c) = - let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in - let clenv' = { clenv with evd = evar_merge clenv.evd sigma} in - let c_typ = clenv_hnf_constr clenv' (clenv_get_type_of clenv' c) in - let evd,c' = w_coerce (cl_env clenv') c c_typ k_typ clenv'.evd in - { clenv' with evd = meta_assign k (c',Coercible c_typ) evd } - let clenv_constrain_last_binding c clenv = let all_mvs = collect_metas clenv.templval.rebus in let k = diff --git a/pretyping/evd.ml b/pretyping/evd.ml index ebd635b807..7b5690e2cc 100644 --- a/pretyping/evd.ml +++ b/pretyping/evd.ml @@ -335,7 +335,8 @@ let map_fl f cfl = { cfl with rebus=f cfl.rebus } *) type instance_status = - IsSuperType | IsSubType | ConvUpToEta of int | Coercible of types + | IsSuperType | IsSubType + | ConvUpToEta of int | Coercible of types | Processed (* Clausal environments *) @@ -538,13 +539,13 @@ let meta_merge evd1 evd2 = type metabinding = metavariable * constr * instance_status -let retract_defined_metas evd = +let retract_coercible_metas evd = let mc,ml = Metamap.fold (fun n v (mc,ml) -> match v with - | Clval (na,(b,s),typ) -> + | Clval (na,(b,s),typ) when s <> Processed -> (n,b.rebus,s)::mc, Metamap.add n (Cltyp (na,typ)) ml - | Cltyp _ as v -> + | v -> mc, Metamap.add n v ml) evd.metas ([],Metamap.empty) in mc, { evd with metas = ml } diff --git a/pretyping/evd.mli b/pretyping/evd.mli index 784e066b71..b6ffd02c12 100644 --- a/pretyping/evd.mli +++ b/pretyping/evd.mli @@ -112,7 +112,8 @@ val map_fl : ('a -> 'b) -> 'a freelisted -> 'b freelisted *) type instance_status = - IsSuperType | IsSubType | ConvUpToEta of int | Coercible of types + | IsSuperType | IsSubType + | ConvUpToEta of int | Coercible of types | Processed type clbinding = | Cltyp of name * constr freelisted @@ -180,7 +181,7 @@ val metas_of : evar_defs -> metamap type metabinding = metavariable * constr * instance_status -val retract_defined_metas : evar_defs -> metabinding list * evar_defs +val retract_coercible_metas : evar_defs -> metabinding list * evar_defs val subst_defined_metas : metabinding list -> constr -> constr option (**********************************************************) diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml index 3e9b08beb4..7f05b1cbfa 100644 --- a/pretyping/reductionops.ml +++ b/pretyping/reductionops.ml @@ -882,28 +882,49 @@ let nf_meta env c = meta_instance env (mk_freelisted c) (* Instantiate metas that create beta/iota redexes *) -let meta_reducible_instance env b = - let s = - List.map (fun mv -> (mv,meta_value env mv)) (Metaset.elements b.freemetas) +let meta_value evd mv = + let rec valrec mv = + try + let b,_ = meta_fvalue evd mv in + instance + (List.map (fun mv' -> (mv',valrec mv')) (Metaset.elements b.freemetas)) + b.rebus + with Anomaly _ | Not_found -> + mkMeta mv in + valrec mv + +let meta_reducible_instance evd b = + let fm = Metaset.elements b.freemetas in + let s = List.fold_left (fun l mv -> + try let g,s = meta_fvalue evd mv in (mv,(g.rebus,s))::l + with Anomaly _ | Not_found -> l) [] fm in let rec irec u = let u = whd_betaiota u in match kind_of_term u with | Case (ci,p,c,bl) when isMeta c or isCast c & isMeta (pi1 (destCast c)) -> - let bl' = Array.map irec bl in - let p' = irec p in let m = try destMeta c with _ -> destMeta (pi1 (destCast c)) in - let g = List.assoc m s in - (match kind_of_term g with - | Construct _ -> whd_betaiota (mkCase (ci,p',g,bl')) - | _ -> mkCase (ci,p',c,bl')) + (match + try + let g,s = List.assoc m s in + if isConstruct g or s = Processed then Some g else None + with Not_found -> None + with + | Some g -> irec (mkCase (ci,p,g,bl)) + | None -> mkCase (ci,irec p,c,Array.map irec bl)) | App (f,l) when isMeta f or isCast f & isMeta (pi1 (destCast f)) -> - let l' = Array.map irec l in let m = try destMeta f with _ -> destMeta (pi1 (destCast f)) in - let g = List.assoc m s in - (match kind_of_term g with - | Lambda _ -> beta_appvect g l' - | _ -> mkApp (f,l')) + (match + try + let g,s = List.assoc m s in + if isLambda g or s = Processed then Some g else None + with Not_found -> None + with + | Some g -> irec (mkApp (g,l)) + | None -> mkApp (f,Array.map irec l)) + | Meta m -> + (try let g,s = List.assoc m s in if s = Processed then irec g else u + with Not_found -> u) | _ -> map_constr irec u in - if s = [] then b.rebus else irec b.rebus + if fm = [] then (* nf_betaiota? *) b.rebus else irec b.rebus diff --git a/pretyping/unification.ml b/pretyping/unification.ml index e296737f25..bd6fb5ad88 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -65,7 +65,7 @@ let prod_pb = function ConvUnderApp _ -> topconv | pb -> pb let opp_status = function | IsSuperType -> IsSubType | IsSubType -> IsSuperType - | ConvUpToEta _ | Coercible _ as x -> x + | ConvUpToEta _ | Coercible _ | Processed as x -> x let extract_instance_status = function | Cumul -> (IsSubType,IsSuperType) @@ -231,13 +231,13 @@ let merge_instances env sigma mod_delta st1 st2 c1 c2 = | (ConvUpToEta n1, ConvUpToEta n2) -> let side = left (* arbitrary choice, but agrees with compatibility *) in unify_with_eta side mod_delta env sigma n1 n2 c1 c2 - | ((IsSubType | ConvUpToEta _ | Coercible _ as oppst1), - (IsSubType | ConvUpToEta _ | Coercible _)) -> + | ((IsSubType | ConvUpToEta _ | Coercible _ | Processed as oppst1), + (IsSubType | ConvUpToEta _ | Coercible _ | Processed)) -> let res = unify_0 env sigma Cumul mod_delta c2 c1 in if oppst1=st2 then (* arbitrary choice *) (left, st1, res) else (st2=IsSubType, ConvUpToEta 0, res) - | ((IsSuperType | ConvUpToEta _ | Coercible _ as oppst1), - (IsSuperType | ConvUpToEta _ | Coercible _)) -> + | ((IsSuperType | ConvUpToEta _ | Coercible _ | Processed as oppst1), + (IsSuperType | ConvUpToEta _ | Coercible _ | Processed)) -> let res = unify_0 env sigma Cumul mod_delta c1 c2 in if oppst1=st2 then (* arbitrary choice *) (left, st1, res) else (st2=IsSuperType, ConvUpToEta 0, res) @@ -379,7 +379,7 @@ let w_merge env with_types mod_delta metas evars evd = else begin let evd,n = - if with_types (* or occur_meta mvty *) then + if with_types & status <> Processed then let sigma = evars_of evd in let metas = metas_of evd in let mvty = Typing.meta_type evd mv in @@ -439,7 +439,7 @@ let w_merge env with_types mod_delta metas evars evd = types of metavars are unifiable with the types of their instances *) let w_unify_core_0 env with_types cv_pb mod_delta m n evd = - let (mc1,evd') = retract_defined_metas evd in + let (mc1,evd') = retract_coercible_metas evd in let (mc2,ec) = unify_0_with_initial_metas mc1 env (evars_of evd') cv_pb mod_delta m n in w_merge env with_types mod_delta mc2 ec evd' |
