Set Implicit Arguments.
Notation "'exists' x1 ',' P" :=
(exists x1, P)
(at level 200, x1 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 ',' P" :=
(exists x1, exists x2, P)
(at level 200, x1 ident, x2 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 ',' P" :=
(exists x1, exists x2, exists x3, P)
(at level 200, x1 ident, x2 ident, x3 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 x4 ',' P" :=
(exists x1, exists x2, exists x3, exists x4, P)
(at level 200, x1 ident, x2 ident, x3 ident, x4 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 x4 x5 ',' P" :=
(exists x1, exists x2, exists x3, exists x4, exists x5, P)
(at level 200, x1 ident, x2 ident, x3 ident, x4 ident, x5 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 x4 x5 x6 ',' P" :=
(exists x1, exists x2, exists x3, exists x4, exists x5, exists x6, P)
(at level 200, x1 ident, x2 ident, x3 ident, x4 ident, x5 ident,
x6 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 x4 x5 x6 x7 ',' P" :=
(exists x1, exists x2, exists x3, exists x4, exists x5, exists x6,
exists x7, P)
(at level 200, x1 ident, x2 ident, x3 ident, x4 ident, x5 ident,
x6 ident, x7 ident,
right associativity) : type_scope.
Notation "'exists' x1 x2 x3 x4 x5 x6 x7 x8 ',' P" :=
(exists x1, exists x2, exists x3, exists x4, exists x5, exists x6,
exists x7, exists x8, P)
(at level 200, x1 ident, x2 ident, x3 ident, x4 ident, x5 ident,
x6 ident, x7 ident, x8 ident,
right associativity) : type_scope.
Notation "'=' x" := (fun y => y = x) (at level 71).
Notation "'proj21' P" := (proj1 P) (at level 69, only parsing).
Notation "'proj22' P" := (proj2 P) (at level 69, only parsing).
Notation "'proj31' P" := (proj1 P) (at level 69).
Notation "'proj32' P" := (proj1 (proj2 P)) (at level 69).
Notation "'proj33' P" := (proj2 (proj2 P)) (at level 69).
Notation "'proj41' P" := (proj1 P) (at level 69).
Notation "'proj42' P" := (proj1 (proj2 P)) (at level 69).
Notation "'proj43' P" := (proj1 (proj2 (proj2 P))) (at level 69).
Notation "'proj44' P" := (proj2 (proj2 (proj2 P))) (at level 69).
Notation "'proj51' P" := (proj1 P) (at level 69).
Notation "'proj52' P" := (proj1 (proj2 P)) (at level 69).
Notation "'proj53' P" := (proj1 (proj2 (proj2 P))) (at level 69).
Notation "'proj54' P" := (proj1 (proj2 (proj2 (proj2 P)))) (at level 69).
Notation "'proj55' P" := (proj2 (proj2 (proj2 (proj2 P)))) (at level 69).
Inductive ltac_No_arg : Set :=
| ltac_no_arg : ltac_No_arg.
Definition ltac_tag_result (A:Type) (x:A) := x.
Ltac build_result t :=
match type of t with ?T =>
let H := fresh "TEMP" in
assert (H : ltac_tag_result T);
[ unfold ltac_tag_result; exact t | generalize H; clear H ]
end.
Ltac if_is_result :=
match goal with |- ltac_tag_result _ -> _ => idtac end.
Tactic Notation "name_result" simple_intropattern(H) :=
match goal with |- ltac_tag_result _ -> _ =>
unfold ltac_tag_result at 1;
first [ intros H
| let H' := fresh "NameAlreadyUsed" in intros H'] end.
Inductive Carrier : forall A, A -> Type :=
| carrier : forall A x, @Carrier A x.
Ltac _put x :=
generalize (carrier x); intro.
Ltac _put2 x y :=
_put y; _put x.
Ltac _put3 x y z :=
_put z; _put y; _put x.
Ltac _get :=
match goal with H: Carrier ?t |- _ => t end.
Ltac _rem :=
match goal with H: Carrier ?t |- _ => clear H end.
Require Import List.
Inductive ltac_Wild : Set :=
| ltac_wild : ltac_Wild.
Notation "'__'" := ltac_wild : ltac_scope.
Inductive ltac_Wilds : Set :=
| ltac_wilds : ltac_Wilds.
Notation "'___'" := ltac_wilds : ltac_scope.
Inductive Boxer : Type :=
| boxer : forall (A:Type), A -> Boxer.
Notation "'>>>'" :=
(@nil Boxer)
(at level 0)
: ltac_scope.
Notation "'>>>' v1" :=
((boxer v1)::nil)
(at level 0, v1 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2" :=
((boxer v1)::(boxer v2)::nil)
(at level 0, v1 at level 0, v2 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2 v3" :=
((boxer v1)::(boxer v2)::(boxer v3)::nil)
(at level 0, v1 at level 0, v2 at level 0, v3 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2 v3 v4" :=
((boxer v1)::(boxer v2)::(boxer v3)::(boxer v4)::nil)
(at level 0, v1 at level 0, v2 at level 0, v3 at level 0,
v4 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2 v3 v4 v5" :=
((boxer v1)::(boxer v2)::(boxer v3)::(boxer v4)::(boxer v5)::nil)
(at level 0, v1 at level 0, v2 at level 0, v3 at level 0,
v4 at level 0, v5 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2 v3 v4 v5 v6" :=
((boxer v1)::(boxer v2)::(boxer v3)::(boxer v4)::(boxer v5)
::(boxer v6)::nil)
(at level 0, v1 at level 0, v2 at level 0, v3 at level 0,
v4 at level 0, v5 at level 0, v6 at level 0)
: ltac_scope.
Notation "'>>>' v1 v2 v3 v4 v5 v6 v7" :=
((boxer v1)::(boxer v2)::(boxer v3)::(boxer v4)::(boxer v5)
::(boxer v6)::(boxer v7)::nil)
(at level 0, v1 at level 0, v2 at level 0, v3 at level 0,
v4 at level 0, v5 at level 0, v6 at level 0, v7 at level 0)
: ltac_scope.
Open Scope ltac_scope.
Inductive ltac_inst : Set :=
| Args : ltac_inst
| Hyps : ltac_inst
| Vars : ltac_inst
| Hnts : ltac_inst.
Ltac ltac_args E :=
match type of E with
| List.list Boxer =>
match E with
| (@boxer ltac_inst _)::_ => constr:(E)
| _ => constr:((boxer Hnts)::E)
end
| _ => constr:((boxer Hnts)::(boxer E)::nil)
end.
Ltac nat_from_number N := constr:(N).
Tactic Notation "show" tactic(tac) :=
let R := tac in pose R.
Lemma dup_lemma : forall P, P -> P -> P.
Proof. auto. Qed.
Ltac dup_tactic N :=
match nat_from_number N with
| 0 => idtac
| S 0 => idtac
| S ?N' => apply dup_lemma; [ | dup_tactic N' ]
end.
Tactic Notation "dup" constr(N) :=
dup_tactic N.
Tactic Notation "dup" :=
dup 2.
Ltac get_head E :=
match E with
| ?P _ _ _ _ _ _ _ _ _ => constr:(P)
| ?P _ _ _ _ _ _ _ _ => constr:(P)
| ?P _ _ _ _ _ _ _ => constr:(P)
| ?P _ _ _ _ _ _ => constr:(P)
| ?P _ _ _ _ _ => constr:(P)
| ?P _ _ _ _ => constr:(P)
| ?P _ _ _ => constr:(P)
| ?P _ _ => constr:(P)
| ?P _ => constr:(P)
| ?P => constr:(P)
end.
Ltac is_metavar E :=
match E with
| ?P _ _ _ _ _ _ _ _ _ => constr:(false)
| ?P _ _ _ _ _ _ _ _ => constr:(false)
| ?P _ _ _ _ _ _ _ => constr:(false)
| ?P _ _ _ _ _ _ => constr:(false)
| ?P _ _ _ _ _ => constr:(false)
| ?P _ _ _ _ => constr:(false)
| ?P _ _ _ => constr:(false)
| ?P _ _ => constr:(false)
| ?P _ => constr:(false)
| ?P => constr:(true)
end.
Tactic Notation "lets" simple_intropattern(I) ":" constr(E) :=
generalize E; intros I.
Tactic Notation "lets" simple_intropattern(I1)
simple_intropattern(I2) ":" constr(E) :=
lets [I1 I2]: E.
Tactic Notation "lets" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) ":" constr(E) :=
lets [I1 [I2 I3]]: E.
Tactic Notation "lets" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) ":" constr(E) :=
lets [I1 [I2 [I3 I4]]]: E.
Tactic Notation "lets" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5) ":" constr(E) :=
lets [I1 [I2 [I3 [I4 I5]]]]: E.
Tactic Notation "lets" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5)
simple_intropattern(I6) ":" constr(E) :=
lets [I1 [I2 [I3 [I4 [I5 I6]]]]]: E.
Tactic Notation "lets_simpl" ident(H) ":" constr(E) :=
lets H: E; simpl in H.
Tactic Notation "lets_hnf" ident(H) ":" constr(E) :=
lets H: E; hnf in H.
Tactic Notation "lets" ":" constr(E1) :=
generalize E1; intro.
Tactic Notation "lets" ":" constr(E1) constr(E2) :=
lets: E1; lets: E2.
Tactic Notation "lets" ":" constr(E1) constr(E2) constr(E3) :=
lets: E1; lets: E2; lets: E3.
Tactic Notation "lets_simpl" ":" constr(T) :=
let H := fresh in lets_simpl H: T.
Tactic Notation "lets_hnf" ":" constr(T) :=
let H := fresh in lets_hnf H: T.
Tactic Notation "put" ident(X) ":" constr(E) :=
pose (X := E).
Tactic Notation "put" ":" constr(E) :=
let X := fresh "X" in pose (X := E).
Tactic Notation "applys" constr(t) :=
first
[ refine (@t)
| refine (@t _)
| refine (@t _ _)
| refine (@t _ _ _)
| refine (@t _ _ _ _)
| refine (@t _ _ _ _ _)
| refine (@t _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _ _ _ _ _)
| refine (@t _ _ _ _ _ _ _ _ _ _ _ _ _)
].
Tactic Notation "applys_0" constr(t) :=
refine (@t).
Tactic Notation "applys_1" constr(t) :=
refine (@t _).
Tactic Notation "applys_2" constr(t) :=
refine (@t _ _).
Tactic Notation "applys_3" constr(t) :=
refine (@t _ _ _).
Tactic Notation "applys_4" constr(t) :=
refine (@t _ _ _ _).
Tactic Notation "applys_5" constr(t) :=
refine (@t _ _ _ _ _).
Tactic Notation "applys_6" constr(t) :=
refine (@t _ _ _ _ _ _).
Tactic Notation "applys_7" constr(t) :=
refine (@t _ _ _ _ _ _ _).
Tactic Notation "applys_8" constr(t) :=
refine (@t _ _ _ _ _ _ _ _).
Tactic Notation "applys_9" constr(t) :=
refine (@t _ _ _ _ _ _ _ _ _).
Tactic Notation "applys_10" constr(t) :=
refine (@t _ _ _ _ _ _ _ _ _ _).
Tactic Notation "applys_to" hyp(H) constr(E) :=
let H' := fresh in rename H into H';
(first [ lets H: (E H')
| lets H: (E _ H')
| lets H: (E _ _ H')
| lets H: (E _ _ _ H')
| lets H: (E _ _ _ _ H')
| lets H: (E _ _ _ _ _ H')
| lets H: (E _ _ _ _ _ _ H')
| lets H: (E _ _ _ _ _ _ _ H')
| lets H: (E _ _ _ _ _ _ _ _ H')
| lets H: (E _ _ _ _ _ _ _ _ _ H') ]
); clear H'.
Tactic Notation "applys_in" hyp(H) constr(E) :=
let H' := fresh in rename H into H';
(first [ lets H: (H' E)
| lets H: (H' _ E)
| lets H: (H' _ _ E)
| lets H: (H' _ _ _ E)
| lets H: (H' _ _ _ _ E)
| lets H: (H' _ _ _ _ _ E)
| lets H: (H' _ _ _ _ _ _ E)
| lets H: (H' _ _ _ _ _ _ _ E)
| lets H: (H' _ _ _ _ _ _ _ _ E)
| lets H: (H' _ _ _ _ _ _ _ _ _ E) ]
); clear H'.
Tactic Notation "applys_clear" constr(E) :=
applys E; let H := get_head E in clear E.
Tactic Notation "apply_clear" constr(E) :=
applys_clear E.
Tactic Notation "constructors" :=
first [ constructor | econstructor ].
Tactic Notation "false_goal" :=
elimtype False.
Tactic Notation "false" :=
false_goal; try assumption; try discriminate.
Tactic Notation "tryfalse" :=
try solve [ false ].
Tactic Notation "tryfalse" "by" tactic(tac) "/" :=
try solve [ false; tac ].
Tactic Notation "false" constr(T) "by" tactic(tac) "/" :=
false_goal; first
[ first [ apply T | eapply T | applys T]; tac
| let H := fresh in lets H: T; discriminate H ].
Tactic Notation "false" constr(T) :=
false T by idtac/.
Ltac false_inv_tactic :=
match goal with H:_ |- _ =>
solve [ inversion H
| clear H; false_inv_tactic
| fail 2 ] end.
Tactic Notation "false_inv" :=
false_inv_tactic.
Tactic Notation "tryfalse_inv" :=
try solve [ false | false_inv ].
Tactic Notation "asserts" simple_intropattern(I) ":" constr(T) :=
let H := fresh in assert (H : T);
[ | generalize H; clear H; intros I ].
Tactic Notation "asserts" simple_intropattern(I1)
simple_intropattern(I2) ":" constr(T) :=
asserts [I1 I2]: T.
Tactic Notation "asserts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) ":" constr(T) :=
asserts [I1 [I2 I3]]: T.
Tactic Notation "asserts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) ":" constr(T) :=
asserts [I1 [I2 [I3 I4]]]: T.
Tactic Notation "asserts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5) ":" constr(T) :=
asserts [I1 [I2 [I3 [I4 I5]]]]: T.
Tactic Notation "asserts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5)
simple_intropattern(I6) ":" constr(T) :=
asserts [I1 [I2 [I3 [I4 [I5 I6]]]]]: T.
Tactic Notation "asserts" ":" constr(T) "as" simple_intropattern(I) :=
asserts I : T.
Tactic Notation "asserts" ":" constr(T) :=
let H := fresh in asserts H : T.
Tactic Notation "cuts" simple_intropattern(I) ":" constr(T) :=
cut (T); [ intros I | idtac ].
Tactic Notation "cuts" ":" constr(T) :=
let H := fresh in cuts H: T.
Tactic Notation "cuts" simple_intropattern(I1)
simple_intropattern(I2) ":" constr(T) :=
cuts [I1 I2]: T.
Tactic Notation "cuts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) ":" constr(T) :=
cuts [I1 [I2 I3]]: T.
Tactic Notation "cuts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) ":" constr(T) :=
cuts [I1 [I2 [I3 I4]]]: T.
Tactic Notation "cuts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5) ":" constr(T) :=
cuts [I1 [I2 [I3 [I4 I5]]]]: T.
Tactic Notation "cuts" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5)
simple_intropattern(I6) ":" constr(T) :=
cuts [I1 [I2 [I3 [I4 [I5 I6]]]]]: T.
Ltac app_arg t P v cont :=
let H := fresh "TEMP" in
assert (H : P); [ apply v | cont(t H); try clear H ].
Ltac app_assert t P cont :=
let H := fresh "TEMP" in
assert (H : P); [ | cont(t H); clear H ].
Ltac app_evar t A cont :=
let x := fresh "TEMP" in
evar (x:A);
let t' := constr:(t x) in
let t'' := (eval unfold x in t') in
subst x; cont t''.
Ltac build_app_alls t final :=
let rec go t :=
match type of t with
| ?P -> ?Q => app_assert t P go
| forall _:?A, _ => app_evar t A go
| _ => final t
end in
go t.
Ltac build_app_args t vs final :=
let rec go t vs :=
match vs with
| nil => first [ final t | fail 1 ]
| (boxer ltac_wilds)::_ => first [ build_app_alls t final | fail 1 ]
| (boxer ?v)::?vs' =>
let cont t' := go t' vs' in
match v with
| ltac_wild =>
match type of t with
| ?P -> ?Q => first [ app_assert t P cont | fail 3 ]
| forall _:?A, _ => first [ app_evar t A cont | fail 3 ]
end
| _ =>
match type of t with
| ?P -> ?Q => first [ app_arg t P v cont | fail 3 ]
| forall _:?A, _ => first [ cont (t v) | fail 3 ]
end
end
end in
go t vs.
Ltac build_app_vars t vs final :=
let rec go t vs :=
match vs with
| nil => first [ final t | fail 1 ]
| (boxer ltac_wilds)::_ => first [ build_app_alls t final | fail 1 ]
| (boxer ?v)::?vs' =>
match type of t with
| ?P -> ?Q =>
let cont t' := go t' vs in
first [ app_assert t P cont | fail 3 ]
| forall _:?A, _ =>
let cont t' := go t' vs' in
match v with
| ltac_wild => first [ app_evar t A cont | fail 3 ]
| _ => first [ cont(t v) | fail 3 ]
end
end
end in
go t vs.
Ltac build_app_hyps t vs final :=
let rec go t vs :=
match vs with
| nil => first [ final t | fail 1 ]
| (boxer ltac_wilds)::_ => first [ build_app_alls t final | fail 1 ]
| (boxer ?v)::?vs' =>
match type of t with
| ?P -> ?Q =>
let cont t' := go t' vs' in
match v with
| ltac_wild => first [ app_assert t P cont | fail 3 ]
| _ => first [ app_arg t P v cont | fail 3 ]
end
| forall _:?A, _ =>
let cont t' := go t' vs in
first [ app_evar t A cont | fail 3 ]
end
end in
go t vs.
Ltac boxerlist_next_type vs :=
match vs with
| nil => constr:(ltac_wild)
| (boxer ltac_wild)::?vs' => boxerlist_next_type vs'
| (boxer ltac_wilds)::_ => constr:(ltac_wild)
| (@boxer ?T _)::_ => constr:(T)
end.
Ltac build_app_hnts t vs final :=
let rec go t vs :=
match vs with
| nil => first [ final t | fail 1 ]
| (boxer ltac_wilds)::_ => first [ build_app_alls t final | fail 1 ]
| (boxer ?v)::?vs' =>
let cont t' := go t' vs in
let cont' t' := go t' vs' in
match v with
| ltac_wild =>
first [ let T := boxerlist_next_type vs' in
match T with
| ltac_wild =>
match type of t with
| ?P -> ?Q => first [ app_assert t P cont' | fail 3 ]
| forall _:?A, _ => first [ app_evar t A cont' | fail 3 ]
end
| _ =>
match type of t with
| T -> ?Q => first [ app_assert t T cont' | fail 3 ]
| forall _:T, _ => first [ app_evar t T cont' | fail 3 ]
| ?P -> ?Q => first [ app_assert t P cont | fail 3 ]
| forall _:?A, _ => first [ app_evar t A cont | fail 3 ]
end
end
| fail 2 ]
| _ =>
match type of t with
| ?P -> ?Q => first [ app_arg t P v cont'
| app_assert t P cont
| fail 3 ]
| forall _:?A, _ => first [ cont' (t v)
| app_evar t A cont
| fail 3 ]
end
end
end in
go t vs.
Ltac build_app Ei final :=
let args := ltac_args Ei in
first [
match args with (boxer ?mode)::(boxer ?t)::?vs =>
match mode with
| Hnts => build_app_hnts t vs final
| Args => build_app_args t vs final
| Vars => build_app_vars t vs final
| Hyps => build_app_hyps t vs final
end end
| fail 1 "Instantiation fails for:" args].
Ltac lets_build I Ei :=
build_app Ei ltac:(fun R => lets I: R).
Tactic Notation "lets" simple_intropattern(I) ":" constr(E) :=
lets_build I E.
Tactic Notation "lets" ":" constr(E) :=
let H := fresh in lets H: E.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2)
":" constr(E) :=
lets [I1 I2]: E.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) ":" constr(E) :=
lets [I1 [I2 I3]]: E.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) ":" constr(E) :=
lets [I1 [I2 [I3 I4]]]: E.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) simple_intropattern(I5)
":" constr(E) :=
lets [I1 [I2 [I3 [I4 I5]]]]: E.
Tactic Notation "lets" simple_intropattern(I) ":" constr(E0)
constr(A1) :=
lets I: (>>> E0 A1).
Tactic Notation "lets" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) :=
lets I: (>>> E0 A1 A2).
Tactic Notation "lets" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) :=
lets I: (>>> E0 A1 A2 A3).
Tactic Notation "lets" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) :=
lets I: (>>> E0 A1 A2 A3 A4).
Tactic Notation "lets" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) constr(A5) :=
lets I: (>>> E0 A1 A2 A3 A4 A5).
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2) ":" constr(E0)
constr(A1) :=
lets [I1 I2]: E0 A1.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2) ":" constr(E0)
constr(A1) constr(A2) :=
lets [I1 I2]: E0 A1 A2.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2) ":" constr(E0)
constr(A1) constr(A2) constr(A3) :=
lets [I1 I2]: E0 A1 A2 A3.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) :=
lets [I1 I2]: E0 A1 A2 A3 A4.
Tactic Notation "lets" simple_intropattern(I1) simple_intropattern(I2) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) constr(A5) :=
lets [I1 I2]: E0 A1 A2 A3 A4 A5.
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E) :=
let E' := ltac_args E in
let E'' := (eval simpl in (E' ++ ((boxer ___)::nil))) in
lets I: E''.
Tactic Notation "forwards" ":" constr(E) :=
let H := fresh in forwards H: E.
Tactic Notation "forwards" simple_intropattern(I1) simple_intropattern(I2)
":" constr(E) :=
forwards [I1 I2]: E.
Tactic Notation "forwards" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) ":" constr(E) :=
forwards [I1 [I2 I3]]: E.
Tactic Notation "forwards" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) ":" constr(E) :=
forwards [I1 [I2 [I3 I4]]]: E.
Tactic Notation "forwards" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) simple_intropattern(I5)
":" constr(E) :=
forwards [I1 [I2 [I3 [I4 I5]]]]: E.
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E0)
constr(A1) :=
forwards I: (>>> E0 A1).
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) :=
forwards I: (>>> E0 A1 A2).
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) :=
forwards I: (>>> E0 A1 A2 A3).
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) :=
forwards I: (>>> E0 A1 A2 A3 A4).
Tactic Notation "forwards" simple_intropattern(I) ":" constr(E0)
constr(A1) constr(A2) constr(A3) constr(A4) constr(A5) :=
forwards I: (>>> E0 A1 A2 A3 A4 A5).
Ltac applys_build Ei :=
build_app Ei ltac:(fun R =>
first [ apply R | eapply R | applys R ]).
Tactic Notation "applys" constr(E0) :=
match type of E0 with
| list Boxer => applys_build E0
| _ => applys E0
end.
Tactic Notation "applys" constr(E0) constr(A1) :=
applys (>>> E0 A1).
Tactic Notation "applys" constr(E0) constr(A1) constr(A2) :=
applys (>>> E0 A1 A2).
Tactic Notation "applys" constr(E0) constr(A1) constr(A2) constr(A3) :=
applys (>>> E0 A1 A2 A3).
Tactic Notation "applys" constr(E0) constr(A1) constr(A2) constr(A3) constr(A4) :=
applys (>>> E0 A1 A2 A3 A4).
Tactic Notation "applys" constr(E0) constr(A1) constr(A2) constr(A3) constr(A4) constr(A5) :=
applys (>>> E0 A1 A2 A3 A4 A5).
Ltac specializes_build H Ei :=
let H' := fresh "TEMP" in rename H into H';
let Ei' := ltac_args Ei in
match Ei' with (boxer ?mode)::?vs =>
let Ei'' := constr:((boxer mode)::(boxer H')::vs) in
build_app Ei'' ltac:(fun R => lets H: R);
clear H'
end.
Tactic Notation "specializes" hyp(H) constr(A) :=
specializes_build H A.
Tactic Notation "specializes" hyp(H) constr(A1) constr(A2) :=
specializes H (>>> A1 A2).
Tactic Notation "specializes" hyp(H) constr(A1) constr(A2) constr(A3) :=
specializes H (>>> A1 A2 A3).
Tactic Notation "specializes" hyp(H) constr(A1) constr(A2) constr(A3) constr(A4) :=
specializes H (>>> A1 A2 A3 A4).
Tactic Notation "specializes" hyp(H) constr(A1) constr(A2) constr(A3) constr(A4) constr(A5) :=
specializes H (>>> A1 A2 A3 A4 A5).
Tactic Notation "fapply" constr(E) :=
let H := fresh in forwards H: E;
first [ apply H | eapply H | hnf; apply H
| hnf; eapply H | applys H ].
Tactic Notation "sapply" constr(H) :=
first [ apply H | eapply H | applys H
| hnf; apply H | hnf; eapply H | hnf; applys H
| fapply H ].
Definition ltac_tag_subst (A:Type) (x:A) := x.
Ltac introv_rec :=
match goal with
| |- (ltac_tag_subst (?x = ?y) -> ?Q) =>
let H := fresh "Aux" in
intro H; unfold ltac_tag_subst in H;
try subst x; introv_rec
| |- ?P -> ?Q => idtac
| |- forall _, _ => intro; introv_rec
| |- _ => idtac
end.
Ltac introv_to :=
match goal with
| |- (ltac_tag_subst (?x = ?y) -> ?Q) =>
let H := fresh "Aux" in
intro H; unfold ltac_tag_subst in H;
try subst x; introv_to
| |- ?P -> ?Q => idtac
| |- forall _, _ => intro; introv_to
| |- ?G => let P := get_head G in progress (unfold P); introv_to
end.
Ltac introv_base :=
match goal with
| |- forall _, _ => introv_rec
| |- ?G => let P := get_head G in unfold P; introv_rec
end.
Tactic Notation "introv" :=
introv_base.
Tactic Notation "introv" simple_intropattern(I) :=
introv_to; intros I.
Tactic Notation "introv" simple_intropattern(I1) simple_intropattern(I2) :=
introv_to; intros I1; introv_to; intros I2.
Tactic Notation "introv" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) :=
introv; intros I1; introv; intros I2; introv; intros I3.
Tactic Notation "introv" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) :=
introv; intros I1; introv; intros I2; introv; intros I3;
introv; intros I4.
Tactic Notation "introv" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) simple_intropattern(I5) :=
introv; intros I1; introv; intros I2; introv; intros I3;
introv; intros I4; introv; intros I5.
Tactic Notation "introv" simple_intropattern(I1) simple_intropattern(I2)
simple_intropattern(I3) simple_intropattern(I4) simple_intropattern(I5)
simple_intropattern(I6) :=
introv; intros I1; introv; intros I2; introv; intros I3;
introv; intros I4; introv; intros I5; introv; intros I6.
Tactic Notation "intros_all" :=
repeat intro.
Tactic Notation "gen" ident(X1) :=
generalize dependent X1.
Tactic Notation "gen" ident(X1) ident(X2) :=
gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) :=
gen X3; gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) ident(X4) :=
gen X4; gen X3; gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) ident(X4) ident(X5) :=
gen X5; gen X4; gen X3; gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) ident(X4) ident(X5)
ident(X6) :=
gen X6; gen X5; gen X4; gen X3; gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) ident(X4) ident(X5)
ident(X6) ident(X7) :=
gen X7; gen X6; gen X5; gen X4; gen X3; gen X2; gen X1.
Tactic Notation "gen" ident(X1) ident(X2) ident(X3) ident(X4) ident(X5)
ident(X6) ident(X7) ident(X8) :=
gen X8; gen X7; gen X6; gen X5; gen X4; gen X3; gen X2; gen X1.
Tactic Notation "generalizes" hyp(X) :=
generalize X; clear X.
Tactic Notation "sets" ident(X) ":" constr(E) :=
set (X := E) in *.
Ltac def_to_eq X HX E :=
assert (HX : X = E) by reflexivity; clearbody X.
Ltac def_to_eq_sym X HX E :=
assert (HX : E = X) by reflexivity; clearbody X.
Tactic Notation "set_eq" ident(X) ident(HX) ":" constr(E) :=
set (X := E); def_to_eq X HX E.
Tactic Notation "set_eq" ident(X) ":" constr(E) :=
let HX := fresh "EQ" X in set_eq X HX: E.
Tactic Notation "set_eq" ":" constr(E) :=
let X := fresh "X" in set_eq X: E.
Tactic Notation "set_eq" "<-" ident(X) ident(HX) ":" constr(E) :=
set (X := E); def_to_eq_sym X HX E.
Tactic Notation "set_eq" "<-" ident(X) ":" constr(E) :=
let HX := fresh "EQ" X in set_eq <- X HX: E.
Tactic Notation "set_eq" "<-" ":" constr(E) :=
let X := fresh "X" in set_eq <- X: E.
Tactic Notation "sets_eq" ident(X) ident(HX) ":" constr(E) :=
set (X := E) in *; def_to_eq X HX E.
Tactic Notation "sets_eq" ident(X) ":" constr(E) :=
let HX := fresh "EQ" X in sets_eq X HX: E.
Tactic Notation "sets_eq" ":" constr(E) :=
let X := fresh "X" in sets_eq X: E.
Tactic Notation "sets_eq" "<-" ident(X) ident(HX) ":" constr(E) :=
set (X := E) in *; def_to_eq_sym X HX E.
Tactic Notation "sets_eq" "<-" ident(X) ":" constr(E) :=
let HX := fresh "EQ" X in sets_eq <- X HX: E.
Tactic Notation "sets_eq" "<-" ":" constr(E) :=
let X := fresh "X" in sets_eq <- X: E.
Tactic Notation "set_eq" ident(X) ident(HX) ":" constr(E) "in" hyp(H) :=
set (X := E) in H; def_to_eq X HX E.
Tactic Notation "set_eq" ident(X) ":" constr(E) "in" hyp(H) :=
let HX := fresh "EQ" X in set_eq X HX: E in H.
Tactic Notation "set_eq" ":" constr(E) "in" hyp(H) :=
let X := fresh "X" in set_eq X: E in H.
Tactic Notation "set_eq" "<-" ident(X) ident(HX) ":" constr(E) "in" hyp(H) :=
set (X := E) in H; def_to_eq_sym X HX E.
Tactic Notation "set_eq" "<-" ident(X) ":" constr(E) "in" hyp(H) :=
let HX := fresh "EQ" X in set_eq <- X HX: E in H.
Tactic Notation "set_eq" "<-" ":" constr(E) "in" hyp(H) :=
let X := fresh "X" in set_eq <- X: E in H.
Tactic Notation "set_eq" ident(X) ident(HX) ":" constr(E) "in" "|-" :=
set (X := E) in |-; def_to_eq X HX E.
Tactic Notation "set_eq" ident(X) ":" constr(E) "in" "|-" :=
let HX := fresh "EQ" X in set_eq X HX: E in |-.
Tactic Notation "set_eq" ":" constr(E) "in" "|-" :=
let X := fresh "X" in set_eq X: E in |-.
Tactic Notation "set_eq" "<-" ident(X) ident(HX) ":" constr(E) "in" "|-" :=
set (X := E) in |-; def_to_eq_sym X HX E.
Tactic Notation "set_eq" "<-" ident(X) ":" constr(E) "in" "|-" :=
let HX := fresh "EQ" X in set_eq <- X HX: E in |-.
Tactic Notation "set_eq" "<-" ":" constr(E) "in" "|-" :=
let X := fresh "X" in set_eq <- X: E in |-.
Tactic Notation "ltac_pattern" constr(E) "at" constr(K) :=
match K with
| 1 => pattern E at 1
| 2 => pattern E at 2
| 3 => pattern E at 3
| 4 => pattern E at 4
| 5 => pattern E at 5
| 6 => pattern E at 6
| 7 => pattern E at 7
| 8 => pattern E at 8
end.
Tactic Notation "ltac_pattern" constr(E) "at" constr(K) "in" hyp(H) :=
match K with
| 1 => pattern E at 1 in H
| 2 => pattern E at 2 in H
| 3 => pattern E at 3 in H
| 4 => pattern E at 4 in H
| 5 => pattern E at 5 in H
| 6 => pattern E at 6 in H
| 7 => pattern E at 7 in H
| 8 => pattern E at 8 in H
end.
Tactic Notation "ltac_action_at" constr(K) "of" constr(E) "do" tactic(Tac) :=
let p := fresh in ltac_pattern E at K;
match goal with |- ?P _ => set (p:=P) end;
Tac; unfold p; clear p.
Tactic Notation "ltac_action_at" constr(K) "of" constr(E) "in" hyp(H) "do" tactic(Tac) :=
let p := fresh in ltac_pattern E at K in H;
match type of H with ?P _ => set (p:=P) in H end;
Tac; unfold p in H; clear p.
Tactic Notation "protects" constr(E) "do" tactic(T) :=
let x := fresh in sets_eq x: E; T; subst x.
Tactic Notation "protects" constr(E) "do" tactic(T) "/" :=
protects E do T.
Tactic Notation "rewrite_all" constr(E) :=
repeat rewrite E.
Tactic Notation "rewrite_all" "<-" constr(E) :=
repeat rewrite <- E.
Tactic Notation "rewrite_all" constr(E) "in" ident(H) :=
repeat rewrite E in H.
Tactic Notation "rewrite_all" "<-" constr(E) "in" ident(H) :=
repeat rewrite <- E in H.
Tactic Notation "rewrite_all" constr(E) "in" "*" :=
repeat rewrite E in *.
Tactic Notation "rewrite_all" "<-" constr(E) "in" "*" :=
repeat rewrite <- E in *.
Ltac asserts_rewrite_tactic E action :=
let EQ := fresh in (assert (EQ : E);
[ idtac | action EQ; clear EQ ]).
Tactic Notation "asserts_rewrite" constr(E) :=
asserts_rewrite_tactic E ltac:(fun EQ => rewrite EQ).
Tactic Notation "asserts_rewrite" "<-" constr(E) :=
asserts_rewrite_tactic E ltac:(fun EQ => rewrite <- EQ).
Tactic Notation "asserts_rewrite" constr(E) "in" hyp(H) :=
asserts_rewrite_tactic E ltac:(fun EQ => rewrite EQ in H).
Tactic Notation "asserts_rewrite" "<-" constr(E) "in" hyp(H) :=
asserts_rewrite_tactic E ltac:(fun EQ => rewrite <- EQ in H).
Ltac cuts_rewrite_tactic E action :=
let EQ := fresh in (cuts EQ: E;
[ action EQ; clear EQ | idtac ]).
Tactic Notation "cuts_rewrite" constr(E) :=
cuts_rewrite_tactic E ltac:(fun EQ => rewrite EQ).
Tactic Notation "cuts_rewrite" "<-" constr(E) :=
cuts_rewrite_tactic E ltac:(fun EQ => rewrite <- EQ).
Tactic Notation "cuts_rewrite" constr(E) "in" hyp(H) :=
cuts_rewrite_tactic E ltac:(fun EQ => rewrite EQ in H).
Tactic Notation "cuts_rewrite" "<-" constr(E) "in" hyp(H) :=
cuts_rewrite_tactic E ltac:(fun EQ => rewrite <- EQ in H).
Ltac rewrite_except H EQ :=
let K := fresh in let T := type of H in
set (K := T) in H;
rewrite EQ in *; unfold K in H; clear K.
Tactic Notation "rewrites" constr(E) "at" constr(K) :=
match type of E with ?T1 = ?T2 =>
ltac_action_at K of T1 do (rewrite E) end.
Tactic Notation "rewrites" "<-" constr(E) "at" constr(K) :=
match type of E with ?T1 = ?T2 =>
ltac_action_at K of T2 do (rewrite <- E) end.
Tactic Notation "rewrites" constr(E) "at" constr(K) "in" hyp(H) :=
match type of E with ?T1 = ?T2 =>
ltac_action_at K of T1 in H do (rewrite E in H) end.
Tactic Notation "rewrites" "<-" constr(E) "at" constr(K) "in" hyp(H) :=
match type of E with ?T1 = ?T2 =>
ltac_action_at K of T2 in H do (rewrite <- E in H) end.
Tactic Notation "replaces" constr(E) "with" constr(F) :=
let T := fresh in assert (T: E = F); [ | replace E with F; clear T ].
Tactic Notation "replaces" constr(E) "with" constr(F) "in" hyp(H) :=
let T := fresh in assert (T: E = F); [ | replace E with F in H; clear T ].
Tactic Notation "replaces" constr(E) "at" constr(K) "with" constr(F) :=
let T := fresh in assert (T: E = F); [ | rewrites T at K; clear T ].
Tactic Notation "replaces" constr(E) "at" constr(K) "with" constr(F) "in" hyp(H) :=
let T := fresh in assert (T: E = F); [ | rewrites T at K in H; clear T ].
Tactic Notation "renames" ident(X1) "to" ident(Y1) :=
rename X1 into Y1.
Tactic Notation "renames" ident(X1) "to" ident(Y1) ","
ident(X2) "to" ident(Y2) :=
renames X1 to Y1; renames X2 to Y2.
Tactic Notation "renames" ident(X1) "to" ident(Y1) ","
ident(X2) "to" ident(Y2) "," ident(X3) "to" ident(Y3) :=
renames X1 to Y1; renames X2 to Y2, X3 to Y3.
Tactic Notation "renames" ident(X1) "to" ident(Y1) ","
ident(X2) "to" ident(Y2) "," ident(X3) "to" ident(Y3) ","
ident(X4) "to" ident(Y4) :=
renames X1 to Y1; renames X2 to Y2, X3 to Y3, X4 to Y4.
Tactic Notation "renames" ident(X1) "to" ident(Y1) ","
ident(X2) "to" ident(Y2) "," ident(X3) "to" ident(Y3) ","
ident(X4) "to" ident(Y4) "," ident(X5) "to" ident(Y5) :=
renames X1 to Y1; renames X2 to Y2, X3 to Y3, X4 to Y4, X5 to Y5.
Tactic Notation "renames" ident(X1) "to" ident(Y1) ","
ident(X2) "to" ident(Y2) "," ident(X3) "to" ident(Y3) ","
ident(X4) "to" ident(Y4) "," ident(X5) "to" ident(Y5) ","
ident(X6) "to" ident(Y6) :=
renames X1 to Y1; renames X2 to Y2, X3 to Y3, X4 to Y4, X5 to Y5, X6 to Y6.
Ltac unfolds_callback E cont :=
let go E := let P := get_head E in cont P in
match E with
| ?A = ?B => first [ go A | go B ]
| ?A => go A
end.
Ltac unfolds_base :=
match goal with |- ?G =>
unfolds_callback G ltac:(fun P => unfold P) end.
Tactic Notation "unfolds" :=
unfolds_base.
Ltac unfolds_in_base H :=
match type of H with ?G =>
unfolds_callback G ltac:(fun P => unfold P in H) end.
Tactic Notation "unfolds" "in" hyp(H) :=
unfolds_in_base H.
Tactic Notation "unfolds" reference(F1) :=
unfold F1 in *.
Tactic Notation "unfolds" reference(F1) "," reference(F2) :=
unfold F1,F2 in *.
Tactic Notation "unfolds" reference(F1) "," reference(F2)
"," reference(F3) :=
unfold F1,F2,F3 in *.
Tactic Notation "unfolds" reference(F1) "," reference(F2)
"," reference(F3) "," reference(F4) :=
unfold F1,F2,F3,F4 in *.
Tactic Notation "folds" constr(H) :=
fold H in *.
Tactic Notation "folds" constr(H1) "," constr(H2) :=
folds H1; folds H2.
Tactic Notation "folds" constr(H1) "," constr(H2) "," constr(H3) :=
folds H1; folds H2; folds H3.
Tactic Notation "folds" constr(H1) "," constr(H2) "," constr(H3)
"," constr(H4) :=
folds H1; folds H2; folds H3; folds H4.
Tactic Notation "folds" constr(H1) "," constr(H2) "," constr(H3)
"," constr(H4) "," constr(H5) :=
folds H1; folds H2; folds H3; folds H4; folds H5.
Tactic Notation "simpls" :=
simpl in *.
Tactic Notation "simpls" reference(F1) :=
simpl F1 in *.
Tactic Notation "simpls" reference(F1) "," reference(F2) :=
simpls F1; simpls F2.
Tactic Notation "simpls" reference(F1) "," reference(F2)
"," reference(F3) :=
simpls F1; simpls F2; simpls F3.
Tactic Notation "simpls" reference(F1) "," reference(F2)
"," reference(F3) "," reference(F4) :=
simpls F1; simpls F2; simpls F3; simpls F4.
Tactic Notation "unsimpl" constr(E) :=
let F := (eval simpl in E) in change F with E.
Tactic Notation "unsimpl" constr(E) "in" hyp(H) :=
let F := (eval simpl in E) in change F with E in H.
Tactic Notation "unsimpl" constr(E) "in" "*" :=
let F := (eval simpl in E) in change F with E in *.
Tactic Notation "substs" :=
repeat (match goal with H: ?x = ?y |- _ =>
first [ subst x | subst y ] end).
Ltac substs_below limit :=
match goal with H: ?T |- _ =>
match T with
| limit => idtac
| ?x = ?y =>
first [ subst x; substs_below limit
| subst y; substs_below limit
| generalizes H; substs_below limit; intro ]
end end.
Tactic Notation "substs" "below" "body" constr(M) :=
substs_below M.
Tactic Notation "substs" "below" hyp(H) :=
match type of H with ?M => substs below body M end.
Ltac fequal_base :=
let go := f_equal; [ fequal_base | ] in
match goal with
| |- (_,_,_) = (_,_,_) => go
| |- (_,_,_,_) = (_,_,_,_) => go
| |- (_,_,_,_,_) = (_,_,_,_,_) => go
| |- (_,_,_,_,_,_) = (_,_,_,_,_,_) => go
| |- _ => f_equal
end.
Tactic Notation "fequal" :=
fequal_base.
Ltac fequal_post :=
first [ reflexivity | congruence | idtac ].
Tactic Notation "fequals" :=
fequal; fequal_post.
Tactic Notation "fequals_rec" :=
repeat (progress fequals).
Inductive ltac_Mark : Type :=
| ltac_mark : ltac_Mark.
Ltac gen_until_mark :=
match goal with H: ?T |- _ =>
match T with
| ltac_Mark => clear H
| _ => generalizes H; gen_until_mark
end end.
Ltac intro_until_mark :=
match goal with
| |- (ltac_Mark -> _) => intros _
| _ => intro; intro_until_mark
end.
Tactic Notation "invert" "keep" hyp(H) :=
pose ltac_mark; inversion H; gen_until_mark.
Tactic Notation "invert" "keep" hyp(H) "as" simple_intropattern(I1) :=
invert keep H; introv I1.
Tactic Notation "invert" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) :=
invert keep H; introv I1 I2.
Tactic Notation "invert" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) :=
invert keep H; introv I1 I2 I3.
Tactic Notation "invert" hyp(H) :=
invert keep H; clear H.
Tactic Notation "invert_tactic" hyp(H) tactic(tac) :=
let H' := fresh in rename H into H'; tac H'; clear H'.
Tactic Notation "invert" hyp(H) "as" simple_intropattern(I1) :=
invert_tactic H (fun H => invert keep H as I1).
Tactic Notation "invert" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) :=
invert_tactic H (fun H => invert keep H as I1 I2).
Tactic Notation "invert" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) :=
invert_tactic H (fun H => invert keep H as I1 I2 I3).
Require Import Eqdep.
Ltac inverts_tactic H i1 i2 i3 i4 i5 :=
let rec go i1 i2 i3 i4 i5 :=
match goal with
| |- (ltac_Mark -> _) => intros _
| |- (?x = ?y -> _) => let H := fresh in intro H;
first [ subst x | subst y ];
go i1 i2 i3 i4 i5
| |- (existT ?P ?p ?x = existT ?P ?p ?y -> _) =>
let H := fresh in intro H;
generalize (@EqdepTheory.inj_pair2 _ P p x y H);
clear H; go i1 i2 i3 i4 i5
| |- (?P -> ?Q) => i1; go i2 i3 i4 i5 ltac:(intro)
| |- (forall _, _) => intro; go i1 i2 i3 i4 i5
end in
generalize ltac_mark; invert keep H; go i1 i2 i3 i4 i5.
Tactic Notation "inverts" "keep" hyp(H) :=
inverts_tactic H ltac:(intro) ltac:(intro) ltac:(intro) ltac:(intro) ltac:(intro).
Tactic Notation "inverts" "keep" hyp(H) "as" simple_intropattern(I1) :=
inverts_tactic H ltac:(intros I1)
ltac:(intro) ltac:(intro) ltac:(intro) ltac:(intro).
Tactic Notation "inverts" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) :=
inverts_tactic H ltac:(intros I1) ltac:(intros I2)
ltac:(intro) ltac:(intro) ltac:(intro).
Tactic Notation "inverts" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) :=
inverts_tactic H ltac:(intros I1) ltac:(intros I2) ltac:(intros I3)
ltac:(intro) ltac:(intro).
Tactic Notation "inverts" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) simple_intropattern(I4) :=
inverts_tactic H ltac:(intros I1) ltac:(intros I2) ltac:(intros I3)
ltac:(intros I4) ltac:(intro).
Tactic Notation "inverts" "keep" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) simple_intropattern(I4)
simple_intropattern(I5) :=
inverts_tactic H ltac:(intros I1) ltac:(intros I2) ltac:(intros I3)
ltac:(intros I4) ltac:(intros I5).
Tactic Notation "inverts" hyp(H) :=
inverts keep H; clear H.
Tactic Notation "inverts_tactic" hyp(H) tactic(tac) :=
let H' := fresh in rename H into H'; tac H'; clear H'.
Tactic Notation "inverts" hyp(H) "as" simple_intropattern(I1) :=
invert_tactic H (fun H => inverts keep H as I1).
Tactic Notation "inverts" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) :=
invert_tactic H (fun H => inverts keep H as I1 I2).
Tactic Notation "inverts" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) :=
invert_tactic H (fun H => inverts keep H as I1 I2 I3).
Tactic Notation "inverts" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) simple_intropattern(I4) :=
invert_tactic H (fun H => inverts keep H as I1 I2 I3 I4).
Tactic Notation "inverts" hyp(H) "as" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) simple_intropattern(I4)
simple_intropattern(I5) :=
invert_tactic H (fun H => inverts keep H as I1 I2 I3 I4 I5).
Ltac injects_tactic H :=
let rec go _ :=
match goal with
| |- (ltac_Mark -> _) => intros _
| |- (?x = ?y -> _) => let H := fresh in intro H;
first [ subst x | subst y | idtac ];
go tt
end in
generalize ltac_mark; injection H; go tt.
Tactic Notation "injects" "keep" hyp(H) :=
injects_tactic H.
Tactic Notation "injects" hyp(H) :=
injects_tactic H; clear H.
Tactic Notation "inject" hyp(H) :=
injection H.
Tactic Notation "inject" hyp(H) "as" ident(X1) :=
injection H; intros X1.
Tactic Notation "inject" hyp(H) "as" ident(X1) ident(X2) :=
injection H; intros X1 X2.
Tactic Notation "inject" hyp(H) "as" ident(X1) ident(X2) ident(X3) :=
injection H; intros X1 X2 X3.
Tactic Notation "inject" hyp(H) "as" ident(X1) ident(X2) ident(X3)
ident(X4) :=
injection H; intros X1 X2 X3 X4.
Tactic Notation "inject" hyp(H) "as" ident(X1) ident(X2) ident(X3)
ident(X4) ident(X5) :=
injection H; intros X1 X2 X3 X4 X5.
Tactic Notation "inversions" "keep" hyp(H) :=
inversion H; subst.
Tactic Notation "inversions" hyp(H) :=
inversion H; subst; clear H.
Tactic Notation "injections" "keep" hyp(H) :=
injection H; intros; subst.
Tactic Notation "injections" "keep" hyp(H) :=
injection H; clear H; intros; subst.
Ltac case_if_on_tactic E Eq :=
let X := fresh in
sets_eq <- X Eq: E;
destruct X.
Tactic Notation "case_if_on" constr(E) "as" simple_intropattern(Eq) :=
case_if_on_tactic E Eq.
Tactic Notation "case_if" "as" simple_intropattern(Eq) :=
match goal with
| |- context [if ?B then _ else _] => case_if_on B as Eq
| K: context [if ?B then _ else _] |- _ => case_if_on B as Eq
end.
Tactic Notation "case_if" "in" hyp(H) "as" simple_intropattern(Eq) :=
match type of H with context [if ?B then _ else _] =>
case_if_on B as Eq end.
Tactic Notation "case_if" :=
let Eq := fresh in case_if as Eq.
Tactic Notation "case_if" "in" hyp(H) :=
let Eq := fresh in case_if in H as Eq.
Tactic Notation "gen_eq" ident(X) ":" constr(E) :=
let EQ := fresh in sets_eq X EQ: E; revert EQ.
Tactic Notation "gen_eq" ":" constr(E) :=
let X := fresh "X" in gen_eq X: E.
Tactic Notation "gen_eq" ":" constr(E) "as" ident(X) :=
gen_eq X: E.
Tactic Notation "gen_eq" ident(X1) ":" constr(E1) ","
ident(X2) ":" constr(E2) :=
gen_eq X2: E2; gen_eq X1: E1.
Tactic Notation "gen_eq" ident(X1) ":" constr(E1) ","
ident(X2) ":" constr(E2) "," ident(X3) ":" constr(E3) :=
gen_eq X3: E3; gen_eq X2: E2; gen_eq X1: E1.
Ltac gen_eq_for_inductions H E :=
let X := fresh "aux" in
let HX := fresh "H" X in
set (X := E) in H |-;
assert (HX : ltac_tag_subst (X = E));
[ unfold ltac_tag_subst; reflexivity
| clearbody X; generalizes HX ].
Ltac apply_to_all_args T go :=
match T with
| ?P ?E1 ?E2 ?E3 ?E4 ?E5 ?E6 => go E1; go E2; go E3; go E4; go E5; go E6
| ?P ?E1 ?E2 ?E3 ?E4 ?E5 => go E1; go E2; go E3; go E4; go E5
| ?P ?E1 ?E2 ?E3 ?E4 => go E1; go E2; go E3; go E4
| ?P ?E1 ?E2 ?E3 => go E1; go E2; go E3
| ?P ?E1 ?E2 => go E1; go E2
| ?P ?E1 => go E1
end.
Tactic Notation "gen_eqs'" hyp(H) :=
let T := type of H in
let go E := try gen_eq_for_inductions H E in
apply_to_all_args T go.
Tactic Notation "gen_eqs" hyp(H) :=
let T := type of H in
let go E :=
match is_metavar E with
| true => idtac
| false => try gen_eq_for_inductions H E
end in
apply_to_all_args T go.
Ltac intros_head_ltac_tag_subst :=
try match goal with |- (ltac_tag_subst (?x = ?y) -> ?Q) =>
let H := fresh "Aux" in
intro H; unfold ltac_tag_subst in H;
try subst x; intros_head_ltac_tag_subst
end.
Ltac inductions_post :=
intros_head_ltac_tag_subst;
unfold ltac_tag_subst in * |-.
Tactic Notation "inductions" hyp(H) :=
gen_eqs H; induction H; inductions_post.
Tactic Notation "inductions" hyp(H) "as" simple_intropattern(I) :=
gen_eqs H; induction H as I; inductions_post.
Tactic Notation "inductions" hyp(H) tactic(Gen) "end" :=
gen_eqs H; Gen; induction H; inductions_post.
Tactic Notation "inductions" hyp(H) "as" simple_intropattern(I)
tactic(Gen) "end" :=
gen_eqs H; Gen; induction H as I; inductions_post.
Tactic Notation "inductions'" hyp(H) :=
gen_eqs' H; induction H; inductions_post.
Tactic Notation "inductions'" hyp(H) "as" simple_intropattern(I) :=
gen_eqs' H; induction H as I; inductions_post.
Tactic Notation "inductions'" hyp(H) tactic(Gen) "end" :=
gen_eqs' H; Gen; induction H; inductions_post.
Tactic Notation "inductions'" hyp(H) "as" simple_intropattern(I)
tactic(Gen) "end" :=
gen_eqs' H; Gen; induction H as I; inductions_post.
Tactic Notation "induction_wf" ident(IH) ":" constr(E) ident(X) :=
pattern X; apply (well_founded_ind E); clear X; intros X IH.
Tactic Notation "induction_wf" ":" constr(E) ident(X) :=
let IH := fresh "IH" in induction_wf IH: E X.
Tactic Notation "induction_wf" ":" constr(E) ident(X) "as" ident(IH) :=
induction_wf IH: E X.
Tactic Notation "induction_wf" ":" constr(E) ident(X) :=
induction_wf: E X.
Ltac decides_equality_tactic :=
first [ decide equality | progress(unfolds); decides_equality_tactic ].
Tactic Notation "decides_equality" :=
decides_equality_tactic.
Ltac splits_tactic N :=
match N with
| O => fail
| S O => idtac
| S ?N' => split; [| splits_tactic N']
end.
Ltac unfold_goal_until_conjunction :=
match goal with
| |- _ /\ _ => idtac
| _ => progress(unfolds); unfold_goal_until_conjunction
end.
Ltac get_term_conjunction_arity T :=
match T with
| _ /\ _ /\ _ /\ _ /\ _ /\ _ /\ _ /\ _ => constr:(8)
| _ /\ _ /\ _ /\ _ /\ _ /\ _ /\ _ => constr:(7)
| _ /\ _ /\ _ /\ _ /\ _ /\ _ => constr:(6)
| _ /\ _ /\ _ /\ _ /\ _ => constr:(5)
| _ /\ _ /\ _ /\ _ => constr:(4)
| _ /\ _ /\ _ => constr:(3)
| _ /\ _ => constr:(2)
| _ -> ?T' => get_term_conjunction_arity T'
| _ => let P := get_head T in
let T' := eval unfold P in T in
match T' with
| T => fail 1
| _ => get_term_conjunction_arity T'
end
end.
Ltac get_goal_conjunction_arity :=
match goal with |- ?T => get_term_conjunction_arity T end.
Tactic Notation "splits" :=
unfold_goal_until_conjunction;
let N := get_goal_conjunction_arity in
splits_tactic N.
Tactic Notation "splits" constr(N) :=
splits_tactic N.
Tactic Notation "splits_all" :=
repeat split.
Ltac destructs_conjunction_tactic N T :=
match N with
| 2 => destruct T as [? ?]
| 3 => destruct T as [? [? ?]]
| 4 => destruct T as [? [? [? ?]]]
| 5 => destruct T as [? [? [? [? ?]]]]
| 6 => destruct T as [? [? [? [? [? ?]]]]]
| 7 => destruct T as [? [? [? [? [? [? ?]]]]]]
end.
Tactic Notation "destructs" constr(T) :=
let TT := type of T in
let N := get_term_conjunction_arity TT in
destructs_conjunction_tactic N T.
Tactic Notation "destructs" constr(N) constr(T) :=
destructs_conjunction_tactic N T.
Ltac branch_tactic K N :=
match constr:(K,N) with
| (_,0) => fail 1
| (0,_) => fail 1
| (1,1) => idtac
| (1,_) => left
| (S ?K', S ?N') => right; branch_tactic K' N'
end.
Ltac unfold_goal_until_disjunction :=
match goal with
| |- _ \/ _ => idtac
| _ => progress(unfolds); unfold_goal_until_disjunction
end.
Ltac get_term_disjunction_arity T :=
match T with
| _ \/ _ \/ _ \/ _ \/ _ \/ _ \/ _ \/ _ => constr:(8)
| _ \/ _ \/ _ \/ _ \/ _ \/ _ \/ _ => constr:(7)
| _ \/ _ \/ _ \/ _ \/ _ \/ _ => constr:(6)
| _ \/ _ \/ _ \/ _ \/ _ => constr:(5)
| _ \/ _ \/ _ \/ _ => constr:(4)
| _ \/ _ \/ _ => constr:(3)
| _ \/ _ => constr:(2)
| _ -> ?T' => get_term_disjunction_arity T'
| _ => let P := get_head T in
let T' := eval unfold P in T in
match T' with
| T => fail 1
| _ => get_term_disjunction_arity T'
end
end.
Ltac get_goal_disjunction_arity :=
match goal with |- ?T => get_term_disjunction_arity T end.
Tactic Notation "branch" constr(K) :=
unfold_goal_until_disjunction;
let N := get_goal_disjunction_arity in
branch_tactic K N.
Tactic Notation "branch" constr(K) "of" constr(N) :=
branch_tactic K N.
Ltac destructs_disjunction_tactic N T :=
match N with
| 2 => destruct T as [? | ?]
| 3 => destruct T as [? | ? | ?]
| 4 => destruct T as [? | ? | ? | ?]
| 5 => destruct T as [? | ? | ? | ? | ?]
| 6 => destruct T as [? | ? | ? | ? | ? | ?]
| 7 => destruct T as [? | ? | ? | ? | ? | ? | ?]
end.
Tactic Notation "branches" constr(T) :=
let TT := type of T in
let N := get_term_disjunction_arity TT in
destructs_disjunction_tactic N T.
Tactic Notation "branches" constr(N) constr(T) :=
destructs_disjunction_tactic N T.
Ltac get_term_existential_arity T :=
match T with
| exists x1 x2 x3 x4 x5 x6 x7 x8, _ => constr:(8)
| exists x1 x2 x3 x4 x5 x6 x7, _ => constr:(7)
| exists x1 x2 x3 x4 x5 x6, _ => constr:(6)
| exists x1 x2 x3 x4 x5, _ => constr:(5)
| exists x1 x2 x3 x4, _ => constr:(4)
| exists x1 x2 x3, _ => constr:(3)
| exists x1 x2, _ => constr:(2)
| exists x1, _ => constr:(1)
| _ -> ?T' => get_term_existential_arity T'
| _ => let P := get_head T in
let T' := eval unfold P in T in
match T' with
| T => fail 1
| _ => get_term_existential_arity T'
end
end.
Ltac get_goal_existential_arity :=
match goal with |- ?T => get_term_existential_arity T end.
Tactic Notation "exists_original" constr(T1) :=
exists T1.
Tactic Notation "exists" constr(T1) :=
match T1 with
| ltac_wild => esplit
| _ => exists T1
end.
Tactic Notation "exists" constr(T1) constr(T2) :=
exists T1; exists T2.
Tactic Notation "exists" constr(T1) constr(T2) constr(T3) :=
exists T1; exists T2; exists T3.
Tactic Notation "exists" constr(T1) constr(T2) constr(T3) constr(T4) :=
exists T1; exists T2; exists T3; exists T4.
Tactic Notation "exists" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) :=
exists T1; exists T2; exists T3; exists T4; exists T5.
Tactic Notation "exists" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) constr(T6) :=
exists T1; exists T2; exists T3; exists T4; exists T5; exists T6.
Tactic Notation "exists_" constr(N) :=
let rec aux N :=
match N with
| 0 => idtac
| S ?N' => esplit; aux N'
end in
aux N.
Tactic Notation "exists_" :=
let N := get_goal_existential_arity in
exists_ N.
Ltac auto_tilde := auto.
Ltac auto_star := try solve [ auto | intuition eauto ].
Tactic Notation "auto" "~" :=
auto_tilde.
Tactic Notation "auto" "~" constr(E1) :=
lets: E1; auto_tilde.
Tactic Notation "auto" "~" constr(E1) constr(E2) :=
lets: E1 E2; auto_tilde.
Tactic Notation "auto" "~" constr(E1) constr(E2) constr(E3) :=
lets: E1 E2 E3; auto_tilde.
Tactic Notation "auto" "*" :=
auto_star.
Tactic Notation "auto" "*" constr(E1) :=
lets: E1; auto_star.
Tactic Notation "auto" "*" constr(E1) constr(E2) :=
lets: E1 E2; auto_star.
Tactic Notation "auto" "*" constr(E1) constr(E2) constr(E3) :=
lets: E1 E2 E3; auto_star.
Tactic Notation "f_equal" :=
f_equal.
Tactic Notation "constructor" :=
constructor.
Tactic Notation "simple" :=
simpl.
Tactic Notation "apply" "~" constr(H) :=
sapply H; auto_tilde.
Tactic Notation "applys" "~" constr(H) :=
sapply H; auto_tilde.
Tactic Notation "apply_clear" "~" constr(H) :=
apply_clear H; auto_tilde.
Tactic Notation "applys_clear" "~" constr(H) :=
applys_clear H; auto_tilde.
Tactic Notation "destruct" "~" constr(H) :=
destruct H; auto_tilde.
Tactic Notation "destruct" "~" constr(H) "as" simple_intropattern(I) :=
destruct H as I; auto_tilde.
Tactic Notation "f_equal" "~" :=
f_equal; auto_tilde.
Tactic Notation "induction" "~" constr(H) :=
induction H; auto_tilde.
Tactic Notation "inversion" "~" constr(H) :=
inversion H; auto_tilde.
Tactic Notation "split" "~" :=
split; auto_tilde.
Tactic Notation "subst" "~" :=
subst; auto_tilde.
Tactic Notation "right" "~" :=
right; auto_tilde.
Tactic Notation "left" "~" :=
left; auto_tilde.
Tactic Notation "constructor" "~" :=
constructor; auto_tilde.
Tactic Notation "constructors" "~" :=
constructors; auto_tilde.
Tactic Notation "false" "~" :=
false; auto_tilde.
Tactic Notation "false" "~" constr(T) :=
false T by auto_tilde/.
Tactic Notation "tryfalse" "~" :=
tryfalse by auto_tilde/.
Tactic Notation "tryfalse_inv" "~" :=
first [ tryfalse~ | false_inv ].
Tactic Notation "asserts" "~" simple_intropattern(H) ":" constr(E) :=
asserts H: E; [ auto_tilde | idtac ].
Tactic Notation "cuts" "~" simple_intropattern(H) ":" constr(E) :=
cuts H: E; [ auto_tilde | idtac ].
Tactic Notation "cuts" "~" ":" constr(E) :=
cuts: E; [ auto_tilde | idtac ].
Tactic Notation "lets" "~" simple_intropattern(I) ":" constr(E) :=
lets I: E; auto_tilde.
Tactic Notation "lets" "~" ":" constr(E1) :=
lets: E1; auto_tilde.
Tactic Notation "lets" "~" ":" constr(E1) constr(E2) :=
lets: E1 E2; auto_tilde.
Tactic Notation "lets" "~" ":" constr(E1) constr(E2) constr(E3) :=
lets: E1 E2 E3; auto_tilde.
Tactic Notation "applys" "~" constr(E) constr(A) :=
applys E A; auto_tilde.
Tactic Notation "specializes" "~" hyp(H) constr(A) :=
specializes H A; auto_tilde.
Tactic Notation "lets" "~" simple_intropattern(I) ":" constr(E) constr(A) :=
lets I: E A; auto_tilde.
Tactic Notation "lets" "~" simple_intropattern(I) ":" constr(E) constr(A1) constr(A2) :=
lets I: E A1 A2; auto_tilde.
Tactic Notation "lets" "~" simple_intropattern(I) ":" constr(E) constr(A1) constr(A2) constr(A3) :=
lets I: E A1 A2 A3; auto_tilde.
Tactic Notation "forwards" "~" simple_intropattern(I) ":" constr(E) :=
forwards I: E; auto_tilde.
Tactic Notation "forwards" "~" ":" constr(E) :=
forwards: E; auto_tilde.
Tactic Notation "fapply" "~" constr(E) :=
fapply E; auto_tilde.
Tactic Notation "sapply" "~" constr(E) :=
sapply E; auto_tilde.
Tactic Notation "intros_all" "~" :=
intros_all; auto_tilde.
Tactic Notation "unfolds" "~" reference(F1) :=
unfolds F1; auto_tilde.
Tactic Notation "unfolds" "~" reference(F1) reference(F2) :=
unfolds F1, F2; auto_tilde.
Tactic Notation "unfolds" "~" reference(F1) reference(F2) reference(F3) :=
unfolds F1, F2, F3; auto_tilde.
Tactic Notation "unfolds" "~" reference(F1) reference(F2) reference(F3)
reference(F4) :=
unfolds F1, F2, F3, F4; auto_tilde.
Tactic Notation "simple" "~" :=
simpl; auto_tilde.
Tactic Notation "simple" "~" "in" hyp(H) :=
simpl in H; auto_tilde.
Tactic Notation "simpls" "~" :=
simpls; auto_tilde.
Tactic Notation "substs" "~" :=
substs; auto_tilde.
Tactic Notation "rewrite" "~" constr(E) :=
rewrite E; auto_tilde.
Tactic Notation "rewrite" "~" "<-" constr(E) :=
rewrite <- E; auto_tilde.
Tactic Notation "rewrite" "~" constr(E) "in" hyp(H) :=
rewrite E in H; auto_tilde.
Tactic Notation "rewrite" "~" "<-" constr(E) "in" hyp(H) :=
rewrite <- E in H; auto_tilde.
Tactic Notation "rewrite_all" "~" constr(E) :=
rewrite_all E; auto_tilde.
Tactic Notation "rewrite_all" "~" "<-" constr(E) :=
rewrite_all <- E; auto_tilde.
Tactic Notation "rewrite_all" "~" constr(E) "in" ident(H) :=
rewrite_all E in H; auto_tilde.
Tactic Notation "rewrite_all" "~" "<-" constr(E) "in" ident(H) :=
rewrite_all <- E in H; auto_tilde.
Tactic Notation "rewrite_all" "~" constr(E) "in" "*" :=
rewrite_all E in *; auto_tilde.
Tactic Notation "rewrite_all" "~" "<-" constr(E) "in" "*" :=
rewrite_all <- E in *; auto_tilde.
Tactic Notation "asserts_rewrite" "~" constr(E) :=
asserts_rewrite E; auto_tilde.
Tactic Notation "asserts_rewrite" "~" "<-" constr(E) :=
asserts_rewrite <- E; auto_tilde.
Tactic Notation "asserts_rewrite" "~" constr(E) "in" hyp(H) :=
asserts_rewrite E in H; auto_tilde.
Tactic Notation "asserts_rewrite" "~" "<-" constr(E) "in" hyp(H) :=
asserts_rewrite <- E in H; auto_tilde.
Tactic Notation "cuts_rewrite" "~" constr(E) :=
cuts_rewrite E; auto_tilde.
Tactic Notation "cuts_rewrite" "~" "<-" constr(E) :=
cuts_rewrite <- E; auto_tilde.
Tactic Notation "cuts_rewrite" "~" constr(E) "in" hyp(H) :=
cuts_rewrite E in H; auto_tilde.
Tactic Notation "cuts_rewrite" "~" "<-" constr(E) "in" hyp(H) :=
cuts_rewrite <- E in H; auto_tilde.
Tactic Notation "fequal" "~" :=
fequal; auto_tilde.
Tactic Notation "fequals" "~" :=
fequals; auto_tilde.
Tactic Notation "invert" "~" hyp(H) :=
invert H; auto_tilde.
Tactic Notation "inverts" "~" hyp(H) :=
inverts H; auto_tilde.
Tactic Notation "injects" "~" hyp(H) :=
injects H; auto_tilde.
Tactic Notation "inversions" "~" hyp(H) :=
inversions H; auto_tilde.
Tactic Notation "case_if" "~" :=
case_if; auto_tilde.
Tactic Notation "case_if" "~" "in" hyp(H) :=
case_if in H; auto_tilde.
Tactic Notation "decides_equality" "~" :=
decides_equality; auto_tilde.
Tactic Notation "splits" "~" :=
splits; auto_tilde.
Tactic Notation "splits" "~" constr(N) :=
splits N; auto_tilde.
Tactic Notation "destructs" "~" constr(T) :=
destructs T; auto_tilde.
Tactic Notation "destructs" "~" constr(N) constr(T) :=
destructs N T; auto_tilde.
Tactic Notation "branch" "~" constr(N) :=
branch N; auto_tilde.
Tactic Notation "branch" "~" constr(K) "of" constr(N) :=
branch K of N; auto_tilde.
Tactic Notation "branches" "~" constr(T) :=
branches T; auto_tilde.
Tactic Notation "branches" "~" constr(N) constr(T) :=
branches N T; auto_tilde.
Tactic Notation "exists_" "~" :=
exists_; auto_tilde.
Tactic Notation "exists" "~" constr(T1) :=
exists T1; auto_tilde.
Tactic Notation "exists" "~" constr(T1) constr(T2) :=
exists T1 T2; auto_tilde.
Tactic Notation "exists" "~" constr(T1) constr(T2) constr(T3) :=
exists T1 T2 T3; auto_tilde.
Tactic Notation "exists" "~" constr(T1) constr(T2) constr(T3) constr(T4) :=
exists T1 T2 T3 T4; auto_tilde.
Tactic Notation "exists" "~" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) :=
exists T1 T2 T3 T4 T5; auto_tilde.
Tactic Notation "exists" "~" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) constr(T6) :=
exists T1 T2 T3 T4 T5 T6; auto_tilde.
Tactic Notation "apply" "*" constr(H) :=
sapply H; auto_star.
Tactic Notation "applys" "*" constr(H) :=
sapply H; auto_star.
Tactic Notation "apply_clear" "*" constr(H) :=
applys_clear H; auto_star.
Tactic Notation "applys_clear" "*" constr(H) :=
applys_clear H; auto_star.
Tactic Notation "destruct" "*" constr(H) :=
destruct H; auto_star.
Tactic Notation "destruct" "*" constr(H) "as" simple_intropattern(I) :=
destruct H as I; auto_star.
Tactic Notation "f_equal" "*" :=
f_equal; auto_star.
Tactic Notation "induction" "*" constr(H) :=
induction H; auto_star.
Tactic Notation "inversion" "*" constr(H) :=
inversion H; auto_star.
Tactic Notation "split" "*" :=
split; auto_star.
Tactic Notation "subs" "*" :=
subst; auto_star.
Tactic Notation "subst" "*" :=
subst; auto_star.
Tactic Notation "right" "*" :=
right; auto_star.
Tactic Notation "left" "*" :=
left; auto_star.
Tactic Notation "constructor" "*" :=
constructor; auto_star.
Tactic Notation "constructors" "*" :=
constructors; auto_star.
Tactic Notation "false" "*" :=
false; auto_star.
Tactic Notation "false" "*" constr(T) :=
false T by auto_star/.
Tactic Notation "tryfalse" "*" :=
tryfalse by auto_star/.
Tactic Notation "tryfalse_inv" "*" :=
first [ tryfalse* | false_inv ].
Tactic Notation "asserts" "*" simple_intropattern(H) ":" constr(E) :=
asserts H: E; [ auto_star | idtac ].
Tactic Notation "cuts" "*" simple_intropattern(H) ":" constr(E) :=
cuts H: E; [ auto_star | idtac ].
Tactic Notation "cuts" "*" ":" constr(E) :=
cuts: E; [ auto_star | idtac ].
Tactic Notation "lets" "*" simple_intropattern(I) ":" constr(E) :=
lets I: E; auto_star.
Tactic Notation "lets" "*" ":" constr(E1) :=
lets: E1; auto_star.
Tactic Notation "lets" "*" ":" constr(E1) constr(E2) :=
lets: E1 E2; auto_star.
Tactic Notation "lets" "*" ":" constr(E1) constr(E2) constr(E3) :=
lets: E1 E2 E3; auto_star.
Tactic Notation "applys" "*" constr(E) constr(A) :=
applys E A; auto_star.
Tactic Notation "specializes" "*" hyp(H) constr(A) :=
specializes H A; auto_star.
Tactic Notation "lets" "*" simple_intropattern(I) ":" constr(E) constr(A) :=
lets I: E A; auto_star.
Tactic Notation "lets" "*" simple_intropattern(I) ":" constr(E) constr(A1) constr(A2) :=
lets I: E A1 A2; auto_star.
Tactic Notation "lets" "*" simple_intropattern(I) ":" constr(E) constr(A1) constr(A2) constr(A3) :=
lets I: E A1 A2 A3; auto_star.
Tactic Notation "forwards" "*" simple_intropattern(I) ":" constr(E) :=
forwards I: E; auto_star.
Tactic Notation "forwards" "*" ":" constr(E) :=
forwards: E; auto_star.
Tactic Notation "fapply" "*" constr(E) :=
fapply E; auto_star.
Tactic Notation "sapply" "*" constr(E) :=
sapply E; auto_star.
Tactic Notation "intros_all" "*" :=
intros_all; auto_star.
Tactic Notation "unfolds" "*" reference(F1) :=
unfolds F1; auto_star.
Tactic Notation "unfolds" "*" reference(F1) reference(F2) :=
unfolds F1, F2; auto_star.
Tactic Notation "unfolds" "*" reference(F1) reference(F2) reference(F3) :=
unfolds F1, F2, F3; auto_star.
Tactic Notation "unfolds" "*" reference(F1) reference(F2) reference(F3)
reference(F4) :=
unfolds F1, F2, F3, F4; auto_star.
Tactic Notation "simple" "*" :=
simpl; auto_star.
Tactic Notation "simple" "*" "in" hyp(H) :=
simpl in H; auto_star.
Tactic Notation "simpls" "*" :=
simpls; auto_star.
Tactic Notation "substs" "*" :=
substs; auto_star.
Tactic Notation "rewrite" "*" constr(E) :=
rewrite E; auto_star.
Tactic Notation "rewrite" "*" "<-" constr(E) :=
rewrite <- E; auto_star.
Tactic Notation "rewrite" "*" constr(E) "in" hyp(H) :=
rewrite E in H; auto_star.
Tactic Notation "rewrite" "*" "<-" constr(E) "in" hyp(H) :=
rewrite <- E in H; auto_star.
Tactic Notation "rewrite_all" "*" constr(E) :=
rewrite_all E; auto_star.
Tactic Notation "rewrite_all" "*" "<-" constr(E) :=
rewrite_all <- E; auto_star.
Tactic Notation "rewrite_all" "*" constr(E) "in" ident(H) :=
rewrite_all E in H; auto_star.
Tactic Notation "rewrite_all" "*" "<-" constr(E) "in" ident(H) :=
rewrite_all <- E in H; auto_star.
Tactic Notation "rewrite_all" "*" constr(E) "in" "*" :=
rewrite_all E in *; auto_star.
Tactic Notation "rewrite_all" "*" "<-" constr(E) "in" "*" :=
rewrite_all <- E in *; auto_star.
Tactic Notation "asserts_rewrite" "*" constr(E) :=
asserts_rewrite E; auto_star.
Tactic Notation "asserts_rewrite" "*" "<-" constr(E) :=
asserts_rewrite <- E; auto_star.
Tactic Notation "asserts_rewrite" "*" constr(E) "in" hyp(H) :=
asserts_rewrite E; auto_star.
Tactic Notation "asserts_rewrite" "*" "<-" constr(E) "in" hyp(H) :=
asserts_rewrite <- E; auto_star.
Tactic Notation "cuts_rewrite" "*" constr(E) :=
cuts_rewrite E; auto_star.
Tactic Notation "cuts_rewrite" "*" "<-" constr(E) :=
cuts_rewrite <- E; auto_star.
Tactic Notation "cuts_rewrite" "*" constr(E) "in" hyp(H) :=
cuts_rewrite E in H; auto_star.
Tactic Notation "cuts_rewrite" "*" "<-" constr(E) "in" hyp(H) :=
cuts_rewrite <- E in H; auto_star.
Tactic Notation "fequal" "*" :=
fequal; auto_star.
Tactic Notation "fequals" "*" :=
fequals; auto_star.
Tactic Notation "invert" "*" hyp(H) :=
invert H; auto_star.
Tactic Notation "inverts" "*" hyp(H) :=
inverts H; auto_star.
Tactic Notation "injects" "*" hyp(H) :=
injects H; auto_star.
Tactic Notation "inversions" "*" hyp(H) :=
inversions H; auto_star.
Tactic Notation "case_if" "*" :=
case_if; auto_star.
Tactic Notation "case_if" "*" "in" hyp(H) :=
case_if in H; auto_star.
Tactic Notation "decides_equality" "*" :=
decides_equality; auto_star.
Tactic Notation "splits" "*" :=
splits; auto_star.
Tactic Notation "splits" "*" constr(N) :=
splits N; auto_star.
Tactic Notation "destructs" "*" constr(T) :=
destructs T; auto_star.
Tactic Notation "destructs" "*" constr(N) constr(T) :=
destructs N T; auto_star.
Tactic Notation "branch" "*" constr(N) :=
branch N; auto_star.
Tactic Notation "branch" "*" constr(K) "of" constr(N) :=
branch K of N; auto_star.
Tactic Notation "branches" "*" constr(T) :=
branches T; auto_star.
Tactic Notation "branches" "*" constr(N) constr(T) :=
branches N T; auto_star.
Tactic Notation "exists_" "*" :=
exists_; auto_star.
Tactic Notation "exists" "*" constr(T1) :=
exists T1; auto_star.
Tactic Notation "exists" "*" constr(T1) constr(T2) :=
exists T1 T2; auto_star.
Tactic Notation "exists" "*" constr(T1) constr(T2) constr(T3) :=
exists T1 T2 T3; auto_star.
Tactic Notation "exists" "*" constr(T1) constr(T2) constr(T3) constr(T4) :=
exists T1 T2 T3 T4; auto_star.
Tactic Notation "exists" "*" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) :=
exists T1 T2 T3 T4 T5; auto_star.
Tactic Notation "exists" "*" constr(T1) constr(T2) constr(T3) constr(T4)
constr(T5) constr(T6) :=
exists T1 T2 T3 T4 T5 T6; auto_star.
Ltac sort_tactic :=
match goal with H: ?T |- _ =>
match type of T with Prop =>
generalizes H; (try sort_tactic); intro
end end.
Tactic Notation "sort" :=
sort_tactic.
Tactic Notation "clears" ident(X1) :=
let rec doit _ :=
match goal with
| H:context[X1] |- _ => clear H; try (doit tt)
| _ => clear X1
end in doit tt.
Tactic Notation "clears" ident(X1) ident(X2) :=
clears X1; clears X2.
Tactic Notation "clears" ident(X1) ident(X2) ident(X3) :=
clears X1; clears X2; clear X3.
Tactic Notation "clears" ident(X1) ident(X2) ident(X3) ident(X4) :=
clears X1; clears X2; clear X3; clear X4.
Tactic Notation "clears" ident(X1) ident(X2) ident(X3) ident(X4)
ident(X5) :=
clears X1; clears X2; clear X3; clear X4; clear X5.
Tactic Notation "clears" ident(X1) ident(X2) ident(X3) ident(X4)
ident(X5) ident(X6) :=
clears X1; clears X2; clear X3; clear X4; clear X5; clear X6.
Ltac clears_tactic :=
match goal with H: ?T |- _ =>
match type of T with
| Prop => generalizes H; (try clears_tactic); intro
| ?TT => clear H; (try clears_tactic)
| ?TT => generalizes H; (try clears_tactic); intro
end end.
Tactic Notation "clears" :=
clears_tactic.
Tactic Notation "clear_last" :=
match goal with H: ?T |- _ => clear H end.
Ltac clear_last_base n :=
match n with
| 0 => idtac
| S ?p => clear_last; clear_last_base p
end.
Tactic Notation "clear_last" constr(n) :=
clear_last_base n.
Ltac skip_with_existential :=
match goal with |- ?G =>
let H := fresh in evar(H:G); eexact H end.
Variable skip_axiom : False.
Ltac skip_with_axiom :=
assert False; [ apply skip_axiom | contradiction ].
Tactic Notation "skip" :=
skip_with_axiom.
Tactic Notation "skip'" :=
skip_with_existential.
Tactic Notation "skip" simple_intropattern(I) ":" constr(T) :=
asserts I: T; [ skip | ].
Tactic Notation "skip" ":" constr(T) :=
let H := fresh in skip H: T.
Tactic Notation "skip" simple_intropattern(I1)
simple_intropattern(I2) ":" constr(T) :=
skip [I1 I2]: T.
Tactic Notation "skip" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3) ":" constr(T) :=
skip [I1 [I2 I3]]: T.
Tactic Notation "skip" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) ":" constr(T) :=
skip [I1 [I2 [I3 I4]]]: T.
Tactic Notation "skip" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5) ":" constr(T) :=
skip [I1 [I2 [I3 [I4 I5]]]]: T.
Tactic Notation "skip" simple_intropattern(I1)
simple_intropattern(I2) simple_intropattern(I3)
simple_intropattern(I4) simple_intropattern(I5)
simple_intropattern(I6) ":" constr(T) :=
skip [I1 [I2 [I3 [I4 [I5 I6]]]]]: T.
Tactic Notation "skip_asserts" simple_intropattern(I) ":" constr(T) :=
skip I: T.
Tactic Notation "skip_asserts" ":" constr(T) :=
skip: T.
Tactic Notation "skip_cuts" constr(T) :=
cuts: T; [ skip | ].
Tactic Notation "skip_goal" ident(H) :=
match goal with |- ?G => skip H: G end.
Tactic Notation "skip_goal" :=
let IH := fresh "IH" in skip_goal IH.
Tactic Notation "skip_rewrite" constr(T) :=
let M := fresh in skip_asserts M: T; rewrite M; clear M.
Tactic Notation "skip_rewrite" constr(T) "in" hyp(H) :=
let M := fresh in skip_asserts M: T; rewrite M in H; clear M.
Tactic Notation "skip_rewrite_all" constr(T) :=
let M := fresh in skip_asserts M: T; rewrite_all M; clear M.
Tactic Notation "skip_induction" constr(E) :=
let IH := fresh "IH" in skip_goal IH; destruct E.
Tactic Notation "apply" "*" constr(H) :=
sapply H; auto_star.