Martin Escardo, 29 June 2018

To get closure under sums constructively, we need to restrict to
particular kinds of ordinals. Having a top element is a simple
sufficient condition, which holds in the applications we have in mind
(for compact ordinals).  Classically, ordinals with a top element are
precisely the successor ordinals. Constructively, β„•βˆž is an example of
an ordinal with a top element, which "is not" a successor ordinal, as
its top element is not isolated.

TODO. Generalize this from 𝓀₀ to an arbitrary universe. The
(practical) problem is that the type of natural numbers is defined at
𝓀₀. We could (1) either using universe lifting, or (2) define the type
in any universe (like we did for the the types 𝟘 and πŸ™). But (1) is
cumbersome and (2) requires much work in other modules.


\begin{code}

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

open import UF.FunExt

module Ordinals.ToppedArithmetic
        (fe : FunExt)
       where

open import CoNaturals.Type
open import MLTT.Spartan
open import Notation.CanonicalMap
open import Ordinals.Arithmetic fe
open import Ordinals.Injectivity
open import Ordinals.Notions
open import Ordinals.ToppedType fe
open import Ordinals.Type
open import Ordinals.Underlying
open import Ordinals.WellOrderArithmetic
open import TypeTopology.SquashedSum fe
open import UF.ClassicalLogic
open import UF.Subsingletons
open import UF.Subsingletons-FunExt
open import UF.SubtypeClassifier

private
 feβ‚€ = fe 𝓀₀ 𝓀₀

Ordα΅€ = Ordinalα΅€ 𝓀₀

succβ‚’ : Ordinal 𝓀 β†’ Ordinalα΅€ 𝓀
succβ‚’ Ξ± = Ξ± +β‚’ πŸ™β‚’  ,
          plus.top-preservation
           (underlying-order Ξ±)
           (underlying-order πŸ™β‚’)
           (prop.topped πŸ™ πŸ™-is-prop ⋆)

succβ‚’-is-trichotomous : (Ξ± : Ordinal 𝓀)
                      β†’ is-trichotomous Ξ±
                      β†’ is-trichotomous [ succβ‚’ Ξ± ]
succβ‚’-is-trichotomous Ξ± t = +β‚’-is-trichotomous Ξ± πŸ™β‚’ t πŸ™β‚’-is-trichotomous

πŸ™α΅’ πŸšα΅’ : Ordinalα΅€ 𝓀
πŸ™α΅’ = πŸ™β‚’ , prop.topped πŸ™ πŸ™-is-prop ⋆
πŸšα΅’ = succβ‚’ πŸ™β‚’

β„•βˆžα΅’ : Ordα΅€
β„•βˆžα΅’ = (β„•βˆžβ‚’ , ∞ , ∞-top)

\end{code}

Sum of an ordinal-indexed family of ordinals:

\begin{code}

βˆ‘ : (Ο„ : Ordinalα΅€ 𝓀) β†’ (⟨ Ο„ ⟩ β†’ Ordinalα΅€ 𝓀) β†’ Ordinalα΅€ 𝓀
βˆ‘ {𝓀} ((X , _<_ , o) , t) Ο… = ((Ξ£ x κž‰ X , ⟨ Ο… x ⟩) ,
                               Sum.order ,
                               Sum.well-order o (Ξ» x β†’ tis-well-ordered (Ο… x))) ,
                              Sum.top-preservation t
 where
  _β‰Ί_ : {x : X} β†’ ⟨ Ο… x ⟩ β†’ ⟨ Ο… x ⟩ β†’ 𝓀 Μ‡
  y β‰Ί z = y β‰ΊβŸ¨ Ο… _ ⟩ z

  module Sum = sum-top fe _<_ _β‰Ί_ (Ξ» x β†’ top (Ο… x)) (Ξ» x β†’ top-is-top (Ο… x))

βˆ‘-is-trichotomous : (Ο„ : Ordinalα΅€ 𝓀) (Ο… : ⟨ Ο„ ⟩ β†’ Ordinalα΅€ 𝓀)
                  β†’ is-trichotomous [ Ο„ ]
                  β†’ ((x : ⟨ Ο„ ⟩) β†’ is-trichotomous [ Ο… x ])
                  β†’ is-trichotomous [ βˆ‘ Ο„ Ο… ]
