Last active
February 23, 2018 00:11
-
-
Save scott-fleischman/b5bd1c13fb682b85e97ebf69e1861f2b to your computer and use it in GitHub Desktop.
OPLSS 2014 - My reworkings of Ulf Norell's Introduction to Agda
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module _ where | |
data πΉ : Set where | |
true false : πΉ | |
if_then_else_ : {A : Set} (b : πΉ) (t f : A) β A | |
if true then t else f = t | |
if false then t else f = f | |
data β : Set where | |
zero : β | |
suc : β β β | |
{-# BUILTIN NATURAL β #-} | |
_+_ : (m n : β) β β | |
zero + n = n | |
suc m + n = suc (m + n) | |
data List (A : Set) : Set where | |
[] : List A | |
_β·_ : (x : A) (xs : List A) β List A | |
infixr 5 _β·_ | |
infixl 3 _β_ | |
data _β_ {A : Set} (x : A) : List A β Set where | |
zero : {xs : List A} β x β x β· xs | |
suc : {y : A} {xs : List A} (p : x β xs) β x β y β· xs | |
lookup : {A : Set} {x : A} {xs : List A} (i : x β xs) β A | |
lookup {x = x} zero = x | |
lookup (suc i) = lookup i | |
data All {A : Set} (P : A β Set) : List A β Set where | |
[] : All P [] | |
_β·_ : {xs : List A} {x : A} (px : P x) (pxs : All P xs) β All P (x β· xs) | |
lookup-all : {A : Set} {x : A} {xs : List A} {P : A β Set} (i : x β xs) (a : All P xs) β P x | |
lookup-all zero (px β· pxs) = px | |
lookup-all (suc i) (px β· pxs) = lookup-all i pxs | |
data Type : Set where | |
nat bool : Type | |
data Expr (Ξ : List Type) : Type β Set where | |
var : {x : Type} (i : x β Ξ) β Expr Ξ x | |
value : (n : β) β Expr Ξ nat | |
true false : Expr Ξ bool | |
add : (m n : Expr Ξ nat) β Expr Ξ nat | |
if : {r : Type} (b : Expr Ξ bool) (t f : Expr Ξ r) β Expr Ξ r | |
Value : Type β Set | |
Value nat = β | |
Value bool = πΉ | |
eval : {t : Type} {Ξ : List Type} (env : All Value Ξ) (expr : Expr Ξ t) β Value t | |
eval env (var i) = lookup-all i env | |
eval env (value n) = n | |
eval env true = true | |
eval env false = false | |
eval env (add m n) = eval env m + eval env n | |
eval env (if b t f) = if (eval env b) then (eval env t) else (eval env f) | |
module Test where | |
open import Agda.Builtin.Equality | |
Ξ : List Type | |
Ξ = bool β· bool β· nat β· [] | |
env : All Value Ξ | |
env = true β· false β· 21 β· [] | |
p1 : eval env (add (value 10) (if (var zero) (var (suc (suc zero))) (value 6))) β‘ 31 | |
p1 = refl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module _ where | |
data β₯ : Set where | |
β₯-elim : {A : Set} β β₯ β A | |
β₯-elim () | |
open import Agda.Builtin.Bool | |
open import Agda.Builtin.Equality | |
open import Agda.Builtin.Nat hiding (_+_) renaming (Nat to β) | |
open import Agda.Builtin.String | |
cong : {A B : Set} (f : A β B) {x y : A} (eq : x β‘ y) β f x β‘ f y | |
cong f refl = refl | |
sym : {A : Set} {x y : A} (eq : x β‘ y) β y β‘ x | |
sym refl = refl | |
data List (A : Set) : Set where | |
[] : List A | |
_β·_ : (x : A) (xs : List A) β List A | |
infixr 5 _β·_ | |
record _Γ_ (A B : Set) : Set where | |
constructor _,_ | |
field | |
fst : A | |
snd : B | |
record Ξ£ (A : Set) (B : A β Set) : Set where | |
constructor _,_ | |
field | |
fst : A | |
snd : B fst | |
data _+_ (A B : Set) : Set where | |
inl : A β A + B | |
inr : B β A + B | |
over-inr : {A B1 B2 : Set} (f : B1 β B2) (e : A + B1) β A + B2 | |
over-inr f (inl x) = inl x | |
over-inr f (inr x) = inr (f x) | |
data Dec {A : Set} (x y : A) : Set where | |
eq : x β‘ y β Dec x y | |
neq : (x β‘ y β β₯) β Dec x y | |
_>>=_ : {A B C : Set} β A + B β (B β A + C) β A + C | |
inl x >>= f = inl x | |
inr x >>= f = f x | |
dec-string : (x y : String) β Dec x y | |
dec-string x y with primStringEquality x y | |
dec-string x y | false = neq (β₯-elim trustme) where postulate trustme : β₯ | |
dec-string x y | true = eq primTrustMe where open import Agda.Builtin.TrustMe | |
data All {A : Set} (P : A β Set) : List A β Set where | |
[] : All P [] | |
_β·_ : {x : A} {xs : List A} (px : P x) (pxs : All P xs) β All P (x β· xs) | |
data Any {A : Set} (P : A β Set) : List A β Set where | |
zero : {x : A} {xs : List A} β Any P (x β· xs) | |
suc : {x : A} {xs : List A} (p : Any P xs) β Any P (x β· xs) | |
_β_ : {A : Set} (x : A) (xs : List A) β Set | |
x β xs = Any (x β‘_) xs | |
data Type : Set where | |
Nat : Type | |
_β_ : (A B : Type) β Type | |
injlβ : {A B C D : Type} β (A β B) β‘ (C β D) -> A β‘ C | |
injlβ refl = refl | |
injrβ : {A B C D : Type} β (A β B) β‘ (C β D) -> B β‘ D | |
injrβ refl = refl | |
dec-type : (S T : Type) β Dec S T | |
dec-type Nat Nat = eq refl | |
dec-type Nat (T β Tβ) = neq (Ξ» ()) | |
dec-type (S β Sβ) Nat = neq (Ξ» ()) | |
dec-type (S β T) (P β Q) with dec-type S P | |
dec-type (S β T) (P β Q) | eq p rewrite p with dec-type T Q | |
dec-type (S β T) (P β Q) | eq p | eq q rewrite q = eq refl | |
dec-type (S β T) (P β Q) | eq p | neq q = neq Ξ» r β q (injrβ r) | |
dec-type (S β T) (P β Q) | neq p = neq Ξ» r β p (injlβ r) | |
data TermU : Set where | |
var : (name : String) β TermU | |
lit : β β TermU | |
suc : (num : TermU) β TermU | |
lam : (name : String) (T : Type) (body : TermU) β TermU | |
app : (fun arg : TermU) β TermU | |
data TermT (Ξ : List (String Γ Type)) : Type β Set where | |
var : (name : String) (T : Type) (valid : (name , T) β Ξ) β TermT Ξ T | |
lit : β β TermT Ξ Nat | |
suc : (num : TermT Ξ Nat) β TermT Ξ Nat | |
lam : (name : String) (S : Type) {T : Type} (body : TermT (name , S β· Ξ) T) β TermT Ξ T | |
app : {S T : Type} (fun : TermT Ξ (S β T)) (arg : TermT Ξ S) β TermT Ξ T | |
forgetTypes : {Ξ : List (String Γ Type)} {T : Type} β TermT Ξ T β TermU | |
forgetTypes (var name T valid) = var name | |
forgetTypes (lit x) = lit x | |
forgetTypes (suc t) = suc (forgetTypes t) | |
forgetTypes (lam name S b) = lam name S (forgetTypes b) | |
forgetTypes (app f x) = app (forgetTypes f) (forgetTypes x) | |
data Checked (Ξ : List (String Γ Type)) : TermU β Set where | |
ok : {u : TermU} (T : Type) (t : TermT Ξ T) (same : forgetTypes t β‘ u) β Checked Ξ u | |
checkSuc : β {Ξ u} β Checked Ξ u β String + Checked Ξ (suc u) | |
checkSuc (ok Nat t same) = inr (ok Nat (suc t) (cong suc same)) | |
checkSuc (ok (T β Tβ) t same) = inl "Can't do suc of function" | |
checkLam : β name T {Ξ u} β Checked ((name , T) β· Ξ) u β String + Checked Ξ (lam name T u) | |
checkLam name S (ok T t same) = inr (ok T (lam name S t) (cong (lam name S) same)) | |
checkAppEq : β {S Ξ T} (tf : TermT Ξ (S β T)) (tx : TermT Ξ S) | |
(f x : TermU) β | |
forgetTypes tf β‘ f β | |
forgetTypes tx β‘ x β | |
forgetTypes (app tf tx) β‘ app f x | |
checkAppEq tf tx f x same-f same-x rewrite same-f | same-x = refl | |
checkApp : β {Ξ f x} β Checked Ξ f β Checked Ξ x β String + Checked Ξ (app f x) | |
checkApp (ok Nat tf same-f) (ok TX tx same-x) = inl "Can't apply a Nat to an argument" | |
checkApp (ok {f} (S β T) tf same-f) (ok {x} TX tx same-x) with dec-type S TX | |
checkApp (ok {f} (S β T) tf same-f) (ok {x} TX tx same-x) | eq p rewrite p = inr (ok T (app tf tx) (checkAppEq tf tx f x same-f same-x)) | |
checkApp (ok (S β T) tf same-f) (ok TX tx same-x) | neq x = inl "Arg type does not match function type" | |
weakenVar : β {n v T Ξ} β Checked Ξ (var n) β Checked ((v , T) β· Ξ) (var n) | |
weakenVar (ok T (var name .T valid) same) = ok T (var name T (suc valid)) same | |
weakenVar (ok .Nat (lit x) ()) | |
weakenVar (ok .Nat (suc t) ()) | |
weakenVar (ok T (lam name S t) ()) | |
weakenVar (ok T (app t tβ) ()) | |
lookupVar : β name Ξ β String + Checked Ξ (var name) | |
lookupVar n [] = inl (primStringAppend "Var not found: " n) | |
lookupVar n ((v , T) β· Ξ) with dec-string n v | |
lookupVar n ((v , T) β· Ξ) | eq p = inr (ok T (var n T zero) refl) | |
lookupVar n ((v , T) β· Ξ) | neq p = lookupVar n Ξ >>= Ξ» c β inr (weakenVar c) | |
typeCheck : (Ξ : List (String Γ Type)) (u : TermU) β String + Checked Ξ u | |
typeCheck Ξ (var name) = lookupVar name Ξ | |
typeCheck Ξ (lit x) = inr (ok Nat (lit x) refl) | |
typeCheck Ξ (suc u) = typeCheck Ξ u >>= checkSuc | |
typeCheck Ξ (lam name T u) = typeCheck (name , T β· Ξ) u >>= checkLam name T | |
typeCheck Ξ (app f x) = | |
typeCheck Ξ f >>= Ξ» tf β | |
typeCheck Ξ x >>= Ξ» tx β | |
checkApp tf tx |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment