Top Banner
. . . . . . Introduction to Agda (for Haskellers) Jan Malakhovski @oxij at twier July, 12 2012 Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 1 / 32
39

Ян Малаховски. Введение в Agda

May 12, 2015

Download

Technology

FProg

С точки зрения программиста Agda представляет собой язык с зависимой системой типов и Haskellеподобным синтаксисом. С точки зрения математика — это система проверки доказательств, отдающая предпочтение прямому манипулированию proof-термами, а не тактикам. Доклад рассматривает основные особенности и идиомы системы Agda на примерах, широко используемых в дискретной математике.

От слушателя ожидаются базовые знания функционального программирования и дискретной математики на уровне первого курса университета, хотя бы поверхностное знакомство с зависимыми типами.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Ян Малаховски. Введение в Agda

. . . . . .

Introduction to Agda (for Haskellers)

Jan Malakhovski

@oxij at twier

July, 12 2012

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 1 / 32

Page 2: Ян Малаховски. Введение в Agda

. . . . . .

.

......Здесь нет ничего интересного.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 2 / 32

Page 3: Ян Малаховски. Введение в Agda

. . . . . .

Tools.Agda and agda-mode for Emacs..

......

Установите emacs.

Установите всё с подстрокой “agda” из пакетного менеджера илиcabal.

Запустите agda-mode setup.

Запустите emacs. C-x C-f Test.agda <RET> M-x agda2-mode.

Интерактивное конструирование программ доступно только вemacs, vim не покатит.

Комбинации клавиш на странице в Agda Wiki. Самые главные:C-c C-l, C-c C-r, C-c C-,, C-c C-c.

.Standart Library..

......

http://www.cse.chalmers.se/~nad/repos/lib/

Огромная. Полгода для того чтобы начать её понимать.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 3 / 32

Page 4: Ян Малаховски. Введение в Agda

. . . . . .

Syntax.Lexing..

......

Мегапростой лексер делит строку по: “ ”, “( )” и “ ”. Допустимылюбые символы UNICODE в именах.

Большие буквы ничего не значат.

forall ⇔ ∀ (\all в agda2-mode)-> ⇔ → (\to в agda2-mode)

.Parsing..

......

MixFix. “_” в именах функций обозначают позиции аргументов.

→ — не типовая стрелка в обычном понимании, иногда можноопускать.

.Compilation........is top-down. Это важно.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 4 / 32

Page 5: Ян Малаховски. Введение в Agda

. . . . . .

Haskell vs. Agda

-- Haskell

module FProg120712 wheredata Tree a = Leaf

| Node a (Tree a) (Tree a)

data Either a b = Le a| Right b

lemost : Tree a -> Either () alemost Leaf = Le ()lemost (Node a Leaf _) = Right alemost (Node _ l _) = lemost l

-- Agda (*)

module FProg120712 wheredata Tree A : Set where

Leaf : Tree ANode : A → Tree A

→ Tree A → Tree A

data _or_ A B : Set wherele : A → A or Bright : B → A or B

record ⊤ : Set wherelemost : ∀ {A} → Tree A

→ ⊤ or Alemost Leaf = le _lemost (Node a Leaf _) = right alemost (Node _ l _) = lemost l

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32

Page 6: Ян Малаховски. Введение в Agda

. . . . . .

Haskell vs. Agda

-- Agda (*)

module FProg120712 wheredata Tree A : Set where

Leaf : Tree ANode : A → Tree A

→ Tree A → Tree A

data _or_ A B : Set wherele : A → A or Bright : B → A or B

record ⊤ : Set wherelemost : ∀ {A} → Tree A

→ ⊤ or Alemost Leaf = le _lemost (Node a Leaf _) = right alemost (Node _ l _) = lemost l

-- Agda (**)

module FProg120712 wheredata Tree (A : Set) : Set where

Leaf : Tree ANode : (_ : A) → (_ : Tree A)

→ (_ : Tree A) → Tree A

data _or_ (A B : Set) : Set wherele : (_ : A) → A or Bright : (_ : B) → A or B

record ⊤ : Set whereconstructor -- Faked name

lemost : {A : _} → Tree A→ ⊤ or A