βˆ‘-is-trichotomous Ο„ Ο… = sum.trichotomy-preservation _ _

\end{code}

Added by Martin Escardo 2nd September 2026.

The top of the index is needed only for the sum to have a top, and the
sum over an index without one is still an ordinal.

\begin{code}

βˆ‘β‚’ : (Ξ± : Ordinal 𝓀) β†’ (⟨ Ξ± ⟩ β†’ Ordinalα΅€ 𝓀) β†’ Ordinal 𝓀
βˆ‘β‚’ {𝓀} (X , _<_ , o) Ο… = (Ξ£ x κž‰ X , ⟨ Ο… x ⟩) ,
                         Sum.order ,
                         Sum.well-order o (Ξ» x β†’ tis-well-ordered (Ο… x))
 where
  _β‰Ί_ : {x : X} β†’ ⟨ Ο… x ⟩ β†’ ⟨ Ο… x ⟩ β†’ 𝓀 Μ‡
  y β‰Ί z = y β‰ΊβŸ¨ Ο… _ ⟩ z

  module Sum = sum-top fe _<_ _β‰Ί_ (Ξ» x β†’ top (Ο… x)) (Ξ» x β†’ top-is-top (Ο… x))

βˆ‘-is-βˆ‘β‚’ : (Ο„ : Ordinalα΅€ 𝓀) (Ο… : ⟨ Ο„ ⟩ β†’ Ordinalα΅€ 𝓀)
        β†’ [ βˆ‘ Ο„ Ο… ] = βˆ‘β‚’ [ Ο„ ] Ο…
βˆ‘-is-βˆ‘β‚’ Ο„ Ο… = refl

\end{code}

End of addition.

Some restriction is needed to get extensionality of the lexicographic
order on sums. Two such restrictions are trichotomy and having
top. Without a restriction, the lexicographic order on the sum of an
ordinal-indexed family of ordinals need not be extensional, and asking
that it always be gives excluded middle, by Shulman's example in
Ordinals.ShulmanTaboo.

\begin{code}

Extensionality-of-Ordinal-Indexed-Sums : (𝓀 : Universe) β†’ 𝓀 ⁺ Μ‡
Extensionality-of-Ordinal-Indexed-Sums 𝓀 =
   (Ο„ : Ordinal 𝓀) (Ο… : ⟨ Ο„ ⟩ β†’ Ordinal 𝓀)
 β†’ is-extensional (sum.order
                    (underlying-order Ο„)
                    (Ξ» {x} β†’ underlying-order (Ο… x)))

module _ (pe : propext 𝓀₀) where

 open import Ordinals.OrdinalOfTruthValues fe 𝓀₀ pe
 open import Ordinals.ShulmanTaboo fe pe

 extensionality-of-ordinal-indexed-sums-gives-EM
  : Extensionality-of-Ordinal-Indexed-Sums 𝓀₁ β†’ EM 𝓀₀
 extensionality-of-ordinal-indexed-sums-gives-EM h = shulmans-taboo e
  where
   Ο… : ⟨ Ξ©β‚’ ⟩ β†’ Ordinal 𝓀₁
   Ο… p = prop-ordinal (Β¬ (p = βŠ₯)) (negations-are-props (fe 𝓀₁ 𝓀₀))

   _⊏_ : X β†’ X β†’ 𝓀₁ Μ‡
   _⊏_ = sum.order (underlying-order Ξ©β‚’) (Ξ» {p} β†’ underlying-order (Ο… p))

   lex-gives-β‰Ί : (z w : X) β†’ z ⊏ w β†’ z β‰Ί w
   lex-gives-β‰Ί z w (inl l)       = l
   lex-gives-β‰Ί z w (inr (r , l)) = 𝟘-elim l

   e : is-extensional _β‰Ί_
   e x y f g = h Ξ©β‚’ Ο… x y
                (Ξ» z l β†’ inl (f z (lex-gives-β‰Ί z x l)))
                (Ξ» z l β†’ inl (g z (lex-gives-β‰Ί z y l)))

\end{code}

Addition and multiplication can be reduced to βˆ‘, given the ordinal πŸšα΅’
defined above:

\begin{code}

