module Realisability.Data.Sum {β„“} (𝔸 : PCA β„“) where

Sums in a PCAπŸ”—

We define an encoding for sum types in a partial combinatory algebra in terms of the encoding for booleans and pairs in a PCA. The constructors will be defined to simply pair a value with a distinguishable tag.

`inl : ↯⁺ ⌞ 𝔸 ⌟
`inl = val ⟨ x ⟩ (`true `, x)

`inr : ↯⁺ ⌞ 𝔸 ⌟
`inr = val ⟨ x ⟩ (`false `, x)

We can define a β€˜pattern-matching’ program by conditional. Note the slightly fancy β€˜higher-order’ nature of this definition, which computes the function to apply by conditional. Of course, when given enough arguments, this is equivalent to pushing the application onto the branches.

`match : ↯⁺ ⌞ 𝔸 ⌟
`match = val ⟨ f ⟩ ⟨ g ⟩ ⟨ s ⟩ (`if (`fst `· s) then f else g) `· (`snd `· s)

As usual we can prove that the constructors are defined when applied to an argument, as is the matching function when applied to two, and that pattern matching computes as expected.

abstract
  `inl↓₁ : ⌞ x ⌟ β†’ ⌞ `inl ⋆ x ⌟
  `inl↓₁ {x} hx = subst ⌞_⌟ (sym (abs-Ξ² _ [] (x , hx))) (`pair↓₂ (`true .snd) hx)

  `inr↓₁ : ⌞ x ⌟ β†’ ⌞ `inr ⋆ x ⌟
  `inr↓₁ {x} hx = subst ⌞_⌟ (sym (abs-Ξ² _ [] (x , hx))) (`pair↓₂ (`false .snd) hx)

  `match↓₂ : ⌞ f ⌟ β†’ ⌞ g ⌟ β†’ ⌞ `match ⋆ f ⋆ g ⌟
  `match↓₂ {f = f} {g} hf hg = subst ⌞_⌟ (sym (abs-Ξ²β‚™ [] ((g , hg) ∷ (f , hf) ∷ []))) (abs↓ _ _)

  `match-Ξ²l
    : ⌞ x ⌟ β†’ ⌞ f ⌟ β†’ ⌞ g ⌟
    β†’ `match ⋆ f ⋆ g ⋆ (`inl ⋆ x) ≑ f ⋆ x
  `match-Ξ²l {x = x} {f} {g} hx hf hg =
    `match ⋆ f ⋆ g ⋆ (`inl ⋆ x)                                        β‰‘βŸ¨ abs-Ξ²β‚™ [] ((`inl ⋆ x , `inl↓₁ hx) ∷ (g , hg) ∷ (f , hf) ∷ []) βŸ©β‰‘
    `fst ⋆ ⌜ `inl ⋆ x ⌝ ⋆ f ⋆ g ⋆ (`snd ⋆ ⌜ `inl ⋆ x ⌝)                β‰‘βŸ¨ ap! (abs-Ξ² _ [] (x , hx)) βŸ©β‰‘
    `fst ⋆ (`pair ⋆ `true ⋆ x) ⋆ f ⋆ g ⋆ (`snd ⋆ (`pair ⋆ `true ⋆ x))  β‰‘βŸ¨ apβ‚‚ (Ξ» e p β†’ e % f % g % p) (`fst-Ξ² (`true .snd) hx) (`snd-Ξ² (`true .snd) hx) βŸ©β‰‘
    `true ⋆ f ⋆ g ⋆ x                                                  β‰‘βŸ¨ ap (Ξ» e β†’ e ⋆ x) (`true-Ξ² hf hg) βŸ©β‰‘
    f ⋆ x                                                              ∎

  `match-Ξ²r
    : ⌞ x ⌟ β†’ ⌞ f ⌟ β†’ ⌞ g ⌟
    β†’ `match ⋆ f ⋆ g ⋆ (`inr ⋆ x) ≑ g ⋆ x
  `match-Ξ²r {x = x} {f} {g} hx hf hg =
    `match ⋆ f ⋆ g ⋆ (`inr ⋆ x)                                          β‰‘βŸ¨ abs-Ξ²β‚™ [] ((`inr ⋆ x , `inr↓₁ hx) ∷ (g , hg) ∷ (f , hf) ∷ []) βŸ©β‰‘
    `fst ⋆ ⌜ `inr ⋆ x ⌝ ⋆ f ⋆ g ⋆ (`snd ⋆ ⌜ `inr ⋆ x ⌝)                  β‰‘βŸ¨ ap! (abs-Ξ² _ [] (x , hx)) βŸ©β‰‘
    `fst ⋆ (`pair ⋆ `false ⋆ x) ⋆ f ⋆ g ⋆ (`snd ⋆ (`pair ⋆ `false ⋆ x))  β‰‘βŸ¨ apβ‚‚ (Ξ» e p β†’ e % f % g % p) (`fst-Ξ² (`false .snd) hx) (`snd-Ξ² (`false .snd) hx) βŸ©β‰‘
    `false ⋆ f ⋆ g ⋆ x                                                   β‰‘βŸ¨ ap (Ξ» e β†’ e ⋆ x) (`false-Ξ² hf hg) βŸ©β‰‘
    g ⋆ x                                                                ∎