open import 1Lab.Prelude

open import Data.Partial.Total
open import Data.Partial.Base
open import Data.Vec.Base

open import Realisability.PCA

import Realisability.PCA.Sugar as S
module Realisability.Data.Pair {β„“} (𝔸@(A , _) : PCA β„“) where
open S 𝔸
private variable
  a b : β†― ⌞ 𝔸 ⌟

Pairs in a PCAπŸ”—

`true : ↯⁺ 𝔸
`true = val ⟨ x ⟩ ⟨ y ⟩ x

`false : ↯⁺ 𝔸
`false = val ⟨ x ⟩ ⟨ y ⟩ y

`pair : ↯⁺ 𝔸
`pair = val ⟨ a ⟩ ⟨ b ⟩ ⟨ i ⟩ i `· a `· b

`fst : ↯⁺ 𝔸
`fst = val ⟨ p ⟩ p `· `true

`snd : ↯⁺ 𝔸
`snd = val ⟨ p ⟩ p `· `false

abstract
  `true↓₁ : ⌞ a ⌟ β†’ ⌞ `true ⋆ a ⌟
  `true↓₁ x = subst ⌞_⌟ (sym (abs-Ξ²β‚™ [] ((_ , x) ∷ []))) (abs↓ _ _)

  `false↓₁ : ⌞ a ⌟ β†’ ⌞ `false .fst % a ⌟
  `false↓₁ ah = subst ⌞_⌟ (sym (abs-Ξ²β‚™ [] ((_ , ah) ∷ []))) (abs↓ _ _)

  `false-Ξ² : ⌞ a ⌟ β†’ ⌞ b ⌟ β†’ `false ⋆ a ⋆ b ≑ b
  `false-Ξ² {a} {b} ah bh = abs-Ξ²β‚™ [] ((b , bh) ∷ (a , ah) ∷ [])

  `true-Ξ² : ⌞ a ⌟ β†’ ⌞ b ⌟ β†’ `true ⋆ a ⋆ b ≑ a
  `true-Ξ² {a} {b} ah bh = abs-Ξ²β‚™ [] ((b , bh) ∷ (a , ah) ∷ [])

  `pair↓₂ : ⌞ a ⌟ β†’ ⌞ b ⌟ β†’ ⌞ `pair .fst % a % b ⌟
  `pair↓₂ {a} {b} ah bh = subst ⌞_⌟ (sym (abs-Ξ²β‚™ [] ((b , bh) ∷ (a , ah) ∷ []))) (abs↓ _ ((b , bh) ∷ (a , ah) ∷ []))

  `fst-Ξ² : ⌞ a ⌟ β†’ ⌞ b ⌟ β†’ `fst ⋆ (`pair ⋆ a ⋆ b) ≑ a
  `fst-Ξ² {a} {b} ah bh =
    `fst ⋆ (`pair ⋆ a ⋆ b)  β‰‘βŸ¨ abs-Ξ² _ [] (_ , `pair↓₂ ah bh) ⟩
    `pair ⋆ a ⋆ b ⋆ `true   β‰‘βŸ¨ abs-Ξ²β‚™ [] (`true ∷ (b , bh) ∷ (a , ah) ∷ []) ⟩
    `true ⋆ a ⋆ b           β‰‘βŸ¨ `true-Ξ² ah bh ⟩
    a                       ∎

  `snd-Ξ² : ⌞ a ⌟ β†’ ⌞ b ⌟ β†’ `snd ⋆ (`pair ⋆ a ⋆ b) ≑ b
  `snd-Ξ² {a} {b} ah bh =
    `snd ⋆ (`pair ⋆ a ⋆ b)  β‰‘βŸ¨ abs-Ξ² _ [] (_ , `pair↓₂ ah bh) ⟩
    `pair ⋆ a ⋆ b ⋆ `false  β‰‘βŸ¨ abs-Ξ²β‚™ [] (`false ∷ (b , bh) ∷ (a , ah) ∷ []) ⟩
    `false ⋆ a ⋆ b          β‰‘βŸ¨ `false-Ξ² ah bh ⟩
    b                       ∎