Evan Cavallo, 2nd July 2025, updated 3rd July 2025.

A proof that the natural numbers form a set that does not use a universe, in
response to a question asked by Naïm Favier on Mastodon:

 https://types.pl/@ncf/114779291760324789
 https://mathstodon.xyz/@ecavallo/114780841234656632

In Martin-Löf type theory without a universe or large elimination from ℕ, it is
impossible to prove that 0 ≠ 1:

 Jan M. Smith. The independence of Peano's fourth axiom from Martin-Löf's type
 theory without universes. The Journal of Symbolic Logic, Volume 53, Issue 3,
 September 1988, pp. 840–845. doi:10.2307/2274575.
 https://www.cse.chalmers.se/~smith/JSLPeano.pdf

Thus, we cannot take the usual route of showing that ℕ has decidable equality
and then applying Hedberg's theorem.

There are multiple proofs of the same result in this file: the first one is the
original, and the others are subsequent simplifications. At the end, there is
also a proof that if A is a set then List A is a set.

\begin{code}

{-# OPTIONS --safe --without-K #-}

open import MLTT.Id
open import MLTT.NaturalNumbers
open import MLTT.Pi
open import MLTT.Plus
open import MLTT.Sigma
open import MLTT.List
open import UF.Base using (ap₂)
open import UF.Hedberg
open import UF.Sets using (is-set)
open import UF.Subsingletons using (is-prop)
open import UF.Subsingletons-Properties using (props-are-sets)
open import Naturals.Properties using (pred)

module Various.NatIsSetWithoutUniverse where

\end{code}

First we show that if 0 = succ n for some n : ℕ, then ℕ is an h-proposition.
This will be used in all the proofs.

\begin{code}

[0=succ]-implies-ℕ-is-prop : {n : }  0  succ n  is-prop 
[0=succ]-implies-ℕ-is-prop eq m k = ap distinguish eq
 where
  distinguish :   
  distinguish 0 = m
  distinguish (succ _) = k

\end{code}

For the first proof we follow the standard proof that ℕ is a set from Hedberg's
theorem, but we use is-prop ℕ as a substitute for the empty type. This proof
strategy is inspired by Friedman's A-translation (or "Friedman's trick") from

 Harvey Friedman. Classically and intuitionistically provably recursive functions.
 In: Higher Set Theory. Lecture Notes in Mathematics, Volume 669, 1978, pp 21–27,
 doi:10.1007/BFb0103100.

Another option would be to use 0 = 1 instead of is-prop ℕ.

We can't show that ℕ has decidable equality, but we can show that any m,n : ℕ
are either equal or their equality would imply that ℕ is a proposition (thus
contractible):

\begin{code}

ℕ-=-holds-or-makes-ℕ-prop
 : (m n : )  (m  n) + ((m  n)  is-prop )
ℕ-=-holds-or-makes-ℕ-prop zero zero =
 inl refl
ℕ-=-holds-or-makes-ℕ-prop zero (succ n) =
 inr [0=succ]-implies-ℕ-is-prop
ℕ-=-holds-or-makes-ℕ-prop (succ m) zero =
 inr ([0=succ]-implies-ℕ-is-prop  _⁻¹)
ℕ-=-holds-or-makes-ℕ-prop (succ m) (succ n) =
 bump (ℕ-=-holds-or-makes-ℕ-prop m n)
 where
  bump : ((m  n) + ((m  n)  is-prop ))
        (succ m  succ n) + ((succ m  succ n)  is-prop )
  bump (inl eq) = inl (ap succ eq)
  bump (inr neq) = inr (neq  ap pred)

\end{code}

From this decision procedure we derive double "negation" elimination for
equality in ℕ in the usual way. Here, we need that our "empty type" is-prop ℕ
implies whatever equality in ℕ we need.

\begin{code}

ℕ-=-double-[to-is-prop]-elim-helper
 : (m n : )
  ((m  n) + ((m  n)  is-prop ))
  (((m  n)  is-prop )  is-prop )  m  n
ℕ-=-double-[to-is-prop]-elim-helper m n (inl eq) _ = eq
ℕ-=-double-[to-is-prop]-elim-helper m n (inr neq) nneq = nneq neq m n

ℕ-=-double-[to-is-prop]-elim
 : (m n : )  (((m  n)  is-prop )  is-prop )  m  n
ℕ-=-double-[to-is-prop]-elim m n =
 ℕ-=-double-[to-is-prop]-elim-helper m n (ℕ-=-holds-or-makes-ℕ-prop m n)

\end{code}

To apply a Hedberg-like argument, we will also need to know that double
"negation" elimination is weakly constant. Here, we need that our "empty type"
is-prop ℕ implies that all elements of identity types in ℕ are equal (i.e., ℕ is
a set).

If we assumed function extensionality, ((m = n) → is-prop ℕ) → is-prop ℕ) would
be a proposition and this would be immediate.

