├── Handouts ├── List_of_inference_rules.pdf └── Proof-strategies.pdf ├── README.md ├── Week1.md ├── Week2.md ├── Week3.md ├── Week4.md ├── Week5.md ├── Week6.md ├── predicate-logic ├── ProblemSheet_PredLogic_with_Solutions.md ├── exists-not-forall.png ├── exists-to-not-forall.png ├── forall-and.png ├── forall-forall-or-not.png ├── forall-to-forall-to-forall-and.png ├── forall-to-not-exists.png ├── forall-to-to-forall-forall.png └── not-exists-to-forall.png ├── project ├── Compiler.md └── SATsolver.md └── propositional-logic ├── ProblemSheet_PropLogic_with_Solutions.md ├── and.lean ├── false.lean ├── impl.lean ├── or.lean ├── parsetree_exercise1.png └── proofs-in-prop-logic.lean /Handouts/List_of_inference_rules.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/Handouts/List_of_inference_rules.pdf -------------------------------------------------------------------------------- /Handouts/Proof-strategies.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/Handouts/Proof-strategies.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Teaching repository for Software Verification 2 | 3 |
Motivation 4 | 5 | How can we ensure that software does not crash and is guaranteed to be correct? In this course we tackle this question by viewing programs and programming languages as mathematical objects. In this way we can use logic to prove properties about programs and thereby guarantee that software is correct. To make reasoning about actual programs and programming languages feasible, we will not be doing these proofs by hand, but instead use a tool called a proof assistant. Such tools help building proofs that can be checked by a computer. As we will show during this course, proof assistants turn the activity of doing proofs into programming. 6 |
7 | 8 | ## Contact & Help 9 | 10 | Join our chat at https://quantumformalism.zulipchat.com/. We highly encourage you to join the chat so you can get the most out of the course! 11 | 12 | ## YouTube Playlist 13 | 14 | The course's video content including mini lectures can be found on this YouTube playlist: https://www.youtube.com/watch?v=9kjld2Swg5w&list=PL6N_Y7ao_aHsHaECz813UGIvAGmrfrOYX&pp=iAQB. 15 | 16 | ## Overview of the course 17 | 18 | 19 |
Introduction 20 | 21 | * Presentation of the learning material 22 | * Explanation of learning mode: flipped classroom 23 | * Means of contact (git repository, Zulip chat) 24 | * Introduction to Lean 25 | 26 |
27 | 28 |
Propositional logic 29 | 30 | * Logic of statements https://en.wikipedia.org/wiki/Propositional_calculus 31 | * Study of logical operations "and", "or", and implication 32 | * Proofs of propositions in natural deduction style https://en.wikipedia.org/wiki/Natural_deduction 33 | 34 |
35 | 36 |
Predicate logic aka first order logic 37 | 38 | * Study of quantifiers, universal ("for all") and existential ("there exists") 39 | * https://en.wikipedia.org/wiki/First-order_logic 40 | 41 |
42 | 43 |
Functional programming and verification 44 | 45 | * Programming style supported in Haskell, Ocaml, Python, etc, https://en.wikipedia.org/wiki/Functional_programming 46 | * Functional programs are particularly well-suited for formal verification 47 | * Lean supports functional programming natively 48 | 49 |
50 | 51 | 52 |
Use of a computer proof assistant 53 | 54 | * Computer proof assistants provide a language suitable for both programming and proving: an algorithm can be both implemented and proved correct in the same language. 55 | * Computer proof assistants check the correctness of user-provided proofs. 56 | * Programs can be executed directly in the computer proof assistant. 57 | 58 |
59 | 60 | 61 | 62 | 63 | 64 | ## Meetings 65 | 66 | TBA 67 | 68 | ## Plan 69 | 70 | For every week, a workplan for you is specified on the dedicated page: 71 | 72 | - [Week 1](./Week1.md) 73 | - [Week 2](./Week2.md) 74 | - [Week 3](./Week3.md) 75 | - [Week 4](./Week4.md) 76 | - [Week 5](./Week5.md) 77 | - [Week 6](./Week6.md) 78 | 79 | The workplans will be provided on a rolling basis. 80 | 81 | 82 | ## External resources 83 | 84 | ### Materials used in the course 85 | 86 | - Book [Logic and Proof](https://leanprover.github.io/logic_and_proof/) 87 | - Course [Logical Verification](https://lean-forward.github.io/logical-verification/2021/index.html) 88 | - [Textbook](https://github.com/benediktahrens/logical_verification_2021/raw/main/hitchhikers_guide.pdf) 89 | - [Git repository with Lean files](https://github.com/benediktahrens/logical_verification_2021) 90 | - Lecture videos are available on [Logical Verification](https://lean-forward.github.io/logical-verification/2021/index.html) 91 | 92 | ### Additional resources 93 | - [Lean in the browser](https://leanprover-community.github.io/lean-web-editor/) 94 | - [Installation instructions for Lean](https://github.com/benediktahrens/logical_verification_2021/blob/main/README.md) 95 | - [Lean tutorial](https://leanprover.github.io/theorem_proving_in_lean/) 96 | - Book [Concrete Semantics](http://concrete-semantics.org/), using [Isabelle/HOL](https://en.wikipedia.org/wiki/Isabelle_(proof_assistant)) 97 | - Our [Zulip server](https://quantumformalism.zulipchat.com) 98 | -------------------------------------------------------------------------------- /Week1.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 1 2 | 3 | 4 | ## What you should before our meeting in Week 1 5 | 6 | - Carefully study the information in the [README](./README.md) 7 | - Join our [Zulip chat](https://quantumformalism.zulipchat.com/). 8 | - Study Sections 1-4 of [Logic and Proof](https://leanprover.github.io/logic_and_proof/), including the examples and exercises. 9 | - Try to solve the problems of the [Problem Sheet](./propositional-logic/ProblemSheet_PropLogic_with_Solutions.md). 10 | - Extra materials: [List of inference rules](./Handouts/List_of_inference_rules.pdf), [Proof strategies](./Handouts/Proof-strategies.pdf) 11 | 12 | -------------------------------------------------------------------------------- /Week2.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 2 2 | 3 | 4 | ## What you should before our meeting in Week 2 5 | 6 | - Study Sections 7-9 of [Logic and Proof](https://leanprover.github.io/logic_and_proof/), including the examples and exercises. 7 | - Try to solve the problems of the [Problem Sheet](./predicate-logic/ProblemSheet_PredLogic_with_Solutions.md). 8 | - Study the extra materials: [List of inference rules](./Handouts/List_of_inference_rules.pdf), [Proof strategies](./Handouts/Proof-strategies.pdf) 9 | 10 | -------------------------------------------------------------------------------- /Week3.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 3 2 | 3 | 4 | ## What you should before our meeting in Week 3 5 | 6 | 1. Work through Sections 1 and 2 of [Logical Verification](https://github.com/benediktahrens/logical_verification_2021/raw/main/hitchhikers_guide.pdf). 7 | 2. Watch the videos that go with Sections 1 and 2, linked to from [LoVe](https://lean-forward.github.io/logical-verification/2021/index.html). 8 | 3. Work through the Lean files that go with Sections 1 and 2: 9 | - [Demo 1](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love01_definitions_and_statements_demo.lean) 10 | - [Exercises 1](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love01_definitions_and_statements_exercise_sheet.lean) 11 | - [Solutions to Exercises 1](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love01_definitions_and_statements_exercise_solution.lean) 12 | - [Homework 1](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love01_definitions_and_statements_homework_sheet.lean) 13 | - [Demo 2](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love02_backward_proofs_demo.lean) 14 | - [Exercises 2](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love02_backward_proofs_exercise_sheet.lean) 15 | - [Solutions to Exercises 2](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love02_backward_proofs_exercise_solution.lean) 16 | - [Homework 2](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love02_backward_proofs_homework_sheet.lean) 17 | -------------------------------------------------------------------------------- /Week4.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 4 2 | 3 | 4 | ## What you should before our meeting in Week 4 5 | 6 | 1. Work through Section 3 of [Logical Verification](https://github.com/benediktahrens/logical_verification_2021/raw/main/hitchhikers_guide.pdf). 7 | 2. Watch the videos that go with Section 3, linked to from [LoVe](https://lean-forward.github.io/logical-verification/2021/index.html). 8 | 3. Work through the Lean files that go with Sections 1 and 2: 9 | - [Demo 3](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love03_forward_proofs_demo.lean) 10 | - [Exercises 3](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love03_forward_proofs_exercise_sheet.lean) 11 | - [Solutions to Exercises 3](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love03_forward_proofs_exercise_solution.lean) 12 | - [Homework 3](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love03_forward_proofs_homework_sheet.lean) 13 | -------------------------------------------------------------------------------- /Week5.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 5 2 | 3 | 4 | ## What you should before our meeting in Week 5 5 | 6 | 1. Work through Section 4 of [Logical Verification](https://github.com/benediktahrens/logical_verification_2021/raw/main/hitchhikers_guide.pdf). 7 | 2. Watch the videos that go with Section 4, linked to from [LoVe](https://lean-forward.github.io/logical-verification/2021/index.html). 8 | 3. Work through the Lean files that go with Section 4: 9 | - [Demo 4](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love04_functional_programming_demo.lean) 10 | - [Exercises 4](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love04_functional_programming_exercise_sheet.lean) 11 | - [Solutions to Exercises 4](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love04_functional_programming_exercise_solution.lean) 12 | - [Homework 4](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love04_functional_programming_homework_sheet.lean) 13 | -------------------------------------------------------------------------------- /Week6.md: -------------------------------------------------------------------------------- 1 | # Workplan for Week 6 2 | 3 | 4 | ## What you should before our meeting in Week 6 5 | 6 | 1. Work through Section 5 of [Logical Verification](https://github.com/benediktahrens/logical_verification_2021/raw/main/hitchhikers_guide.pdf). 7 | 2. Watch the videos that go with Section 5, linked to from [LoVe](https://lean-forward.github.io/logical-verification/2021/index.html). 8 | 3. Work through the Lean files that go with Section 5: 9 | - [Demo 5](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love05_inductive_predicates_demo.lean) 10 | - [Exercises 5](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love05_inductive_predicates_exercise_sheet.lean) 11 | - [Solutions to Exercises 5](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love05_inductive_predicates_exercise_solution.lean) 12 | - [Homework 5](https://github.com/benediktahrens/logical_verification_2021/blob/main/lean/love05_inductive_predicates_homework_sheet.lean) 13 | -------------------------------------------------------------------------------- /predicate-logic/ProblemSheet_PredLogic_with_Solutions.md: -------------------------------------------------------------------------------- 1 | # Problem Sheet on Predicate Logic 2 | 3 | ## Exercise 1 4 | 5 | Over the domain of animals, consider the three predicates 6 | - W(x) = "x is white" 7 | - M(x) = "x is a mouse" 8 | - T(x) = "x has a tail" 9 | 10 | - (i) Express the following five sentences in predicate logic 11 | - (a) All white animals are mice. 12 | - (b) Basil is a mouse but he is not white. 13 | - (c) All white mice have tails. 14 | - (d) Not all mice are white. 15 | - (e) At least one of Basil and Charlie has a tail. 16 | - (ii) Write your predicates in Lean. 17 | 18 |
Solution 19 | 20 | - (i) 21 | - (a) ∀ x, W(x) → M(x) 22 | - (b) M(Basil) ∧ ¬ W(Basil) 23 | - (c) ∀ x, [(W(x)∧ M(x))→ T(x)] 24 | - (d) ¬ ∀ x, M(x)→ W(x) 25 | - (e) T(Basil) ∨ T(Charlie) 26 | 27 | - (ii) 28 | ```lean 29 | section animals 30 | 31 | variable animal : Type 32 | variables W M T : animal → Prop 33 | 34 | --i 35 | #check ∀ x : animal, W x → M x 36 | 37 | variable Basil : animal 38 | --ii 39 | #check M Basil ∧ ¬ W Basil 40 | 41 | --iii 42 | #check ∀ y : animal, M y ∧ W y → T y 43 | 44 | --iv 45 | #check ∃ z : animal, M z ∧ ¬ W z 46 | 47 | --v 48 | variable Charlie : animal 49 | #check T Basil ∨ T Charlie 50 | 51 | end animals 52 | ``` 53 | 54 |
55 | 56 | ## Exercise 2 57 | 58 | Over the domain of people, use the two predicates 59 | - L(x,y) = x loves y 60 | - H(x,y) = x hates y 61 | 62 | to express the following six sentences in predicate logic: 63 | 64 | - (a) Bob loves Dele and everybody hates Charlie. 65 | - (b) Somebody loves both Charlie and Dele. 66 | - (c) Bob loves everybody but nobody loves Bob. 67 | - (d) Everyone who loves Dele also loves either Charlie or Bob. 68 | - (e) Everyone who loves Charlie loves someone who loves Bob. 69 | - (f) Everybody who loves everybody loves themselves. 70 | 71 | Write the predicates in Lean. 72 | 73 |
Solution 74 | 75 | - (a) L(Bob, Dele) ∧ ∀x, [H(x, Charlie)] 76 | - (b) ∃x, [L(x, Charlie) ∧ L(x, Dele)] 77 | - (c) ∀x, [L(Bob, x)] ∧ ¬∃x, [L(x, Bob)] 78 | Another answer: ∀x, [L(Bob, x)] ∧ ∀x, [¬L(x, Bob)] 79 | - (d) ∀x, L(x, Dele) → L(x, Charlie) ∨ L(x, Bob) 80 | - (e) ∀x, L(x, Charlie) → ∃y, [L(x, y) ∧ L(y, Bob)] 81 | - (f) ∀x, ∀y, [L(x, y)] → L(x, x) 82 | 83 | ```lean 84 | section people 85 | 86 | variable people : Type 87 | variables L H : people → people → Prop 88 | 89 | variables Bob Charlie Dele : people 90 | 91 | --(a) 92 | #check L Bob Dele ∧ ∀ x : people, H x Charlie 93 | 94 | --(b) 95 | #check ∃ y : people, L y Charlie ∧ L y Dele 96 | 97 | --(c) 98 | #check ∀ x : people, L Bob x ∧ ¬ exists y : people, L y Bob 99 | 100 | --(d) 101 | #check ∀ z : people, L z Dele → L z Charlie ∨ L z Bob 102 | 103 | --(e) 104 | #check ∀ x : people, L x Charlie → ∃ y, L x y ∧ L y Bob 105 | 106 | --(f) 107 | #check ∀ x : people, (∀ y : people, L x y) → L x x 108 | --note that here, parentheses are necessary around ∀ y : people, L x y 109 | 110 | end people 111 | ``` 112 | 113 |
114 | 115 | ## Exercise 3 116 | 117 | Without using Lean, find and correct the mistakes in the following proof, assuming that the first line (the formula) is correct. 118 | ``` 119 | example (A B C : Prop) : A ∧ (B ∨ C) → (A ∧ B) ∨ (A ∧ C) := 120 | assume h1 : A ∨ (B ∧ C), 121 | or.elim (and.left h1) 122 | (assume h2 : C, 123 | or.intro_right (A ∧ C) (and.intro (and.elim_right h2) h1)) 124 | (assume h2 : B, 125 | or.intro_left (A ∧ B) (and.intro (and.elim_right h2) h1)) 126 | ``` 127 | 128 |
Solution 129 | 130 | ```lean 131 | example (A B C : Prop) : A ∧ (B ∨ C) → (A ∧ B) ∨ (A ∧ C) := 132 | assume h1 : A ∧ (B ∨ C), 133 | or.elim (and.right h1) 134 | (assume h2 : B, 135 | or.intro_left (A ∧ C) (and.intro (and.elim_left h1) h2)) 136 | (assume h2 : C, 137 | or.intro_right (A ∧ B) (and.intro (and.elim_left h1) h2)) 138 | ``` 139 | 140 |
141 | 142 | ## Exercise 4 143 | 144 | **Does the ordering of the quantifiers matter?** 145 | Let the domain be people, and A(x,y) be the predicate x admires y. 146 | - Express ∀x ∃y A(x, y) in English. 147 | - Express ∃y ∀x A(x, y) in English. 148 | 149 | Is ∀x ∃y A(x, y) the same as ∃y ∀x A(x, y) in general? 150 | 151 |
Solution 152 | 153 | - ∀x ∃y A(x, y) in English translates to ``every person admires someone". 154 | - ∃y ∀x A(x, y) in English translates to ``there is someone who is admired by everyone". 155 | 156 | Hence, ∀x ∃y A(x, y) is not the same as ∃y ∀x A(x, y) in general, i.e., ordering of the quantifiers matters! 157 | 158 |
159 | 160 | ## Exercise 5 161 | 162 | Show that (∀z(P(z)∧Q(z))) → ((∀x P(x))∧(∀y Q(y))), both in Lean and in natural deduction. 163 | 164 |
Solution 165 | 166 | ![Proof in natural deduction](forall-and.png "Forall-and") 167 | 168 | ```lean 169 | section exo2 170 | 171 | variable U : Type 172 | variables P Q : U → Prop 173 | 174 | example : (∀ x, P x ∧ Q x) → ((∀ x, P x) ∧ (∀ x, Q x)) := 175 | assume h : ∀ x, P x ∧ Q x, 176 | and.intro 177 | (assume t : U, and.elim_left (h t)) 178 | (assume s : U, and.elim_right (h s)) 179 | 180 | --variant using "have" 181 | example : (∀ x, P x ∧ Q x) → ((∀ x, P x) ∧ (∀ x, Q x)) := 182 | assume h : ∀ x, P x ∧ Q x, 183 | and.intro 184 | (assume t : U, 185 | have k : P t ∧ Q t, from h t, 186 | and.elim_left k) 187 | (assume s : U, 188 | have m : P s ∧ Q s, from h s, 189 | and.elim_right m) 190 | 191 | end exo2 192 | ``` 193 | 194 |
195 | 196 | ## Exercise 6 197 | 198 | Show that (∃y (¬P (y))) → (¬(∀x P (x))), both in Lean and in natural deduction. 199 | 200 |
Solution 201 | 202 | ![Proof in natural deduction](exists-not-forall.png "Exists not forall") 203 | 204 | ```lean 205 | section exo3 206 | 207 | variable U : Type 208 | variable P : U → Prop 209 | 210 | example : (∃ y, ¬ P y) → ¬ ∀ x, P x := 211 | assume h : ∃ y, ¬ P y, 212 | assume k : ∀ x, P x, 213 | exists.elim h 214 | (assume t : U, 215 | assume np : ¬ P t, 216 | np (k t) 217 | ) 218 | 219 | 220 | --variant using "have" 221 | example : (∃ y, ¬ P y) → ¬ ∀ x, P x := 222 | assume h : ∃ y, ¬ P y, 223 | assume k : ∀ x, P x, 224 | exists.elim h 225 | (assume t : U, 226 | assume np : ¬ P t, 227 | have p : P t, from k t, 228 | np p 229 | ) 230 | 231 | end exo3 232 | ``` 233 | 234 | Remark: Note that the proof tree and the Lean proof are not translations of each other: 235 | there is a small difference in when the [∃E] rule is applied. 236 | 237 |
238 | 239 | ## Exercise 7 240 | 241 | Prove ∀z, Q(z) from the hypotheses ∀x,(P(x) ∨ Q(x)) and ∀y, (¬P(y)), both in Lean and in natural deduction. 242 | Bonus: use `have` statements in your Lean proof. 243 | 244 |
Solution 245 | 246 | ![Proof in natural deduction](forall-forall-or-not.png "Forall from forall-not and forall-or") 247 | 248 | ```lean 249 | section exo4 250 | 251 | variable U : Type 252 | variables P Q : U → Prop 253 | 254 | example : (∀ x, P x ∨ Q x) → (∀ y, ¬ P y) → ∀ z, Q z := 255 | assume h : ∀ x, P x ∨ Q x, 256 | assume k : ∀ y, ¬ P y, 257 | assume t : U, 258 | or.elim (h t) 259 | (assume p : P t, false.elim (k t p)) 260 | (assume q : Q t, q) 261 | 262 | --variant using "have" 263 | 264 | example : (∀ x, P x ∨ Q x) → (∀ y, ¬ P y) → ∀ z, Q z := 265 | assume h : ∀ x, P x ∨ Q x, 266 | assume k : ∀ y, ¬ P y, 267 | assume t : U, 268 | or.elim (h t) 269 | (assume p : P t, 270 | have np : ¬ P t, from k t, 271 | have x : false, from np p, 272 | false.elim x) 273 | (assume q : Q t, q) 274 | 275 | end exo4 276 | ``` 277 | 278 |
279 | 280 | ## Exercise 8 281 | 282 | Show that (¬∃x, (A(x) ∧ B(x))) ←→ (∀y, (A(y) → ¬B(y))), both in Lean and in natural 283 | deduction. 284 | 285 |
Solution 286 | 287 | ![Proof in natural deduction](not-exists-to-forall.png "") 288 | 289 | ```lean 290 | variable U : Type 291 | variables A B : U → Prop 292 | example : (¬ ∃ x, (A x ∧ B x)) → ∀ y, A y → ¬ B y := 293 | assume h1 : ¬ ∃ x, (A x ∧ B x), 294 | assume t : U, 295 | assume a : A t, 296 | assume b : B t, 297 | h1 (exists.intro t (and.intro a b)) 298 | ``` 299 | 300 | ![Proof in natural deduction](forall-to-not-exists.png "") 301 | ```lean 302 | variable U : Type 303 | variables A B : U → Prop 304 | example : (∀ y, (A y → ¬ B y)) → ¬ ∃ x, (A x ∧ B x) := 305 | assume h1 : ∀ y, (A y → ¬ B y), 306 | assume h2 : ∃ x, (A x ∧ B x), 307 | exists.elim h2 308 | ( 309 | assume t: U, 310 | assume p : A t ∧ B t, 311 | ((h1 t) (and.elim_left p)) (and.elim_right p) 312 | ) 313 | ``` 314 | Finally, here is a proof that uses `have` statements: 315 | ```lean 316 | variable U : Type 317 | variables A B : U → Prop 318 | example : (∀ y, (A y → ¬ B y)) → ¬ ∃ x, (A x ∧ B x) := 319 | assume h1 : ∀ y, (A y → ¬ B y), 320 | assume h2 : ∃ x, (A x ∧ B x), 321 | exists.elim h2 322 | ( 323 | assume t: U, 324 | assume p : A t ∧ B t, 325 | have k : A t → ¬ B t, from h1 t, 326 | have nb : ¬ B t, from k (and.elim_left p), 327 | have b : B t, from and.elim_right p, 328 | nb b 329 | ) 330 | ``` 331 | 332 |
333 | 334 | ## Exercise 9 335 | Show that (∃y, (A(y) ∧ ¬B(y))) → (¬∀x, (A(x) → B(x))), both in Lean and in natural deduction. 336 | 337 | 338 |
Solution 339 | 340 | ![foo](exists-to-not-forall.png "") 341 | 342 | ```lean 343 | variable U : Type 344 | variables A B : U → Prop 345 | example : (∃ y, (A y ∧ ¬ B y) ) → ¬ ∀ x, (A x → B x) := 346 | assume h1 : ∃ y, (A y ∧ ¬ B y), 347 | assume h2 : ∀ x, (A x → B x) , 348 | exists.elim h1 349 | ( 350 | assume t : U, 351 | assume p : A t ∧ ¬ B t, 352 | (and.elim_right p) ((h2 t) (and.elim_left p)) 353 | ) 354 | ``` 355 | Or 356 | ```lean 357 | variable U : Type 358 | variables A B : U → Prop 359 | example : (∃ y, (A y ∧ ¬ B y) ) → ¬ ∀ x, (A x → B x) := 360 | assume h1 : ∃ y, (A y ∧ ¬ B y), 361 | assume h2 : ∀ x, (A x → B x) , 362 | exists.elim h1 363 | ( 364 | assume t : U, 365 | assume p : A t ∧ ¬ B t, 366 | have nb : ¬ B t, from and.elim_right p, 367 | have a : A t, from and.elim_left p, 368 | have b : B t, from h2 t a, 369 | nb b 370 | ) 371 | ``` 372 | 373 |
374 | 375 | ## Exercise 10 376 | 377 | Translate the proof tree below to Lean: 378 | 379 | ![](forall-to-to-forall-forall.png "") 380 | 381 |
Solution 382 | 383 | ```lean 384 | variable U : Type 385 | variables P Q : U → Prop 386 | example : (∀ x, P x → Q x) → (∀ x, P x) → ∀ x, Q x := 387 | assume h1 : ∀ x, P x → Q x, 388 | assume h2 : ∀ x, P x, 389 | assume a : U, 390 | (h1 a) (h2 a) 391 | ``` 392 | 393 |
394 | 395 | ## Exercise 11 396 | 397 | Translate the Lean code below into a proof tree. 398 | ```lean 399 | variable U : Type 400 | variables P Q : U → Prop 401 | example : (∀ x, P x ) → (∀ y, Q y) → ∀ z, P z ∧ Q z := 402 | assume h1 : ∀ x, P x, 403 | assume h2 : ∀ y, Q y, 404 | assume a : U, 405 | and.intro (h1 a) (h2 a) 406 | ``` 407 | 408 |
Solution 409 | 410 | ![](forall-to-forall-to-forall-and.png "") 411 | 412 |
413 | 414 | ## Exercise 12 415 | 416 | **Nobody trusts a politician!** 417 | 418 | Consider the predicates 419 | - P(x) = "x is a politician" 420 | - T(x, y) = "x trusts y" 421 | 422 | and the following four formulations of 423 | 424 | - (1) ∀ x, (P(x) → ∀ y , ¬ T (y , x)) 425 | - (2) ∀ x, y, (P(x) → ¬ T (y , x)) 426 | - (3) ¬∃ x, y, (P(x) ∧ T (y , x)) 427 | - (4) ∀ x, y, (T (y, x) → ¬ P(x)) 428 | 429 | 430 | Show that all of these formulations are equivalent. How many proofs do you have to write? 431 | 432 | Hint: you can do with strictly less than 12 proofs. 433 | 434 |
Solution 435 | 436 | (2) implies (4) 437 | ```lean 438 | variable U : Type 439 | variable P : U → Prop 440 | variable T : U → U → Prop 441 | -- two implies four 442 | example (h : ∀ x y,(P x → (¬T y x))) : ∀ x y,(T y x →(¬P x)) := 443 | assume a : U, -- x 444 | assume b : U, -- y 445 | assume r : T b a, 446 | assume p : P a, 447 | ((h a b) p) r 448 | ``` 449 | (1) implies (2) 450 | ```lean 451 | variable U : Type 452 | variable P : U → Prop 453 | variable T : U → U → Prop 454 | -- one implies two 455 | example (h : ∀x,(P x →(∀y, ¬T y x))) : ∀xy,(P x →(¬T y x)):= 456 | assume a : U, -- x 457 | assume b : U, -- y 458 | assume p : P a, 459 | assume q : T b a, 460 | (((h a) p) b) q 461 | ``` 462 | (2) implies (1) 463 | ```lean 464 | variable U : Type 465 | variable P : U → Prop 466 | variable T : U → U → Prop 467 | -- two implies one 468 | example (h : ∀ x y, (P x →(¬T y x))) : ∀ x, (P x → (∀y, ¬T y x)) := 469 | assume a : U, -- x 470 | assume p : P a, 471 | assume b : U, -- y 472 | assume q : T b a, 473 | ((h a b) p) q 474 | ``` 475 | (3) implies (2) 476 | ```lean 477 | variable U : Type 478 | variable P : U → Prop 479 | variable T : U → U → Prop 480 | -- three implies two 481 | example (h : ¬∃ x y, (P x ∧ T y x)) : ∀ x y, (P x →(¬T y x)) := 482 | assume a : U, -- x 483 | assume b : U, -- y 484 | assume p : P a, 485 | assume q : T b a, 486 | h (exists.intro a (exists.intro b (and.intro p q))) 487 | ``` 488 | (2) implies (3) 489 | ```lean 490 | variable U : Type 491 | variable P : U → Prop 492 | variable T : U → U → Prop 493 | example (h : ∀ x y, (P x →(¬T y x))) : ¬ ∃ x y,(P x ∧ T y x) := 494 | assume k: ∃ x y, (P x ∧ T y x), 495 | exists.elim k 496 | (assume a : U, -- x 497 | assume q : ∃ (y : U), P a ∧ T y a, 498 | exists.elim q 499 | (assume b : U, -- y 500 | assume foo: P a ∧ T b a , 501 | have i : P a → ¬ T b a, from h a b, 502 | (i (and.elim_left foo)) (and.elim_right foo) 503 | ) 504 | ) 505 | ``` 506 | (4) implies (2) 507 | ```lean 508 | variable U : Type 509 | variable P : U → Prop 510 | variable T : U → U → Prop 511 | 512 | example (h : ∀ x y, (T y x → (¬ P x))) : (∀ x y, (P x → (¬ T y x))) := 513 | assume a : U, -- x 514 | assume b : U, --y 515 | assume p : P a, 516 | assume q : T b a, 517 | ((h a b) q) p 518 | ``` 519 | (2) implies (1) 520 | ```lean 521 | variable U : Type 522 | variable P : U → Prop 523 | variable T : U → U → Prop 524 | 525 | example (h : ∀ x y, (P x → (¬ T y x))) : ∀ x, (P x → (∀ y, ¬ T y x)) := 526 | assume a : U, -- x 527 | assume p : P a, 528 | assume b : U, -- y 529 | assume q : T b a, 530 | ((h a b) p) q 531 | 532 | ``` 533 | (3) implies (1) 534 | ```lean 535 | variable U : Type 536 | variable P : U → Prop 537 | variable T : U → U → Prop 538 | 539 | example (h : ¬ ∃ x y, (P x ∧ T y x)) : ∀ x, (P x → (∀ y, ¬ T y x)) := 540 | assume a : U, -- x 541 | assume p : P a, 542 | assume b : U, --y 543 | assume q : T b a, 544 | h 545 | (exists.intro a (exists.intro b (and.intro p q))) 546 | ``` 547 | 548 |
549 | -------------------------------------------------------------------------------- /predicate-logic/exists-not-forall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/exists-not-forall.png -------------------------------------------------------------------------------- /predicate-logic/exists-to-not-forall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/exists-to-not-forall.png -------------------------------------------------------------------------------- /predicate-logic/forall-and.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/forall-and.png -------------------------------------------------------------------------------- /predicate-logic/forall-forall-or-not.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/forall-forall-or-not.png -------------------------------------------------------------------------------- /predicate-logic/forall-to-forall-to-forall-and.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/forall-to-forall-to-forall-and.png -------------------------------------------------------------------------------- /predicate-logic/forall-to-not-exists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/forall-to-not-exists.png -------------------------------------------------------------------------------- /predicate-logic/forall-to-to-forall-forall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/forall-to-to-forall-forall.png -------------------------------------------------------------------------------- /predicate-logic/not-exists-to-forall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/predicate-logic/not-exists-to-forall.png -------------------------------------------------------------------------------- /project/Compiler.md: -------------------------------------------------------------------------------- 1 | # Arithmetic expression compiler 2 | 3 | The goal of this project is to implement a compiler that translates arithmetic expressions to programs for a stack machine. You have to prove that your compiler is correct. 4 | 5 | We consider a language for arithmetic expressions: 6 | ```lean 7 | inductive val : Type 8 | | VBool : bool → val 9 | | VNat : nat → val 10 | 11 | open val 12 | 13 | inductive bin_op : Type 14 | | PlusOp : bin_op 15 | | MinusOp : bin_op 16 | | LeOp : bin_op 17 | | LtOp : bin_op 18 | | EqOp : bin_op 19 | 20 | open bin_op 21 | 22 | inductive exp : Type 23 | | EVal : val → exp 24 | | EOp : bin_op → exp → exp → exp 25 | | EIf : exp → exp → exp → exp 26 | 27 | open exp 28 | ``` 29 | 30 | --- 31 | 32 | ## Exercise 1 33 | Define a big-step semantics for this language: 34 | ```lean 35 | inductive big_step : exp → val → Prop 36 | -- fill in 37 | ``` 38 | 39 | --- 40 | 41 | The first part of this project is to define the target language of your compiler: a small stack machine language with instructions in reverse Polish notation. 42 | The instructions are given by the following Lean definitions: 43 | ```lean 44 | inductive instruction : Type 45 | | IPush : val → instruction 46 | | IOp : bin_op → instruction 47 | | IBranch : nat → instruction 48 | | IJump : nat → instruction 49 | ``` 50 | The intuitive semantics of these instructions is as follows: 51 | * The instruction `IPush v` pushes a value `v` on the stack. 52 | * The instruction `IOp op` pops two values of the stack, performs the operation `op`, and pushes the result back on the stack. 53 | * The instruction `IBranch n` pops a Boolean from the stack, and continues execution if the Boolean is true, otherwise it skips the subsequent `n` instructions. 54 | * The instruction `IJump n` skips `n` instructions. 55 | 56 | --- 57 | 58 | ## Exercise 2 59 | 60 | Define a big-step semantics for the stack machine: 61 | ```lean 62 | inductive vm_big_step : list instruction → list val → list val → Prop 63 | -- fill in 64 | ``` 65 | You should define the semantics by processing the instructions in sequence. 66 | The first `list val` is the input stack, and the second `list val` is the output stack. 67 | The big-step semantics should be undefined (i.e., have no applicable rules) in case the wrong arguments for an instruction are on the stack, a stack underflow occurs, or an out-of-bounds jump occurs. 68 | To define the semantics of branches and jumps, you will need to define a helper function or helper inductive predicate on lists. 69 | 70 | --- 71 | 72 | --- 73 | 74 | ## Exercise 3 75 | 76 | Prove the following positive and negative tests of the big-step semantics: 77 | ```lean 78 | lemma example1 : 79 | vm_big_step 80 | [IPush (VNat 10), IPush (VNat 20), IOp EqOp, IBranch 1, IPush (VNat 1), IPush (VNat 2), IPush (VNat 3)] 81 | [] 82 | [VNat 3, VNat 2] 83 | := sorry 84 | 85 | lemma example2 : ¬ exists out, 86 | vm_big_step 87 | [ IPush ( VNat 10), IPush ( VBool false ), IOp EqOp ] 88 | [] 89 | out 90 | := sorry 91 | ``` 92 | Write an additional positive test and negative test and prove these. 93 | 94 | --- 95 | 96 | The next part of this project is to define a compiler from the arithmetic expression language to the stack machine. 97 | We will prove *soundness* of the compiler, which says that whenever a program has a certain outcome according to the big-step semantics for arithmetic expressions, the target program has the same outcome according to the big-step semantics for the stack machine. 98 | 99 | --- 100 | 101 | ## Exercise 4 102 | 103 | Implement a compiler: 104 | ```lean 105 | def compile : exp → list instruction 106 | -- fill in 107 | ``` 108 | 109 | --- 110 | 111 | ## Exercise 5 112 | 113 | Prove soundness of your compiler: 114 | ```lean 115 | lemma compile_sound (e : exp) (v : val) : big_step e v → vm_big_step (compile e) [] [v] := sorry 116 | ``` 117 | In order to prove this lemma, you might need to state and prove a more general helper lemma first. 118 | Also, you might need to prove some helper lemmas for the function on lists that you have used for defining the big-step semantics of branches and jumps. 119 | 120 | --- 121 | 122 | ## Exercise 6 123 | 124 | Prove completeness of the compiler (the reverse implication of soundness): 125 | ```lean 126 | lemma compile_complete (e : exp) (v : val) : vm_big_step (compile e) [] [v] → big_step e v := sorry 127 | ``` 128 | You might need to state a more general helper lemma. 129 | 130 | -------------------------------------------------------------------------------- /project/SATsolver.md: -------------------------------------------------------------------------------- 1 | # SAT Solver 2 | 3 | The goal of this project is to implement a Boolean Satisfiability (SAT) solver in Lean and to prove soundness of your implementation. 4 | 5 | Boolean formulas are given by the following grammar: 6 | ``` 7 | p, q ::= x | ⊤ | ⊥ | p ∧ q | p ∨ q | p → q | ¬p 8 | ``` 9 | Here, `x` ranges over an infinite set of propositional variables. 10 | Examples of formulas are `(x ∨ ¬y) ∧ (¬x ∨ y)`, and `¬y → (x ∨ y)`, and `x ∧ ¬x ∧ ⊤`. 11 | 12 | A Boolean formula `p` is said to be satisfiable in case its truth table contains at least one row whose outcome is 1. 13 | For example, the formula `¬ y → (x ∨ y)` has the truth table 14 | ``` 15 | x | y | (¬ y → (x ∨ y)) 16 | f | f | f 17 | t | f | t 18 | f | t | t 19 | t | t | t 20 | ``` 21 | and thus is satisfiable. 22 | The formula `x ∧ ¬ x ∧ ⊤` has the truth table 23 | ``` 24 | x | (x ∧ ¬ x ∧ ⊤) 25 | f | f 26 | t | f 27 | ``` 28 | and hence is not satisfiable. 29 | 30 | 31 | The first part of this project is to represent Boolean formulas in Lean and to formally define the notion of satisfiability. 32 | 33 | --- 34 | 35 | ## Exercise 1 36 | 37 | ```lean 38 | inductive form : Type 39 | | FVar : string → form 40 | --fill in 41 | ``` 42 | 43 | --- 44 | 45 | ## Exercise 2 46 | 47 | 48 | Give Lean definitions of type `form` corresponding to 49 | - `(x ∨ ¬y) ∧ (¬x ∨ y)` 50 | - `¬y → (x ∨ y)` 51 | - `x ∧ ¬x ∧ ⊤` 52 | 53 | --- 54 | 55 | In order to define satisfiability we introduce the notion of a valuation, which is a function that assigns true or false to each propositional variable. 56 | 57 | ```lean 58 | def valuation : Type := string → bool 59 | ``` 60 | 61 | 62 | --- 63 | 64 | ## Exercise 3 65 | 66 | Define *validity* of Boolean formulas (using the 'truth table semantics') by filling out the following definition: 67 | 68 | ```lean 69 | def valid : valuation → form → Prop := sorry 70 | --fill in 71 | ``` 72 | 73 | --- 74 | 75 | 76 | A formula is said to be satisfiable if there exists a valuation that makes the formula true. This corresponds to the following definition in Lean: 77 | 78 | ```lean 79 | def satisfiable (p : form) : Prop := ∃ V : valuation, valid V p 80 | ``` 81 | 82 | --- 83 | 84 | ## Exercise 4 85 | 86 | Prove in Lean that `(x ∨ ¬y) ∧ (¬x ∨ y)` and `¬y → (x ∨ y)` are satisfiable. You should create two lemmas of the shape below, replacing `foo` by the respective formulas in the lemma: 87 | 88 | ```lean 89 | definition foo : form := sorry 90 | lemma testX : satisfiable foo := sorry 91 | ``` 92 | 93 | --- 94 | 95 | ## Exercise 5 96 | 97 | Define a function `find_valuation` that given a formula `p` computes a valuation in which `p` is true. 98 | You should implement this function by enumerating all possible valuations, i.e., you should generate the formula's truth table and check if there is a row whose outcome is 1. 99 | The function `find_valuation` should yield `none` in case no such valuation exists. 100 | 101 | ```lean 102 | def find_valuation (p : form) : option valuation := sorry 103 | ``` 104 | 105 | --- 106 | 107 | We now define our SAT solver as follows: 108 | 109 | ```lean 110 | def solver (p : form) : bool := 111 | match find_valuation p with 112 | | option.some _ := tt 113 | | option.none := ff 114 | end 115 | ``` 116 | 117 | --- 118 | 119 | ## Exercise 6 120 | 121 | Explain the difference between `satisfiable` and `solver`. 122 | 123 | --- 124 | 125 | ## Exercise 7 126 | 127 | Write 2 positive and 2 negative tests of the solver and prove these through proof by simplication via the `refl` tactic. 128 | 129 | ---- 130 | 131 | ## Exercise 8 132 | 133 | Prove that `solver` is sound. That means: 134 | 135 | ```lean 136 | theorem solver_sound (p : form) : solver p = tt → satisfiable p := sorry 137 | ``` 138 | 139 | You might want to state a helper lemma first, which you should prove by varying the induction hypothesis. 140 | 141 | --- 142 | 143 | ## Exercise 9 144 | 145 | Write an optimizer that simplifies a Boolean formula using the laws below, and prove correctness of your optimizer. 146 | 147 | - `x ∧ ⊤ = x` 148 | - `⊤ ∧ x = x` 149 | - `x ∧ ⊥ = ⊥` 150 | - `⊥ ∧ x = ⊥` 151 | - `x ∨ ⊤ = ⊤` 152 | - `⊤ ∨ x = ⊤` 153 | - `x ∨ ⊥ = x` 154 | - `⊥ ∨ x = x` 155 | 156 | -------------------------------------------------------------------------------- /propositional-logic/ProblemSheet_PropLogic_with_Solutions.md: -------------------------------------------------------------------------------- 1 | # Problem Sheet on Propositional Logic 2 | 3 | 4 | ## Exercise 1 5 | 6 | Draw a parse tree for the formula ((¬A) ∧ (B ∨ C)) → D. 7 | 8 |
Solution 9 | 10 | ![Parsetree](parsetree_exercise1.png "Parse tree exercise 1") 11 | 12 |
13 | 14 | ## Exercise 2 15 | 16 | Write two sentences in English : one which uses "or" in an exclusive way, and one which uses "or" in an inclusive way. 17 | 18 |
Solution 19 | 20 | - Inclusive: "Would you like cream or sugar in your coffee?" 21 | - Exclusive: "Are you for or against Fred's suggestion?" 22 | 23 |
24 | 25 | ## Exercise 3 26 | 27 | Note: This is an exercise about the importance of parentheses. 28 | 29 | Let P be the proposition 2+2=5. Let Q be the proposition 1+1=3. Let R be the proposition 5+5=10. For the aforementioned definitions of P, Q, and R, check that (P∧ Q)∨ R is true and P∧ (Q∨ R) is false, and hence they are indeed two different formulas! 30 | 31 |
Solution 32 | 33 | P is false, Q is false and R is true. We use the symbol ⊥ for false and ⊤ for true. Then (P∧ Q)∨ R is same as (⊥ ∧ ⊥) ∨ ⊤, which is equivalent to ⊤, and P∧ (Q∨ R) is same as ⊥ ∧ (⊥ ∨ ⊤) is equivalent to ⊥. Note that there is a bit of subtlety here about "giving meaning to propositions". 34 | 35 |
36 | 37 | ## Exercise 4 38 | 39 | Give a (natural deduction) proof of (Q → R) → R from the hypothesis Q. 40 | 41 |
Solution 42 | 43 | ``` 44 | ---[Hyp] ------[Ass(1)] 45 | Q Q → R 46 | --------------------- [→ E] 47 | R 48 | -------------- [→ I, 1] 49 | (Q → R) → R 50 | ``` 51 | 52 |
53 | 54 | ## Exercise 5 55 | 56 | Give a (natural deduction) proof of P → (Q ∧ R) from the hypotheses P → Q , Q → R. 57 | 58 |
Solution 59 | 60 | ``` 61 | --[Ass(1)] -----[Hyp] --(1) -----[Hyp] 62 | P P→ Q Q Q → R 63 | ---------------[→ E] -------------[→ E] 64 | Q R 65 | ---------------------------------[∧ I] 66 | Q ∧ R 67 | --------------- [→ I, 1] 68 | P → (Q ∧ R) 69 | ``` 70 | 71 |
72 | 73 | ## Exercise 6 74 | 75 | Give a (natural deduction) proof of ¬(A ∧ B) from the hypothesis (A → C) ∧ (B → ¬C). 76 | 77 |
Solution 78 | 79 | ``` 80 | -----[Ass(1)] -----[Ass(1)] 81 | A ∧ B A ∧ B 82 | ----- -----[Hyp] -----[∧ E] -------[Hyp] 83 | A A → C B B → ¬C 84 | ------------[→ E] -------------------[→ E] 85 | C ¬ C 86 | -------------------------------- [¬ E] 87 | ⊥ 88 | -------------------------------- [→ I, 1] 89 | ¬ (A ∧ B) 90 | ``` 91 | 92 |
93 | 94 | ## Exercise 7 95 | 96 | In the Lean code below, replace all uses of "sorry" by proofs. 97 | Hint: Start by replacing `sorry` by `_` (an underscore) to make Lean show you the proof goal. 98 | 99 | ```lean 100 | variables A B C : Prop 101 | 102 | section and_or 103 | variable a : A 104 | variable b : B 105 | variable c : C 106 | include a 107 | include b 108 | include c 109 | 110 | example : C ∨ B := sorry 111 | example : B ∨ C := sorry 112 | 113 | example : (A ∧ B) ∧ (C ∨ B) := 114 | and.intro 115 | sorry 116 | sorry 117 | 118 | example : (B ∨ C) ∨ A := sorry 119 | end and_or 120 | 121 | section or_elimination 122 | variable h : C ∨ B 123 | variable ba : B → A 124 | variable ca : C → A 125 | example : A := sorry 126 | end or_elimination 127 | 128 | section from_false_get_anything 129 | variable f : false 130 | include f 131 | example : A := sorry 132 | end from_false_get_anything 133 | 134 | example : true := sorry 135 | ``` 136 | 137 |
Solution 138 | 139 | ```lean 140 | section exercise 141 | 142 | variables A B C : Prop 143 | 144 | section and_or 145 | variable a : A 146 | variable b : B 147 | variable c : C 148 | include a 149 | include b 150 | include c 151 | 152 | example : C ∨ B := or.intro_left B c 153 | --other possibility: or.intro_right C b 154 | 155 | example : B ∨ C := or.intro_right B c 156 | --other possibility: or.intro_left C b 157 | 158 | example : (A ∧ B) ∧ (C ∨ B) := 159 | and.intro 160 | (and.intro a b) 161 | (or.intro_right C b) --other possibility: or.intro_left B c 162 | 163 | example : (B ∨ C) ∨ A := 164 | or.intro_right _ a 165 | -- more explicitly: or.intro_right (B ∨ C) a 166 | --Note that Lean infers "B ∨ C", we can leave an underscore here 167 | -- 168 | --other possibilities: 169 | -- or.intro_left _ (or.intro_left C b) 170 | -- or.intro_left _ (or.intro_right B c) 171 | end and_or 172 | 173 | section or_elimination 174 | variable h : C ∨ B 175 | variable ba : B → A 176 | variable ca : C → A 177 | example : A := or.elim h ca ba 178 | end or_elimination 179 | 180 | section from_false_get_anything 181 | variable f : false 182 | include f 183 | example : A := false.elim f 184 | end from_false_get_anything 185 | 186 | example : true := trivial 187 | 188 | end exercise 189 | ``` 190 | 191 |
192 | 193 | ## Exercise 8 194 | 195 | Formulate and prove the following statements in Lean: 196 | - (a) A → B → C → (A ∧ B) ∧ (A ∧ C) 197 | - (b) C → A → B → (A ∧ B) ∧ (A ∧ C) 198 | - (c) A → A ∨ A 199 | - (d) A ∧ B → B ∧ A 200 | 201 |
Solution 202 | 203 | ```lean 204 | section exercise 205 | 206 | --assume propositions A, B, C 207 | variables A B C : Prop 208 | 209 | -- A → B → C → (A ∧ B) ∧ (A ∧ C) 210 | -- To understand how to construct the proof, 211 | -- consider the following sequence of intermediate steps. 212 | -- The underscores `_` tell you what is required next. 213 | -- See also the handout on proof strategies. 214 | 215 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := _ 216 | 217 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 218 | assume a : A, _ 219 | 220 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 221 | assume a : A, 222 | assume b : B, _ 223 | 224 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 225 | assume a : A, 226 | assume b : B, 227 | assume c : C, _ 228 | 229 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 230 | assume a : A, 231 | assume b : B, 232 | assume c : C, 233 | and.intro 234 | _ 235 | _ 236 | 237 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 238 | assume a : A, 239 | assume b : B, 240 | assume c : C, 241 | and.intro 242 | (and.intro _ _) 243 | _ 244 | 245 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 246 | assume a : A, 247 | assume b : B, 248 | assume c : C, 249 | and.intro 250 | (and.intro a b) 251 | (and.intro _ _) 252 | 253 | example : A → B → C → (A ∧ B) ∧ (A ∧ C) := 254 | assume a : A, 255 | assume b : B, 256 | assume c : C, 257 | and.intro 258 | (and.intro a b) 259 | (and.intro a c) 260 | 261 | 262 | -- C → A → B → (A ∧ B) ∧ (A ∧ C) 263 | example : C → A → B → (A ∧ B) ∧ (A ∧ C) := 264 | assume c : C, 265 | assume a : A, 266 | assume b : B, 267 | and.intro 268 | (and.intro a b) 269 | (and.intro a c) 270 | 271 | -- A → A ∨ A 272 | example : A → A ∨ A := 273 | assume a : A, 274 | or.intro_left A a 275 | 276 | -- A ∧ B → B ∧ A 277 | example : A ∧ B → B ∧ A := 278 | assume h : A ∧ B, 279 | and.intro 280 | (and.right h) 281 | (and.left h) 282 | 283 | end exercise 284 | ``` 285 | 286 |
287 | 288 | ## Exercise 9 289 | 290 | In this exercise, you learn about the introduction and elimination rule of bi-implication. 291 | First, read the explanation given below. 292 | Then fill in the holes in the proofs below, indicated by `sorry` 293 | 294 | 295 | When A → B and B → A, then we call A and B "equivalent". Intuitively, they are equally "strong" as propositions. 296 | Bi-implication expresses this concept. Bi-implication could be *defined*, just like negation, in terms of the other logical 297 | connectives: 298 | `A ↔ B = (A → B) ∧ (B → A)` 299 | In Lean, bi-implication is, however a primitive concept, implemented through introduction and elimination rules. 300 | The introduction rule is 301 | ``` 302 | A → B B → A 303 | --------------- 304 | A ↔ B 305 | ``` 306 | as one might expect. Similarly, 307 | we get two elimination rules: 308 | ``` 309 | A ↔ B 310 | ------- 311 | A → B 312 | ``` 313 | and 314 | ``` 315 | A ↔ B 316 | ------- 317 | B → A 318 | ``` 319 | See the Lean code below. 320 | Note that "iff" in the Lean code stands for "if and only if", a common way to state a bi-implication in mathematics. 321 | 322 | 323 | ```lean 324 | section bi_impl 325 | 326 | variables A B : Prop 327 | variable f : A → B 328 | variable g : B → A 329 | 330 | #check iff.intro f g 331 | 332 | variable h : A ↔ B 333 | 334 | #check iff.elim_left h 335 | #check iff.elim_right h 336 | 337 | end bi_impl 338 | 339 | 340 | theorem Not_Or {A B : Prop} : 341 | ¬ (A ∨ B) → ¬ A ∧ ¬ B := 342 | sorry 343 | 344 | theorem Not_Or_inv {A B : Prop} : 345 | (¬ A ∧ ¬ B) → ¬ (A ∨ B) := 346 | sorry 347 | 348 | theorem Not_And_inv {A B : Prop} : 349 | ¬ A ∨ ¬ B → ¬ (A ∧ B) := 350 | sorry 351 | 352 | -- use the introduction rule for ↔ and 353 | -- the theorems above to fill this hole with 354 | -- little effort 355 | theorem deM_Not_Or (A B : Prop) : 356 | (¬ A ∧ ¬ B) ↔ ¬ (A ∨ B) := 357 | sorry 358 | ``` 359 | 360 |
Solution 361 | 362 | ```lean 363 | theorem Not_Or {A B : Prop} : 364 | ¬ (A ∨ B) → ¬ A ∧ ¬ B := 365 | assume h : ¬ (A ∨ B), 366 | and.intro 367 | (assume a : A, h (or.intro_left B a)) 368 | (assume b : B, h (or.intro_right A b)) 369 | 370 | theorem Not_Or_inv {A B : Prop} : 371 | (¬ A ∧ ¬ B) → ¬ (A ∨ B) := 372 | assume (h : ¬ A ∧ ¬ B), 373 | assume (k : A ∨ B), 374 | or.elim k h.left h.right 375 | 376 | theorem Not_And_inv {A B : Prop} : 377 | ¬ A ∨ ¬ B → ¬ (A ∧ B) := 378 | assume h : ¬ A ∨ ¬ B, 379 | or.elim h 380 | (assume na : ¬ A, 381 | assume k : A ∧ B, na k.left) 382 | (assume nb : ¬ B, 383 | assume k : A ∧ B, nb k.right) 384 | 385 | -- use the introduction rule for ↔ and 386 | -- the theorems above to fill this hole with 387 | -- little effort 388 | theorem deM_Not_Or (A B : Prop) : 389 | (¬ A ∧ ¬ B) ↔ ¬ (A ∨ B) := 390 | iff.intro Not_Or_inv Not_Or 391 | ``` 392 | 393 |
394 | 395 | ## Exercise 10 396 | 397 | Formulate and prove the following statements as theorems in Lean: 398 | - (a) A ∧ (A → B) → B 399 | - (b) (A → (B → C)) → (A ∧ B → C) 400 | - (c) (A ∧ B → C) → (A → (B → C)) 401 | - (d) (A ∨ B) ∨ C → A ∨ (B ∨ C) 402 | - (e) (A ∧ B) ∨ (A ∧ C) → A ∧ (B ∨ C) 403 | - (f) A ∧ (B ∧ C) → (A ∧ B) ∧ C 404 | - (g) (A → B) → A ∧ C → B ∧ C 405 | - (h) A ∧ B → B ∧ A 406 | - (i) Difficult: prove A ∧ (B ∧ C) → (B ∧ A) ∧ C using only `assume`, f, g, and h. 407 | 408 |
Solution 409 | 410 | Note that given hypothesis ` h : A ∧ B`, the AND-elimination (left) `and.elim_left h` can also be abbreviated as `h.left`. 411 | Similar for (right): `and.elim_right h` can be abbreviated as `h.right`. 412 | Below we use both variants. 413 | 414 | ```lean 415 | --(a) 416 | theorem mod_ponens (A B : Prop) : 417 | A ∧ (A → B) → B := 418 | assume h : A ∧ (A → B), 419 | (and.elim_right h) (and.elim_left h) 420 | 421 | --see https://en.wikipedia.org/wiki/Currying 422 | --(b) 423 | theorem uncurry (A B C : Prop) : 424 | (A → (B → C)) → (A ∧ B → C) := 425 | assume h : A → (B → C), 426 | assume k : A ∧ B, 427 | h (and.elim_left k) (and.elim_right k) 428 | 429 | --(c) 430 | theorem curry (A B C : Prop) : 431 | (A ∧ B → C) → (A → (B → C)) := 432 | assume h : A ∧ B → C, 433 | assume a : A, 434 | assume b : B, 435 | h (and.intro a b) 436 | 437 | --(d) 438 | theorem or_associative (A B C : Prop) : 439 | (A ∨ B) ∨ C → A ∨ (B ∨ C) := 440 | assume h : (A ∨ B) ∨ C, 441 | or.elim h 442 | (assume k : A ∨ B, or.elim k 443 | (assume a : A, or.intro_left _ a) 444 | (assume b : B, or.intro_right A (or.intro_left C b))) 445 | (assume c : C, or.intro_right A (or.intro_right B c)) 446 | /- 447 | Remark: In this proof, it is crucial to do 448 | OR-elim BEFORE OR-intro. 449 | Explanation: OR-elim gives you two cases, each with 450 | a different additional hypothesis/resource. 451 | Only when you know which additional hypothesis you 452 | have, can you make an INFORMED choice with OR-intro 453 | (whether to prove the left proposition or the right 454 | proposition) 455 | -/ 456 | 457 | --(e) 458 | theorem and_distrib_left_inv (A B C : Prop) : 459 | (A ∧ B) ∨ (A ∧ C) → A ∧ (B ∨ C) := 460 | assume h : (A ∧ B) ∨ (A ∧ C), 461 | or.elim h 462 | (assume k : A ∧ B, and.intro k.left (or.intro_left C k.right) ) 463 | (assume k : A ∧ C, and.intro k.left (or.intro_right B k.right) ) 464 | /- 465 | The same remark as with exercise (d) applies: 466 | OR-elim needs to come before OR-intro. 467 | -/ 468 | 469 | --(f) 470 | theorem and_associative {A B C : Prop} : 471 | A ∧ (B ∧ C) → (A ∧ B) ∧ C := 472 | assume h : A ∧ (B ∧ C), 473 | and.intro (and.intro h.left h.right.left) h.right.right 474 | 475 | --(g) 476 | theorem and_left_cong {A B C : Prop} : 477 | (A → B) → (A ∧ C → B ∧ C) := 478 | assume f : A → B, 479 | assume k : A ∧ C, and.intro (f k.left) k.right 480 | 481 | --(h) 482 | theorem and_commutative {A B : Prop} : 483 | A ∧ B → B ∧ A := 484 | assume h : A ∧ B, 485 | and.intro h.right h.left 486 | 487 | --(i) 488 | theorem foo (A B C : Prop) : 489 | A ∧ (B ∧ C) → (B ∧ A) ∧ C := 490 | assume k : A ∧ (B ∧ C), 491 | and_left_cong and_commutative (and_associative k) 492 | ``` 493 | 494 |
495 | 496 | ## Exercise 11 497 | 498 | Prove `¬A ∨ B ⊢ A → B` in natural deduction and in Lean. 499 | Can you prove `A → B ⊢ ¬A ∨ B`? 500 | 501 |
Solution 502 | 503 | #### First part 504 | ``` 505 | ----[Hyp (2)] -----[Hyp (3)] 506 | A ¬A 507 | -----------------[¬E] ---[Ass (1)] 508 | ⊥ B 509 | ------[⊥ E] --- 510 | B B 511 | -------[Hyp] --------[→ I, 3] --------[→ I, 1] 512 | ¬A ∨ B ¬A → B B → B 513 | --------------------------------------[∨ E] 514 | B 515 | -------[→ I, 2] 516 | A → B 517 | ``` 518 | 519 | #### Second part 520 | In order to deduce ¬A ∨ B, one has two possibilities, either using ∨-introduction or through ∨-elimination. To use the introduction rule, we need to find a proof of either ¬A or B. Our hypothesis is A → B, so we could find a proof of B from A (by → -elimination). Hence, we would need to find a proof of A to find a proof of B, or we have to find a proof of ¬A. So we would be able to deduce ¬A ∨ B from A → B if we would have a proof of ¬A ∨ A. 521 | To use the elimination rule, we have to find a proposition X together with proofs of X → ¬A and X → B. The only assumption/hypothesis we have is A → B. So we could try to use X := A → B. In this case, we have to give proofs of both (A → B) → ¬A and (A → B) → B. In both cases we should use → -introduction. Yet again, this reduces to having a proof of either ¬A (in the former) or A (in the latter). 522 | So in both cases it reduces to having a proof of ¬A ∨ A. Although you might think it should hold, it does not follow from our axioms. If this is included, we call our logic *classical*. 523 | 524 |
525 | 526 | ## Exercise 12 527 | 528 | Find two proofs of A → (A → B → C) → B → C. Write each proof in natural deduction and in Lean. 529 | 530 |
Solution 531 | 532 | This proof is obtained by following the proof strategy of using implication-introduction whenever possible, starting at the bottom and going up to C: 533 | ``` 534 | -----------f --a 535 | A → B → C A 536 | ------------------- --- b 537 | B → C B 538 | ---------------------------- impl-elim 539 | C 540 | ---------- asm b 541 | B → C 542 | ---------------------------- asm f 543 | (A → B → C) → B → C 544 | ---------------------------- asm a 545 | A → (A → B → C) → B → C 546 | ``` 547 | In the next proof, when going bottom-up, upon reaching B -> C, we notice that we have a hypothesis `f : A -> (B -> C)` which gives us exactly what we need, provided we can produce a proof of A. 548 | And indeed we do have a proof `a : A` around: 549 | ``` 550 | -------------f ---a 551 | A → (B → C) A 552 | ----------------------- impl-elim 553 | B → C 554 | ---------------------------- asm f 555 | (A → B → C) → B → C 556 | ---------------------------- asm a 557 | A → (A → B → C) → B → C 558 | ``` 559 | In Lean: 560 | ```lean 561 | -(a) 562 | 563 | example (A B C : Prop) : A → (A → B → C) → B → C := 564 | assume a : A, 565 | assume f : A → B → C, 566 | assume b : B, 567 | f a b 568 | 569 | /- 570 | -----------f --a 571 | A → B → C A 572 | ------------------ --- b 573 | B → C B 574 | ---------------------------- impl-elim 575 | C 576 | ---------- asm b 577 | B → C 578 | ---------------------------- asm f 579 | (A → B → C) → B → C 580 | ---------------------------- asm a 581 | A → (A → B → C) → B → C 582 | -/ 583 | 584 | 585 | --(b) 586 | 587 | example (A B C : Prop) : A → (A → B → C) → B → C := 588 | assume a : A, 589 | assume f : A → B → C, 590 | f a 591 | 592 | 593 | /- 594 | ------------f ---a 595 | A → (B → C) A 596 | ----------------------- impl-elim 597 | B → C 598 | ---------------------------- asm f 599 | (A → B → C) → B → C 600 | ---------------------------- asm a 601 | A → (A → B → C) → B → C 602 | -/ 603 | ``` 604 | 605 |
606 | 607 | ## Exercise 13 608 | 609 | - (a) Complete the following proof tree, i.e., construct the sub-trees (X) and (Y): 610 | ``` 611 | (X) (Y) 612 | ------h ----------- ----------- 613 | A ∨ B A → C ∨ D B → C ∨ D 614 | -------------------------------------- or-elim h 615 | C ∨ D 616 | ------------------ asm g 617 | (B → D) -> C ∨ D 618 | ------------------------------ asm f 619 | (A → C) → (B → D) → C ∨ D 620 | ---------------------------------------- asm h 621 | A ∨ B → (A → C) → (B → D) → C ∨ D 622 | ``` 623 | - (b) Translate the complete proof into Lean. 624 | - (c) Give a description of the proof in the English language. 625 | - (d) If the proof were given in Lean, could you derive the other formats? If the proof were given in English, could you derive the other formats? 626 | 627 |
Solution 628 | 629 | - (a) 630 | For X 631 | ``` 632 | ------f ---a 633 | A → C A 634 | ----------------- 635 | C 636 | -------------- or-intro-left 637 | C ∨ D 638 | ------------ asm a 639 | A → C ∨ D 640 | ``` 641 | For Y: 642 | ``` 643 | ------g ---b 644 | B → D A 645 | ----------------- 646 | D 647 | -------------- or-intro-right 648 | C ∨ D 649 | ------------ asm b 650 | B → C ∨ D 651 | ``` 652 | - (b) 653 | ```lean 654 | example (A B C D : Prop) : 655 | A ∨ B → (A → C) → (B → D) → C ∨ D := 656 | assume h : A ∨ B, 657 | assume f : A → C, 658 | assume g : B → D, 659 | or.elim h 660 | (assume a : A , or.intro_left D (f a)) 661 | (assume b : B, or.intro_right C (g b)) 662 | ``` 663 | - (c) 664 | In order to prove A ∨ B → (A → C) → (B → D) → C ∨ D, we assume having h : A ∨ B and f : A → C and g : B → D, and we prove C ∨ D. 665 | To do so, we do a case distinction on h : A ∨ B. In the first case, h ''contains'' a proof a : A. In this case, we can prove C, and thus C∨ D, from f and a. 666 | In the second case, h ''contains'' a proof b : B. In this case, we can prove D,and thus C ∨ D, from g and b. 667 | 668 | - (d) By the end of this lesson, you should be able to translate in all directions. Test for yourself if you are able, and ask questions if not. 669 | 670 |
671 | 672 | ## Exercise 14 673 | Translate the following Lean proofs into proofs in natural deduction. 674 | ```lean 675 | theorem uncurry (A B C : Prop) : (A → (B → C)) → (A ∧ B → C) := 676 | assume h1 : A → (B → C), 677 | assume h2 : A ∧ B, 678 | h1 (and.left h2) (and.right h2) 679 | 680 | 681 | theorem and_distribute (A B C : Prop) : A ∧ (B ∨ C) → (A ∧ B) ∨ (A ∧ C) := 682 | assume h1 : A ∧ (B ∨ C), 683 | or.elim (and.right h1) 684 | (assume h2 : B, 685 | or.intro_left (A ∧ C) (and.intro (and.elim_left h1) h2)) 686 | (assume h2 : C, 687 | or.intro_right (A ∧ B) (and.intro (and.elim_left h1) h2)) 688 | ``` 689 | 690 |
Solution 691 | 692 | #### Solution uncurry 693 | 694 | ``` 695 | -------------[Ass(0)] --------------- [Ass(1)] 696 | (A → (B → C)) (A ∧ B) 697 | --------------[→ E] ---------[∧ E right] 698 | B → C B 699 | ------------------------------[→ E] 700 | C 701 | ----------------------------[→ I, 1] 702 | (A ∧ B → C) 703 | ----------------------------[→ I, 0] 704 | (A → (B → C)) → (A ∧ B → C) 705 | ``` 706 | 707 | #### Solution and distribute 708 | 709 | ``` 710 | A ∧ (B ∨ C) A ∧ (B ∨ C) 711 | [∧ E left]---------- ----[Ass (1)] ---[∧ E left] ---[Ass (2)] 712 | A B A C 713 | ----------[Ass (0)] ---------------[∧ I] ----------------------[∧ I] 714 | A ∧ (B ∨ C) (A ∧ B) (A ∧ C) 715 | -----------[∧ E right] -----------[→ I, 1] -----------[→ I, 2] 716 | (B ∨ C) B → (A ∧ B) C → (A ∧ C) 717 | -------------------------------------------------------------------------[∨ E] 718 | (A ∧ B) ∨ (A ∧ C) 719 | ------------------------------[→ I](0) 720 | A ∧ (B ∨ C) → (A ∧ B) ∨ (A ∧ C) 721 | ``` 722 | 723 |
724 | -------------------------------------------------------------------------------- /propositional-logic/and.lean: -------------------------------------------------------------------------------- 1 | variables A B : Prop 2 | #check A 3 | #check B 4 | 5 | section and_intro 6 | --Reminder: 7 | --variables are assumptions 8 | variable a : A 9 | variable b : B 10 | include a b 11 | #check a 12 | #check and.intro a b 13 | --Synonymous with 14 | #check (⟨ a , b ⟩ : A ∧ B) 15 | --written \ langle , \ rangle 16 | --this needs type annotation 17 | 18 | 19 | example : A ∧ B := and.intro a b 20 | 21 | /- corresponds to 22 | 23 | a--- ---b 24 | A B 25 | ----- and-introduction 26 | A ∧ B 27 | -/ 28 | end and_intro 29 | 30 | 31 | section and_elim 32 | variable h : A ∧ B 33 | include h 34 | #check h 35 | #check and.left h 36 | #check h.left --synonymous 37 | #check and.right h 38 | 39 | example : A := h.left 40 | 41 | example : B := h.right 42 | 43 | /- correspond to 44 | 45 | ------ h 46 | A ∧ B 47 | ----- and-elimination-left 48 | A 49 | 50 | and 51 | 52 | ----- h 53 | A ∧ B 54 | ----- and-elimination-right 55 | B 56 | -/ 57 | end and_elim 58 | -------------------------------------------------------------------------------- /propositional-logic/false.lean: -------------------------------------------------------------------------------- 1 | section false_elim 2 | 3 | #check false 4 | variable f : false 5 | include f 6 | 7 | #check false.elim 8 | #check false.elim f 9 | --prints false.elim f : ?M_1 10 | 11 | --signals that one can prove 12 | --anything from false 13 | 14 | 15 | variable A : Prop 16 | #check A 17 | example : A := false.elim f 18 | 19 | /- corresponds to 20 | 21 | false 22 | ----- false-elim 23 | A 24 | -/ 25 | 26 | end false_elim -------------------------------------------------------------------------------- /propositional-logic/impl.lean: -------------------------------------------------------------------------------- 1 | variables A B : Prop 2 | #check A 3 | 4 | section impl_intro 5 | 6 | variable a : A 7 | include a 8 | 9 | example : B := _ 10 | 11 | end impl_intro 12 | 13 | section impl_intro_2 14 | example : A → B := 15 | assume a : A, _ 16 | end impl_intro_2 17 | 18 | /- 19 | "assume a : A" is 20 | implication-introduction 21 | 22 | 23 | ---a 24 | A 25 | . 26 | . 27 | . 28 | B 29 | --------- assume a 30 | A → B 31 | 32 | -/ 33 | 34 | 35 | 36 | section impl_elim 37 | variable f : A → B 38 | variable a : A 39 | include f a 40 | #check f a 41 | 42 | example : B := f a 43 | 44 | 45 | /- corresponds to 46 | 47 | f----- ---a 48 | A → B A 49 | ---------- implication-elim 50 | B 51 | -/ 52 | end impl_elim 53 | 54 | -------------------------------------------------------------------------------- /propositional-logic/or.lean: -------------------------------------------------------------------------------- 1 | variables A B C : Prop 2 | #check A 3 | 4 | section or_intro 5 | variable a : A 6 | include a 7 | 8 | #check @or.intro_left A B 9 | 10 | example : A ∨ B := or.intro_left B a 11 | 12 | variable b : B 13 | include b 14 | 15 | example : A ∨ B := or.intro_right A b 16 | 17 | /- Information "B" has to 18 | be given explicitly, whereas 19 | A can be deduced from "a" 20 | -/ 21 | /- corresponds to 22 | 23 | ---a 24 | A 25 | ----- or-introduction-left 26 | A ∨ B 27 | 28 | 29 | B 30 | ----- or-introduction-right 31 | A ∨ B 32 | 33 | -/ 34 | 35 | 36 | 37 | 38 | variable b : B 39 | #check or.intro_right A b 40 | 41 | example : A ∨ B := _ 42 | 43 | /- corresponds to 44 | 45 | ---b 46 | B 47 | ----- or-introduction-right 48 | A ∨ B 49 | -/ 50 | end or_intro 51 | 52 | 53 | 54 | section or_elim 55 | variable h : A ∨ B 56 | include h 57 | 58 | variable ha : A → C 59 | variable hb : B → C 60 | #check (or.elim h ha hb) 61 | #check @or.elim 62 | 63 | example : C := or.elim h (ha) (hb) 64 | 65 | /- corresponds to 66 | 67 | ----h ----ha ----hb 68 | A ∨ B A → C B → C 69 | ---------------------------- 70 | C 71 | -/ 72 | /- 73 | Example: 74 | C = put nail in wall 75 | A = hammer 76 | B = shoe 77 | A ∨ B = toolbox containing 78 | one of hammer and shoe, 79 | but you don't know which 80 | -/ 81 | end or_elim -------------------------------------------------------------------------------- /propositional-logic/parsetree_exercise1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantumformalism/software-verification/b9f93c808a117985fddd24868550d6d4a3da8d57/propositional-logic/parsetree_exercise1.png -------------------------------------------------------------------------------- /propositional-logic/proofs-in-prop-logic.lean: -------------------------------------------------------------------------------- 1 | 2 | -- proof using lambda terms directly 3 | example (A : Prop) : A → A ∧ A := 4 | assume (a : A), and.intro a a 5 | 6 | -- proof using tactics 7 | example (A : Prop) : A → A ∧ A := 8 | begin 9 | intro a, 10 | apply and.intro, 11 | { apply a }, 12 | { apply a } 13 | end 14 | 15 | -- proof using lambda terms directly 16 | example (A B : Prop) : A ∧ (A → B) → B := 17 | assume h : A ∧ (A → B), 18 | h.2 h.1 19 | 20 | -- proof using tactics 21 | example (A B : Prop) : A ∧ (A → B) → B := 22 | begin 23 | intro h, 24 | apply h.2, 25 | apply h.1 26 | end 27 | 28 | -- proof using lambda terms directly 29 | example (A B C : Prop) : (A → (B → C)) → (A ∧ B → C) := 30 | assume (h : A → (B → C)), 31 | assume (j : A ∧ B), 32 | h (j.1) (j.2) 33 | 34 | -- proof using tactics 35 | example (A B C : Prop) : (A → (B → C)) → (A ∧ B → C) := 36 | begin 37 | intro h, 38 | intro j, 39 | apply h, 40 | { apply j.1 } , 41 | { apply j.2 } 42 | end 43 | 44 | --------------------------------------------------------------------------------