module Algorithmic.Examples where
open import Utils using (*;_⇒_)
open import Relation.Binary.PropositionalEquality using (refl)
renaming (subst to substEq)
open import Type using (_,⋆_;_⇒_;Z;S;_⊢⋆_)
open _⊢⋆_
open import Type.BetaNormal using (_⊢Nf⋆_;_⊢Ne⋆_;embNf;ne)
open _⊢Nf⋆_
open _⊢Ne⋆_
open import Type.BetaNBE.RenamingSubstitution using (_[_]Nf)
import Type.RenamingSubstitution as ⋆
open import Algorithmic using (Ctx;∅;_⊢_;_∋_)
open _⊢_
open _∋_
open import Type.BetaNBE using (nf)
open import Type.BetaNBE.Stability using (stability)
From http://lucacardelli.name/Papers/Notes/scott2.pdf
M = μ X . G X G X = ∀ R. R → (X → R) → R) μ X . G X = ∀ X . (G X → X) → X – what is the status of this? N = G M in : N → M out : M → N
0 = Λ R . λ x : R . λ y : M → R . x : N succ = λ n : N . Λ R . λ x : R . λ y : M → R . y (in n) : N → N mycase = λ n : N . Λ R . λ a : R . λ f : N → N . n [R] a (f ∘ out) : N → ∀ R . R → (N → R) → R
–
-- bound variable names inserted below are not meaningful
module Scott where
_·Nf_ : ∀{Γ}{K J}
→ Γ ⊢Nf⋆ K ⇒ J
→ Γ ⊢Nf⋆ K
→ Γ ⊢Nf⋆ J
f ·Nf a = nf (embNf f · embNf a)
μ0 : ∀{Γ} → Γ ⊢Nf⋆ (* ⇒ *) ⇒ *
μ0 = ƛ (μ (ƛ (ƛ (ne (` Z · ne (` (S Z) · ne (` Z)))))) (ne (` Z)))
wrap0 : ∀{Φ Γ}
→ (A : Φ ⊢Nf⋆ * ⇒ *)
→ Γ ⊢ A ·Nf (μ0 ·Nf A)
→ Γ ⊢ μ0 ·Nf A
wrap0 A X rewrite stability A = wrap _ A X
unwrap0 : ∀{Φ Γ}
→ (A : Φ ⊢Nf⋆ * ⇒ *)
→ Γ ⊢ μ0 ·Nf A
→ Γ ⊢ A ·Nf (μ0 ·Nf A)
unwrap0 A X rewrite stability A = unwrap X refl
G : ∀{Γ} → Γ ,⋆ * ⊢Nf⋆ *
G = Π (ne (` Z) ⇒ (ne (` (S Z)) ⇒ ne (` Z)) ⇒ ne (` Z))
M : ∀{Γ} → Γ ⊢Nf⋆ *
M = μ0 ·Nf ƛ G
N : ∀{Γ} → Γ ⊢Nf⋆ *
N = G [ M ]Nf
Zero : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N
Zero = Λ (ƛ (ƛ (` (S (Z )))))
Succ : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N ⇒ N
Succ = ƛ (Λ (ƛ (ƛ (` Z · wrap0 (ƛ G) (` (S (S (T Z))))))))
One : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N
One = Succ · Zero
Two : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N
Two = Succ · One
Three : ∅ ⊢ N
Three = Succ · Two
Four : ∅ ⊢ N
Four = Succ · Three
mycase : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N ⇒ (Π (ne (` Z) ⇒ (N ⇒ ne (` Z)) ⇒ ne (` Z)))
mycase = ƛ (Λ (ƛ (ƛ (((` (S (S (T Z)))) ·⋆ ne (` Z) / refl) · (` (S Z)) · (ƛ (` (S Z) · unwrap0 (ƛ G) (` Z) ))))))
{-
Y-comb : ∀{Γ} → Γ ⊢ Π ((ne (` Z) ⇒ ne (` Z)) ⇒ ne (` Z))
Y-comb = Λ (ƛ ((ƛ (` (S Z) · (unwrap • refl (` Z) · (` Z)))) · wrap (ne (` Z) ⇒ ne (` (S Z))) • (ƛ (` (S Z) · (unwrap • refl (` Z) · (` Z)))) refl ))
-}
Z-comb : ∀{Φ}{Γ : Ctx Φ} →
Γ ⊢ Π (Π (((ne (` (S Z)) ⇒ ne (` Z)) ⇒ ne (` (S Z)) ⇒ ne (` Z)) ⇒ ne (` (S Z)) ⇒ ne (` Z)))
Z-comb = Λ (Λ (ƛ (ƛ (` (S Z) · ƛ (unwrap0 (ƛ (ne (` Z) ⇒ ne (` (S (S Z))) ⇒ ne (` (S Z)))) (` (S Z)) · ` (S Z) · ` Z)) · wrap0 (ƛ (ne (` Z) ⇒ ne (` (S (S Z))) ⇒ ne (` (S Z)))) (ƛ (` (S Z) · ƛ (unwrap0 (ƛ (ne (` Z) ⇒ ne (` (S (S Z))) ⇒ ne (` (S Z)))) (` (S Z)) · ` (S Z) · ` Z))))))
OnePlus : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ (N ⇒ N) ⇒ N ⇒ N
OnePlus = ƛ (ƛ ((((mycase · (` Z)) ·⋆ N / refl) · One) · (ƛ (Succ · (` (S (S Z)) · (` Z))))))
OnePlusOne : ∅ ⊢ N
OnePlusOne = ((Z-comb ·⋆ N / refl) ·⋆ N / refl) · OnePlus · One
-- Roman's more efficient version
Plus : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N ⇒ N ⇒ N
Plus = ƛ (ƛ (((Z-comb ·⋆ N / refl) ·⋆ N / refl) · (ƛ (ƛ ((((mycase · ` Z) ·⋆ N / refl) · ` (S (S (S Z)))) · (ƛ (Succ · (` (S (S Z)) · ` Z)))))) · ` (S Z)))
TwoPlusTwo : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N
TwoPlusTwo = (Plus · Two) · Two
eval (gas 10000000) Scott.Four
(done
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ (ƛ (ƛ (` (S Z)))))))))))))))))))))
.Term.Reduction.Value.V-Λ_)
eval (gas 10000000) Scott.Two
(done
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ
(ƛ
(ƛ
(( Z) ·
wrap (Π ( Z) ⇒ (( (S Z)) ⇒ ( Z)) ⇒ ( Z))
(Λ (ƛ (ƛ (` (S Z)))))))))))))
.Term.Reduction.Value.V-Λ_)
module Church where
N : ∀{Φ} → Φ ⊢Nf⋆ *
N = Π ((ne (` Z)) ⇒ (ne (` Z) ⇒ ne (` Z)) ⇒ (ne (` Z)))
Zero : ∅ ⊢ N
Zero = Λ (ƛ (ƛ (` (S Z))))
Succ : ∅ ⊢ N ⇒ N
Succ = ƛ (Λ (ƛ (ƛ (` Z · (((` (S (S (T Z)))) ·⋆ (ne (` Z)) / refl) · (` (S Z)) · (` Z))))))
Iter : ∅ ⊢ Π (ne (` Z) ⇒ (ne (` Z) ⇒ ne (` Z)) ⇒ N ⇒ ne (` Z))
Iter = Λ (ƛ (ƛ (ƛ (((` Z) ·⋆ ne (` Z) / refl) · (` (S (S Z))) · (` (S Z))))))
-- two plus two
One : ∅ ⊢ N
One = Succ · Zero
Two : ∅ ⊢ N
Two = Succ · One
Three : ∅ ⊢ N
Three = Succ · Two
Four : ∅ ⊢ N
Four = Succ · Three
Plus : ∅ ⊢ N → ∅ ⊢ N → ∅ ⊢ N
Plus x y = (Iter ·⋆ N / refl) · x · Succ · y -- by induction on the second y
TwoPlusTwo = Plus Two Two
TwoPlusTwo' : ∅ ⊢ N
TwoPlusTwo' = (Two ·⋆ N / refl) · Two · Succ
open Church public
– Church “4”
eval (gas 100000000) Four
(done
(Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) · (((Λ (ƛ (ƛ ( (S Z))))) ·⋆ ( Z)) · ( (S Z)) · ( Z)))))
·⋆ ( Z))
· ( (S Z))
· ( Z)))))
·⋆ ( Z))
· ( (S Z))
· ( Z)))))
·⋆ ( Z))
· ( (S Z))
· (` Z)))))
V-Λ_)
– Church “2 + 2” using iterator eval (gas 100000000) (Plus Two Two)
(done
(Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) ·
(((Λ
(ƛ
(ƛ
( Z) · (((Λ (ƛ (ƛ ( (S Z))))) ·⋆ ( Z)) · ( (S Z)) · ( Z)))))
·⋆ ( Z))
· ( (S Z))
· ( Z)))))
·⋆ ( Z))
· ( (S Z))
· ( Z)))))
·⋆ ( Z))
· ( (S Z))
· (` Z)))))
V-Λ_)
– Church “2 + 2” using the numerals directly eval (gas 10000000) (Two ·⋆ N · Two · Succ)
(done
(Λ
(ƛ
(ƛ
(( Z) ·
((((Λ
(ƛ
(ƛ
(( Z) ·
((((Λ
(ƛ
(ƛ
(( Z) ·
((((Λ
(ƛ
(ƛ
(( Z) ·
((((Λ (ƛ (ƛ ( (S Z))))) ·⋆ ( Z)) · ( (S Z))) · ( Z))))))
·⋆ ( Z))
· ( (S Z)))
· ( Z))))))
·⋆ ( Z))
· ( (S Z)))
· ( Z))))))
·⋆ ( Z))
· ( (S Z)))
· (` Z))))))
V-Λ_)