Intro to Agda by Larry Diehl (larrytheliquid)
Jun 16, 2015
Intro to Agda
by Larry Diehl (larrytheliquid)
Why?
induction centric
data Nat : Set where zero : Nat suc : Nat -> Nat
one = suc zerotwo = suc (suc zero)
unicode centric
data ℕ : Set where zero : ℕ suc : ℕ → ℕ
suc₂ : ℕ → ℕsuc₂ n = suc (suc n)
unicode in emacs
\r →\bn ℕ\:: ∷\member ∈ \equiv ≡\and ∧\or ∨\neg ¬\ex ∃\all ∀
built-ins
data ℕ : Set where zero : ℕ suc : ℕ → ℕ
{-# BUILTIN NATURAL ℕ #-}{-# BUILTIN ZERO zero #-}{-# BUILTIN SUC suc #-}
nine = suc₂ 7
standard library
open import Data.Nat
infix & pattern matching
infixl 6 _+_infixl 7 _*__+_ : ℕ → ℕ → ℕzero + n = nsuc m + n = suc (m + n)
_*_ : ℕ → ℕ → ℕzero * n = zerosuc m * n = n + m * n
emacs goal mode
_+_ : ℕ → ℕ → ℕ n + m = ? _+_ : ℕ → ℕ → ℕn + m = {!!}
_+_ : ℕ → ℕ → ℕn + m = { }0-- ?0 : ℕ
coverage checking
data Day : Set where Sunday Monday Tuesday : Day Wednesday Thursday : Day Friday Saturday : Day isWeekend : Day → BoolisWeekend Sunday = trueisWeekend Saturday = trueisWeekend _ = false
termination checking (fail)
isWeekend : Day → BoolisWeekend day = isWeekend day
isWeekend : Day → BoolisWeekend Sunday = trueisWeekend Saturday = isWeekend SundayisWeekend _ = false
termination checking (win)
_+_ : ℕ → ℕ → ℕzero + n = nsuc m + n = suc (m + n)
_*_ : ℕ → ℕ → ℕzero * n = zerosuc m * n = n + m * n
data type polymorphism
data List (A : Set) : Set where [] : List A _∷_ : (x : A) (xs : List A) → List A
-- open import Data.List
type-restriction
append : List ℕ → List ℕ → List ℕappend [] ys = ysappend (x ∷ xs) ys = x ∷ (append xs ys)
parametric polymorphism
append : (A : Set) → List A → List A → List Aappend A [] ys = ysappend A (x ∷ xs) ys = x ∷ (append A xs ys)
implicit arguments
append : {A : Set} → List A → List A → List Aappend [] ys = ysappend (x ∷ xs) ys = x ∷ (append xs ys)
-- append = _++_
indexed types
data Vec (A : Set) : ℕ → Set where [] : Vec A zero _∷_ : {n : ℕ} (x : A) (xs : Vec A n) → Vec A (suc n)
bool-vec : Vec Bool 2bool-vec = _∷_ {1} true (_∷_ {0} false []) bool-vec : Vec Bool 2bool-vec = true ∷ false ∷ []
indexed types
append : {n m : ℕ} {A : Set} → Vec A n → Vec A m → Vec A (n + m)append [] ys = ysappend (x ∷ xs) ys = x ∷ (append xs ys)
coverage checking
head : {A : Set} → Vec A 9 → Ahead (x ∷ xs) = x head : {n : ℕ} {A : Set} → Vec A (suc n) → Ahead (x ∷ xs) = x head : {n : ℕ} {A : Set} → Vec A (1 + 1 * n) → Ahead (x ∷ xs) = x
records
record Car : Set where field make : Make model : Model year : ℕ
electricCar : CarelectricCar = record { make = Tesla ; model = Roadster ; year = 2010 }
records
record Car : Set where constructor _,_,_ field make : Make model : Model year : ℕ
electricCar : CarelectricCar = Tesla , Roadster , 2010carYear : ℕcarYear = Car.year electricCar
truth & absurdity
record ⊤ : Set wheredata ⊥ : Set where
T : Bool → SetT true = ⊤T false = ⊥
preconditions
even : ℕ → Booleven zero = trueeven (suc zero) = falseeven (suc (suc n)) = even n
evenSquare : (n : ℕ) → {_ : T (even n)} → ℕevenSquare n = n * n
preconditions
nonZero : ℕ → BoolnonZero zero = falsenonZero _ = true
postulate _div_ : ℕ → (n : ℕ) → {_ : T (nonZero n)} → ℕ
propositional equality
infix 4 _≡_data _≡_ {A : Set} (x : A) : A → Set where refl : x ≡ x
testMultiplication : 56 ≡ 8 * 7testMultiplication = refl
preconditions
lookup : {A : Set}(n : ℕ)(xs : List A) {_ : T (n < length xs)} → Alookup n []{()}lookup zero (x ∷ xs) = xlookup (suc n) (x ∷ xs) {p} = lookup n xs {p}
testLookup : 2 ≡ lookup 1 (1 ∷ 2 ∷ [])testLookup = refl
finite sets
data Fin : ℕ → Set where zero : {n : ℕ} → Fin (suc n) suc : {n : ℕ} (i : Fin n) → Fin (suc n)
finTest : Fin 3finTest = zero
finTest₂ : Fin 3finTest₂ = suc (suc zero)
precondition with indexes
lookup : {A : Set}{n : ℕ} → Fin n → Vec A n → Alookup zero (x ∷ xs) = xlookup (suc i) (x ∷ xs) = lookup i xs testLookup : 2 ≡ lookup (suc zero) (1 ∷ 2 ∷ [])testLookup = refl
testLookup₂ : 2 ≡ lookup (fromℕ 1) (1 ∷ 2 ∷ [])testLookup₂ = refl
with
doubleOrNothing : ℕ → ℕdoubleOrNothing n with even ndoubleOrNothing n | true = n * 2doubleOrNothing n | false = 0 doubleOrNothing : ℕ → ℕdoubleOrNothing n with even n... | true = n * 2... | false = 0
views
parity : (n : ℕ) → Parity nparity zero = even zeroparity (suc n) with parity nparity (suc .(k * 2)) | even k = odd kparity (suc .(1 + k * 2)) | odd k = even (suc k)
half : ℕ → ℕhalf n with parity nhalf .(k * 2) | even k = khalf .(1 + k * 2) | odd k = k
inverse
data Image_∋_ {A B : Set}(f : A → B) : B → Set where im : {x : A} → Image f ∋ f x
inv : {A B : Set}(f : A → B)(y : B) → Image f ∋ y → Ainv f .(f x) (im {x}) = x
inverse
Bool-to-ℕ : Bool → ℕBool-to-ℕ false = 0Bool-to-ℕ true = 1
testImage : Image Bool-to-ℕ ∋ 0testImage = imtestImage₂ : Image Bool-to-ℕ ∋ 1testImage₂ = im
testInv : inv Bool-to-ℕ 0 im ≡ falsetestInv = refltestInv₂ : inv Bool-to-ℕ 1 im ≡ truetestInv₂ = refl
intuitionistic logic
data _∧_ (A B : Set) : Set where <_,_> : A → B → A ∧ B
fst : {A B : Set} → A ∧ B → Afst < a , _ > = asnd : {A B : Set} → A ∧ B → Bsnd < _ , b > = b
intuitionistic logic
data _∨_ (A B : Set) : Set where left : A → A ∨ B right : B → A ∨ B
case : {A B C : Set} → A ∨ B → (A → C) → (B → C) → Ccase (left a) x _ = x acase (right b) _ y = y b
intuitionistic logic
record ⊤ : Set where constructor tt
data ⊥ : Set where
exFalso : {A : Set} → ⊥ → AexFalso ()
¬ : Set → Set¬ A = A → ⊥
intuitionistic logic
_=>_ : (A B : Set) → SetA => B = A → B
modusPonens : {A B : Set} → A => B → A → BmodusPonens f a = f a
_<=>_ : Set → Set → SetA <=> B = (A => B) ∧ (B => A)
intuitionistic logic
∀′ : (A : Set)(B : A → Set) → Set∀′ A B = (a : A) → B a
data ∃ (A : Set)(B : A → Set) : Set where exists : (a : A) → B a → ∃ A B
witness : {A : Set}{B : A → Set} → ∃ A B → Awitness (exists a _) = a
intuitionistic logic
data Man : Set where person : Man
isMan : Man → SetisMan m = ⊤
isMortal : Man → SetisMortal m = ⊤
socratesIsMortal : {Socrates : Man} → (∀′ Man isMortal ∧ isMan Socrates) => isMortal SocratessocratesIsMortal {soc} < lemma , _ > = lemma soc
The End
Agda Wikihttp://is.gd/8YgYM
Dependently Typed Programming in Agdahttp://is.gd/8Ygyz
Dependent Types at Work
http://is.gd/8YggR
lemmatheultimate.com