\begin{code}

ℕ-=-double-[to-is-prop]-elim-is-wconstant
 : (m n : )  wconstant (ℕ-=-double-[to-is-prop]-elim m n)
ℕ-=-double-[to-is-prop]-elim-is-wconstant m n =
 ℕ-=-double-[to-is-prop]-elim-helper-is-wconstant
  (ℕ-=-holds-or-makes-ℕ-prop m n)
 where
  ℕ-=-double-[to-is-prop]-elim-helper-is-wconstant
   : (dec : (m  n) + ((m  n)  is-prop ))
    wconstant (ℕ-=-double-[to-is-prop]-elim-helper m n dec)
  ℕ-=-double-[to-is-prop]-elim-helper-is-wconstant (inl eq) _ _ =
   refl
  ℕ-=-double-[to-is-prop]-elim-helper-is-wconstant (inr neq) nneq _ =
   props-are-sets (nneq neq) _ _

\end{code}

We can use the following variation on Hedberg's theorem to prove the main
result. (Although the type signature involves two universes, we use these
hypotheses only as types / type families.)

\begin{code}

reflexive-relation-that-wconstantly-implies-equality-gives-set
 : {X : 𝓤 ̇ }
  (_R_ : X  X  𝓥 ̇ )
  ((x : X)  x R x)
  (e : (x y : X)  x R y  x  y)
  ((x y : X)  wconstant (e x y))
  is-set X
reflexive-relation-that-wconstantly-implies-equality-gives-set
 {𝓤} {𝓥} {X} _R_ r e ec = γ
 where
  f : {x y :  X}  x  y  x  y
  f {x} {y} p = e x y (transport (x R_) p (r x))

  κ : {x y : X}  wconstant (f {x} {y})
  κ p q = ec _ _ _ _

  γ : is-set X
  γ = Id-collapsibles-are-sets (f , κ)

ℕ-is-set-without-universe : is-set 
ℕ-is-set-without-universe =
 reflexive-relation-that-wconstantly-implies-equality-gives-set
   m n  ((m  n)  is-prop )  is-prop )
   n neq  neq refl)
  ℕ-=-double-[to-is-prop]-elim
  ℕ-=-double-[to-is-prop]-elim-is-wconstant

\end{code}

The above proof can be shortened if we inline the Hedberg lemma. Upon inlining,
we see that "f" in the lemma above uses the transport in the family

  n : ℕ ⊢ ((m = n) → is-prop ℕ) → is-prop ℕ

of

  (λ neq → neq refl) : ((m = m) → is-prop ℕ) → is-prop ℕ

along some p : m = n. Using the usual simplifications of transport in function
and identity types, the result is equal to (λ neq → neq p). Making that
substitution, we have:

\begin{code}

ℕ-is-set-without-universe' : is-set 
ℕ-is-set-without-universe' =
  Id-collapsibles-are-sets
   (  p  ℕ-=-double-[to-is-prop]-elim _ _  neq  neq p))
   ,  p q  ℕ-=-double-[to-is-prop]-elim-is-wconstant _ _ _ _)
   )

\end{code}

Added by Evan Cavallo, 3rd July 2025.

We can give a significantly simpler proof that ℕ is a set by proving that ℕ's
identity types are collapsible directly by induction, rather going through a
"decision" procedure first.