_+α΅’_ : Ordinalα΅€ 𝓀 β†’ Ordinalα΅€ 𝓀 β†’ Ordinalα΅€ 𝓀
Ο„ +α΅’ Ο… = βˆ‘ πŸšα΅’ (cases (Ξ» _ β†’ Ο„) (Ξ» _ β†’ Ο…))

+α΅’-is-trichotomous : (Ο„ Ο… : Ordinalα΅€ 𝓀)
                   β†’ is-trichotomous [ Ο„ ]
                   β†’ is-trichotomous [ Ο… ]
                   β†’ is-trichotomous [ Ο„ +α΅’ Ο… ]
+α΅’-is-trichotomous Ο„ Ο… t u = βˆ‘-is-trichotomous πŸšα΅’ (cases (Ξ» _ β†’ Ο„) (Ξ» _ β†’ Ο…))
                              πŸšβ‚’-is-trichotomous
                              (dep-cases (Ξ» _ β†’ t) (Ξ» _ β†’ u))

_Γ—α΅’_ : Ordinalα΅€ 𝓀 β†’ Ordinalα΅€ 𝓀 β†’ Ordinalα΅€ 𝓀
Ο„ Γ—α΅’ Ο… = βˆ‘ Ο„  (Ξ» (_ : ⟨ Ο„ ⟩) β†’ Ο…)

Γ—α΅’-is-trichotomous : (Ο„ Ο… : Ordinalα΅€ 𝓀)
                   β†’ is-trichotomous [ Ο„ ]
                   β†’ is-trichotomous [ Ο… ]
                   β†’ is-trichotomous [ Ο„ Γ—α΅’ Ο… ]
Γ—α΅’-is-trichotomous Ο„ Ο… t u = βˆ‘-is-trichotomous Ο„ (Ξ» _ β†’ Ο…) t (Ξ» _ β†’ u)

\end{code}

Extension of a family X β†’ Ordα΅€ along an embedding j : X β†’ A to get a
family A β†’ Ordα΅€. (This can also be done for Ord-valued families.)
This uses the module InjectiveTypes.Blackboard to calculate Y / j.

Sum of a countable family with an added non-isolated top element. We
first extend the family to β„•βˆž and then take the ordinal-indexed sum of
ordinals defined above.

\begin{code}

open topped-ordinals-injectivity fe

βˆ‘ΒΉ : (β„• β†’ Ordα΅€) β†’ Ordα΅€
βˆ‘ΒΉ Ο„ = βˆ‘ β„•βˆžα΅’ (Ο„ β†— embedding-β„•-to-β„•βˆž feβ‚€)

\end{code}

And now with an isolated top element:

\begin{code}

βˆ‘β‚ : (β„• β†’ Ordα΅€) β†’ Ordα΅€
βˆ‘β‚ Ο„ = βˆ‘ (succβ‚’ Ο‰) (Ο„ β†— (over , over-embedding))

\end{code}

The sum with an isolated top element preserves trichotomy, because the
fibers of the map over are decidable. There is no such statement for
the sum with a non-isolated top element, because the fibers of the map
β„• β†’ β„•βˆž used there are decidable only under LPO.

\begin{code}

βˆ‘β‚-is-trichotomous : (Ο„ : β„• β†’ Ordα΅€)
                   β†’ ((n : β„•) β†’ is-trichotomous [ Ο„ n ])
                   β†’ is-trichotomous [ βˆ‘β‚ Ο„ ]
βˆ‘β‚-is-trichotomous Ο„ t = βˆ‘-is-trichotomous
                          (succβ‚’ Ο‰)
                          (Ο„ β†— (over , over-embedding))
                          (succβ‚’-is-trichotomous Ο‰ Ο‰-is-trichotomous)
                          (β†—-is-trichotomous Ο„
                            (over , over-embedding)
                            over-fibers-are-decidable
                            t)

\end{code}

Added 4th May 2022.

\begin{code}

module Omega {𝓀} (pe : propext 𝓀) where

 open import Ordinals.OrdinalOfTruthValues fe 𝓀 pe
 open import Ordinals.Notions
 open import UF.SubtypeClassifier

 Ξ©α΅’ : Ordinalα΅€ (𝓀 ⁺)
 Ξ©α΅’ = Ξ©β‚’ , ⊀ , h
  where
   h : is-top (underlying-order Ξ©β‚’) ⊀
   h y (p , _) = βŠ₯-is-not-⊀ (p ⁻¹)

\end{code}