This file contains some examples of plutus core terms such as Church and Scott numerals and their respective addition operations.
module Declarative.Examples where
open import Agda.Builtin.Int using (pos) open import Relation.Binary.PropositionalEquality using (refl) open import Type using (_⊢⋆_;_∋⋆_;Z;S) open _⊢⋆_ import Type.RenamingSubstitution as ⋆ open import Type.Equality using (β≡β) open import Declarative using (Ctx;_⊢_;_∋_) open Ctx open _⊢_ open _∋_ open import Builtin using (addInteger) open import Builtin.Constant.Type using (TyCon;aInteger) open TyCon open import Declarative.Examples.StdLib.Function using (unwrap0;Z-comb) import Declarative.Examples.StdLib.ChurchNat using (inc;N;Succ;Zero;Iter) open import Type.Equality using (_≡β_) open _≡β_
integer = atomic aInteger module Builtins where open Declarative.Examples.StdLib.ChurchNat con2 : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ con (^ integer) con2 = con {A = ^ integer} (pos 2) (refl≡β (^ (atomic aInteger))) builtin2plus2 : ∅ ⊢ con (^ integer) builtin2plus2 = builtin addInteger · con2 · con2 builtininc2 : ∅ ⊢ con (^ integer) builtininc2 = inc · con2
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 -}
{- module ScottE where G : ∀{Γ} → Γ ,⋆ * ⊢⋆ * G = Π (` Z ⇒ (` (S Z) ⇒ ` Z) ⇒ ` Z) M : ∀{Γ} → Γ ⊢⋆ * M = μ G N : ∀{Γ} → Γ ⊢⋆ * N = G ⋆.[ M ] Zero : ∀{Γ} → Γ ⊢ N Zero = Λ (ƛ (ƛ (` (S (Z ))))) Succ : ∀{Γ} → Γ ⊢ N ⇒ N Succ = ƛ (Λ (ƛ (ƛ (` Z · wrap G • (` (S (S (T Z)))) refl)))) One : ∀{Γ} → Γ ⊢ N One = Succ · Zero Two : ∀{Γ} → Γ ⊢ N Two = Succ · One Three : ∅ ⊢ N Three = Succ · Two Four : ∅ ⊢ N Four = Succ · Three mycase : ∀{Γ} → Γ ⊢ N ⇒ (Π (` Z ⇒ (N ⇒ ` Z) ⇒ ` Z)) mycase = ƛ (Λ (ƛ (ƛ ((` (S (S (T Z)))) ·⋆ (` Z) · (` (S Z)) · (ƛ (` (S Z) · unwrap • refl (` Z))))))) -- Y : (a -> a) -> a -- Y f = (\x. f (x x)) (\x. f (x x)) -- Y f = (\x : mu x. x -> a. f (x x)) (\x : mu x. x -> a. f (x x)) Y-comb : ∀{Γ} → Γ ⊢ Π ((` Z ⇒ ` Z) ⇒ ` Z) Y-comb = Λ (ƛ ((ƛ (` (S Z) · (unwrap • refl (` Z) · (` Z)))) · wrap (` Z ⇒ ` (S Z)) • (ƛ (` (S Z) · (unwrap • refl (` Z) · (` Z)))) refl )) -- Z : ((a -> b) -> a -> b) -> a -> b -- Z f = (\r. f (\x. r r x)) (\r. f (\x. r r x)) -- Z f = (\r : mu x. x -> a -> b. (\x : a. r r x)) (\r : mu x. x -> a -> b. (\x : a. r r x)) Z-comb : ∀{Γ} → Γ ⊢ Π {- a -} (Π {- b -} (((` (S Z) ⇒ ` Z) ⇒ ` (S Z) ⇒ ` Z) ⇒ ` (S Z) ⇒ ` Z)) Z-comb = Λ {- a -} (Λ {- b -} (ƛ {- f -} (ƛ {- r -} (` (S Z) · ƛ {- x -} (unwrap • refl (` (S Z)) · ` (S Z) · ` Z)) · wrap (` Z ⇒ ` (S (S Z)) ⇒ ` (S Z)) • (ƛ {- r -} (` (S Z) · ƛ {- x -} (unwrap • refl (` (S Z)) · ` (S Z) · ` Z))) refl))) TwoPlus : ∀{Γ} → Γ ⊢ (N ⇒ N) ⇒ N ⇒ N TwoPlus = ƛ (ƛ ((((mycase · (` Z)) ·⋆ N) · Two) · (ƛ (Succ · (` (S (S Z)) · (` Z)))))) TwoPlusOne : ∅ ⊢ N -- TwoPlusTwo = Y-comb ·⋆ (N ⇒ N) · TwoPlus · Two TwoPlusOne = (Z-comb ·⋆ N) ·⋆ N · TwoPlus · One -- Roman's more efficient version Plus : ∀ {Γ} → Γ ⊢ N ⇒ N ⇒ N Plus = ƛ (ƛ ((Z-comb ·⋆ N) ·⋆ N · (ƛ (ƛ ((((mycase · ` Z) ·⋆ N) · ` (S (S (S Z)))) · (ƛ (Succ · (` (S (S Z)) · ` Z)))))) · ` (S Z))) TwoPlusTwo : ∅ ⊢ 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 Scott1 where open import Declarative.Examples.StdLib.Nat 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 ⇒ (Π (` Z ⇒ (N ⇒ ` Z) ⇒ ` Z)) mycase = ƛ (Λ (ƛ (ƛ (` (S (S (T Z))) ·⋆ ` Z · ` (S Z) · ƛ (` (S Z) · conv (β≡β _ _) (unwrap0 _ (` Z))))))) TwoPlus : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ (N ⇒ N) ⇒ N ⇒ N TwoPlus = ƛ (ƛ ((((mycase · (` Z)) ·⋆ N) · Two) · (ƛ (Succ · (` (S (S Z)) · (` Z)))))) TwoPlusOne : ∅ ⊢ N TwoPlusOne = (Z-comb ·⋆ N) ·⋆ N · TwoPlus · One -- Roman's more efficient version Plus : ∀{Φ}{Γ : Ctx Φ} → Γ ⊢ N ⇒ N ⇒ N Plus = ƛ (ƛ ((Z-comb ·⋆ N) ·⋆ N · (ƛ (ƛ ((((mycase · ` Z) ·⋆ N) · ` (S (S (S Z)))) · (ƛ (Succ · (` (S (S Z)) · ` Z)))))) · ` (S Z))) TwoPlusTwo : ∅ ⊢ N TwoPlusTwo = (Plus · Two) · Two
module Church where open Declarative.Examples.StdLib.ChurchNat -- 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 · x · Succ · y -- by induction on the second y TwoPlusTwo = Plus Two Two TwoPlusTwo' : ∅ ⊢ N TwoPlusTwo' = Two ·⋆ N · Two · Succ
{- -- 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-Λ_) -}