diff options
| author | msozeau | 2010-01-26 16:52:53 +0000 |
|---|---|---|
| committer | msozeau | 2010-01-26 16:52:53 +0000 |
| commit | 8be1500b80b0deb0547aaab7c91e4681d981b480 (patch) | |
| tree | 000dde2001cca09b133f618462dcd0877ceae317 | |
| parent | 06bd5357554ce06079b33288d3b9be0e68b44302 (diff) | |
Support for generalized rewriting under dependent binders, using the
[forall_relation] combinator.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12693 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | tactics/rewrite.ml4 | 27 | ||||
| -rw-r--r-- | theories/Classes/Morphisms.v | 18 |
2 files changed, 35 insertions, 10 deletions
diff --git a/tactics/rewrite.ml4 b/tactics/rewrite.ml4 index 50a735e58c..c66b8b6645 100644 --- a/tactics/rewrite.ml4 +++ b/tactics/rewrite.ml4 @@ -193,7 +193,13 @@ let build_signature evars env m (cstrs : 'a option list) (finalcstr : 'a option) let t = Reductionops.whd_betadeltaiota env (fst evars) ty in match kind_of_term t, l with | Prod (na, ty, b), obj :: cstrs -> - if dependent (mkRel 1) b then + if noccurn 1 b (* non-dependent product *) then + let ty = Reductionops.nf_betaiota (fst evars) ty in + let (evars, b', arg, cstrs) = aux env evars (subst1 mkProp b) cstrs in + let evars, relty = mk_relty evars env ty obj in + let newarg = mkApp (Lazy.force respectful, [| ty ; b' ; relty ; arg |]) in + evars, mkProd(na, ty, b), newarg, (ty, Some relty) :: cstrs + else let (evars, b, arg, cstrs) = aux (Environ.push_rel (na, None, ty) env) evars b cstrs in let ty = Reductionops.nf_betaiota (fst evars) ty in let pred = mkLambda (na, ty, b) in @@ -201,12 +207,6 @@ let build_signature evars env m (cstrs : 'a option list) (finalcstr : 'a option) let arg' = mkApp (Lazy.force forall_relation, [| ty ; pred ; liftarg |]) in if obj = None then evars, mkProd(na, ty, b), arg', (ty, None) :: cstrs else error "build_signature: no constraint can apply on a dependent argument" - else - let ty = Reductionops.nf_betaiota (fst evars) ty in - let (evars, b', arg, cstrs) = aux env evars (subst1 mkProp b) cstrs in - let evars, relty = mk_relty evars env ty obj in - let newarg = mkApp (Lazy.force respectful, [| ty ; b' ; relty ; arg |]) in - evars, mkProd(na, ty, b), newarg, (ty, Some relty) :: cstrs | _, obj :: _ -> anomaly "build_signature: not enough products" | _, [] -> (match finalcstr with @@ -548,6 +548,13 @@ let make_leibniz_proof c ty r = { r with rew_car = ty; rew_rel = mkApp (Lazy.force coq_eq, [| ty |]); rew_from = c r.rew_from; rew_to = c r.rew_to; rew_prf = prf } +let pointwise_or_dep_relation n t car rel = + if noccurn 1 car then + mkApp (Lazy.force pointwise_relation, [| t; lift (-1) car; lift (-1) rel |]) + else + mkApp (Lazy.force forall_relation, + [| t; mkLambda (n, t, car); mkLambda (n, t, rel) |]) + let subterm all flags (s : strategy) : strategy = let rec aux env sigma t ty cstr evars = let cstr' = Option.map (fun c -> (ty, c)) cstr in @@ -597,7 +604,7 @@ let subterm all flags (s : strategy) : strategy = in Some (Some res) else rewrite_args None - | Prod (n, x, b) when not (dependent (mkRel 1) b) -> + | Prod (n, x, b) when noccurn 1 b -> let b = subst1 mkProp b in let tx = Typing.type_of env sigma x and tb = Typing.type_of env sigma b in let res = aux env sigma (mkApp (arrow_morphism tx tb, [| x; b |])) ty cstr evars in @@ -634,7 +641,7 @@ let subterm all flags (s : strategy) : strategy = Some (Some { r with rew_prf = mkLambda (n, t, r.rew_prf); rew_car = mkProd (n, t, r.rew_car); - rew_rel = mkApp (Lazy.force pointwise_relation, [| t; r.rew_car; r.rew_rel |]); + rew_rel = pointwise_or_dep_relation n t r.rew_car r.rew_rel; rew_from = mkLambda(n, t, r.rew_from); rew_to = mkLambda (n, t, r.rew_to) }) | _ -> b') @@ -1520,7 +1527,7 @@ let implify id gl = let binders,concl = decompose_prod_assum ctype in let ctype' = match binders with - | (_, None, ty as hd) :: tl when not (dependent (mkRel 1) concl) -> + | (_, None, ty as hd) :: tl when noccurn 1 concl -> let env = Environ.push_rel_context tl (pf_env gl) in let sigma = project gl in let tyhd = Typing.type_of env sigma ty diff --git a/theories/Classes/Morphisms.v b/theories/Classes/Morphisms.v index 2fd85ce2ee..d47092f689 100644 --- a/theories/Classes/Morphisms.v +++ b/theories/Classes/Morphisms.v @@ -166,6 +166,24 @@ Instance pointwise_subrelation {A} `(sub : subrelation B R R') : subrelation (pointwise_relation A R) (pointwise_relation A R') | 4. Proof. reduce. unfold pointwise_relation in *. apply sub. apply H. Qed. +(** For dependent function types. *) +Lemma forall_subrelation A (B : A -> Type) (R S : forall x : A, relation (B x)) : + (forall a, subrelation (R a) (S a)) -> subrelation (forall_relation R) (forall_relation S). +Proof. reduce. apply H. apply H0. Qed. + +(** We use an extern hint to help unification. *) + +Hint Extern 4 (subrelation (@forall_relation ?A ?B ?R) (@forall_relation _ _ ?S)) => + apply (@forall_subrelation A B R S) ; intro : typeclass_instances. + +(** Any symmetric relation is equal to its inverse. *) + +Lemma subrelation_symmetric A R `(Symmetric A R) : subrelation (inverse R) R. +Proof. reduce. red in H0. symmetry. assumption. Qed. + +Hint Extern 4 (subrelation (inverse _) _) => + class_apply @subrelation_symmetric : typeclass_instances. + (** The complement of a relation conserves its proper elements. *) Program Instance complement_proper |
