We define types expressing what ordinal exponentiation should be for zero,
successor and supremum exponents, and we record a few properties that follow
immediately follow from those specifications.

\begin{code}

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

open import UF.PropTrunc
open import UF.Size
open import UF.Univalence

module Ordinals.Exponentiation.Specification
       (ua : Univalence)
       (pt : propositional-truncations-exist)
       (sr : Set-Replacement pt)
       where

open import MLTT.Spartan
open import UF.FunExt
open import UF.UA-FunExt
open import UF.UniverseEmbedding

private
 fe : FunExt
 fe = Univalence-gives-FunExt ua

open import Ordinals.AdditionProperties ua
open import Ordinals.Arithmetic fe
open import Ordinals.Maps
open import Ordinals.MultiplicationProperties ua
open import Ordinals.OrdinalOfOrdinals ua
open import Ordinals.OrdinalOfOrdinalsSuprema ua
open import Ordinals.Type

open PropositionalTruncation pt
open suprema pt sr

\end{code}

In what follows F should be thought of as implementing ordinal exponentiation
with base ฮฑ, i.e. F ฮฒ produces the ordinal ฮฑ^ฮฒ.

The three requirements below, together with ๐Ÿ˜โ‚’^ฮฒ ๏ผ ๐Ÿ˜โ‚€ for ฮฒ โ‰  ๐Ÿ˜โ‚€, classically
*define* ordinal exponentiation.

\begin{code}

module _
        {๐“ค ๐“ฅ : Universe}
        (ฮฑ : Ordinal ๐“ค)
        (F : Ordinal ๐“ฅ โ†’ Ordinal (๐“ค โŠ” ๐“ฅ))
       where

 exp-specification-zero : (๐“ค โŠ” ๐“ฅ) โบ ฬ‡
 exp-specification-zero = F (๐Ÿ˜โ‚’ {๐“ฅ}) ๏ผ ๐Ÿ™โ‚’

 exp-specification-succ : (๐“ค โŠ” ๐“ฅ) โบ ฬ‡
 exp-specification-succ = (ฮฒ : Ordinal ๐“ฅ) โ†’ F (ฮฒ +โ‚’ ๐Ÿ™โ‚’) ๏ผ (F ฮฒ ร—โ‚’ ฮฑ)

 exp-specification-sup-generalized : (๐“ค โŠ” ๐“ฅ) โบ ฬ‡
 exp-specification-sup-generalized =
  ฮฑ โ‰  ๐Ÿ˜โ‚’ โ†’ {I : ๐“ฅ ฬ‡  } โ†’ โˆฅ I โˆฅ โ†’ (ฮฒ : I โ†’ Ordinal ๐“ฅ)
         โ†’ F (sup ฮฒ) ๏ผ sup (ฮป (i : Lift ๐“ค I) โ†’ F (ฮฒ (lower i)))

module _
        (ฮฑ : Ordinal ๐“ค)
        (F : Ordinal ๐“ค โ†’ Ordinal ๐“ค)
       where

 exp-specification-sup : ๐“ค โบ ฬ‡
 exp-specification-sup =
  ฮฑ โ‰  ๐Ÿ˜โ‚’ โ†’ {I : ๐“ค ฬ‡  } โ†’ โˆฅ I โˆฅ โ†’ (ฮฒ : I โ†’ Ordinal ๐“ค)
         โ†’ F (sup ฮฒ) ๏ผ sup (F โˆ˜ ฮฒ)

 exp-specification-sup-from-generalized : exp-specification-sup-generalized ฮฑ F
                                        โ†’ exp-specification-sup
 exp-specification-sup-from-generalized ฯƒ l {I} I-inh ฮฒ = ฯƒ l I-inh ฮฒ โˆ™ e
  where
   e : sup (F โˆ˜ ฮฒ โˆ˜ lower) ๏ผ sup (F โˆ˜ ฮฒ)
   e = โŠด-antisym _ _
        (sup-composition-โŠด lower (F โˆ˜ ฮฒ))
        (sup-composition-โŠด (lift ๐“ค) (F โˆ˜ ฮฒ โˆ˜ lower))

\end{code}

The following special cases follow directly from the specification.

\begin{code}

module _
        (ฮฑ : Ordinal ๐“ค)
        (exp-ฮฑ : Ordinal ๐“ค โ†’ Ordinal ๐“ค)
        (exp-zero : exp-specification-zero ฮฑ exp-ฮฑ)
        (exp-succ : exp-specification-succ ฮฑ exp-ฮฑ)
 where

 ๐Ÿ™โ‚’-neutral-exp : exp-ฮฑ ๐Ÿ™โ‚’ ๏ผ ฮฑ
 ๐Ÿ™โ‚’-neutral-exp =
  exp-ฮฑ ๐Ÿ™โ‚’             ๏ผโŸจ ap (exp-ฮฑ) (๐Ÿ˜โ‚’-left-neutral ๐Ÿ™โ‚’ โปยน)  โŸฉ
  exp-ฮฑ (๐Ÿ˜โ‚’ {๐“ค} +โ‚’ ๐Ÿ™โ‚’) ๏ผโŸจ exp-succ ๐Ÿ˜โ‚’ โŸฉ
  exp-ฮฑ (๐Ÿ˜โ‚’) ร—โ‚’ ฮฑ      ๏ผโŸจ ap (_ร—โ‚’ ฮฑ) exp-zero โŸฉ
  ๐Ÿ™โ‚’ ร—โ‚’ ฮฑ              ๏ผโŸจ ๐Ÿ™โ‚’-left-neutral-ร—โ‚’ ฮฑ โŸฉ
  ฮฑ                    โˆŽ

 exp-๐Ÿšโ‚’-is-ร—โ‚’ : exp-ฮฑ ๐Ÿšโ‚’ ๏ผ ฮฑ ร—โ‚’ ฮฑ
 exp-๐Ÿšโ‚’-is-ร—โ‚’ =
  exp-ฮฑ (๐Ÿ™โ‚’ +โ‚’ ๐Ÿ™โ‚’) ๏ผโŸจ exp-succ ๐Ÿ™โ‚’ โŸฉ
  exp-ฮฑ ๐Ÿ™โ‚’ ร—โ‚’ ฮฑ    ๏ผโŸจ ap (_ร—โ‚’ ฮฑ) ๐Ÿ™โ‚’-neutral-exp โŸฉ
  ฮฑ ร—โ‚’ ฮฑ           โˆŽ

\end{code}

The specification for suprema implies monotonicity.

\begin{code}

exp-is-monotone-in-exponent : (ฮฑ : Ordinal ๐“ค)
                              (exp-ฮฑ : Ordinal ๐“ฅ โ†’ Ordinal (๐“ค โŠ” ๐“ฅ))
                            โ†’ (ฮฑ โ‰  ๐Ÿ˜โ‚’)
                            โ†’ exp-specification-sup-generalized ฮฑ exp-ฮฑ
                            โ†’ is-monotone (OO ๐“ฅ) (OO (๐“ค โŠ” ๐“ฅ)) exp-ฮฑ
exp-is-monotone-in-exponent ฮฑ exp-ฮฑ ฮฝ exp-sup =
 is-monotone-if-continuous-generalized exp-ฮฑ (exp-sup ฮฝ)

\end{code}