lemost {_} Leaf = le _lemost {_} (Node a Leaf _) = right alemost {_} (Node _ l _) = lemost l

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32

Page 7: Ян Малаховски. Введение в Agda

. . . . . .

Unsugaring datatype syntax

data _or_ (A : Set) (B : Set) : Set wherele : (_ : A) → A or′ Bright : (_ : B) → A or′ B

data _or_ : (_ : Set) → Set → Set wherele : ∀ {A B} → A → A or′ Bright : ∀ {A B} → B → A or′ B

data _or_ : (_ : Set) → (_ : Set) → Set wherele : {A B : _} (_ : A) → A or′ Bright : {A : _} {B : _} → B → A or′ B

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 6 / 32

Page 8: Ян Малаховски. Введение в Agda

. . . . . .

Sets (types, kinds, sorts, . . . )

.Relation..

......

x : Type : Set₀ : Set₁ : Set₂ : Set₃ : …Non-UNICODE:

x : Type : Set0 : Set1 : Set2 : Set3 : …

.Syntax..

......“Set” — алиас для “Set₀” (“*” в Haskell).

.Properties..

......

Not cumulative:

YES: Set : Set₁; Set → Set : Set₁; Set₁ → Set : Set₂;

NO: Set : Set₂; Set₁ → Set : Set₃.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 7 / 32

Page 9: Ян Малаховски. Введение в Agda

. . . . . .

Postulates, BUILTINs, universe polymorphism

