С точки зрения программиста Agda представляет собой язык с зависимой системой типов и Haskellеподобным синтаксисом. С точки зрения математика — это система проверки доказательств, отдающая предпочтение прямому манипулированию proof-термами, а не тактикам. Доклад рассматривает основные особенности и идиомы системы Agda на примерах, широко используемых в дискретной математике.
От слушателя ожидаются базовые знания функционального программирования и дискретной математики на уровне первого курса университета, хотя бы поверхностное знакомство с зависимыми типами.
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Ян Малаховски. Введение в Agda
1. 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
2. .
Здесь нет ничего интересного.
.
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 2 / 32
3. 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
4. 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
5. Haskell vs. Agda
-- Agda (*)
module FProg120712 where
-- Haskell data Tree A : Set where
module FProg120712 where Leaf : Tree A
data Tree a = Leaf Node : A → Tree A
| Node a (Tree a) (Tree a) → Tree A → Tree A
data Either a b = Le a data _or_ A B : Set where
| Right b le : A → A or B
right : B → A or B
lemost : Tree a -> Either () a
lemost Leaf = Le () record ⊤ : Set where
lemost (Node a Leaf _) = Right a lemost : ∀ { A } → Tree A
lemost (Node _ l _) = lemost l → ⊤ or A
lemost Leaf = le _
lemost (Node a Leaf _) = right a
lemost (Node _ l _) = lemost l
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32
6. Haskell vs. Agda
-- Agda (**)
-- Agda (*)
module FProg120712 where
module FProg120712 where
data Tree (A : Set) : Set where
data Tree A : Set where Leaf : Tree A
Leaf : Tree A Node : (_ : A) → (_ : Tree A)
Node : A → Tree A → (_ : Tree A) → Tree A
→ Tree A → Tree A
data _or_ (A B : Set) : Set where
data _or_ A B : Set where le : (_ : A) → A or B
le : A → A or B right : (_ : B) → A or B
right : B → A or B
record ⊤ : Set where
record ⊤ : Set where constructor -- Faked name
lemost : ∀ { A } → Tree A lemost : { A : _ } → Tree A
→ ⊤ or A → ⊤ or A
lemost Leaf = le _ lemost { _ } Leaf = le _
lemost (Node a Leaf _) = right a lemost { _ } (Node a Leaf _) = right a
lemost (Node _ l _) = lemost l lemost { _ } (Node _ l _) = lemost l
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32
7. Unsugaring datatype syntax
data _or_ (A : Set) (B : Set) : Set where
le : (_ : A) → A or′ B
right : (_ : B) → A or′ B
data _or_ : (_ : Set) → Set → Set where
le : ∀ { A B } → A → A or′ B
right : ∀ { A B } → B → A or′ B
data _or_ : (_ : Set) → (_ : Set) → Set where
le : { A B : _ } (_ : A) → A or′ B
right : { A : _ } { B : _ } → B → A or′ B
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 6 / 32
8. 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
9. Postulates, BUILTINs, universe polymorphism
data N : Set where infixl 6 ⊔
zero : N postulate
succ : N → N Level : Set
{-# BUILTIN NATURAL ℕ #-} lzero : Level
{-# BUILTIN ZERO zero #-} lsucc : Level → Level
{-# BUILTIN SUC succ #-} ⊔ : Level → Level → Level
infix 6 _+_ {-# BUILTIN LEVEL Level #-}
_+_ : N → N → N {-# BUILTIN LEVELZERO lzero #-}
0+m = m {-# BUILTIN LEVELSUC lsucc #-}
(succ n) + m = succ (n + m) {-# BUILTIN LEVELMAX #-}
{-# BUILTIN NATPLUS + #-} id : {α : Level } { A : Set α}
one = 0 + 1 → A → A
four = 2 + 2 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
10. Well-known datatypes
infixr 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 → A
headL [ ] = {!!} -- Should be total
headL (a :: as) = a
headV : ∀ {α} { A : Set α} { n } → Vec A (succ n) → A
headV (a ::+ as) = a
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 9 / 32
11. 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 ⇔ ∀AB → C
. Same for “ ”, except for some funny reason {_ : A} has no sugar.
.
Datatypes
.
data Name Parameter* : [ Index →] * SetLevel where
Constructor*
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
12. Syntax unsugar exercises
◦ : ∀ {α β γ } { A : Set α}
infixr 0 _$_
{ B : A → Set β }
_$_ : ∀ {α β } { A : Set α}
{ C : { x : A } → B x → Set γ }
{ B : A → Set β }
→ (∀ { x } (y : B x) → C y)
→ (∀ x → B x)
→ (g : (x : A) → B x)
→ (∀ x → B x)
→ (x : A) → C (g x)
f $ x = fx
f ◦ g = λ x → f ( g 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
13. 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
14. .
Sum and product
.
data ∨ {α β } (A : Set α) (B : Set β) : Set (α ⊔ β) where
inj₁ : A → A ∨ B
inj₂ : B → A ∨ B
record Σ {α β } (A : Set α) (B : A → Set β) : Set (α ⊔ β) where
constructor _, _
field
proj1 : A
proj2 : 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
15. Properties for natural numbers
_≠0 : N → Set
0 ≠0 = ⊥
_ ≠0 = ⊤
data __ : N → N → Set where
0 ∀ : ∀ { n } → 0 succ n
ss : ∀ { n m } → n m → succ n succ m
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 14 / 32
16. Examples
test≠0 : Σ N (λ n → n ≠0)
test≠0 = 1,
syntax Σ A (λ x → B) = ∃ [ x ∶ A ] B
test¬≠0 : ∃ [ n ∶ N ] (¬ ◦ _≠0) n
test¬≠0 = 0, (λ z → z)
test¬0 : ¬ (∃ [ n ∶ N ] (n 0))
test¬0 (n, n0) = sub n n0 where
sub : ∀ n → n 0 → ⊥
sub zero ()
sub (succ n) ()
nzplus : (n : N) → { nz : n ≠0 } → N → N
nzplus zero {()} m
nzplus (succ n) m = n + m
testnzplus = nzplus 1 3
testnzplus′ = nzplus 0 3 -- Unresolved constraint
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 15 / 32
17. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 16 / 32
18. Type-theoretic properties
.
Martin-Lof (propositional) equality
¨
.
infix 4 _≡_
data _≡_ {α} { A : Set α} (a : A) : A → Set α where
refl : a ≡ a
.
z=z : 0 ≡ 0
z=z = refl { _ } { N } { 0 }
cong : ∀ {α β } { A : Set α} { B : Set β }
(f : A → B) { x y }
→ x≡y → fx≡fy
cong f refl = refl
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 17 / 32
19. Arithmetic examples
z+n=n : ∀ n → 0 + n ≡ n
z+n=n n = refl
n+z=n : ∀ n → n + 0 ≡ n
n+z=n zero = refl
n+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
20. Lists
length : ∀ {α} { A : Set α} → List A → N
length [ ] = 0
length (_ :: as) = 1 + length as
elementAt : ∀ {α} { A : Set α} n → (l : List A) → n length l → A
elementAt zero [ ] ()
elementAt zero (a :: _) 0 ∀ = a
elementAt (succ n) [ ] ()
elementAt (succ n) (_ :: as) (ss s) = elementAt n as s
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 19 / 32
21. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
22. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
23. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
24. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
25. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
26. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
27. . . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
28. Interruption
_≤_ : N → N → Set
n ⩽ m = (n ≡ m) ∨ (n m)
unsucc : ∀ { n m } → succ n ≡ succ m → n ≡ m
unsucc refl = refl
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 21 / 32
29. Lists again
take : ∀ {α} { A : Set α} n → (l : List A) → n ⩽ length l → List A
take 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₂ (ss nm)) = a :: take n as (inj₂ nm)
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₂ (ss nm)) = a ::+ takeV n as (inj₂ nm)
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 22 / 32
30. Lists
data Bool : Set where
true false : Bool
isTrue : Bool → Set
isTrue true = ⊤
isTrue false = ⊥
_≤?_ : N → N → Bool
zero ≤? _ = true
succ _ ≤? zero = false
succ 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
31. ∈ for Lists
data _∈_ {α} { 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)
→ (nll : n ⩽ length l) → take n l nll ⊆ l
take ⊆ zero _ _ ()
take ⊆ (succ n) [ ] (inj₁ ()) _
take ⊆ (succ n) [ ] (inj₂ ()) _
take ⊆ (succ n) (a :: as) (inj₁ eq) Z = Z
take ⊆ (succ n) (a :: as) (inj₁ eq) (S n’) =
S (take ⊆ n as (inj₁ $ unsucc eq) n’)
take ⊆ (succ n) (a :: as) (inj₂ (ss nm)) Z = Z
take ⊆ (succ n) (a :: as) (inj₂ (ss nm)) (S n’) =
S (take ⊆ n as (inj₂ nm) n’)
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 24 / 32
32. 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 → z
filter ⊆ 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 = Z
go (S n) = S (filter ⊆ as as p n)
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 25 / 32
33. 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
34. reverse : ∀ { a } { A : Set a } → List A → List A
reverse [ ] = [ ]
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
35. Modules
open import ModuleName instead of Haskell’s
import ModuleName;
Agda’s import ModuleName is import qualified ModuleName in
Haskell (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
36. Environment and visibility control
module Tralala where
-- (1) ∅ at (1)
module Dummy where Tweedledum at (2)
Tweedledum : …
Tweedledum and Tweedledee
Tweedledum = {!!}
at (3)
-- (2)
Dummy.Tweedledum and
Tweedledee : … Dummy.Tweedledee at (4)
Tweedledee = {!!}
Dummy.Tweedledum,
-- (3) Dummy.Tweedledee and
-- (4) Tweedledee at (5)
open Dummy public Tweedledee outside of the
using (Tweedledee) module.
-- (5)
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 29 / 32
37. Заключение
Если кому-то показалось, что что-то выше проверяется в runtime,
то он ошибся.
Всё проверяется статически, доказательства (как правило)
стираются при компиляции.
.
Main features
.
Структурная индукция.
Семейства типов.
Зависимое сопоставление с образцом.
.
Lazyness is essential!
У простых алгоритмов простые доказательства.
I.e. полезно даже если вы не очень математик.
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 30 / 32
38. Не рассмотрены
Всё самое интересное.
Dot-paerns.
IO.
Reflection.
Standart Library.
Back-ends.
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 31 / 32
39. .
. estions?
.
The proof is trivial! Just biject it to a
context-free
topological space
whose elements are
computable
equivalence relations
. hp://theproofistrivial.com/
. . . . . .
Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 32 / 32