(** Can we state proof irrelevance from propositional degeneracy (i.e. propositional extensionality + excluded middle) without dependent case analysis ?  Berardi [[Berardi90]] built a model of CC interpreting inhabited types by the set of all untyped lambda-terms. This model satisfies propositional degeneracy without satisfying proof-irrelevance (nor dependent case analysis). This implies that the previous results cannot be refined.  [[Berardi90]] Stefano Berardi, "Type dependence and constructive mathematics", Ph. D. thesis, Dipartimento Matematica, Università di Torino, 1990. *)
(************************************************************************)
(** ** CC |- excluded-middle + dep elim on bool -> proof-irrelevance *)
(** This is a proof in the pure Calculus of Construction that classical logic in [Prop] + dependent elimination of disjunction entails proof-irrelevance.  Reference:  [[Coquand90]] T. Coquand, "Metamathematical Investigations of a Calculus of Constructions", Proceedings of Logic in Computer Science (LICS'90), 1990.  Proof skeleton: classical logic + dependent elimination of disjunction + discrimination of proofs implies the existence of a retract from [Prop] into [bool], hence inconsistency by encoding any paradox of system U- (e.g. Hurkens' paradox). *)
Section Proof_irrelevance_EM_CC.
Variable or : Prop -> Prop -> Prop.
Variable or_introl : forall A B:Prop, A -> or A B.
Variable or_intror : forall A B:Prop, B -> or A B.
Hypothesis or_elim : forall A B C:Prop, (A -> C) -> (B -> C) -> or A B -> C.
Hypothesis
or_elim_redl :
forall (A B C:Prop) (f:A -> C) (g:B -> C) (a:A),
f a = or_elim A B C f g (or_introl A B a).
Hypothesis
or_elim_redr :
forall (A B C:Prop) (f:A -> C) (g:B -> C) (b:B),
g b = or_elim A B C f g (or_intror A B b).
Hypothesis
or_dep_elim :
forall (A B:Prop) (P:or A B -> Prop),
(forall a:A, P (or_introl A B a)) ->
(forall b:B, P (or_intror A B b)) -> forall b:or A B, P b.
Hypothesis em : forall A:Prop, or A (~ A).
Variable B : Prop.
Variables b1 b2 : B.
(** [p2b] and [b2p] form a retract if [~b1=b2] *)
Let p2b A := or_elim A (~ A) B (fun _ => b1) (fun _ => b2) (em A).
Let b2p b := b1 = b.

Lemma p2p2 : b1 <> b2 -> forall A:Prop, b2p (p2b A) -> A.