aboutsummaryrefslogtreecommitdiffhomepage
path: root/theories/Program/Equality.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/Program/Equality.v')
-rw-r--r--theories/Program/Equality.v154
1 files changed, 77 insertions, 77 deletions
diff --git a/theories/Program/Equality.v b/theories/Program/Equality.v
index f35dc7adc..381a0bae4 100644
--- a/theories/Program/Equality.v
+++ b/theories/Program/Equality.v
@@ -26,7 +26,7 @@ Notation "'refl'" := (@refl_equal _ _).
(** Do something on an heterogeneous equality appearing in the context. *)
-Ltac on_JMeq tac :=
+Ltac on_JMeq tac :=
match goal with
| [ H : @JMeq ?x ?X ?y ?Y |- _ ] => tac H
end.
@@ -44,17 +44,17 @@ Ltac simpl_JMeq := repeat simpl_one_JMeq.
Ltac simpl_one_dep_JMeq :=
on_JMeq
- ltac:(fun H => let H' := fresh "H" in
+ ltac:(fun H => let H' := fresh "H" in
assert (H' := JMeq_eq H)).
Require Import Eqdep.
-(** Simplify dependent equality using sigmas to equality of the second projections if possible.
+(** Simplify dependent equality using sigmas to equality of the second projections if possible.
Uses UIP. *)
Ltac simpl_existT :=
match goal with
- [ H : existT _ ?x _ = existT _ ?x _ |- _ ] =>
+ [ H : existT _ ?x _ = existT _ ?x _ |- _ ] =>
let Hi := fresh H in assert(Hi:=inj_pairT2 _ _ _ _ _ H) ; clear H
end.
@@ -64,15 +64,15 @@ Ltac simpl_existTs := repeat simpl_existT.
Ltac elim_eq_rect :=
match goal with
- | [ |- ?t ] =>
+ | [ |- ?t ] =>
match t with
- | context [ @eq_rect _ _ _ _ _ ?p ] =>
- let P := fresh "P" in
- set (P := p); simpl in P ;
+ | context [ @eq_rect _ _ _ _ _ ?p ] =>
+ let P := fresh "P" in
+ set (P := p); simpl in P ;
((case P ; clear P) || (clearbody P; rewrite (UIP_refl _ _ P); clear P))
- | context [ @eq_rect _ _ _ _ _ ?p _ ] =>
- let P := fresh "P" in
- set (P := p); simpl in P ;
+ | context [ @eq_rect _ _ _ _ _ ?p _ ] =>
+ let P := fresh "P" in
+ set (P := p); simpl in P ;
((case P ; clear P) || (clearbody P; rewrite (UIP_refl _ _ P); clear P))
end
end.
@@ -90,18 +90,18 @@ Ltac simpl_eq := simpl ; unfold eq_rec_r, eq_rec ; repeat (elim_eq_rect ; simpl)
(** Try to abstract a proof of equality, if no proof of the same equality is present in the context. *)
-Ltac abstract_eq_hyp H' p :=
+Ltac abstract_eq_hyp H' p :=
let ty := type of p in
let tyred := eval simpl in ty in
- match tyred with
- ?X = ?Y =>
- match goal with
+ match tyred with
+ ?X = ?Y =>
+ match goal with
| [ H : X = Y |- _ ] => fail 1
| _ => set (H':=p) ; try (change p with H') ; clearbody H' ; simpl in H'
end
end.
-(** Apply the tactic tac to proofs of equality appearing as coercion arguments.
+(** Apply the tactic tac to proofs of equality appearing as coercion arguments.
Just redefine this tactic (using [Ltac on_coerce_proof tac ::=]) to handle custom coercion operators.
*)
@@ -109,7 +109,7 @@ Ltac on_coerce_proof tac T :=
match T with
| context [ eq_rect _ _ _ _ ?p ] => tac p
end.
-
+
Ltac on_coerce_proof_gl tac :=
match goal with
[ |- ?T ] => on_coerce_proof tac T
@@ -120,17 +120,17 @@ Ltac on_coerce_proof_gl tac :=
Ltac abstract_eq_proof := on_coerce_proof_gl ltac:(fun p => let H := fresh "eqH" in abstract_eq_hyp H p).
Ltac abstract_eq_proofs := repeat abstract_eq_proof.
-
-(** Factorize proofs, by using proof irrelevance so that two proofs of the same equality
+
+(** Factorize proofs, by using proof irrelevance so that two proofs of the same equality
in the goal become convertible. *)
Ltac pi_eq_proof_hyp p :=
let ty := type of p in
let tyred := eval simpl in ty in
match tyred with
- ?X = ?Y =>
- match goal with
- | [ H : X = Y |- _ ] =>
+ ?X = ?Y =>
+ match goal with
+ | [ H : X = Y |- _ ] =>
match p with
| H => fail 2
| _ => rewrite (proof_irrelevance (X = Y) p H)
@@ -162,28 +162,28 @@ Ltac rewrite_refl_id := autorewrite with refl_id.
Ltac clear_eq_ctx :=
rewrite_refl_id ; clear_eq_proofs.
-(** Reapeated elimination of [eq_rect] applications.
+(** Reapeated elimination of [eq_rect] applications.
Abstracting equalities makes it run much faster than an naive implementation. *)
-Ltac simpl_eqs :=
+Ltac simpl_eqs :=
repeat (elim_eq_rect ; simpl ; clear_eq_ctx).
(** Clear unused reflexivity proofs. *)
-Ltac clear_refl_eq :=
+Ltac clear_refl_eq :=
match goal with [ H : ?X = ?X |- _ ] => clear H end.
Ltac clear_refl_eqs := repeat clear_refl_eq.
(** Clear unused equality proofs. *)
-Ltac clear_eq :=
+Ltac clear_eq :=
match goal with [ H : _ = _ |- _ ] => clear H end.
Ltac clear_eqs := repeat clear_eq.
(** Combine all the tactics to simplify goals containing coercions. *)
-Ltac simplify_eqs :=
- simpl ; simpl_eqs ; clear_eq_ctx ; clear_refl_eqs ;
+Ltac simplify_eqs :=
+ simpl ; simpl_eqs ; clear_eq_ctx ; clear_refl_eqs ;
try subst ; simpl ; repeat simpl_uip ; rewrite_refl_id.
(** A tactic that tries to remove trivial equality guards in induction hypotheses coming
@@ -219,7 +219,7 @@ Ltac simpl_IH_eq H :=
Ltac simpl_IH_eqs H := repeat simpl_IH_eq H.
-Ltac do_simpl_IHs_eqs :=
+Ltac do_simpl_IHs_eqs :=
match goal with
| [ H : context [ @JMeq _ _ _ _ -> _ ] |- _ ] => progress (simpl_IH_eqs H)
| [ H : context [ _ = _ -> _ ] |- _ ] => progress (simpl_IH_eqs H)
@@ -227,17 +227,17 @@ Ltac do_simpl_IHs_eqs :=
Ltac simpl_IHs_eqs := repeat do_simpl_IHs_eqs.
-(** We split substitution tactics in the two directions depending on which
+(** We split substitution tactics in the two directions depending on which
names we want to keep corresponding to the generalization performed by the
[generalize_eqs] tactic. *)
Ltac subst_left_no_fail :=
- repeat (match goal with
+ repeat (match goal with
[ H : ?X = ?Y |- _ ] => subst X
end).
Ltac subst_right_no_fail :=
- repeat (match goal with
+ repeat (match goal with
[ H : ?X = ?Y |- _ ] => subst Y
end).
@@ -250,32 +250,32 @@ Ltac inject_right H :=
Ltac autoinjections_left := repeat autoinjection ltac:inject_left.
Ltac autoinjections_right := repeat autoinjection ltac:inject_right.
-Ltac simpl_depind := subst_no_fail ; autoinjections ; try discriminates ;
+Ltac simpl_depind := subst_no_fail ; autoinjections ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
-Ltac simpl_depind_l := subst_left_no_fail ; autoinjections_left ; try discriminates ;
+Ltac simpl_depind_l := subst_left_no_fail ; autoinjections_left ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
-Ltac simpl_depind_r := subst_right_no_fail ; autoinjections_right ; try discriminates ;
+Ltac simpl_depind_r := subst_right_no_fail ; autoinjections_right ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simpl_IHs_eqs.
(** Support for the [Equations] command.
- These tactics implement the necessary machinery to solve goals produced by the
- [Equations] command relative to dependent pattern-matching.
+ These tactics implement the necessary machinery to solve goals produced by the
+ [Equations] command relative to dependent pattern-matching.
It is completely inspired from the "Eliminating Dependent Pattern-Matching" paper by
Goguen, McBride and McKinna. *)
(** The NoConfusionPackage class provides a method for making progress on proving a property
[P] implied by an equality on an inductive type [I]. The type of [noConfusion] for a given
- [P] should be of the form [ Π Δ, (x y : I Δ) (x = y) -> NoConfusion P x y ], where
+ [P] should be of the form [ Π Δ, (x y : I Δ) (x = y) -> NoConfusion P x y ], where
[NoConfusion P x y] for constructor-headed [x] and [y] will give a formula ending in [P].
This gives a general method for simplifying by discrimination or injectivity of constructors.
-
+
Some actual instances are defined later in the file using the more primitive [discriminate] and
[injection] tactics on which we can always fall back.
*)
-
+
Class NoConfusionPackage (I : Type) := { NoConfusion : Π P : Prop, Type ; noConfusion : Π P, NoConfusion P }.
(** The [DependentEliminationPackage] provides the default dependent elimination principle to
@@ -287,13 +287,13 @@ Class DependentEliminationPackage (A : Type) :=
(** A higher-order tactic to apply a registered eliminator. *)
-Ltac elim_tac tac p :=
+Ltac elim_tac tac p :=
let ty := type of p in
let eliminator := eval simpl in (elim (A:=ty)) in
tac p eliminator.
-(** Specialization to do case analysis or induction.
- Note: the [equations] tactic tries [case] before [elim_case]: there is no need to register
+(** Specialization to do case analysis or induction.
+ Note: the [equations] tactic tries [case] before [elim_case]: there is no need to register
generated induction principles. *)
Ltac elim_case p := elim_tac ltac:(fun p el => destruct p using el) p.
@@ -308,7 +308,7 @@ Class BelowPackage (A : Type) := {
(** The [Recursor] class defines a recursor on a type, based on some definition of [Below]. *)
-Class Recursor (A : Type) (BP : BelowPackage A) :=
+Class Recursor (A : Type) (BP : BelowPackage A) :=
{ rec_type : A -> Type ; rec : Π (a : A), rec_type a }.
(** Lemmas used by the simplifier, mainly rephrasings of [eq_rect], [eq_ind]. *)
@@ -332,7 +332,7 @@ Proof. intros. apply X. apply inj_pair2. exact H. Defined.
Lemma simplification_existT1 : Π A (P : A -> Type) B (p q : A) (x : P p) (y : P q),
(p = q -> existT P p x = existT P q y -> B) -> (existT P p x = existT P q y -> B).
Proof. intros. injection H. intros ; auto. Defined.
-
+
Lemma simplification_K : Π A (x : A) (B : x = x -> Type), B (refl_equal x) -> (Π p : x = x, B p).
Proof. intros. rewrite (UIP_refl A). assumption. Defined.
@@ -342,26 +342,26 @@ Ltac unfold_equations :=
unfold solution_left, solution_right, deletion, simplification_heq,
simplification_existT1, simplification_existT2, eq_rect_r, eq_rec, eq_ind.
-(** The tactic [simplify_equations] is to be used when a program generated using [Equations]
- is in the goal. It simplifies it as much as possible, possibly using [K] if needed. *)
+(** The tactic [simplify_equations] is to be used when a program generated using [Equations]
+ is in the goal. It simplifies it as much as possible, possibly using [K] if needed. *)
-Ltac simplify_equations := repeat (unfold_equations ; simplify_eqs).
+Ltac simplify_equations := repeat (unfold_equations ; simplify_eqs).
-(** We will use the [block_induction] definition to separate the goal from the
+(** We will use the [block_induction] definition to separate the goal from the
equalities generated by the tactic. *)
Definition block_dep_elim {A : Type} (a : A) := a.
-(** Using these we can make a simplifier that will perform the unification
+(** Using these we can make a simplifier that will perform the unification
steps needed to put the goal in normalised form (provided there are only
constructor forms). Compare with the lemma 16 of the paper.
- We don't have a [noCycle] procedure yet. *)
+ We don't have a [noCycle] procedure yet. *)
Ltac simplify_one_dep_elim_term c :=
match c with
| @JMeq _ _ _ _ -> _ => refine (simplification_heq _ _ _ _ _)
| ?t = ?t -> _ => intros _ || refine (simplification_K _ t _ _)
- | eq (existT _ _ _) (existT _ _ _) -> _ =>
+ | eq (existT _ _ _) (existT _ _ _) -> _ =>
refine (simplification_existT2 _ _ _ _ _ _ _) ||
refine (simplification_existT1 _ _ _ _ _ _ _ _)
| ?x = ?y -> _ => (* variables case *)
@@ -413,12 +413,12 @@ Definition inaccessible_pattern {A : Type} (t : A) := t.
Notation "?( t )" := (inaccessible_pattern t).
(** To handle sections, we need to separate the context in two parts:
- variables introduced by the section and the rest. We introduce a dummy variable
+ variables introduced by the section and the rest. We introduce a dummy variable
between them to indicate that. *)
CoInductive end_of_section := the_end_of_the_section.
-Ltac set_eos := let eos := fresh "eos" in
+Ltac set_eos := let eos := fresh "eos" in
assert (eos:=the_end_of_the_section).
(** We have a specialized [reverse_local] tactic to reverse the goal until the begining of the
@@ -426,14 +426,14 @@ Ltac set_eos := let eos := fresh "eos" in
Ltac reverse_local :=
match goal with
- | [ H : ?T |- _ ] =>
+ | [ H : ?T |- _ ] =>
match T with
| end_of_section => idtac | _ => revert H ; reverse_local end
| _ => idtac
end.
(** Do as much as possible to apply a method, trying to get the arguments right.
- !!Unsafe!! We use [auto] for the [_nocomp] variant of [Equations], in which case some
+ !!Unsafe!! We use [auto] for the [_nocomp] variant of [Equations], in which case some
non-dependent arguments of the method can remain after [apply]. *)
Ltac simpl_intros m := ((apply m || refine m) ; auto) || (intro ; simpl_intros m).
@@ -453,7 +453,7 @@ Ltac simplify_method tac := repeat (tac || simplify_one_dep_elim) ; reverse_loca
(** Solving a method call: we can solve it by splitting on an empty family member
or we must refine the goal until the body can be applied. *)
-
+
Ltac solve_method rec :=
match goal with
| [ H := ?body : nat |- _ ] => subst H ; clear ; abstract (simplify_method idtac ; solve_empty body)
@@ -463,21 +463,21 @@ Ltac solve_method rec :=
(** Impossible cases, by splitting on a given target. *)
Ltac solve_split :=
- match goal with
+ match goal with
| [ |- let split := ?x : nat in _ ] => clear ; abstract (intros _ ; solve_empty x)
end.
(** If defining recursive functions, the prototypes come first. *)
Ltac intro_prototypes :=
- match goal with
+ match goal with
| [ |- Π x : _, _ ] => intro ; intro_prototypes
| _ => idtac
end.
-Ltac introduce p := first [
- match p with _ => (* Already there, generalize dependent hyps *)
- generalize dependent p ; intros p
+Ltac introduce p := first [
+ match p with _ => (* Already there, generalize dependent hyps *)
+ generalize dependent p ; intros p
end
| intros until p | intros ].
@@ -489,7 +489,7 @@ Ltac dep_elimify := match goal with [ |- ?T ] => change (block_dep_elim T) end.
Ltac un_dep_elimify := unfold block_dep_elim in *.
Ltac case_last := dep_elimify ;
- on_last_hyp ltac:(fun p =>
+ on_last_hyp ltac:(fun p =>
let ty := type of p in
match ty with
| ?x = ?x => revert p ; refine (simplification_K _ x _ _)
@@ -497,28 +497,28 @@ Ltac case_last := dep_elimify ;
| _ => simpl in p ; generalize_eqs p ; do_case p
end).
-Ltac nonrec_equations :=
+Ltac nonrec_equations :=
solve [solve_equations (case_last) (solve_method idtac)] || solve [ solve_split ]
|| fail "Unnexpected equations goal".
Ltac recursive_equations :=
- solve [solve_equations (case_last) (solve_method ltac:intro)] || solve [ solve_split ]
+ solve [solve_equations (case_last) (solve_method ltac:intro)] || solve [ solve_split ]
|| fail "Unnexpected recursive equations goal".
(** The [equations] tactic is the toplevel tactic for solving goals generated
by [Equations]. *)
Ltac equations := set_eos ;
- match goal with
+ match goal with
| [ |- Π x : _, _ ] => intro ; recursive_equations
| _ => nonrec_equations
end.
(** The following tactics allow to do induction on an already instantiated inductive predicate
- by first generalizing it and adding the proper equalities to the context, in a maner similar to
+ by first generalizing it and adding the proper equalities to the context, in a maner similar to
the BasicElim tactic of "Elimination with a motive" by Conor McBride. *)
-(** The [do_depind] higher-order tactic takes an induction tactic as argument and an hypothesis
+(** The [do_depind] higher-order tactic takes an induction tactic as argument and an hypothesis
and starts a dependent induction using this tactic. *)
Ltac do_depind tac H :=
@@ -532,36 +532,36 @@ Ltac do_depind' tac H :=
(** Calls [destruct] on the generalized hypothesis, results should be similar to inversion.
By default, we don't try to generalize the hyp by its variable indices. *)
-Tactic Notation "dependent" "destruction" ident(H) :=
+Tactic Notation "dependent" "destruction" ident(H) :=
do_depind' ltac:(fun hyp => do_case hyp) H.
-Tactic Notation "dependent" "destruction" ident(H) "using" constr(c) :=
+Tactic Notation "dependent" "destruction" ident(H) "using" constr(c) :=
do_depind' ltac:(fun hyp => destruct hyp using c) H.
(** This tactic also generalizes the goal by the given variables before the induction. *)
-Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) :=
+Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) :=
do_depind' ltac:(fun hyp => revert l ; do_case hyp) H.
-Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
+Tactic Notation "dependent" "destruction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
do_depind' ltac:(fun hyp => revert l ; destruct hyp using c) H.
-(** Then we have wrappers for usual calls to induction. One can customize the induction tactic by
+(** Then we have wrappers for usual calls to induction. One can customize the induction tactic by
writting another wrapper calling do_depind. We suppose the hyp has to be generalized before
calling [induction]. *)
-Tactic Notation "dependent" "induction" ident(H) :=
+Tactic Notation "dependent" "induction" ident(H) :=
do_depind ltac:(fun hyp => do_ind hyp) H.
-Tactic Notation "dependent" "induction" ident(H) "using" constr(c) :=
+Tactic Notation "dependent" "induction" ident(H) "using" constr(c) :=
do_depind ltac:(fun hyp => induction hyp using c) H.
(** This tactic also generalizes the goal by the given variables before the induction. *)
-Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) :=
+Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) :=
do_depind' ltac:(fun hyp => generalize l ; clear l ; do_ind hyp) H.
-Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
+Tactic Notation "dependent" "induction" ident(H) "generalizing" ne_hyp_list(l) "using" constr(c) :=
do_depind' ltac:(fun hyp => generalize l ; clear l ; induction hyp using c) H.
Ltac simplify_IH_hyps := repeat