module SF.PHOAS where

open import Agda.Primitive using (_โŠ”_)

module Prelude where

  infixr 3 โˆƒ๐‘ ๐‘ก
  infixl 5 _โˆจ_
  infixr 20 _โˆท_
  
  data ๐”น : Set where
    T : ๐”น
    F : ๐”น

  data _โˆจ_ {โ„“โ‚ โ„“โ‚‚} (A : Set โ„“โ‚) (B : Set โ„“โ‚‚) : Set (โ„“โ‚ โŠ” โ„“โ‚‚) where
    Inl : A โ†’ A โˆจ B
    Inr : B โ†’ A โˆจ B

  syntax โˆƒ๐‘ ๐‘ก A (ฮป x โ†’ B) = โˆƒ x โฆ‚ A ๐‘ ๐‘ก B
  data โˆƒ๐‘ ๐‘ก {โ„“โ‚ โ„“โ‚‚} (A : Set โ„“โ‚) (B : A โ†’ Set โ„“โ‚‚) : Set (โ„“โ‚ โŠ” โ„“โ‚‚) where
    โŸจโˆƒ_,_โŸฉ : โˆ€ (x : A) โ†’ B x โ†’ โˆƒ x โฆ‚ A ๐‘ ๐‘ก B x

  data โŸฌ_โŸญ {โ„“} (A : Set โ„“) : Set โ„“ where
    [] : โŸฌ A โŸญ
    _โˆท_ : A โ†’ โŸฌ A โŸญ โ†’ โŸฌ A โŸญ

open Prelude

data type : Set where
  _โŸจโ†’โŸฉ_ : type โ†’ type โ†’ type

data exp-phoas (var : type โ†’ โŸฌ type โŸญ โ†’ Set) : โˆ€ (ฮ“ : โŸฌ type โŸญ) (ฯ„ : type) โ†’ Set where
  Var : โˆ€ {ฮ“ ฯ„}
    (x : var ฯ„ ฮ“)
    โ†’ exp-phoas var ฮ“ ฯ„
  โŸจฮปโŸฉ : โˆ€ {ฮ“ ฯ„โ‚ ฯ„โ‚‚}
    (e : var ฯ„โ‚ (ฯ„โ‚ โˆท ฮ“) โ†’ exp-phoas var (ฯ„โ‚ โˆท ฮ“) ฯ„โ‚‚)
    โ†’ exp-phoas var ฮ“ (ฯ„โ‚ โŸจโ†’โŸฉ ฯ„โ‚‚)
  _โŸจโ‹…โŸฉ_ : โˆ€ {ฮ“ ฯ„โ‚ ฯ„โ‚‚}
    (eโ‚ : exp-phoas var ฮ“ (ฯ„โ‚ โŸจโ†’โŸฉ ฯ„โ‚‚))
    (eโ‚‚ : exp-phoas var ฮ“ ฯ„โ‚)
    โ†’ exp-phoas var ฮ“ ฯ„โ‚‚

infix 10 _โˆˆ_
data _โˆˆ_ {โ„“} {A : Set โ„“} (x : A) : โˆ€ (xs : โŸฌ A โŸญ) โ†’ Set โ„“ where
  Z : โˆ€ {xs} โ†’ x โˆˆ x โˆท xs
  S : โˆ€ {xโ€ฒ xs} โ†’ x โˆˆ xs โ†’ x โˆˆ xโ€ฒ โˆท xs

infix 10 _โŠข_
data _โŠข_ : โˆ€ (ฮ“ : โŸฌ type โŸญ) (ฯ„ : type) โ†’ Set where
  Var : โˆ€ {ฮ“ ฯ„}
    (x : ฯ„ โˆˆ ฮ“)
    โ†’ ฮ“ โŠข ฯ„
  โŸจฮปโŸฉ : โˆ€ {ฮ“ ฯ„โ‚ ฯ„โ‚‚}
    (e : ฯ„โ‚ โˆท ฮ“ โŠข ฯ„โ‚‚)
    โ†’ ฮ“ โŠข ฯ„โ‚ โŸจโ†’โŸฉ ฯ„โ‚‚
  _โŸจโ‹…โŸฉ_ : โˆ€ {ฮ“ ฯ„โ‚ ฯ„โ‚‚}
    (eโ‚ : ฮ“ โŠข ฯ„โ‚ โŸจโ†’โŸฉ ฯ„โ‚‚)
    (eโ‚‚ : ฮ“ โŠข ฯ„โ‚)
    โ†’ ฮ“ โŠข ฯ„โ‚‚

โŸฆ_โŸงโ‚ : โˆ€ {ฮ“ ฯ„} (e : exp-phoas _โˆˆ_ ฮ“ ฯ„) โ†’ ฮ“ โŠข ฯ„
โŸฆ Var x โŸงโ‚ = Var x
โŸฆ โŸจฮปโŸฉ e โŸงโ‚ = โŸจฮปโŸฉ โŸฆ e Z โŸงโ‚
โŸฆ eโ‚ โŸจโ‹…โŸฉ eโ‚‚ โŸงโ‚ = โŸฆ eโ‚ โŸงโ‚ โŸจโ‹…โŸฉ โŸฆ eโ‚‚ โŸงโ‚

โŸฆ_โŸงโ‚‚ : โˆ€ {ฮ“ ฯ„} (e : ฮ“ โŠข ฯ„) โ†’ exp-phoas _โˆˆ_ ฮ“ ฯ„
โŸฆ Var x โŸงโ‚‚ = Var x
โŸฆ โŸจฮปโŸฉ e โŸงโ‚‚ = โŸจฮปโŸฉ (ฮป _ โ†’ โŸฆ e โŸงโ‚‚)
โŸฆ eโ‚ โŸจโ‹…โŸฉ eโ‚‚ โŸงโ‚‚ = โŸฆ eโ‚ โŸงโ‚‚ โŸจโ‹…โŸฉ โŸฆ eโ‚‚ โŸงโ‚‚