diff options
author | msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2009-05-20 20:07:00 +0000 |
---|---|---|
committer | msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2009-05-20 20:07:00 +0000 |
commit | 3b585059c16dbfbd0558196549d1130509611b35 (patch) | |
tree | 39907abe6d4545724511d1194bac9661a8fd9f06 /pretyping | |
parent | 8a6e3f648fa3171e3583e7c93c8967ac853a0d60 (diff) |
Many fixes in unification:
- Restore failure when types don't unify in [unify_types] (undoing
r12075) but try to be more clever about cumulativity using the meta's
[instance_status] information.
- Fix second-order abstraction when K is not allowed to ensure that
we don't unify twice with the same subterm in
[w_unify_to_subterm_list]. A more elaborate solution would be give the
list to [w_unify_to_subterm] so that it keeps going when it finds an
already-found instantiation.
- Two "obvious" errors fixed: taking the wrong instance status when
unifying with a meta on the right and forgoting type equations in
[w_merge].
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12136 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'pretyping')
-rw-r--r-- | pretyping/unification.ml | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/pretyping/unification.ml b/pretyping/unification.ml index 64d96adc9..83c7b8370 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -206,7 +206,7 @@ let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flag | _, Meta k when not (dependent cN cM) -> (* Here we check that [cM] does not contain any local variables *) if nb = 0 then - (sigma,(k,cM,snd (extract_instance_status pb))::metasubst,evarsubst) + (sigma,(k,cM,fst (extract_instance_status pb))::metasubst,evarsubst) else if noccur_between 1 nb cM then (sigma,(k,lift (-nb) cM,fst (extract_instance_status pb))::metasubst, @@ -545,19 +545,25 @@ let w_coerce env evd mv c = let mvty = Typing.meta_type evd mv in w_coerce_to_type env evd c cty mvty -let unify_to_type env sigma flags c u = +let unify_to_type env sigma flags c status u = let c = refresh_universes c in let t = get_type_of env sigma c in let t = Tacred.hnf_constr env sigma (nf_betaiota sigma (nf_meta sigma t)) in let u = Tacred.hnf_constr env sigma u in - try unify_0 env sigma Cumul flags t u - with e when precatchable_exception e -> (sigma,[],[]) + if status = IsSuperType then + unify_0 env sigma Cumul flags u t + else if status = IsSubType then + unify_0 env sigma Cumul flags t u + else + try unify_0 env sigma Cumul flags t u + with e when precatchable_exception e -> + unify_0 env sigma Cumul flags u t -let unify_type env sigma flags mv c = +let unify_type env sigma flags mv status c = let mvty = Typing.meta_type sigma mv in - if occur_meta_or_existential mvty or is_arity env sigma mvty then - unify_to_type env sigma flags c mvty - else (sigma,[],[]) +(* if occur_meta_or_existential mvty or is_arity env sigma mvty then *) + unify_to_type env sigma flags c status mvty +(* else (sigma,[],[]) *) (* Move metas that may need coercion at the end of the list of instances *) @@ -614,10 +620,10 @@ let w_merge env with_types flags (evd,metas,evars) = if with_types & to_type <> TypeProcessed then if to_type = CoerceToType then (* Some coercion may have to be inserted *) - (w_coerce env evd mv c,([],[])),[] + (w_coerce env evd mv c,([],[])),eqns else (* No coercion needed: delay the unification of types *) - ((evd,c),([],[])),(mv,c)::eqns + ((evd,c),([],[])),(mv,status,c)::eqns else ((evd,c),([],[])),eqns in if meta_defined evd mv then @@ -637,8 +643,8 @@ let w_merge env with_types flags (evd,metas,evars) = (* Process type eqns *) match eqns with - | (mv,c)::eqns -> - let (evd,metas,evars) = unify_type env evd flags mv c in + | (mv,status,c)::eqns -> + let (evd,metas,evars) = unify_type env evd flags mv status c in w_merge_rec evd metas evars eqns | [] -> evd @@ -721,7 +727,7 @@ let w_unify_to_subterm env ?(flags=default_unify_flags) (op,cl) evd = let cl = strip_outer_cast cl in (try if closed0 cl - then w_unify_0 env topconv flags op cl evd,cl + then w_typed_unify env topconv flags op cl evd,cl else error "Bound 1" with ex when precatchable_exception ex -> (match kind_of_term cl with @@ -784,9 +790,12 @@ let w_unify_to_subterm_list env flags allow_K oplist t evd = try (* This is up to delta for subterms w/o metas ... *) w_unify_to_subterm env ~flags (strip_outer_cast op,t) evd - with PretypeError (env,NoOccurrenceFound _) when allow_K -> (evd,op) + with PretypeError (env,NoOccurrenceFound _) when allow_K -> (evd,op) in - (evd',cl::l) + if not allow_K && (* ensure we found a different instance *) + List.exists (fun op -> eq_constr op cl) l + then error "Unify_to_subterm_list" + else (evd',cl::l) else if allow_K or dependent op t then (evd,op::l) else |