data N : Set wherezero : Nsucc : N → N{-# BUILTIN NATURAL ℕ #-}{-# BUILTIN ZERO zero #-}{-# BUILTIN SUC succ #-}infix 6 _+__+_ : N → N → N0 + m = m(succ n) + m = succ (n + m)

{-# BUILTIN NATPLUS + #-}one = 0 + 1four = 2 + 2

infixl 6 ⊔postulate

Level : Setlzero : Levellsucc : Level → Level⊔ : Level → Level → Level

{-# BUILTIN LEVEL Level #-}{-# BUILTIN LEVELZERO lzero #-}{-# BUILTIN LEVELSUC lsucc #-}{-# BUILTIN LEVELMAX � #-}

id : {α : Level} {A : Set α}→ A → A

id {α} {A} a = a

Level is just a non-paernmatchable N with “maximum” operation ( ⊔ ).

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 8 / 32

Page 10: Ян Малаховски. Введение в Agda

. . . . . .

Well-known datatypesinfixr 5 _::_data List {α} (A : Set α) : Set α where[ ] : List A_::_ : A → List A → List A

infixr 5 _::+_data Vec {α} (A : Set α) : N → Set α where[0] : Vec A 0_::+_ : ∀ {n} → A → Vec A n → Vec A (succ n)

testList = 0 :: 1 :: 2 :: 3 :: [ ]testVec = 0 ::+ 1 ::+ 2 ::+ 3 ::+ [0]

headL : ∀ {α} {A : Set α} → List A → AheadL [ ] = { !!} -- Should be totalheadL (a :: as) = a

headV : ∀ {α} {A : Set α} {n} → Vec A (succ n) → AheadV (a ::+ as) = a

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 9 / 32

Page 11: Ян Малаховски. Введение в Agda

. . . . . .

Syntax sugar.Types..

......

(_ : A) → B ⇔ A → B(A : X) → (B : Y) → C ⇔ (A : X) (B : Y) → C(A : X) → (B : X) → C ⇔ (A B : X) → C

(A B : _) → C ⇔ ∀ A B → CSame for “ ”, except for some funny reason {_ : A} has no sugar.

.Datatypes..

......

data Name Parameter* : [Index → ] * SetLevel whereConstructor*

Parameters are universally quantified Indexes.

Parameters are implicit arguments for datatype Constructors.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 10 / 32

Page 12: Ян Малаховски. Введение в Agda

. . . . . .

Syntax unsugar exercises

◦ : ∀ {α β γ} {A : Set α}{B : A → Set β}{C : {x : A} → B x → Set γ}→ (∀ {x} (y : B x) → C y)→ (g : (x : A) → B x)→ (x : A) → C (g x)

f ◦ g = λ x → f (g x)

infixr 0 _$__$_ : ∀ {α β} {A : Set α}{B : A → Set β}→ (∀ x → B x)→ (∀ x → B x)

f $ x = f x

_o_ : {α β γ : Level} {A : Set α} {B : A → Set β}{C : {x : A} → B x → Set γ}→ (f : {x : A} → (y : B x) → C {x} y)→ (g : (x : A) → B x)→ (x : A) → C {x} (g x)

f o g = λ x → f {x} (g x)

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 11 / 32

Page 13: Ян Малаховски. Введение в Agda

. . . . . .

Type theoretic datatypes

.Negation..

......

data ⊥ : Set where⊥-elim : ∀ {α} {A : Set α} → ⊥ → A⊥-elim ()

¬ : ∀ {α} → Set α → Set α¬ P = P → ⊥

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 12 / 32

Page 14: Ян Малаховски. Введение в Agda

. . . . . .

.Sum and product..

......

data ∨ {α β} (A : Set α) (B : Set β) : Set (α ⊔ β) whereinj₁ : A → A ∨ Binj₂ : B → A ∨ B

record Σ {α β} (A : Set α) (B : A → Set β) : Set (α ⊔ β) whereconstructor _, _field

proj1 : Aproj2 : B proj1

open Σ public∧ : ∀ {α β} (A : Set α) (B : Set β) → Set (α ⊔ β)

A ∧ B = Σ A (λ _ → B)

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 13 / 32

Page 15: Ян Малаховски. Введение в Agda

. . . . . .

Properties for natural numbers

_≠0 : N → Set0 ≠0 = ⊥_ ≠0 = ⊤data _<_ : N → N → Set where

0 <∀ : ∀ {n} → 0 < succ ns<s : ∀ {n m} → n < m → succ n < succ m

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 14 / 32

Page 16: Ян Малаховски. Введение в Agda

. . . . . .

Examples

test≠0 : Σ N (λ n → n ≠0)test≠0 = 1,

syntax Σ A (λ x → B) = ∃ [x ∶ A ] B

test¬≠0 : ∃ [n ∶ N ] (¬ ◦ _≠0) ntest¬≠0 = 0, (λ z → z)

test¬<0 : ¬ (∃ [n ∶ N ] (n < 0))test¬<0 (n, n<0) = sub n n<0 where

sub : ∀ n → n < 0 → ⊥sub zero ()sub (succ n) ()

nzplus : (n : N) → {nz : n ≠0} → N → Nnzplus zero {()} mnzplus (succ n) m = n + m

testnzplus = nzplus 1 3testnzplus′ = nzplus 0 3 -- Unresolved constraint

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 15 / 32

Page 17: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 16 / 32

Page 18: Ян Малаховски. Введение в Agda

. . . . . .

Type-theoretic properties

.Martin-Lof (propositional) equality..

......

infix 4 _≡_data _≡_ {α} {A : Set α} (a : A) : A → Set α where

refl : a ≡ a

z=z : 0 ≡ 0z=z = refl {_} {N} {0}cong : ∀ {α β} {A : Set α} {B : Set β}(f : A → B) {x y}→ x ≡ y → f x ≡ f y

cong f refl = refl

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 17 / 32

Page 19: Ян Малаховски. Введение в Agda

. . . . . .

Arithmetic examples

z+n=n : ∀ n → 0 + n ≡ nz+n=n n = refl

n+z=n : ∀ n → n + 0 ≡ nn+z=n zero = refln+z=n (succ n) = cong succ $ n+z=n n

+-assoc : ∀ n m l → n + (m + l) ≡ (n + m) + l+-assoc zero m l = refl+-assoc (succ n) m l = cong succ $ +-assoc n m l

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 18 / 32

Page 20: Ян Малаховски. Введение в Agda

. . . . . .

Lists

length : ∀ {α} {A : Set α} → List A → Nlength [ ] = 0length (_ :: as) = 1 + length as

elementAt : ∀ {α} {A : Set α} n → (l : List A) → n < length l → AelementAt zero [ ] ()elementAt zero (a :: _) 0 <∀ = aelementAt (succ n) [ ] ()elementAt (succ n) (_ :: as) (s<s s) = elementAt n as s

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 19 / 32

Page 21: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 22: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 23: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 24: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 25: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 26: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 27: Ян Малаховски. Введение в Agda

. . . . . .

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32

Page 28: Ян Малаховски. Введение в Agda

. . . . . .

Interruption

_≤_ : N → N → Setn ⩽ m = (n ≡ m) ∨ (n < m)

unsucc : ∀ {n m} → succ n ≡ succ m → n ≡ munsucc refl = refl

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 21 / 32

Page 29: Ян Малаховски. Введение в Agda

. . . . . .

Lists again

take : ∀ {α} {A : Set α} n → (l : List A) → n ⩽ length l → List Atake zero _ _ = [ ]take (succ n) [ ] (inj₁ ())take (succ n) [ ] (inj₂ ())take (succ n) (a :: as) (inj₁ eq) = a :: take n as (inj₁ $ unsucc eq)take (succ n) (a :: as) (inj₂ (s<s n<m)) = a :: take n as (inj₂ n<m)

takeV : ∀ {α} {A : Set α} {m} n → (l : Vec A m) → n ⩽ m→ Vec A n

takeV zero _ _ = [0]takeV (succ n) [0] (inj₁ ())takeV (succ n) [0] (inj₂ ())takeV (succ n) (a ::+ as) (inj₁ eq) = a ::+ takeV n as (inj₁ $ unsucc eq)takeV (succ n) (a ::+ as) (inj₂ (s<s n<m)) = a ::+ takeV n as (inj₂ n<m)

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 22 / 32

Page 30: Ян Малаховски. Введение в Agda

. . . . . .

Listsdata Bool : Set where

true false : Bool

isTrue : Bool → SetisTrue true = ⊤isTrue false = ⊥_≤?_ : N → N → Boolzero ≤? _ = truesucc _ ≤? zero = falsesucc n ≤? succ m = n ≤? m

unsuccIt : ∀ n m → isTrue (succ n ≤? succ m) → isTrue (n ≤? m)unsuccIt n m = id

take′ : ∀ {α} {A : Set α} n → (l : List A)→ {_ : isTrue (n ≤? length l)} → List A

take′ zero _ = [ ]take′ (succ n) [ ] {()}take′ (succ n) (a :: as) { it} = a :: take′ n as { it}Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 23 / 32

Page 31: Ян Малаховски. Введение в Agda

. . . . . .

∈ for Listsdata _∈_ {α} {A : Set α} : A → List A → Set α where

Z : ∀ {a as} → a ∈ (a :: as)S : ∀ {a b as} (n : a ∈ as) → a ∈ (b :: as)

⊆ : ∀ {α} {A : Set α} → List A → List A → Set αas ⊆ bs = ∀ {a} → a ∈ as → a ∈ bs

take ⊆ : ∀ {α} {A : Set α} n (l : List A)→ (n<ll : n ⩽ length l) → take n l n<ll ⊆ l

take ⊆ zero _ _ ()take ⊆ (succ n) [ ] (inj₁ ()) _take ⊆ (succ n) [ ] (inj₂ ()) _take ⊆ (succ n) (a :: as) (inj₁ eq) Z = Ztake ⊆ (succ n) (a :: as) (inj₁ eq) (S n’) =

S (take ⊆ n as (inj₁ $ unsucc eq) n’)take ⊆ (succ n) (a :: as) (inj₂ (s<s n<m)) Z = Ztake ⊆ (succ n) (a :: as) (inj₂ (s<s n<m)) (S n’) =

S (take ⊆ n as (inj₂ n<m) n’)

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 24 / 32

Page 32: Ян Малаховски. Введение в Agda

. . . . . .

filter : ∀ {α} {A : Set α} → (p : A → Bool)→ List A → List A

filter p [ ] = [ ]filter p (a :: as) with p a… | true = a :: (filter p as)… | false = filter p as

filter ⊆ as : ∀ {α} {A : Set α}→ (as : List A) → (p : A → Bool) → (filter p as) ⊆ as

filter ⊆ as [ ] p = λ z → zfilter ⊆ as {A = A} (a :: as) p with p a… | false = λ n → S (filter ⊆ as as p n)… | true = go where

go : {a’ : A} → a’ ∈ (a :: filter p as) → a’ ∈ (a :: as)go Z = Zgo (S n) = S (filter ⊆ as as p n)

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 25 / 32

Page 33: Ян Малаховски. Введение в Agda

. . . . . .

reverse

≡-sym : ∀ {α} {τ : Set α} {a b : τ} → a ≡ b → b ≡ a≡-sym refl = refl

≡-trans : ∀ {α} {τ : Set α} {a b c : τ}→ a ≡ b → b ≡ c → a ≡ c

≡-trans refl refl = refl

infixl 5 _++__++_ : ∀ {a} {A : Set a} → List A → List A → List A[ ] ++ bs = bs(a :: as) ++ bs = a :: (as ++ bs)

++-assoc : ∀ {α} {A : Set α} → (as bs cs : List A)→ (as ++ (bs ++ cs)) ≡ ((as ++ bs) ++ cs)

++-assoc [ ] bs cs = refl++-assoc (a :: as) bs cs = cong (λ ℓ → a :: ℓ) (++-assoc as bs cs)

++ [ ] : ∀ {α} {A : Set α} → (as : List A) → (as ++ [ ]) ≡ as++ [ ] [ ] = refl++ [ ] (a :: as) = cong (λ ℓ → a :: ℓ) (++ [ ] as)Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 26 / 32

Page 34: Ян Малаховски. Введение в Agda

. . . . . .

reverse : ∀ {a} {A : Set a} → List A → List Areverse [ ] = [ ]reverse (a :: as) = (reverse as) ++ (a :: [ ])

reverse++ : ∀ {a} {A : Set a} → (as bs : List A)→ (reverse (as ++ bs)) ≡ ((reverse bs) ++ (reverse as))

reverse++ [ ] bs = ≡-sym $ ++ [ ] (reverse bs)reverse++ (a :: as) bs = ≡-trans(cong (λ ℓ → ℓ ++ (a :: [ ])) (reverse++ as bs))(≡-sym $ ++-assoc (reverse bs) (reverse as) (a :: [ ]))

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 27 / 32

Page 35: Ян Малаховски. Введение в Agda

. . . . . .

Modules

open import ModuleName instead of Haskell’simport ModuleName;

Agda’s import ModuleName is import qualified ModuleName inHaskell (i.e. import, but don’t open module’s namespace);Special keywords:

▶ as — give another name;▶ using — cherry pick names;▶ hiding — hide some names;▶ renaming — cherry pick and rename names;▶ public — and add to module export list.

Nested modules are OK.

Modules can have parameters.

records are modules.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 28 / 32

Page 36: Ян Малаховски. Введение в Agda

. . . . . .

Environment and visibility control

module Tralala where-- (1)

module Dummy whereTweedledum : …Tweedledum = {!!}

-- (2)

Tweedledee : …Tweedledee = {!!}

-- (3)

-- (4)

open Dummy publicusing (Tweedledee)

-- (5)

∅ at (1)

Tweedledum at (2)

Tweedledum and Tweedledeeat (3)

Dummy.Tweedledum andDummy.Tweedledee at (4)

Dummy.Tweedledum,Dummy.Tweedledee andTweedledee at (5)

Tweedledee outside of themodule.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 29 / 32

Page 37: Ян Малаховски. Введение в Agda

. . . . . .

Заключение

Если кому-то показалось, что что-то выше проверяется в runtime,то он ошибся.

Всё проверяется статически, доказательства (как правило)стираются при компиляции.

.Main features..

......

Структурная индукция.

Семейства типов.

Зависимое сопоставление с образцом.

Lazyness is essential!

У простых алгоритмов простые доказательства.

I.e. полезно даже если вы не очень математик.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 30 / 32

Page 38: Ян Малаховски. Введение в Agda

. . . . . .

Не рассмотрены

Всё самое интересное.

Dot-paerns.

IO.

Reflection.

Standart Library.

Back-ends.

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 31 / 32

Page 39: Ян Малаховски. Введение в Agda

. . . . . .

.

...... estions?

.

......

The proof is trivial! Just biject it to a

context-freetopological space

whose elements are

computableequivalence relations

hp://theproofistrivial.com/

Jan Malakhovski (@oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 32 / 32