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.Data.Bool
import Realisability.PCA.Sugar
module Realisability.Data.Pair {β„“} (𝔸@(A , _) : PCA β„“) where
open Realisability.PCA.Sugar 𝔸
open Realisability.Data.Bool 𝔸
private variable
  a b : β†― ⌞ 𝔸 ⌟

Pairs in a PCAπŸ”—

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

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

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

abstract
  `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                       ∎