├── .gitignore ├── Exercises ├── 01-Boolean.agda ├── 02-Natural.agda ├── 03-Equality.agda ├── 04-Logic.agda ├── 05-List.agda └── HelloWorld.agda ├── Makefile ├── README.md ├── Slides ├── 01 - Intro-History.pdf ├── 02 - Basic Inductive Types.pdf ├── 03 - Simple Normalization.pdf ├── 04 - Dependent Types.pdf └── 05 - Negation.pdf └── Solutions ├── 01-Boolean.agda ├── 02-Natural.agda ├── 03-Equality.agda ├── 04-Logic.agda ├── 05-List.agda ├── Everything.agda └── HelloWorld.agda /.gitignore: -------------------------------------------------------------------------------- 1 | *.agdai 2 | *.hi 3 | *.o 4 | *.agda# 5 | *.agda~ 6 | .#*.agda 7 | **/MAlonzo/ 8 | -------------------------------------------------------------------------------- /Exercises/01-Boolean.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --exact-split #-} 2 | 3 | module 01-Boolean where 4 | 5 | -- Precedences 6 | 7 | infixl 6 _or_ _xor_ _iff_ 8 | infixl 7 _and_ 9 | infixl 4 _≡_ 10 | 11 | -- Data Types 12 | 13 | data Boolean : Set where 14 | false true : Boolean 15 | 16 | data Unit : Set where 17 | unit : Unit 18 | 19 | data Empty : Set where 20 | 21 | data _≡_ (x : Boolean) : Boolean → Set where 22 | equal : x ≡ x 23 | 24 | -- Functions 25 | 26 | not : Boolean → Boolean 27 | not false = true 28 | not true = false 29 | 30 | _and_ : Boolean → Boolean → Boolean 31 | false and _ = false 32 | true and y = y 33 | 34 | _or_ : Boolean → Boolean → Boolean 35 | x or y = {!!} 36 | 37 | _nand_ : Boolean → Boolean → Boolean 38 | x nand y = {!!} 39 | 40 | _nor_ : Boolean → Boolean → Boolean 41 | x nor y = {!!} 42 | 43 | _iff_ : Boolean → Boolean → Boolean 44 | false iff false = true 45 | false iff true = false 46 | true iff false = false 47 | true iff true = true 48 | 49 | _xor_ : Boolean → Boolean → Boolean 50 | x xor y = {!!} 51 | 52 | if_then_else_ : {X : Set} → Boolean → X → X → X 53 | if false then _ else y = y 54 | if true then x else _ = x 55 | 56 | not′ : Boolean → Boolean 57 | not′ b = if b then false else true 58 | 59 | -- Sanity checks 60 | 61 | not-true-eq-false : not true ≡ false 62 | not-true-eq-false = equal 63 | 64 | not-false-eq-true : not false ≡ true 65 | not-false-eq-true = equal 66 | 67 | true-and-true-eq-true : true and true ≡ true 68 | true-and-true-eq-true = equal 69 | 70 | false-or-false-eq-false : false or false ≡ false 71 | false-or-false-eq-false = {!!} 72 | 73 | if-true-then-false-eq-false : if true then false else true ≡ false 74 | if-true-then-false-eq-false = equal 75 | 76 | -- Trivial Properties 77 | 78 | false-and-x-eq-false : (x : Boolean) → false and x ≡ false 79 | false-and-x-eq-false _ = equal 80 | 81 | true-or-x-eq-true : (x : Boolean) → true or x ≡ true 82 | true-or-x-eq-true x = {!!} 83 | 84 | -- Properties requiring proof 85 | 86 | not-eq-not′ : (x : Boolean) → not x ≡ not′ x 87 | not-eq-not′ false = equal -- Goal: not false ≡ not′ false 88 | not-eq-not′ true = equal -- Goal: not true ≡ not′ true 89 | 90 | x-and-false-eq-false : (x : Boolean) → x and false ≡ false 91 | x-and-false-eq-false false = equal -- Goal: false and false ≡ false 92 | x-and-false-eq-false true = equal -- Goal: true and false ≡ false 93 | 94 | true-eq-true-or-x : (x : Boolean) → x or true ≡ true 95 | true-eq-true-or-x x = {!!} 96 | 97 | nand-eq-not-and : (x y : Boolean) → x nand y ≡ not (x and y) 98 | nand-eq-not-and x y = {!!} 99 | 100 | nor-eq-not-or : (x y : Boolean) → x nor y ≡ not (x or y) 101 | nor-eq-not-or x y = {!!} 102 | 103 | xor-eq-not-iff : (x y : Boolean) → x xor y ≡ not (x iff y) 104 | xor-eq-not-iff x y = {!!} 105 | 106 | -- Properties using other proofs 107 | 108 | iff-same-true : (x y : Boolean) → x ≡ y → x iff y ≡ true 109 | iff-same-true false .false equal = equal 110 | iff-same-true true .true equal = equal 111 | 112 | xor-same-false : (x y : Boolean) → x ≡ y → x xor y ≡ false 113 | xor-same-false x y p = {!!} 114 | 115 | -- Simple properties involving negation 116 | 117 | true-and-true-not-false : true and true ≡ false → Empty 118 | true-and-true-not-false () 119 | 120 | false-or-false-not-true : false or false ≡ true → Empty 121 | false-or-false-not-true p = {!!} 122 | 123 | false-and-x-not-true : (x : Boolean) → false and x ≡ true → Empty 124 | false-and-x-not-true x () 125 | 126 | true-or-x-not-false : (x : Boolean) → true or x ≡ false → Empty 127 | true-or-x-not-false x p = {!!} 128 | 129 | x-and-false-not-true : (x : Boolean) → x and false ≡ true → Empty 130 | x-and-false-not-true false () 131 | x-and-false-not-true true () 132 | 133 | x-or-true-not-false : (x : Boolean) → x or true ≡ false → Empty 134 | x-or-true-not-false x p = {!!} 135 | 136 | -- Properties using other negations 137 | 138 | empty-to-anything : {A : Set} → Empty → A 139 | empty-to-anything () 140 | 141 | iff-different-false : (x y : Boolean) → (x ≡ y → Empty) → x iff y ≡ false 142 | iff-different-false false false p = empty-to-anything (p equal) 143 | iff-different-false false true p = equal 144 | iff-different-false true false p = equal 145 | iff-different-false true true p = empty-to-anything (p equal) 146 | 147 | xor-different-true : (x y : Boolean) → (x ≡ y → Empty) → x xor y ≡ true 148 | xor-different-true x y p = {!!} 149 | -------------------------------------------------------------------------------- /Exercises/02-Natural.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --exact-split #-} 2 | 3 | module 02-Natural where 4 | 5 | infixl 6 _+_ 6 | infixl 7 _*_ 7 | infixl 4 _≡_ _≢_ 8 | 9 | data Natural : Set where 10 | zero : Natural 11 | suc : Natural → Natural 12 | {-# BUILTIN NATURAL Natural #-} 13 | 14 | _+_ : Natural → Natural → Natural 15 | zero + y = y 16 | (suc x) + y = suc (x + y) 17 | {-# BUILTIN NATPLUS _+_ #-} 18 | 19 | _-_ : Natural → Natural → Natural 20 | x - y = {!!} 21 | 22 | _*_ : Natural → Natural → Natural 23 | zero * y = zero 24 | suc x * y = y + (x * y) 25 | {-# BUILTIN NATTIMES _*_ #-} 26 | 27 | _^_ : Natural → Natural → Natural 28 | x ^ y = {!!} 29 | 30 | open import Agda.Primitive using (Level) 31 | data _≡_ {ℓ : Level} {X : Set ℓ} (x : X) : X → Set ℓ where 32 | equal : x ≡ x 33 | {-# BUILTIN EQUALITY _≡_ #-} 34 | {-# BUILTIN REFL equal #-} 35 | 36 | data Empty : Set where 37 | 38 | _≢_ : {ℓ : Level} → {X : Set ℓ} → (x y : X) → Set ℓ 39 | x ≢ y = x ≡ y → Empty 40 | 41 | 0+0 : 0 + 0 ≡ 0 42 | 0+0 = equal 43 | 44 | 2+2 : 2 + 2 ≡ 4 45 | 2+2 = {!!} 46 | 47 | 2+2≢5 : 2 + 2 ≢ 5 48 | 2+2≢5 () 49 | 50 | 1+1≢3 : 1 + 1 ≢ 3 51 | 1+1≢3 = {!!} 52 | 53 | 2^3 : 2 ^ 3 ≡ 8 54 | 2^3 = {!!} 55 | 56 | 2^8 : 2 ^ 8 ≡ 256 57 | 2^8 = {!!} 58 | 59 | 0*x : (x : Natural) → 0 * x ≡ 0 60 | 0*x x = equal 61 | 62 | x*0 : (x : Natural) → x * 0 ≡ 0 63 | x*0 zero = equal 64 | x*0 (suc x) = x*0 x 65 | 66 | symmetry 67 | : {x y : Natural} 68 | → x ≡ y 69 | → y ≡ x 70 | symmetry equal = equal 71 | 72 | congruence 73 | : {x y : Natural} 74 | → (f : Natural → Natural) 75 | → x ≡ y 76 | → f x ≡ f y 77 | congruence f equal = equal 78 | 79 | 0+x : (x : Natural) → 0 + x ≡ x 80 | 0+x x = equal 81 | 82 | x+0 : (x : Natural) → x + 0 ≡ x 83 | x+0 zero = equal -- Goal: zero + 0 ≡ zero 84 | x+0 (suc x) rewrite x+0 x = equal -- Goal: suc x + 0 ≡ suc x 85 | 86 | x*1 : (x : Natural) → x * 1 ≡ x 87 | x*1 x = {!!} 88 | 89 | 1*x : (x : Natural) → 1 * x ≡ x 90 | 1*x x = {!!} 91 | 92 | +-associative : (x y z : Natural) → (x + y) + z ≡ x + (y + z) 93 | +-associative zero y z = equal 94 | +-associative (suc x) y z rewrite +-associative x y z = equal 95 | 96 | +-suc : (x y : Natural) → x + suc y ≡ suc (x + y) 97 | +-suc x y = {!!} 98 | 99 | +-commutative : (x y : Natural) → x + y ≡ y + x 100 | +-commutative zero y rewrite x+0 y = equal 101 | +-commutative (suc x) y 102 | rewrite +-suc y x 103 | | +-commutative x y 104 | = equal 105 | 106 | +*-dist : (x y z : Natural) → (x + y) * z ≡ (x * z) + (y * z) 107 | +*-dist x y z = {!!} 108 | 109 | *-associative : (x y z : Natural) → (x * y) * z ≡ x * (y * z) 110 | *-associative x y z = {!!} 111 | 112 | *-suc : (x y : Natural) → x * suc y ≡ x + (x * y) 113 | *-suc zero y = equal 114 | *-suc (suc x) y 115 | rewrite *-suc x y 116 | | symmetry (+-associative y x (x * y)) 117 | | symmetry (+-associative x y (x * y)) 118 | | +-commutative x y 119 | = equal 120 | 121 | *-commutative : (x y : Natural) → x * y ≡ y * x 122 | *-commutative x y = {!!} 123 | 124 | data _≤_ : Natural → Natural → Set where 125 | zero≤ : (y : Natural) → zero ≤ y 126 | suc≤suc : (x y : Natural) → x ≤ y → suc x ≤ suc y 127 | 128 | data Total≤ (x y : Natural) : Set where 129 | x≤y : x ≤ y → Total≤ x y 130 | y≤x : y ≤ x → Total≤ x y 131 | 132 | totality : (x y : Natural) → Total≤ x y 133 | totality zero y = x≤y (zero≤ y) 134 | totality (suc x) zero = y≤x (zero≤ (suc x)) 135 | totality (suc x) (suc y) with totality x y 136 | totality (suc x) (suc y) | x≤y p = x≤y (suc≤suc x y p) 137 | totality (suc x) (suc y) | y≤x p = y≤x (suc≤suc y x p) 138 | 139 | antisymmetry : (x y : Natural) → x ≤ y → y ≤ x → x ≡ y 140 | antisymmetry .0 .0 (zero≤ .0) (zero≤ .0) = equal 141 | antisymmetry .(suc x) .(suc y) (suc≤suc x y left) (suc≤suc .y .x right) rewrite antisymmetry x y left right = equal 142 | 143 | transitivity : (x y z : Natural) → x ≤ y → y ≤ z → x ≤ z 144 | transitivity x y z left right = {!!} 145 | 146 | data Boolean : Set where 147 | true false : Boolean 148 | 149 | _≤?_ : Natural → Natural → Boolean 150 | x ≤? y = {!!} 151 | 152 | 2≤?3 : 2 ≤? 3 ≡ true 153 | 2≤?3 = {!!} 154 | 155 | 3≤?2 : 3 ≤? 2 ≡ false 156 | 3≤?2 = {!!} 157 | 158 | equal≤? : (x y : Natural) → x ≡ y → x ≤? y ≡ true 159 | equal≤? x y p = {!!} 160 | 161 | antisymmetry-bool : (x y : Natural) → x ≤? y ≡ true → y ≤? x ≡ true → x ≡ y 162 | antisymmetry-bool x y left right = {!!} 163 | 164 | data Total≤? (x y : Natural) : Set where 165 | x≤?y : x ≤? y ≡ true → Total≤? x y 166 | y≤?x : y ≤? x ≡ true → Total≤? x y 167 | 168 | totality-bool : (x y : Natural) → Total≤? x y 169 | totality-bool x y = {!!} 170 | 171 | transitivity-bool : (x y z : Natural) → x ≤? y ≡ true → y ≤? z ≡ true → x ≤? z ≡ true 172 | transitivity-bool x y z left right = {!!} 173 | -------------------------------------------------------------------------------- /Exercises/03-Equality.agda: -------------------------------------------------------------------------------- 1 | module 03-Equality where 2 | 3 | open import Agda.Primitive using (Level) 4 | 5 | data _≡_ {a : Level} {A : Set a} (x : A) : A → Set a where 6 | equal : x ≡ x 7 | {-# BUILTIN EQUALITY _≡_ #-} 8 | {-# BUILTIN REFL equal #-} 9 | 10 | symmetry 11 | : {a : Level} 12 | → {A : Set a} 13 | → (x y : A) 14 | → x ≡ y 15 | → y ≡ x 16 | symmetry x .x equal = equal 17 | 18 | transitivity 19 | : {a : Level} 20 | → {A : Set a} 21 | → (x y z : A) 22 | → x ≡ y 23 | → y ≡ z 24 | → x ≡ z 25 | transitivity x y z left right = {!!} 26 | 27 | congruence 28 | : {a b : Level} 29 | → {A : Set a} {B : Set b} 30 | → (f : A → B) 31 | → (x y : A) 32 | → x ≡ y 33 | → f x ≡ f y 34 | congruence f x y p = {!!} 35 | 36 | transport 37 | : {a b : Level} 38 | → {A : Set a} 39 | → (x y : A) 40 | → (P : A → Set b) 41 | → x ≡ y 42 | → P x 43 | → P y 44 | transport x y P p px = {!!} 45 | -------------------------------------------------------------------------------- /Exercises/04-Logic.agda: -------------------------------------------------------------------------------- 1 | module 04-Logic where 2 | 3 | infixl 6 _or_ 4 | infixl 7 _and_ 5 | 6 | -- A → (B → A) 7 | modus-ponens : {A B : Set} → (A → B) → A → B 8 | modus-ponens f a = f a 9 | 10 | data _and_ (A B : Set) : Set where 11 | both : (a : A) → (b : B) → A and B 12 | 13 | data _or_ (A B : Set) : Set where 14 | first : (a : A) → A or B 15 | second : (b : B) → A or B 16 | 17 | -- A and B → A 18 | proj1 : {A B : Set} → A and B → A 19 | proj1 (both a b) = a 20 | 21 | -- A and B → B 22 | proj2 : {A B : Set} → A and B → B 23 | proj2 x = {!!} 24 | 25 | -- A → A or B 26 | inj1 : {A B : Set} → A → A or B 27 | inj1 = first 28 | 29 | -- B → A or B 30 | inj2 : {A B : Set} → B → A or B 31 | inj2 x = {!!} 32 | 33 | or-over-and 34 | : {A B C : Set} 35 | → (A and B) or C 36 | → (A or C) and (B or C) 37 | or-over-and (first (both a b)) = both (first a) (first b) 38 | or-over-and (second x) = both (second x) (second x) 39 | 40 | and-over-or 41 | : {A B C : Set} 42 | → (A or B) and C 43 | → (A and C) or (B and C) 44 | and-over-or x = {!!} 45 | 46 | data Empty : Set where 47 | 48 | not : (A : Set) → Set 49 | not A = A → Empty 50 | 51 | empty-to-anything : {A : Set} → Empty → A 52 | empty-to-anything () 53 | 54 | -- (A and B) → not (not A or not B) 55 | not-not-and : {A B : Set} → (A and B) → not (not A or not B) 56 | not-not-and (both a b) (first ae) = ae a 57 | not-not-and (both a b) (second be) = be b 58 | 59 | -- (A or B) → not (not A and not B) 60 | not-not-or : {A B : Set} → (A or B) → not (not A and not B) 61 | not-not-or x = {!!} 62 | 63 | -- (not A or not B) → not (A and B) 64 | not-from-or : {A B : Set} → (not A or not B) → not (A and B) 65 | not-from-or x = {!!} 66 | 67 | -- (not A and not B) → not (A or B) 68 | not-from-and : {A B : Set} → (not A and not B) → not (A or B) 69 | not-from-and x = {!!} 70 | 71 | -- (A and B) → not (A → not B) 72 | and-not-arrow : {A B : Set} → (A and B) → not (A → not B) 73 | and-not-arrow x = {!!} 74 | 75 | -- (A → B) → not (A and not B) 76 | arrow-not-and-not : {A B : Set} → (A → B) → not (A and not B) 77 | arrow-not-and-not f (both a be) = be (f a) 78 | 79 | -- (A and not B) → not (A → B) 80 | and-not-not-arrow : {A B : Set} → (A and not B) → not (A → B) 81 | and-not-not-arrow x = {!!} 82 | 83 | -- (A → not B) → not (A and B) 84 | arrow-not-and : {A B : Set} → (A → not B) → not (A and B) 85 | arrow-not-and f = {!!} 86 | 87 | -- not (A and B) → (A → not B) 88 | not-and-arrow-not : {A B : Set} → not (A and B) → (A → not B) 89 | not-and-arrow-not f = {!!} 90 | 91 | -- (A → B) → ((A → (B → C)) → (A → C)) 92 | arrow-trans : {A B C : Set} → (A → B) → ((A → (B → C)) → (A → C)) 93 | arrow-trans f g = {!!} 94 | 95 | -- A → (B → A and B) 96 | arrow-and : {A B : Set} → A → (B → A and B) 97 | arrow-and a b = {!!} 98 | 99 | -- (A → C) → ((B → C) → (A or B → C)) 100 | arrow-or : {A B C : Set} → (A → C) → ((B → C) → (A or B → C)) 101 | arrow-or f g = {!!} 102 | 103 | -- (A → B) → ((A → not B) → not A) 104 | arrow-nots : {A B : Set} → (A → B) → ((A → not B) → not A) 105 | arrow-nots f g = {!!} 106 | 107 | -- not A → (A → B) 108 | not-arrow : {A B : Set} → not A → (A → B) 109 | not-arrow f a = empty-to-anything (f a) 110 | 111 | -- (A or B) → (not A → B) 112 | or-not-arrow : {A B : Set} → (A or B) → (not A → B) 113 | or-not-arrow (first a) ae = empty-to-anything (ae a) 114 | or-not-arrow (second b) ae = b 115 | 116 | -- (not A or B) → (A → B) 117 | not-or-arrow : {A B : Set} → (not A or B) → (A → B) 118 | not-or-arrow x = {!!} 119 | 120 | 121 | module ApplyExample where 122 | data X : Set where 123 | -- constructors... 124 | data A : X → Set where -- note that (A : X → Set) 125 | given : (x : X) → A x 126 | 127 | -- ∀xA(x) → A(t) 128 | apply-example : {X : Set} → {A : X → Set} → ((x : X) → A x) → (t : X) → A t 129 | apply-example f t = f t 130 | 131 | -- A(t) → ∃xA(x) 132 | data Pair (X : Set) (A : X → Set) : Set where 133 | pair : (x : X) → (A x) → Pair X A 134 | 135 | -- A(t) → ∃xA(x) 136 | pair-example : {X : Set} → {A : X → Set} → (t : X) → (A t) → Pair X A 137 | pair-example t v = pair t v 138 | 139 | 140 | -- not (A or B) → (not A and not B) 141 | not-over-or : {A B : Set} → not (A or B) → (not A and not B) 142 | not-over-or {A} {B} f = both notA notB 143 | where 144 | notA : A → Empty 145 | notA x = f (first x) 146 | 147 | notB : B → Empty 148 | notB x = f (second x) 149 | 150 | -- not (not (A or not A)) 151 | not-not-exclusive-middle : {A : Set} → not (not (A or not A)) 152 | not-not-exclusive-middle {A} f = f A-or-not-A 153 | where 154 | -- f : A or (A → Empty) → Empty 155 | not-A : not A -- A → Empty 156 | not-A x = f (first x) 157 | 158 | A-or-not-A : A or not A -- A or (A → Empty) 159 | A-or-not-A = second not-A 160 | -------------------------------------------------------------------------------- /Exercises/05-List.agda: -------------------------------------------------------------------------------- 1 | module 05-List where 2 | 3 | open import Agda.Primitive 4 | open import Agda.Builtin.Nat 5 | open import Agda.Builtin.Equality 6 | 7 | data Boolean : Set where true false : Boolean 8 | 9 | infixr 5 _∷_ 10 | data List {a : Level} (A : Set a) : Set a where 11 | [] : List A 12 | _∷_ : (x : A) → (xs : List A) → List A 13 | 14 | length : {a : Level} → {A : Set a} → List A → Nat 15 | length [] = 0 16 | length (x ∷ xs) = 1 + length xs 17 | 18 | length-empty-0 : {a : Level} → {A : Set a} → length ([] {A = A}) ≡ 0 19 | length-empty-0 = refl 20 | 21 | length-two : {a : Level} → {A : Set a} → {x : A} → length (x ∷ x ∷ []) ≡ 2 22 | length-two = refl 23 | 24 | replicate : {a : Level} → {A : Set a} → Nat → A → List A 25 | replicate zero x = [] 26 | replicate (suc n) x = x ∷ replicate n x 27 | 28 | length-replicate : {a : Level} → {A : Set a} → (n : Nat) → (x : A) → length (replicate n x) ≡ n 29 | length-replicate zero x = refl 30 | length-replicate (suc n) x rewrite length-replicate n x = refl 31 | 32 | map : {a b : Level} → {A : Set a} → {B : Set b} 33 | → (f : A → B) 34 | → List A 35 | → List B 36 | map f [] = [] 37 | map f (x ∷ xs) = f x ∷ map f xs 38 | 39 | map-preserves-length : {a b : Level} → {A : Set a} → {B : Set b} 40 | → (f : A → B) 41 | → (xs : List A) 42 | → length (map f xs) ≡ length xs 43 | map-preserves-length f [] = refl 44 | map-preserves-length f (x ∷ xs) rewrite map-preserves-length f xs = refl 45 | 46 | apply : {a b : Level} → {A : Set a} → {B : Set b} 47 | → List (A → B) 48 | → List A 49 | → List B 50 | apply [] [] = [] 51 | apply [] (x ∷ xs) = [] 52 | apply (f ∷ fs) [] = [] 53 | apply (f ∷ fs) (x ∷ xs) = f x ∷ apply fs xs 54 | 55 | append : {a : Level} → {A : Set a} → List A → List A → List A 56 | append xs ys = {!!} 57 | 58 | append-length : {a : Level} → {A : Set a} 59 | → (xs : List A) 60 | → (ys : List A) 61 | → length (append xs ys) ≡ length xs + length ys 62 | append-length xs ys = {!!} 63 | 64 | data Vec {a : Level} (A : Set a) : Nat → Set a where 65 | [] : Vec A zero 66 | _∷_ : {n : Nat} → A → Vec A n → Vec A (suc n) 67 | 68 | vlength : {a : Level} → {A : Set a} → {n : Nat} → Vec A n → Nat 69 | vlength {n = n} v = n 70 | 71 | vreplicate : {a : Level} → {A : Set a} → (n : Nat) → A → Vec A n 72 | vreplicate zero x = [] 73 | vreplicate (suc n) x = x ∷ vreplicate n x 74 | 75 | vmap : {a b : Level} → {A : Set a} → {B : Set b} → {n : Nat} 76 | → (f : A → B) 77 | → Vec A n 78 | → Vec B n 79 | vmap f [] = [] 80 | vmap f (x ∷ xs) = f x ∷ vmap f xs 81 | 82 | vapply : {a b : Level} → {A : Set a} → {B : Set b} → {n : Nat} 83 | → Vec (A → B) n 84 | → Vec A n 85 | → Vec B n 86 | vapply [] [] = [] 87 | vapply (f ∷ fs) (x ∷ xs) = f x ∷ vapply fs xs 88 | 89 | vappend : {a : Level} → {A : Set a} → {n m : Nat} 90 | → Vec A n 91 | → Vec A m 92 | → Vec A (n + m) 93 | vappend xs ys = {!!} 94 | -------------------------------------------------------------------------------- /Exercises/HelloWorld.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --no-termination-check #-} 2 | 3 | module HelloWorld where 4 | 5 | open import Agda.Builtin.IO 6 | open import Agda.Builtin.String 7 | open import Agda.Builtin.Unit 8 | 9 | postulate 10 | putStrLn : String → IO ⊤ 11 | _⟫=_ : {A B : Set} → IO A → (A → IO B) → IO B 12 | 13 | {-# IMPORT Data.Text.IO #-} 14 | {-# COMPILED putStrLn Data.Text.IO.putStrLn #-} 15 | {-# COMPILED _⟫=_ (\ _ _ a f -> a >>= f) #-} 16 | 17 | main : IO ⊤ 18 | main 19 | = putStrLn "Hello, world!" 20 | ⟫= λ _ → main 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | agda = agda 2 | 3 | default : type-check 4 | 5 | everything : 6 | @echo "module Everything where" > Solutions/Everything.agda 7 | @find Solutions -name '*.agda' -not -path 'Solutions/Everything.agda' | sed -e 's/Solutions\///;s/\//./g;s/\.agda$$//;s/^/import /' >> Solutions/Everything.agda 8 | 9 | type-check : everything 10 | $(agda) -i Solutions Solutions/Everything.agda 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Agda from Nothing 2 | 3 | A workshop on learning Agda with minimal prerequisites. 4 | 5 | ### Installing Agda 6 | The exercises are written for Agda 2.5.1. 7 | 8 | #### Official Agda installation instructions 9 | * http://agda.readthedocs.io/en/latest/getting-started/installation.html 10 | * http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.Download 11 | 12 | #### On Mac 13 | You may find `stack` more reliable than `cabal` to build Agda. 14 | 15 | 1. Install [stack](http://docs.haskellstack.org/en/stable/install_and_upgrade/#mac-os-x) 16 | 2. In a terminal run: `stack install --resolver nightly-2016-05-08 Agda` 17 | 3. Install [Aquamacs](http://aquamacs.org/) 18 | 4. In a terminal run: `agda-mode setup` 19 | 5. (Restart Aquamacs) 20 | 21 | #### Docker 22 | 23 | ##### Docker with Emacs and exercises 24 | I created a Docker image with Agda, Emacs and the exercises. See [scottfleischman/agda-from-nothing](https://hub.docker.com/r/scottfleischman/agda-from-nothing/) 25 | 26 | `docker run -it scottfleischman/agda-from-nothing` 27 | 28 | **Note** The Mac Terminal has issues sending common control sequences such as Control+Comma. It may be better to do a full install as above, or use Docker with Agda as below with a local editor and agda-mode. 29 | 30 | ##### Docker with Agda only 31 | See [banacorn/docker-agda](https://github.com/banacorn/docker-agda). 32 | 33 | ### Emacs Keybindings 34 | See the [Agda docs](http://agda.readthedocs.io/en/latest/tools/emacs-mode.html) for all of the keybindsings. Here are ones I commonly use. Note `C-` means `Control+`. 35 | 36 | #### Global (can be used anywhere) 37 | * C-c C-l — Load file. I use this constantly. 38 | * C-c C-f — Move to next goal (**f**orward) 39 | * C-c C-b — Move to previous goal (**b**ackwards) 40 | * C-c C-d — Infer (**d**educe) type. Type in any expression and it infers the type. 41 | * C-c C-n — Compute **n**ormal form. In other words, reduces the expression as much as possible. 42 | * C-g — Quit what command sequence you started. 43 | 44 | #### In a hole/goal 45 | * C-c C-c — Case split. Type in an argument name and it creates lines for each possible case. It works with multiple arguments. 46 | * C-u C-c C-Comma — Show unnormalized goal type and context. 47 | * C-u C-u C-c C-Comma — Show fully normalized goal type and context. 48 | * C-c C-Space — Give (fill goal). Type checks the expression you typed in the hole, and if successful fills the hole. 49 | * C-c C-r — Refine. Partial give: makes new holes for missing arguments. 50 | * If you've entered an expression in the hole, it will fill in the hole with that expression and make new holes for any missing arguments. 51 | * If you haven't entered anything in the hole, and if the hole is constrained to one constructor, it fills in the hole with that constructor and makes new holes for each of the constructor's arguments. 52 | * C-c C-a — Automatic Proof Search (Auto). Tries to fill the hole with any solution. Note—this may not be a correct solution if the types aren't precise enough to constrain the term to only correct ones. Note also that it often fails to find a solution. 53 | 54 | #### Unicode characters 55 | * `\r-` or `\to` for `→` 56 | * `\==` for `≡` 57 | * `\==n` for `≢` 58 | * `\all` for `∀` 59 | * `\<=` for `≤` 60 | * `\<=n` for `≰` 61 | * `\ell` for `ℓ` 62 | * `\lambda` or `\Gl` for `λ` 63 | * `\'` for `′` 64 | * `\::` for `∷` (it looks like two colons, but it is a single Unicode character) 65 | * `\_0` for `₀` (subscript 0) 66 | * `\_1` for `₁` (and so on) 67 | * `\^0` for `⁰` (superscript 0) 68 | * `\^1` for `¹` (and so on) 69 | * `\in` for `∈` 70 | * `\ni` for `∋` 71 | * `\lub` for `⊔` (least upper bound; max) 72 | * `\Pi` for `Π` 73 | * `\Sigma` or `\GS` for `Σ` 74 | * To see info on a character under the cursor, use `C-u C-x Equals` 75 | 76 | ### Resources 77 | * [Agda Documentation (new, unfinished)](http://agda.readthedocs.io/) 78 | * The [Agda Wiki](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.Documentation) has links to other resources. 79 | * Book: [Verified Functional Programming in Agda](http://www.amazon.com/Verified-Functional-Programming-Aaron-Stump/dp/1970001240) by Aaron Stump 80 | -------------------------------------------------------------------------------- /Slides/01 - Intro-History.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scott-fleischman/agda-from-nothing/dab66f9bd77fc6af388744cdcd5ab12ff28896b9/Slides/01 - Intro-History.pdf -------------------------------------------------------------------------------- /Slides/02 - Basic Inductive Types.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scott-fleischman/agda-from-nothing/dab66f9bd77fc6af388744cdcd5ab12ff28896b9/Slides/02 - Basic Inductive Types.pdf -------------------------------------------------------------------------------- /Slides/03 - Simple Normalization.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scott-fleischman/agda-from-nothing/dab66f9bd77fc6af388744cdcd5ab12ff28896b9/Slides/03 - Simple Normalization.pdf -------------------------------------------------------------------------------- /Slides/04 - Dependent Types.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scott-fleischman/agda-from-nothing/dab66f9bd77fc6af388744cdcd5ab12ff28896b9/Slides/04 - Dependent Types.pdf -------------------------------------------------------------------------------- /Slides/05 - Negation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scott-fleischman/agda-from-nothing/dab66f9bd77fc6af388744cdcd5ab12ff28896b9/Slides/05 - Negation.pdf -------------------------------------------------------------------------------- /Solutions/01-Boolean.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --exact-split #-} 2 | 3 | module 01-Boolean where 4 | 5 | -- Precedences 6 | 7 | infixl 6 _or_ _xor_ _iff_ 8 | infixl 7 _and_ 9 | infixl 4 _≡_ 10 | 11 | -- Data Types 12 | 13 | data Boolean : Set where 14 | false true : Boolean 15 | 16 | data Unit : Set where 17 | unit : Unit 18 | 19 | data Empty : Set where 20 | 21 | data _≡_ (x : Boolean) : Boolean → Set where 22 | equal : x ≡ x 23 | 24 | -- Functions 25 | 26 | not : Boolean → Boolean 27 | not false = true 28 | not true = false 29 | 30 | _and_ : Boolean → Boolean → Boolean 31 | false and _ = false 32 | true and y = y 33 | 34 | _or_ : Boolean → Boolean → Boolean 35 | false or y = y 36 | true or _ = true 37 | 38 | _nand_ : Boolean → Boolean → Boolean 39 | false nand false = true 40 | false nand true = true 41 | true nand false = true 42 | true nand true = false 43 | 44 | _nor_ : Boolean → Boolean → Boolean 45 | false nor false = true 46 | false nor true = false 47 | true nor false = false 48 | true nor true = false 49 | 50 | _iff_ : Boolean → Boolean → Boolean 51 | false iff false = true 52 | false iff true = false 53 | true iff false = false 54 | true iff true = true 55 | 56 | _xor_ : Boolean → Boolean → Boolean 57 | false xor false = false 58 | false xor true = true 59 | true xor false = true 60 | true xor true = false 61 | 62 | if_then_else_ : {X : Set} → Boolean → X → X → X 63 | if false then _ else y = y 64 | if true then x else _ = x 65 | 66 | not′ : Boolean → Boolean 67 | not′ b = if b then false else true 68 | 69 | -- Sanity checks 70 | 71 | not-true-eq-false : not true ≡ false 72 | not-true-eq-false = equal 73 | 74 | not-false-eq-true : not false ≡ true 75 | not-false-eq-true = equal 76 | 77 | true-and-true-eq-true : true and true ≡ true 78 | true-and-true-eq-true = equal 79 | 80 | false-or-false-eq-false : false or false ≡ false 81 | false-or-false-eq-false = equal 82 | 83 | if-true-then-false-eq-false : if true then false else true ≡ false 84 | if-true-then-false-eq-false = equal 85 | 86 | -- Trivial Properties 87 | 88 | false-and-x-eq-false : (x : Boolean) → false and x ≡ false 89 | false-and-x-eq-false _ = equal 90 | 91 | true-or-x-eq-true : (x : Boolean) → true or x ≡ true 92 | true-or-x-eq-true _ = equal 93 | 94 | -- Properties requiring proof 95 | 96 | not-eq-not′ : (x : Boolean) → not x ≡ not′ x 97 | not-eq-not′ false = equal -- Goal: not false ≡ not′ false 98 | not-eq-not′ true = equal -- Goal: not true ≡ not′ true 99 | 100 | x-and-false-eq-false : (x : Boolean) → x and false ≡ false 101 | x-and-false-eq-false false = equal -- Goal: false and false ≡ false 102 | x-and-false-eq-false true = equal -- Goal: true and false ≡ false 103 | 104 | true-eq-true-or-x : (x : Boolean) → x or true ≡ true 105 | true-eq-true-or-x false = equal -- Goal: false or true ≡ true 106 | true-eq-true-or-x true = equal -- Goal: true or true ≡ true 107 | 108 | nand-eq-not-and : (x y : Boolean) → x nand y ≡ not (x and y) 109 | nand-eq-not-and false false = equal 110 | nand-eq-not-and false true = equal 111 | nand-eq-not-and true false = equal 112 | nand-eq-not-and true true = equal 113 | 114 | nor-eq-not-or : (x y : Boolean) → x nor y ≡ not (x or y) 115 | nor-eq-not-or false false = equal 116 | nor-eq-not-or false true = equal 117 | nor-eq-not-or true false = equal 118 | nor-eq-not-or true true = equal 119 | 120 | xor-eq-not-iff : (x y : Boolean) → x xor y ≡ not (x iff y) 121 | xor-eq-not-iff false false = equal 122 | xor-eq-not-iff false true = equal 123 | xor-eq-not-iff true false = equal 124 | xor-eq-not-iff true true = equal 125 | 126 | -- Properties using other proofs 127 | 128 | iff-same-true : (x y : Boolean) → x ≡ y → x iff y ≡ true 129 | iff-same-true false .false equal = equal 130 | iff-same-true true .true equal = equal 131 | 132 | xor-same-false : (x y : Boolean) → x ≡ y → x xor y ≡ false 133 | xor-same-false false .false equal = equal 134 | xor-same-false true .true equal = equal 135 | 136 | -- Simple properties involving negation 137 | 138 | true-and-true-not-false : true and true ≡ false → Empty 139 | true-and-true-not-false () 140 | 141 | false-or-false-not-true : false or false ≡ true → Empty 142 | false-or-false-not-true () 143 | 144 | false-and-x-not-true : (x : Boolean) → false and x ≡ true → Empty 145 | false-and-x-not-true x () 146 | 147 | true-or-x-not-false : (x : Boolean) → true or x ≡ false → Empty 148 | true-or-x-not-false x () 149 | 150 | x-and-false-not-true : (x : Boolean) → x and false ≡ true → Empty 151 | x-and-false-not-true false () 152 | x-and-false-not-true true () 153 | 154 | x-or-true-not-false : (x : Boolean) → x or true ≡ false → Empty 155 | x-or-true-not-false false () 156 | x-or-true-not-false true () 157 | 158 | -- Properties using other negations 159 | 160 | empty-to-anything : {A : Set} → Empty → A 161 | empty-to-anything () 162 | 163 | iff-different-false : (x y : Boolean) → (x ≡ y → Empty) → x iff y ≡ false 164 | iff-different-false false false p = empty-to-anything (p equal) 165 | iff-different-false false true p = equal 166 | iff-different-false true false p = equal 167 | iff-different-false true true p = empty-to-anything (p equal) 168 | 169 | xor-different-true : (x y : Boolean) → (x ≡ y → Empty) → x xor y ≡ true 170 | xor-different-true false false p = empty-to-anything (p equal) 171 | xor-different-true false true p = equal 172 | xor-different-true true false p = equal 173 | xor-different-true true true p = empty-to-anything (p equal) 174 | -------------------------------------------------------------------------------- /Solutions/02-Natural.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --exact-split #-} 2 | 3 | module 02-Natural where 4 | 5 | infixl 6 _+_ 6 | infixl 7 _*_ 7 | infixl 4 _≡_ _≢_ 8 | 9 | data Natural : Set where 10 | zero : Natural 11 | suc : Natural → Natural 12 | {-# BUILTIN NATURAL Natural #-} 13 | 14 | _+_ : Natural → Natural → Natural 15 | zero + y = y 16 | (suc x) + y = suc (x + y) 17 | {-# BUILTIN NATPLUS _+_ #-} 18 | 19 | _-_ : Natural → Natural → Natural 20 | x - zero = x 21 | zero - suc y = zero 22 | suc x - suc y = x - y 23 | {-# BUILTIN NATMINUS _-_ #-} 24 | 25 | _*_ : Natural → Natural → Natural 26 | zero * y = zero 27 | suc x * y = y + (x * y) 28 | {-# BUILTIN NATTIMES _*_ #-} 29 | 30 | _^_ : Natural → Natural → Natural 31 | x ^ zero = suc zero 32 | x ^ suc y = x * (x ^ y) 33 | 34 | open import Agda.Primitive using (Level) 35 | data _≡_ {ℓ : Level} {X : Set ℓ} (x : X) : X → Set ℓ where 36 | equal : x ≡ x 37 | {-# BUILTIN EQUALITY _≡_ #-} 38 | {-# BUILTIN REFL equal #-} 39 | 40 | data Empty : Set where 41 | 42 | _≢_ : {ℓ : Level} → {X : Set ℓ} → (x y : X) → Set ℓ 43 | x ≢ y = x ≡ y → Empty 44 | 45 | 0+0 : 0 + 0 ≡ 0 46 | 0+0 = equal 47 | 48 | 2+2 : 2 + 2 ≡ 4 49 | 2+2 = equal 50 | 51 | 2+2≢5 : 2 + 2 ≢ 5 52 | 2+2≢5 () 53 | 54 | 1+1≢3 : 1 + 1 ≢ 3 55 | 1+1≢3 () 56 | 57 | 2^3 : 2 ^ 3 ≡ 8 58 | 2^3 = equal 59 | 60 | 2^8 : 2 ^ 8 ≡ 256 61 | 2^8 = equal 62 | 63 | 0*x : (x : Natural) → 0 * x ≡ 0 64 | 0*x x = equal 65 | 66 | x*0 : (x : Natural) → x * 0 ≡ 0 67 | x*0 zero = equal 68 | x*0 (suc x) = x*0 x 69 | 70 | symmetry 71 | : {x y : Natural} 72 | → x ≡ y 73 | → y ≡ x 74 | symmetry equal = equal 75 | 76 | congruence 77 | : {x y : Natural} 78 | → (f : Natural → Natural) 79 | → x ≡ y 80 | → f x ≡ f y 81 | congruence f equal = equal 82 | 83 | 0+x : (x : Natural) → 0 + x ≡ x 84 | 0+x x = equal 85 | 86 | x+0 : (x : Natural) → x + 0 ≡ x 87 | x+0 zero = equal -- Goal: zero + 0 ≡ zero 88 | x+0 (suc x) = congruence suc (x+0 x) -- Goal: suc x + 0 ≡ suc x 89 | 90 | x*1 : (x : Natural) → x * 1 ≡ x 91 | x*1 zero = equal 92 | x*1 (suc x) rewrite x*1 x = equal 93 | 94 | 1*x : (x : Natural) → 1 * x ≡ x 95 | 1*x zero = equal 96 | 1*x (suc x) rewrite 1*x x = equal 97 | 98 | +-associative : (x y z : Natural) → (x + y) + z ≡ x + (y + z) 99 | +-associative zero y z = equal 100 | +-associative (suc x) y z rewrite +-associative x y z = equal 101 | 102 | +-suc : (x y : Natural) → x + suc y ≡ suc (x + y) 103 | +-suc zero y = equal 104 | +-suc (suc x) y rewrite +-suc x y = equal 105 | 106 | +-commutative : (x y : Natural) → x + y ≡ y + x 107 | +-commutative zero y rewrite x+0 y = equal 108 | +-commutative (suc x) y 109 | rewrite +-suc y x 110 | | +-commutative x y 111 | = equal 112 | 113 | +*-dist : (x y z : Natural) → (x + y) * z ≡ (x * z) + (y * z) 114 | +*-dist zero y z = equal 115 | +*-dist (suc x) y z 116 | rewrite +-associative z (x * z) (y * z) 117 | | +*-dist x y z 118 | = equal 119 | 120 | *-associative : (x y z : Natural) → (x * y) * z ≡ x * (y * z) 121 | *-associative zero y z = equal 122 | *-associative (suc x) y z 123 | rewrite +*-dist y (x * y) z 124 | | *-associative x y z 125 | = equal 126 | 127 | *-suc : (x y : Natural) → x * suc y ≡ x + (x * y) 128 | *-suc zero y = equal 129 | *-suc (suc x) y 130 | rewrite *-suc x y 131 | | symmetry (+-associative y x (x * y)) 132 | | symmetry (+-associative x y (x * y)) 133 | | +-commutative x y 134 | = equal 135 | 136 | *-commutative : (x y : Natural) → x * y ≡ y * x 137 | *-commutative zero y rewrite x*0 y = equal 138 | *-commutative (suc x) y 139 | rewrite *-suc y x 140 | | *-commutative x y 141 | = equal 142 | 143 | data _≤_ : Natural → Natural → Set where 144 | zero≤ : (y : Natural) → zero ≤ y 145 | suc≤suc : (x y : Natural) → x ≤ y → suc x ≤ suc y 146 | 147 | data Total≤ (x y : Natural) : Set where 148 | x≤y : x ≤ y → Total≤ x y 149 | y≤x : y ≤ x → Total≤ x y 150 | 151 | totality : (x y : Natural) → Total≤ x y 152 | totality zero y = x≤y (zero≤ y) 153 | totality (suc x) zero = y≤x (zero≤ (suc x)) 154 | totality (suc x) (suc y) with totality x y 155 | totality (suc x) (suc y) | x≤y p = x≤y (suc≤suc x y p) 156 | totality (suc x) (suc y) | y≤x p = y≤x (suc≤suc y x p) 157 | 158 | antisymmetry : (x y : Natural) → x ≤ y → y ≤ x → x ≡ y 159 | antisymmetry .0 .0 (zero≤ .0) (zero≤ .0) = equal 160 | antisymmetry .(suc x) .(suc y) (suc≤suc x y left) (suc≤suc .y .x right) rewrite antisymmetry x y left right = equal 161 | 162 | transitivity : (x y z : Natural) → x ≤ y → y ≤ z → x ≤ z 163 | transitivity .0 .0 z (zero≤ .0) (zero≤ .z) = zero≤ z 164 | transitivity .0 .(suc x) .(suc y) (zero≤ .(suc x)) (suc≤suc x y right) = zero≤ (suc y) 165 | transitivity .(suc x) .(suc y) .(suc z) (suc≤suc x y left) (suc≤suc .y z right) = suc≤suc x z (transitivity x y z left right) 166 | 167 | open import 01-Boolean using (Boolean; true; false) 168 | 169 | _≤?_ : Natural → Natural → Boolean 170 | zero ≤? y = true 171 | suc x ≤? zero = false 172 | suc x ≤? suc y = x ≤? y 173 | 174 | 2≤?3 : 2 ≤? 3 ≡ true 175 | 2≤?3 = equal 176 | 177 | 3≤?2 : 3 ≤? 2 ≡ false 178 | 3≤?2 = equal 179 | 180 | equal≤? : (x y : Natural) → x ≡ y → x ≤? y ≡ true 181 | equal≤? zero .0 equal = equal 182 | equal≤? (suc x) .(suc x) equal = equal≤? x x equal 183 | 184 | antisymmetry-bool : (x y : Natural) → x ≤? y ≡ true → y ≤? x ≡ true → x ≡ y 185 | antisymmetry-bool zero zero equal equal = equal 186 | antisymmetry-bool zero (suc y) equal () 187 | antisymmetry-bool (suc x) zero () right 188 | antisymmetry-bool (suc x) (suc y) left right with antisymmetry-bool x y left right 189 | antisymmetry-bool (suc x) (suc .x) left right | equal = equal 190 | 191 | data Total≤? (x y : Natural) : Set where 192 | x≤?y : x ≤? y ≡ true → Total≤? x y 193 | y≤?x : y ≤? x ≡ true → Total≤? x y 194 | 195 | totality-bool : (x y : Natural) → Total≤? x y 196 | totality-bool zero zero = x≤?y equal 197 | totality-bool zero (suc y) = x≤?y equal 198 | totality-bool (suc x) zero = y≤?x equal 199 | totality-bool (suc x) (suc y) with totality-bool x y 200 | totality-bool (suc x) (suc y) | x≤?y p = x≤?y p 201 | totality-bool (suc x) (suc y) | y≤?x p = y≤?x p 202 | 203 | transitivity-bool : (x y z : Natural) → x ≤? y ≡ true → y ≤? z ≡ true → x ≤? z ≡ true 204 | transitivity-bool zero zero zero equal equal = equal 205 | transitivity-bool zero zero (suc z) equal equal = equal 206 | transitivity-bool zero (suc y) zero equal () 207 | transitivity-bool zero (suc y) (suc z) left right = equal 208 | transitivity-bool (suc x) zero zero () right 209 | transitivity-bool (suc x) zero (suc z) () right 210 | transitivity-bool (suc x) (suc y) zero left () 211 | transitivity-bool (suc x) (suc y) (suc z) left right = transitivity-bool x y z left right 212 | -------------------------------------------------------------------------------- /Solutions/03-Equality.agda: -------------------------------------------------------------------------------- 1 | module 03-Equality where 2 | 3 | open import Agda.Primitive using (Level) 4 | 5 | data _≡_ {a : Level} {A : Set a} (x : A) : A → Set a where 6 | equal : x ≡ x 7 | {-# BUILTIN EQUALITY _≡_ #-} 8 | {-# BUILTIN REFL equal #-} 9 | 10 | symmetry 11 | : {a : Level} 12 | → {A : Set a} 13 | → (x y : A) 14 | → x ≡ y 15 | → y ≡ x 16 | symmetry x .x equal = equal 17 | 18 | transitivity 19 | : {a : Level} 20 | → {A : Set a} 21 | → (x y z : A) 22 | → x ≡ y 23 | → y ≡ z 24 | → x ≡ z 25 | transitivity x .x .x equal equal = equal 26 | 27 | congruence 28 | : {a b : Level} 29 | → {A : Set a} {B : Set b} 30 | → (f : A → B) 31 | → (x y : A) 32 | → x ≡ y 33 | → f x ≡ f y 34 | congruence f x .x equal = equal 35 | 36 | transport 37 | : {a b : Level} 38 | → {A : Set a} 39 | → (x y : A) 40 | → (P : A → Set b) 41 | → x ≡ y 42 | → P x 43 | → P y 44 | transport x .x P equal px = px 45 | 46 | leibniz 47 | : {a : Level} 48 | → {A : Set a} 49 | → (x y : A) 50 | → ((P : A → Set a) → P x → P y) 51 | → x ≡ y 52 | leibniz x y H = H (x ≡_) equal 53 | -------------------------------------------------------------------------------- /Solutions/04-Logic.agda: -------------------------------------------------------------------------------- 1 | module 04-Logic where 2 | 3 | infixl 6 _or_ 4 | infixl 7 _and_ 5 | 6 | -- A → (B → A) 7 | modus-ponens : {A B : Set} → (A → B) → A → B 8 | modus-ponens f a = f a 9 | 10 | data _and_ (A B : Set) : Set where 11 | both : (a : A) → (b : B) → A and B 12 | 13 | data _or_ (A B : Set) : Set where 14 | first : (a : A) → A or B 15 | second : (b : B) → A or B 16 | 17 | -- A and B → A 18 | proj1 : {A B : Set} → A and B → A 19 | proj1 (both a b) = a 20 | 21 | -- A and B → B 22 | proj2 : {A B : Set} → A and B → B 23 | proj2 (both a b) = b 24 | 25 | -- A → A or B 26 | inj1 : {A B : Set} → A → A or B 27 | inj1 = first 28 | 29 | -- B → A or B 30 | inj2 : {A B : Set} → B → A or B 31 | inj2 = second 32 | 33 | or-over-and 34 | : {A B C : Set} 35 | → (A and B) or C 36 | → (A or C) and (B or C) 37 | or-over-and (first (both a b)) = both (first a) (first b) 38 | or-over-and (second x) = both (second x) (second x) 39 | 40 | and-over-or 41 | : {A B C : Set} 42 | → (A or B) and C 43 | → (A and C) or (B and C) 44 | and-over-or (both (first a) c) = first (both a c) 45 | and-over-or (both (second b) c) = second (both b c) 46 | 47 | data Empty : Set where 48 | 49 | not : (A : Set) → Set 50 | not A = A → Empty 51 | 52 | empty-to-anything : {A : Set} → Empty → A 53 | empty-to-anything () 54 | 55 | -- (A and B) → not (not A or not B) 56 | not-not-and : {A B : Set} → (A and B) → not (not A or not B) 57 | not-not-and (both a b) (first ae) = ae a 58 | not-not-and (both a b) (second be) = be b 59 | 60 | -- (A or B) → not (not A and not B) 61 | not-not-or : {A B : Set} → (A or B) → not (not A and not B) 62 | not-not-or (first a) (both ae be) = ae a 63 | not-not-or (second b) (both ae be) = be b 64 | 65 | -- (not A or not B) → not (A and B) 66 | not-from-or : {A B : Set} → (not A or not B) → not (A and B) 67 | not-from-or (first ae) (both a b) = ae a 68 | not-from-or (second be) (both a b) = be b 69 | 70 | -- (not A and not B) → not (A or B) 71 | not-from-and : {A B : Set} → (not A and not B) → not (A or B) 72 | not-from-and (both ae be) (first a) = ae a 73 | not-from-and (both ae be) (second b) = be b 74 | 75 | -- (A and B) → not (A → not B) 76 | and-not-arrow : {A B : Set} → (A and B) → not (A → not B) 77 | and-not-arrow (both a b) anb = anb a b 78 | 79 | -- (A → B) → not (A and not B) 80 | arrow-not-and-not : {A B : Set} → (A → B) → not (A and not B) 81 | arrow-not-and-not f (both a be) = be (f a) 82 | 83 | -- (A and not B) → not (A → B) 84 | and-not-not-arrow : {A B : Set} → (A and not B) → not (A → B) 85 | and-not-not-arrow (both a be) ab = be (ab a) 86 | 87 | -- (A → not B) → not (A and B) 88 | arrow-not-and : {A B : Set} → (A → not B) → not (A and B) 89 | arrow-not-and f (both a b) = f a b 90 | 91 | -- not (A and B) → (A → not B) 92 | not-and-arrow-not : {A B : Set} → not (A and B) → (A → not B) 93 | not-and-arrow-not f a b = f (both a b) 94 | 95 | -- (A → B) → ((A → (B → C)) → (A → C)) 96 | arrow-trans : {A B C : Set} → (A → B) → ((A → (B → C)) → (A → C)) 97 | arrow-trans f g a = g a (f a) 98 | 99 | -- A → (B → A and B) 100 | arrow-and : {A B : Set} → A → (B → A and B) 101 | arrow-and a b = both a b 102 | 103 | -- (A → C) → ((B → C) → (A or B → C)) 104 | arrow-or : {A B C : Set} → (A → C) → ((B → C) → (A or B → C)) 105 | arrow-or f g (first a) = f a 106 | arrow-or f g (second b) = g b 107 | 108 | -- (A → B) → ((A → not B) → not A) 109 | arrow-nots : {A B : Set} → (A → B) → ((A → not B) → not A) 110 | arrow-nots f g a = g a (f a) 111 | 112 | -- not A → (A → B) 113 | not-arrow : {A B : Set} → not A → (A → B) 114 | not-arrow f a = empty-to-anything (f a) 115 | 116 | -- (A or B) → (not A → B) 117 | or-not-arrow : {A B : Set} → (A or B) → (not A → B) 118 | or-not-arrow (first a) ae = empty-to-anything (ae a) 119 | or-not-arrow (second b) ae = b 120 | 121 | -- (not A or B) → (A → B) 122 | not-or-arrow : {A B : Set} → (not A or B) → (A → B) 123 | not-or-arrow (first ae) a = empty-to-anything (ae a) 124 | not-or-arrow (second b) a = b 125 | 126 | 127 | module ApplyExample where 128 | data X : Set where 129 | -- constructors... 130 | data A : X → Set where -- note that (A : X → Set) 131 | given : (x : X) → A x 132 | 133 | -- ∀xA(x) → A(t) 134 | apply-example : {X : Set} → {A : X → Set} → ((x : X) → A x) → (t : X) → A t 135 | apply-example f t = f t 136 | 137 | -- A(t) → ∃xA(x) 138 | data Pair (X : Set) (A : X → Set) : Set where 139 | pair : (x : X) → (A x) → Pair X A 140 | 141 | -- A(t) → ∃xA(x) 142 | pair-example : {X : Set} → {A : X → Set} → (t : X) → (A t) → Pair X A 143 | pair-example t v = pair t v 144 | 145 | 146 | -- not (A or B) → (not A and not B) 147 | not-over-or : {A B : Set} → not (A or B) → (not A and not B) 148 | not-over-or {A} {B} f = both notA notB 149 | where 150 | notA : A → Empty 151 | notA x = f (first x) 152 | 153 | notB : B → Empty 154 | notB x = f (second x) 155 | 156 | -- not (not (A or not A)) 157 | not-not-exclusive-middle : {A : Set} → not (not (A or not A)) 158 | not-not-exclusive-middle {A} f = f A-or-not-A 159 | where 160 | -- f : A or (A → Empty) → Empty 161 | not-A : not A -- A → Empty 162 | not-A x = f (first x) 163 | 164 | A-or-not-A : A or not A -- A or (A → Empty) 165 | A-or-not-A = second not-A 166 | -------------------------------------------------------------------------------- /Solutions/05-List.agda: -------------------------------------------------------------------------------- 1 | module 05-List where 2 | 3 | open import Agda.Primitive 4 | open import Agda.Builtin.Nat 5 | open import Agda.Builtin.Equality 6 | 7 | data Boolean : Set where true false : Boolean 8 | 9 | infixr 5 _∷_ 10 | data List {a : Level} (A : Set a) : Set a where 11 | [] : List A 12 | _∷_ : (x : A) → (xs : List A) → List A 13 | 14 | length : {a : Level} → {A : Set a} → List A → Nat 15 | length [] = 0 16 | length (x ∷ xs) = 1 + length xs 17 | 18 | length-empty-0 : {a : Level} → {A : Set a} → length ([] {A = A}) ≡ 0 19 | length-empty-0 = refl 20 | 21 | length-two : {a : Level} → {A : Set a} → {x : A} → length (x ∷ x ∷ []) ≡ 2 22 | length-two = refl 23 | 24 | replicate : {a : Level} → {A : Set a} → Nat → A → List A 25 | replicate zero x = [] 26 | replicate (suc n) x = x ∷ replicate n x 27 | 28 | length-replicate : {a : Level} → {A : Set a} → (n : Nat) → (x : A) → length (replicate n x) ≡ n 29 | length-replicate zero x = refl 30 | length-replicate (suc n) x rewrite length-replicate n x = refl 31 | 32 | map : {a b : Level} → {A : Set a} → {B : Set b} 33 | → (f : A → B) 34 | → List A 35 | → List B 36 | map f [] = [] 37 | map f (x ∷ xs) = f x ∷ map f xs 38 | 39 | map-preserves-length : {a b : Level} → {A : Set a} → {B : Set b} 40 | → (f : A → B) 41 | → (xs : List A) 42 | → length (map f xs) ≡ length xs 43 | map-preserves-length f [] = refl 44 | map-preserves-length f (x ∷ xs) rewrite map-preserves-length f xs = refl 45 | 46 | apply : {a b : Level} → {A : Set a} → {B : Set b} 47 | → List (A → B) 48 | → List A 49 | → List B 50 | apply [] [] = [] 51 | apply [] (x ∷ xs) = [] 52 | apply (f ∷ fs) [] = [] 53 | apply (f ∷ fs) (x ∷ xs) = f x ∷ apply fs xs 54 | 55 | append : {a : Level} → {A : Set a} → List A → List A → List A 56 | append [] ys = ys 57 | append (x ∷ xs) ys = x ∷ append xs ys 58 | 59 | append-length : {a : Level} → {A : Set a} 60 | → (xs : List A) 61 | → (ys : List A) 62 | → length (append xs ys) ≡ length xs + length ys 63 | append-length [] ys = refl 64 | append-length (x ∷ xs) ys rewrite append-length xs ys = refl 65 | 66 | data Vec {a : Level} (A : Set a) : Nat → Set a where 67 | [] : Vec A zero 68 | _∷_ : {n : Nat} → A → Vec A n → Vec A (suc n) 69 | 70 | vlength : {a : Level} → {A : Set a} → {n : Nat} → Vec A n → Nat 71 | vlength {n = n} v = n 72 | 73 | vreplicate : {a : Level} → {A : Set a} → (n : Nat) → A → Vec A n 74 | vreplicate zero x = [] 75 | vreplicate (suc n) x = x ∷ vreplicate n x 76 | 77 | vmap : {a b : Level} → {A : Set a} → {B : Set b} → {n : Nat} 78 | → (f : A → B) 79 | → Vec A n 80 | → Vec B n 81 | vmap f [] = [] 82 | vmap f (x ∷ xs) = f x ∷ vmap f xs 83 | 84 | vapply : {a b : Level} → {A : Set a} → {B : Set b} → {n : Nat} 85 | → Vec (A → B) n 86 | → Vec A n 87 | → Vec B n 88 | vapply [] [] = [] 89 | vapply (f ∷ fs) (x ∷ xs) = f x ∷ vapply fs xs 90 | 91 | vappend : {a : Level} → {A : Set a} → {n m : Nat} 92 | → Vec A n 93 | → Vec A m 94 | → Vec A (n + m) 95 | vappend [] ys = ys 96 | vappend (x ∷ xs) ys = x ∷ vappend xs ys 97 | -------------------------------------------------------------------------------- /Solutions/Everything.agda: -------------------------------------------------------------------------------- 1 | module Everything where 2 | import 01-Boolean 3 | import 02-Natural 4 | import 04-Logic 5 | -------------------------------------------------------------------------------- /Solutions/HelloWorld.agda: -------------------------------------------------------------------------------- 1 | {-# OPTIONS --no-termination-check #-} 2 | 3 | module HelloWorld where 4 | 5 | open import Agda.Builtin.IO 6 | open import Agda.Builtin.String 7 | open import Agda.Builtin.Unit 8 | 9 | postulate 10 | putStrLn : String → IO ⊤ 11 | _⟫=_ : {A B : Set} → IO A → (A → IO B) → IO B 12 | 13 | {-# IMPORT Data.Text.IO #-} 14 | {-# COMPILED putStrLn Data.Text.IO.putStrLn #-} 15 | {-# COMPILED _⟫=_ (\ _ _ a f -> a >>= f) #-} 16 | 17 | main : IO ⊤ 18 | main 19 | = putStrLn "Hello, world!" 20 | ⟫= λ _ → main 21 | --------------------------------------------------------------------------------