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

502 views

Published on

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

От слушателя ожидаются базовые знания функционального программирования и дискретной математики на уровне первого курса университета, хотя бы поверхностное знакомство с зависимыми типами.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
502
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

  1. 1. Introduction to Agda (for Haskellers) Jan Malakhovski oxij at twier July, 12 2012 . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 1 / 32
  2. 2. .Здесь нет ничего интересного.. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 2 / 32
  3. 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 3 / 32
  4. 4. Syntax.Lexing. Мегапростой лексер делит строку по: “ ”, “( )” и “ ”. Допустимы любые символы UNICODE в именах. Большие буквы ничего не значат. forall ⇔ ∀ (all в agda2-mode). -> ⇔ → (to в agda2-mode).Parsing. MixFix. “_” в именах функций обозначают позиции аргументов. → — не типовая стрелка в обычном понимании, иногда можно опускать...Compilation.is top-down. Это важно.. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 4 / 32
  5. 5. Haskell vs. Agda -- Agda (*) module FProg120712 where -- Haskell data Tree A : Set wheremodule FProg120712 where Leaf : Tree Adata Tree a = Leaf Node : A → Tree A | Node a (Tree a) (Tree a) → Tree A → Tree Adata Either a b = Le a data _or_ A B : Set where | Right b le : A → A or B right : B → A or Blemost : Tree a -> Either () alemost Leaf = Le () record ⊤ : Set wherelemost (Node a Leaf _) = Right a lemost : ∀ { A } → Tree Alemost (Node _ l _) = lemost l → ⊤ or A lemost Leaf = le _ lemost (Node a Leaf _) = right a lemost (Node _ l _) = lemost l . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32
  6. 6. Haskell vs. Agda -- Agda (**) -- Agda (*) module FProg120712 wheremodule FProg120712 where data Tree (A : Set) : Set wheredata 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 wheredata _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 whererecord ⊤ : Set where constructor  -- Faked namelemost : ∀ { A } → Tree A lemost : { A : _ } → Tree A → ⊤ or A → ⊤ or Alemost Leaf = le _ lemost { _ } Leaf = le _lemost (Node a Leaf _) = right a lemost { _ } (Node a Leaf _) = right alemost (Node _ l _) = lemost l lemost { _ } (Node _ l _) = lemost l . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 5 / 32
  7. 7. Unsugaring datatype syntaxdata _or_ (A : Set) (B : Set) : Set where le : (_ : A) → A or′ B right : (_ : B) → A or′ Bdata _or_ : (_ : Set) → Set → Set where le : ∀ { A B } → A → A or′ B right : ∀ { A B } → B → A or′ Bdata _or_ : (_ : Set) → (_ : Set) → Set where le : { A B : _ } (_ : A) → A or′ B right : { A : _ } { B : _ } → B → A or′ B . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 6 / 32
  8. 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 7 / 32
  9. 9. Postulates, BUILTINs, universe polymorphismdata 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 → Levelinfix 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 → Afour = 2 + 2 id {α} { A } a = aLevel is just a non-paernmatchable N with “maximum” operation ( ⊔ ). . . . . . . Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 8 / 32
  10. 10. Well-known datatypesinfixr 5 _::_data List {α} (A : Set α) : Set α where [ ] : List A _::_ : A → List A → List Ainfixr 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) = aheadV : ∀ {α} { A : Set α} { n } → Vec A (succ n) → AheadV (a ::+ as) = a . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 9 / 32
  11. 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 10 / 32
  12. 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 = fxf ◦ 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 11 / 32
  13. 13. Type theoretic datatypes.Negation.data ⊥ : Set where⊥-elim : ∀ {α} { A : Set α} → ⊥ → A⊥-elim ()¬ : ∀ {α} → Set α → Set α¬P = P → ⊥. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 12 / 32
  14. 14. .Sum and product.data ∨ {α β } (A : Set α) (B : Set β) : Set (α ⊔ β) where inj₁ : A → A ∨ B inj₂ : B → A ∨ Brecord Σ {α β } (A : Set α) (B : A → Set β) : Set (α ⊔ β) where constructor _, _ field proj1 : A proj2 : B proj1open Σ public ∧ : ∀ {α β } (A : Set α) (B : Set β) → Set (α ⊔ β)A ∧ B = Σ A (λ _ → B). . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 13 / 32
  15. 15. Properties for natural numbers_≠0 : N → Set0 ≠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 twier) Introduction to Agda (for Haskellers) July, 12 2012 14 / 32
  16. 16. Examplestest≠0 : Σ N (λ n → n ≠0)test≠0 = 1, syntax Σ A (λ x → B) = ∃ [ x ∶ A ] Btest¬≠0 : ∃ [ n ∶ N ] (¬ ◦ _≠0) ntest¬≠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 → Nnzplus zero {()} mnzplus (succ n) m = n + mtestnzplus = nzplus 1 3testnzplus′ = nzplus 0 3 -- Unresolved constraint . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 15 / 32
  17. 17. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 16 / 32
  18. 18. 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 → fx≡fycong f refl = refl . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 17 / 32
  19. 19. Arithmetic examplesz+n=n : ∀ n → 0 + n ≡ nz+n=n n = refln+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 twier) Introduction to Agda (for Haskellers) July, 12 2012 18 / 32
  20. 20. Listslength : ∀ {α} { A : Set α} → List A → Nlength [ ] = 0length (_ :: as) = 1 + length aselementAt : ∀ {α} { A : Set α} n → (l : List A) → n length l → AelementAt zero [ ] ()elementAt zero (a :: _) 0 ∀ = aelementAt (succ n) [ ] ()elementAt (succ n) (_ :: as) (ss s) = elementAt n as s . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 19 / 32
  21. 21. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  22. 22. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  23. 23. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  24. 24. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  25. 25. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  26. 26. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  27. 27. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 20 / 32
  28. 28. Interruption_≤_ : N → N → Setn ⩽ m = (n ≡ m) ∨ (n m)unsucc : ∀ { n m } → succ n ≡ succ m → n ≡ munsucc refl = refl . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 21 / 32
  29. 29. Lists againtake : ∀ {α} { 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₂ (ss nm)) = a :: take n as (inj₂ nm)takeV : ∀ {α} { A : Set α} { m } n → (l : Vec A m) → n ⩽ m → Vec A ntakeV 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 22 / 32
  30. 30. Listsdata Bool : Set where true false : BoolisTrue : Bool → SetisTrue true = ⊤isTrue false = ⊥_≤?_ : N → N → Boolzero ≤? _ = truesucc _ ≤? zero = falsesucc n ≤? succ m = n ≤? munsuccIt : ∀ n m → isTrue (succ n ≤? succ m) → isTrue (n ≤? m)unsuccIt n m = idtake′ : ∀ {α} { A : Set α} n → (l : List A) → { _ : isTrue (n ≤? length l)} → List Atake′ zero _ = [ ]take′ (succ n) [ ] {()}take′ (succ n) (a :: as) { it } = a :: take′ n as { it } . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 23 / 32
  31. 31. ∈ 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 ∈ bstake ⊆ : ∀ {α} { A : Set α} n (l : List A) → (nll : n ⩽ length l) → take n l nll ⊆ ltake ⊆ 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₂ (ss nm)) Z = Ztake ⊆ (succ n) (a :: as) (inj₂ (ss nm)) (S n’) = S (take ⊆ n as (inj₂ nm) n’) . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 24 / 32
  32. 32. filter : ∀ {α} { A : Set α} → (p : A → Bool) → List A → List Afilter p [ ] = [ ]filter p (a :: as) with p a… | true = a :: (filter p as)… | false = filter p asfilter ⊆ as : ∀ {α} { A : Set α} → (as : List A) → (p : A → Bool) → (filter p as) ⊆ asfilter ⊆ 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 = Z go (S n) = S (filter ⊆ as as p n) . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 25 / 32
  33. 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 = reflinfixl 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 26 / 32
  34. 34. 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 27 / 32
  35. 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 28 / 32
  36. 36. Environment and visibility controlmodule 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 twier) Introduction to Agda (for Haskellers) July, 12 2012 29 / 32
  37. 37. Заключение Если кому-то показалось, что что-то выше проверяется в runtime, то он ошибся. Всё проверяется статически, доказательства (как правило) стираются при компиляции..Main features. Структурная индукция. Семейства типов. Зависимое сопоставление с образцом.. Lazyness is essential! У простых алгоритмов простые доказательства. I.e. полезно даже если вы не очень математик. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 30 / 32
  38. 38. Не рассмотрены Всё самое интересное. Dot-paerns. IO. Reflection. Standart Library. Back-ends. . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 31 / 32
  39. 39. .. estions?. The proof is trivial! Just biject it to a context-free topological space whose elements are computable equivalence relations. hp://theproofistrivial.com/ . . . . . .Jan Malakhovski ( oxij at twier) Introduction to Agda (for Haskellers) July, 12 2012 32 / 32

×