Section Paradox.
(** ** Axiomatisation of impredicative universes in a Martin-Löf style *)
(** System U- has two impredicative universes. In the proof of the paradox they are slightly asymmetric (in particular the reduction rules of the small universe are not needed).  Therefore, the axioms are duplicated allowing for a weaker requirement than the actual system U-. *)
(** *** Large universe *)
Variable U1 : Type.
Variable El1 : U1 -> Type.
(** **** Closure by small product *)
Variable Forall1 : forall u:U1, (El1 u -> U1) -> U1.
Notation "'∀₁' x : A , B" := (Forall1 A (fun x => B)).
Notation "A '⟶₁' B" := (Forall1 A (fun _ => B)).
Variable lam1 : forall u B, (forall x:El1 u, El1 (B x)) -> El1 (∀₁ x:u, B x).
Notation "'λ₁' x , u" := (lam1 _ _ (fun x => u)).
Variable app1 : forall u B (f:El1 (Forall1 u B)) (x:El1 u), El1 (B x).
Notation "f '·₁' x" := (app1 _ _ f x).
Variable beta1 : forall u B (f:forall x:El1 u, El1 (B x)) x,
(λ₁ y, f y) ·₁ x = f x.
(** **** Closure by large products *)
(** [U1] only needs to quantify over itself. *)
Variable ForallU1 : (U1->U1) -> U1.
Notation "'∀₂' A , F" := (ForallU1 (fun A => F)).
Variable lamU1 : forall F, (forall A:U1, El1 (F A)) -> El1 (∀₂ A, F A).
Notation "'λ₂' x , u" := (lamU1 _ (fun x => u)).
Variable appU1 : forall F (f:El1(∀₂ A,F A)) (A:U1), El1 (F A).
Notation "f '·₁' [ A ]" := (appU1 _ f A).
Variable betaU1 : forall F (f:forall A:U1, El1 (F A)) A,
(λ₂ x, f x) ·₁ [ A ] = f A.
(** *** Small universe *)
(** The small universe is an element of the large one. *)
Variable u0 : U1.
Notation U0 := (El1 u0).
Variable El0 : U0 -> Type.
(** **** Closure by small product *)
(** [U0] does not need reduction rules *)
Variable Forall0 : forall u:U0, (El0 u -> U0) -> U0.
Notation "'∀₀' x : A , B" := (Forall0 A (fun x => B)).
Notation "A '⟶₀' B" := (Forall0 A (fun _ => B)).
Variable lam0 : forall u B, (forall x:El0 u, El0 (B x)) -> El0 (∀₀ x:u, B x).
Notation "'λ₀' x , u" := (lam0 _ _ (fun x => u)).
Variable app0 : forall u B (f:El0 (Forall0 u B)) (x:El0 u), El0 (B x).
Notation "f '·₀' x" := (app0 _ _ f x).
(** **** Closure by large products *)
Variable ForallU0 : forall u:U1, (El1 u->U0) -> U0.
Notation "'∀₀¹' A : U , F" := (ForallU0 U (fun A => F)).
Variable lamU0 : forall U F, (forall A:El1 U, El0 (F A)) -> El0 (∀₀¹ A:U, F A).
Notation "'λ₀¹' x , u" := (lamU0 _ _ (fun x => u)).
Variable appU0 : forall U F (f:El0(∀₀¹ A:U,F A)) (A:El1 U), El0 (F A).
Notation "f '·₀' [ A ]" := (appU0 _ _ f A).
(** ** Automating the rewrite rules of our encoding. *)
Local Ltac simplify :=
(* spiwack: ideally we could use [rewrite_strategy] here, but I am a tad scared of the idea of depending on setoid rewrite in such a simple file. *)
(repeat rewrite ?beta1, ?betaU1);
lazy beta.
Local Ltac simplify_in h :=
(repeat rewrite ?beta1, ?betaU1 in h);
lazy beta in h.
(** ** Hurkens's paradox. *)
(** An inhabitant of [U0] standing for [False]. *)
Variable F:U0.
(** *** Preliminary definitions *)
Definition V : U1 := ∀₂ A, ((A ⟶₁ u0) ⟶₁ A ⟶₁ u0) ⟶₁ A ⟶₁ u0.
Definition U : U1 := V ⟶₁ u0.
Definition sb (z:El1 V) : El1 V := λ₂ A, λ₁ r, λ₁ a, r ·₁ (z·₁[A]·₁r) ·₁ a.
Definition le (i:El1 (U⟶₁u0)) (x:El1 U) : U0 :=
x ·₁ (λ₂ A, λ₁ r, λ₁ a, i ·₁ (λ₁ v, (sb v) ·₁ [A] ·₁ r ·₁ a)).
Definition le' : El1 ((U⟶₁u0) ⟶₁ U ⟶₁ u0) := λ₁ i, λ₁ x, le i x.
Definition induct (i:El1 (U⟶₁u0)) : U0 :=
∀₀¹ x:U, le i x ⟶₀ i ·₁ x.
Definition WF : El1 U := λ₁ z, (induct (z·₁[U] ·₁ le')).
Definition I (x:El1 U) : U0 :=
(∀₀¹ i:U⟶₁u0, le i x ⟶₀ i ·₁ (λ₁ v, (sb v) ·₁ [U] ·₁ le' ·₁ x)) ⟶₀ F
.
(** *** Proof *)

Lemma lemma1 : El0 (induct (λ₁ u, I u)).