Ltac proof_irr := match goal with H: ?A, H' : ?A |- _ => generalize (proof_irr H H'); intro; subst H' end.Ltac inversion2 H1 H2 :=
 rewrite H1 in H2; symmetry in H2; inv H2.Ltac invT H :=
match type of H  with
  | existT _ ?a ?b = existT _ ?a ?c =>
     generalize (inj_pair2 _ _ a b c H); clear H; intro H; invT H
  | existT _ _ _ = existT _ _ _ =>
       let HH := fresh in (injection H; intros _ HH; invT HH; invT H)
  | _ => inv H
 end.Ltac invSome :=
 match goal with
 | H: match ?A with Some _ =>  _ | None => None end = Some _ |- _ =>
        let Hx := fresh in
               (revert H; case_eq A; [intros ? H Hx | intros H Hx]; inv Hx)
 | H: match ?A with Some _ => _  | None => False end |- _ =>
             (revert H; case_eq A; [intros ? H ? | intros; contradiction])

 | H: match ?A return _ with Some _ =>  _ | None => _ end eq_refl = Some _ |- _ =>
 let Hx := fresh in
           (revert H; generalize (eq_refl A); pattern A at 1 3; destruct A;
            [ intros Hx H | intros ? H; discriminate H])
 end.Ltac split3 := split; [|split].

(* Specifications: *)
Lemma if_true: forall (A: Prop) (E: {A}+{~A}) (T: Type) (B C: T), A -> (if E then B else C) = B.
Lemma if_false: forall (A: Prop) (E: {A}+{~A}) (T: Type) (B C: T), ~A -> (if E then B else C) = C.