Set Implicit Arguments.
(*  The built-in "remember" tactic is weaker than this one! The built-in one can lead to "Error: The correctness of the conclusion relies on the body of a" where this one will succeed. [this comment may be obsolete, perhaps from Coq 8.2 or before Tactic Notation "remember" constr(a) "as" ident(x) := let x := fresh x in let H := fresh "Heq" x in (set (x:=a) in *; assert (H: x=a) by reflexivity; clearbody x). *)
Ltac simple_if_tac :=
match goal with |- context [if ?A then _ else _] =>
lazymatch type of A with
| bool => destruct A
| sumbool _ _ => fail "Use if_tac instead of simple_if_tac, since your expression "A" has type sumbool"
| ?t => fail "Use simple_if_tac only for bool; your expression"A" has type" t
end end.
Tactic Notation "if_tac" :=
match goal with |- context [if ?a then _ else _] =>
lazymatch type of a with
| sumbool _ _ =>destruct a as [?H | ?H]
| bool => fail "Use simple_if_tac instead of if_tac, since your expression"a" has type bool"
| ?t => fail "Use if_tac only for sumbool; your expression"a" has type" t
end end.
Tactic Notation "if_tac" simple_intropattern(H)
:= match goal with |- context [if ?a then _ else _] =>
lazymatch type of a with
| sumbool _ _ =>destruct a as H
| bool => fail "Use simple_if_tac instead of if_tac, since your expression"a" has type bool"
| ?t => fail "Use if_tac only for sumbool; your expression"a" has type" t
end end.
Tactic Notation "if_tac" "in" hyp(H0)
:= match type of H0 with context [if ?a then _ else _] =>
lazymatch type of a with
| sumbool _ _ =>destruct a as [?H | ?H]
| bool => fail "Use simple_if_tac instead of if_tac, since your expression"a" has type bool"
| ?t => fail "Use if_tac only for sumbool; your expression"a" has type" t
end end.
Tactic Notation "if_tac" simple_intropattern(H) "in" hyp(H1)
:= match type of H1 with context [if ?a then _ else _] =>
lazymatch type of a with
| sumbool _ _ =>destruct a as H
| bool => fail "Use simple_if_tac instead of if_tac, since your expression"a" has type bool"
| ?t => fail "Use if_tac only for sumbool; your expression"a" has type" t
end end.

(* Specifications: *)
Lemma predicate_max:
forall (F: nat -> Prop) (Fdec: forall n, {F n}+{~ F n}) n,
F 0%nat ->
~ F n ->
exists i, F i /\ (i<n)%nat /\ ~ F (S i).
Lemma sumbool_dec_iff: forall A B, {A} + {~A} -> (A <-> B) -> {B} + {~B}.
Lemma sumbool_dec_and: forall A B, {A} + {~A} -> {B} + {~B} -> {A /\ B} + {~(A /\ B)}.
Lemma sumbool_dec_or: forall A B, {A} + {~A} -> {B} + {~B} -> {A \/ B} + {~(A \/ B)}.
Ltac super_pattern t x :=
let t0 := fresh "t" in
set (t0 := t);
pattern x in t0;
cbv beta in (type of t0);
subst t0.