open import Function
open import Data.List
open import Data.String renaming (_==_ to _==ˢ_)
open import Data.Nat.NP
open import Data.Maybe.NP
open import Data.Bool
import Level as L
import Category.Monad.Partiality.NP as Pa
open Pa using (_⊥; run_for_steps; now; later; never)
open import Coinduction
open import NomPa.Examples.Raw hiding (appⁿ)
open import NomPa.Examples.Raw.Parser
import Relation.Binary.PropositionalEquality as ≡
open ≡ using (_≡_)
module NomPa.Examples.BareDB where
infixl 4 _·_
data Tmᴮ : Set where
V : (x : ℕ) → Tmᴮ
ƛ : (t : Tmᴮ) → Tmᴮ
_·_ : (t u : Tmᴮ) → Tmᴮ
`_ : (κ : ℕ) → Tmᴮ
appⁿ : Tmᴮ → List Tmᴮ → Tmᴮ
appⁿ = foldl _·_
_ℕᴮ : ℕ → Tmᴮ
n ℕᴮ = ƛ (ƛ (replicapp n (V 1) (V 0)))
where replicapp : ℕ → Tmᴮ → Tmᴮ → Tmᴮ
replicapp zero t u = u
replicapp (suc n) t u = t · replicapp n t u
CTmᴮ = Tmᴮ
VCTmᴮ = Tmᴮ
shiftVCTmᴮ : (k : ℕ) → VCTmᴮ → VCTmᴮ
shiftVCTmᴮ k (V x) = V (x + k)
shiftVCTmᴮ _ t = t
substCVarTmᴮ : (θ : (x : ℕ) → CTmᴮ) → (ℓ : ℕ) → (x : ℕ) → VCTmᴮ
substCVarTmᴮ θ ℓ x = if suc x <= ℓ then V x else shiftVCTmᴮ ℓ (θ (x ∸ ℓ))
substCTmᴮ : ((x : ℕ) → CTmᴮ) → Tmᴮ → CTmᴮ
substCTmᴮ θ = ! 0 where
! : ℕ → Tmᴮ → CTmᴮ
! ℓ (V x) = substCVarTmᴮ θ ℓ x
! ℓ (t · u) = ! ℓ t · ! ℓ u
! ℓ (ƛ t) = ƛ (! (suc ℓ) t)
! _ (` κ) = ` κ
predWith : ∀ {A : Set} → A → (ℕ → A) → ℕ → A
predWith z _ 0 = z
predWith _ s (suc n) = s n
_[0≔_] : Tmᴮ → Tmᴮ → Tmᴮ
t [0≔ u ] = substCTmᴮ (predWith u V) t
module Parser where
module Tmᴿ⇒Tmᴮ where
Env : Set
Env = String → ℕ
extEnv : String → Env → Env
extEnv b Δ s = if b ==ˢ s then 0 else suc (Δ s)
! : Env → Tmᴿ → Tmᴮ
! Δ (V x) = V (Δ x)
! Δ (ƛ b t) = ƛ (! (extEnv b Δ) t)
! Δ (t · u) = ! Δ t · ! Δ u
conv? : Tmᴿ →? Tmᴮ
conv? = just ∘′ Tmᴿ⇒Tmᴮ.! (const 0)
open ParseConv conv? public renaming (parseConv? to parseTmᴮ?; parseConv to parseTmᴮ; TmOk to TmᴮOk)
open Parser public using (parseTmᴮ?; parseTmᴮ; TmᴮOk)
data Frame : Set where
arg fct : Tmᴮ → Frame
Stack = List Frame
module KAM where
_★_ : Tmᴮ → Stack → Tmᴮ ⊥
(t · u) ★ π = t ★ (arg u ∷ π)
(ƛ t) ★ (arg u ∷ π) = later (♯ (t [0≔ u ] ★ π))
v ★ [] = now v
v ★ (fct t ∷ π) = later (♯ (t ★ (arg v ∷ π)))
(` 1) ★ (arg (` n) ∷ π) = later (♯ (`(suc n) ★ π))
(` 1) ★ (arg u ∷ π) = later (♯ (u ★ (fct (` 1) ∷ π)))
_ ★ _ = never
runTmᴮℕ : Tmᴮ → Tmᴮ ⊥
runTmᴮℕ t = (t · ` 1 · ` 0) ★ []
module AAM where
_★_ : Tmᴮ → Stack → Tmᴮ ⊥
(t · u) ★ π = u ★ (fct t ∷ π)
(ƛ t) ★ (arg u ∷ π) = later (♯ (t [0≔ u ] ★ π))
v ★ [] = now v
v ★ (fct u ∷ π) = later (♯ (u ★ (arg v ∷ π)))
(` 1) ★ (arg (` n) ∷ π) = later (♯ (`(suc n) ★ π))
_ ★ _ = never
runTmᴮℕ : Tmᴮ → Tmᴮ ⊥
runTmᴮℕ t = (t · ` 1 · ` 0) ★ []
idᴮ : Tmᴮ
idᴮ = parseTmᴮ "λx.x"
trueᴮ : Tmᴮ
trueᴮ = parseTmᴮ "λx.λ_.x"
falseᴮ : Tmᴮ
falseᴮ = parseTmᴮ "λ_.λx.x"
pairᴮ : Tmᴮ
pairᴮ = parseTmᴮ "λx.λy.λf.f x y"
fstᴮ : Tmᴮ
fstᴮ = parseTmᴮ "λtrue.λp.p true" · trueᴮ
sndᴮ : Tmᴮ
sndᴮ = parseTmᴮ "λfalse.λp.p false" · falseᴮ
uncurryᴮ : Tmᴮ
uncurryᴮ = parseTmᴮ "λtrue.λfalse.λf.λp.f (p true) (p false)" · trueᴮ · falseᴮ
appᴮ : Tmᴮ
appᴮ = parseTmᴮ "λf.λx.f x"
compᴮ : Tmᴮ
compᴮ = parseTmᴮ "λf.λg.λx.f (g x)"
zeroᴮ : Tmᴮ
zeroᴮ = falseᴮ
sucᴮ : Tmᴮ
sucᴮ = parseTmᴮ "λn.λf.λx.n f (f x)"
addᴮ : Tmᴮ
addᴮ = parseTmᴮ "λsuc.λm.m suc" · sucᴮ
multᴮ : Tmᴮ
multᴮ = parseTmᴮ "λzero.λadd.λm.λn.m (add n) zero" · zeroᴮ · addᴮ
2+1ᴮ : Tmᴮ
2+1ᴮ = addᴮ · 2 ℕᴮ · 1 ℕᴮ
2×2ᴮ : Tmᴮ
2×2ᴮ = multᴮ · 2 ℕᴮ · 2 ℕᴮ
3×4ᴮ : Tmᴮ
3×4ᴮ = multᴮ · 3 ℕᴮ · 4 ℕᴮ
module KAMᴮ-tests where
open KAM using (_★_; runTmᴮℕ)
test-3×4 : run runTmᴮℕ 3×4ᴮ for 90 steps ≡ now (` 12)
test-3×4 = ≡.refl
module AAMᴮ-tests where
open AAM using (_★_; runTmᴮℕ)
test-3×4 : run runTmᴮℕ 3×4ᴮ for 124 steps ≡ now (` 12)
test-3×4 = ≡.refl