├── 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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 |
--------------------------------------------------------------------------------