(** The [paradox] tactic can be called as a shortcut to use the paradox. *)
Ltac paradox h :=
unshelve (refine ((fun h => _) (paradox _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ))).
End Generic.
(** * Impredicative universes are not retracts. *)
(** There can be no retract to an impredicative Coq universe from a smaller type. In this version of the proof, the impredicativity of the universe is postulated with a pair of functions from the universe to its type and back which commute with dependent product in an appropriate way. *)
Module NoRetractToImpredicativeUniverse.
Section Paradox.
Let      U2    := Type.
Let      U1:U2 := Type.
Variable U0:U1.
(** *** [U1] is impredicative *)
Variable u22u1 : U2 -> U1.
Hypothesis u22u1_unit   : forall (c:U2), c -> u22u1 c.
(** [u22u1_counit] and [u22u1_coherent] only apply to dependent product so that the equations happen in the smaller [U1] rather than [U2].  Indeed, it is not generally the case that one can project from a large universe to an impredicative universe and then get back the original type again. It would be too strong a hypothesis to require (in particular, it is not true of [Prop]). The formulation is reminiscent of the monadic characteristic of the projection from a large type to [Prop].*)
Hypothesis u22u1_counit : forall (F:U1->U1), u22u1 (forall A,F A) -> (forall A,F A).
Hypothesis u22u1_coherent : forall (F:U1 -> U1) (f:forall x:U1, F x) (x:U1),
u22u1_counit _ (u22u1_unit _ f) x = f x.
(** *** [U0] is a retract of [U1] *)
Variable u02u1 : U0 -> U1.
Variable u12u0 : U1 -> U0.
Hypothesis u12u0_unit   : forall (b:U1), b -> u02u1 (u12u0 b).
Hypothesis u12u0_counit : forall (b:U1), u02u1 (u12u0 b) -> b.
(** ** Paradox *)

Theorem paradox : forall F:U1, F.
End Paradox.