Source code on Githubopen import Prelude.Init; open SetAsType
open import Prelude.DecEq
open import Prelude.General
open import Prelude.Closures
open import Prelude.InferenceRules
open import Prelude.Decidable
open import Prelude.Membership
open import Prelude.Bifunctor
module ULC.Base (Atom : Type) ⦃ _ : DecEq Atom ⦄ where
open import Nominal Atom
data Term : Type where
`_ : Atom → Term
_·_ : Op₂ Term
ƛ_ : Abs Term → Term
{-# TERMINATING #-}
unquoteDecl Swap-Term = DERIVE Swap [ quote Term , Swap-Term ]
infix 30 `_
infixl 20 _·_
infixr 10 ƛ_
infixr 5 ƛ_⇒_
pattern ƛ_⇒_ x y = ƛ abs x y
variable
x y z w x′ y′ z′ w′ 𝕩 𝕪 𝕫 𝕨 : Atom
t t′ t″ L L′ M M′ N N′ M₁ M₂ : Term
t̂ t̂′ t̂″ : Abs Term
data TermShape : Type where
`∎ : TermShape
ƛ_ : TermShape → TermShape
_·_ : TermShape → TermShape → TermShape
shape : Term → TermShape
shape = λ where
(ƛ t) → ƛ shape (t .term)
(L · M) → shape L · shape M
(` _) → `∎
private
postulate 𝕒 𝕓 : Atom
_ : shape (ƛ 𝕒 ⇒ ƛ 𝕓 ⇒ ` 𝕒 · (` 𝕓 · ` 𝕒))
≡ (ƛ ƛ `∎ · (`∎ · `∎))
_ = refl
isVarShape isLamShape isAppShape : Pred₀ TermShape
isVarShape = λ where
`∎ → ⊤
_ → ⊥
isLamShape = λ where
(ƛ _) → ⊤
_ → ⊥
isAppShape = λ where
(_ · _) → ⊤
_ → ⊥
isƛ isApp isVar : Pred₀ Term
isƛ = isLamShape ∘ shape
isApp = isAppShape ∘ shape
isVar = isVarShape ∘ shape
unƛ : (t : Term) {_ : isƛ t} → Abs Term
unƛ (ƛ t̂) {tt} = t̂
unApp : (t : Term) {_ : isApp t} → Term × Term
unApp (L · M) {tt} = L , M
unVar : (t : Term) {_ : isVar t} → Atom
unVar (` v) {tt} = v
_≡⦅shape⦆_ = _≡_ on shape
app-shape≡ : (L · M) ≡⦅shape⦆ (L′ · M′) → (L ≡⦅shape⦆ L′) × (M ≡⦅shape⦆ M′)
app-shape≡ {L}{M}{L′}{M′} eq
with shape L | shape L′ | shape M | shape M′ | eq
... | _ | _ | _ | _ | refl = refl , refl
app-shape≡˘ : (L ≡⦅shape⦆ L′) → (M ≡⦅shape⦆ M′) → (L · M) ≡⦅shape⦆ (L′ · M′)
app-shape≡˘ {L}{M}{L′}{M′} L≡ M≡
with shape L | shape L′ | L≡
... | _ | _ | refl
with shape M | shape M′ | M≡
... | _ | _ | refl = refl
lam-shape≡ : (ƛ t̂) ≡⦅shape⦆ (ƛ t̂′) → t̂ .term ≡⦅shape⦆ t̂′ .term
lam-shape≡ {t̂}{t̂′} eq
with shape (t̂ .term) | shape (t̂′ .term) | eq
... | _ | _ | refl = refl
lam-shape≡˘ : t̂ .term ≡⦅shape⦆ t̂′ .term → (ƛ t̂) ≡⦅shape⦆ (ƛ t̂′)
lam-shape≡˘ {t̂}{t̂′} eq
with shape (t̂ .term) | shape (t̂′ .term) | eq
... | _ | _ | refl = refl
swap-shape≡ : ∀ x y t → t ≡⦅shape⦆ swap x y t
swap-shape≡ x y = λ where
(` _) → refl
(L · M) → app-shape≡˘ (swap-shape≡ x y L) (swap-shape≡ x y M)
(ƛ t̂) → lam-shape≡˘ {t̂}{swap x y t̂} $ swap-shape≡ x y (t̂ .term)
swap-shape : ∀ t t′ → t ≡⦅shape⦆ t′ → swap x y t ≡⦅shape⦆ swap x′ y′ t′
swap-shape t t′ = flip trans (swap-shape≡ _ _ t′)
∘ trans (sym $ swap-shape≡ _ _ t)
conc-shape : ∀ t̂ t̂′ → t̂ .term ≡⦅shape⦆ t̂′ .term → conc t̂ x ≡⦅shape⦆ conc t̂′ y
conc-shape t̂ t̂′ eq = swap-shape (t̂ .term) (t̂′ .term) eq
conc-shape≡ : ∀ t̂ → t̂ .term ≡⦅shape⦆ conc t̂ x
conc-shape≡ t̂ = swap-shape≡ _ _ (t̂ .term)