Beware that Agda's coverage checker would let us leave out the "impossible"
cases of these inductions, but those omissions are not justified in MLTT without
a universe!

\begin{code}

ℕ-=-collapse : (m n : )  m  n  m  n
ℕ-=-collapse zero zero _ = refl
ℕ-=-collapse zero (succ n) p = [0=succ]-implies-ℕ-is-prop p _ _
ℕ-=-collapse (succ m) zero p = [0=succ]-implies-ℕ-is-prop (p ⁻¹) _ _
ℕ-=-collapse (succ m) (succ n) p = ap succ (ℕ-=-collapse m n (ap pred p))

ℕ-=-collapse-is-wconstant : (m n : )  wconstant (ℕ-=-collapse m n)
ℕ-=-collapse-is-wconstant zero zero _ _ = refl
ℕ-=-collapse-is-wconstant zero (succ n) p _  =
 props-are-sets ([0=succ]-implies-ℕ-is-prop p) _ _
ℕ-=-collapse-is-wconstant (succ m) zero p _ =
 props-are-sets ([0=succ]-implies-ℕ-is-prop (p ⁻¹)) _ _
ℕ-=-collapse-is-wconstant (succ m) (succ n) p q =
 ap (ap succ) (ℕ-=-collapse-is-wconstant m n (ap pred p) (ap pred q))

ℕ-is-Id-collapsible : Id-collapsible 
ℕ-is-Id-collapsible = (ℕ-=-collapse _ _ , ℕ-=-collapse-is-wconstant _ _)

ℕ-is-set-without-universe'' : is-set 
ℕ-is-set-without-universe'' = Id-collapsibles-are-sets ℕ-is-Id-collapsible

\end{code}

An advantage of the preceding proof is that we can apply the same argument to
types that we don't expect to have decidable equality (even with a universe).
For example, we can show that if A is a set then List A is a set:

\begin{code}

module _ {A : 𝓤 ̇ } (setA : is-set A) where

 [nil=cons]-implies-List-is-prop
  : {x : A} {xs : List A}  []  x  xs  is-prop (List A)
 [nil=cons]-implies-List-is-prop p ys zs = ap distinguish p
  where
   distinguish : List A  List A
   distinguish [] = ys
   distinguish (_  _) = zs

 safe-head : A  List A  A
 safe-head a [] = a
 safe-head a (x  xs) = x

 tail : List A  List A
 tail [] = []
 tail (x  xs) = xs

 List-=-collapse : (xs ys : List A)  xs  ys  xs  ys
 List-=-collapse [] [] p = refl
 List-=-collapse [] (y  ys) p = [nil=cons]-implies-List-is-prop p _ _
 List-=-collapse (x  xs) [] p = [nil=cons]-implies-List-is-prop (p ⁻¹) _ _
 List-=-collapse (x  xs) (y  ys) p =
  ap₂ _∷_ (ap (safe-head x) p) (List-=-collapse xs ys (ap tail p))

 List-=-collapse-is-wconstant
  : (xs ys : List A)  wconstant (List-=-collapse xs ys)
 List-=-collapse-is-wconstant [] [] p q = refl
 List-=-collapse-is-wconstant [] (y  ys) p q =
  props-are-sets ([nil=cons]-implies-List-is-prop p) _ _
 List-=-collapse-is-wconstant (x  xs) [] p q =
  props-are-sets ([nil=cons]-implies-List-is-prop (p ⁻¹)) _ _
 List-=-collapse-is-wconstant (x  xs) (y  ys) p q =
   ap₂
    (ap₂ _∷_)
    (setA _ _)
    (List-=-collapse-is-wconstant xs ys (ap tail p) (ap tail q))

 List-is-Id-collapsible : Id-collapsible (List A)
 List-is-Id-collapsible = (List-=-collapse _ _ , List-=-collapse-is-wconstant _ _)

 List-is-set-without-universe : is-set (List A)
 List-is-set-without-universe =
  Id-collapsibles-are-sets List-is-Id-collapsible

\end{code}