@@ -136,6 +136,182 @@ Find a path from `A` to `I` using different reasoning styles. Have at least
136136one purely forward arguing path and one purely backward arguing path.
137137-/
138138
139+ example (A B C D E F G H I : Prop )
140+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
141+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
142+ (q : H → G) (r : H → I) (a : A) : I := by
143+ have b : B := f a
144+ have e : E := i b
145+ have f : F := l e
146+ have i : I := p f
147+ exact i
148+
149+ example (A B C D E F G H I : Prop )
150+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
151+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
152+ (q : H → G) (r : H → I) (a : A) : I := by
153+ have b := f a -- output type is inferred / determined by the term mode proof
154+ have e := i b -- output type is inferred / determined by the term mode proof
155+ have f := l e -- output type is inferred / determined by the term mode proof
156+ have i := p f -- output type is inferred / determined by the term mode proof
157+ exact i
158+
159+ example (A B C D E F G H I : Prop )
160+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
161+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
162+ (q : H → G) (r : H → I) (a : A) : I :=
163+ p <| l <| i <| f a -- Can just collapse everything into term mode
164+
165+ example (A B C D E F G H I : Prop )
166+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
167+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
168+ (q : H → G) (r : H → I) (a : A) : I := by
169+ apply p
170+ apply l
171+ apply i
172+ apply f
173+ exact a
174+
175+ -- mixed reasoning: argue backwards from `I` to `E` and then forwards from `A`
176+ example (A B C D E F G H I : Prop )
177+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
178+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
179+ (q : H → G) (r : H → I) (a : A) : I := by
180+ apply p
181+ apply l
182+ exact i (f a)
183+
184+ /-
185+ ## Forgetting about assumptions with `clear`
186+
187+ The `clear` tactic lets you forget assumptions. You should generally not need
188+ this and instead structure your code to only have necessary assumptions in scope.
189+ -/
190+
191+ example (A B C D E F G H I : Prop )
192+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
193+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
194+ (q : H → G) (r : H → I) (a : A) : I := by
195+ clear g h j k m n q r -- The linter still complains though
196+ exact p <| l <| i <| f a
197+
198+ /-
199+ ## The `suffices` Tactic
200+
201+ Enables explicit backward reasoning by declaring intermediate goals:
202+
203+ 1. Declares a subgoal that would suffice to prove the original goal
204+ 2. Once proven, provides access to the subgoal proof via `this`
205+ 3. Maintains goal context for clearer proof structuring
206+
207+ This tactic is used around 2,600 times in mathlib. But it is very nice
208+ in that mimicks the human language "it suffices to show that ... because ...".
209+ -/
210+
211+ -- Basic suffices example showing goal transformation
212+ example (P Q R : Prop ) (h₁ : P → Q) (h₂ : Q → R) (p : P) : R := by
213+ suffices Q by -- unlike `apply h₂` the result is already visible in code
214+ -- At this point we have entered a sub-proof where we show that it does
215+ -- in fact suffice to show Q, similar to how `have` has its own sub-proof.
216+ -- In this sub-proof the actual assumption you are claiming suffices is
217+ -- introduced as `this`. Note that the term `this` (if not used as an
218+ -- actual variable name as it us here) also refers the last unnamed variable.
219+ exact h₂ this
220+ exact h₁ p
221+
222+ /-
223+ Unlike for example `have`, the tactic `suffices` only supports term mode
224+ proofs, i.e., it always needs the `by` and does not use the `:=` proof indicator.
225+ -/
226+
227+ -- Compare with equivalent `apply`
228+ example (P Q R : Prop ) (h₁ : P → Q) (h₂ : Q → R) (p : P) : R := by
229+ apply h₂
230+ exact h₁ p
231+
232+ -- You can actually name the hypothesis in `suffices`
233+ example (P Q R : Prop ) (h₁ : P → Q) (h₂ : Q → R) (p : P) : R := by
234+ suffices q : Q by
235+ exact h₂ q
236+ exact h₁ p
237+
238+ /-
239+ ## The `refine` Tactic
240+
241+ The `refine` tactic behaves like `exact` but permits placeholders (i.e. `?_`)
242+ in the provided term. Any unsolved hole that is not fixed by unification with
243+ the main goal's target is converted into a new goal. This tactic is used
244+ around 19,000 times in mathlib.
245+ -/
246+
247+ example (P Q : Prop ) (f : P → Q) (p : P) : Q := by
248+ refine f ?_ -- in this case it behaves like `apply`
249+ exact p -- this answers a sub-goal raised `_?`
250+
251+ example (P Q : Prop ) (f : P → Q) (p : P) : Q := by
252+ refine f p -- in this case it behaves like `exact`
253+
254+ -- You can also stack proofs inside proofs for `refine`
255+ example (P Q : Prop ) (f : P → Q) (p : P) : Q := by
256+ refine f (by exact p)
257+
258+ -- In fact this also works for `exact`
259+ example (P Q : Prop ) (f : P → Q) (p : P) : Q := by
260+ exact f (by exact p)
261+
262+ /-
263+ ## Tactics are just "syntactic sugar" to make mathematician's live easier
264+
265+ At its core everything is term mode forward arguing compositing of methods,
266+ but tactics allow you to argue closer to natural language. This inherently
267+ will mean there are many equivalent ways of achieving the same goal
268+ and there will always some weirdness and inconsistencies because of that
269+ flexibility.
270+
271+ ## Notational inconsistencies
272+
273+ Unfortunately the syntax of mathlib tactics is not entirely
274+ consistent, so in particular `:=` is not always used to signal
275+ the start of a sub-proof (`let` and `have` use it, `refine` and
276+ `suffices` do not) and just because one tactic admits a certain
277+ syntax, another does not necessarily allow the same, so the
278+ following are all *invalid* for `suffices`:
279+
280+ * suffices Q -- just leave argument open
281+ * suffices Q by ?_ -- leave an intentional gap
282+ * suffices Q := exact h₂ this -- use term mode
283+
284+ ## Whitespace (indentation and newlines)
285+
286+ Indentation does not matter (since lean / mathlib 4), but you
287+ can use it freely to structure your proofs and indicate when
288+ you are in a sub-proof. Newlines matter, but as in many languages,
289+ you can replace them with `;`, e.g.:
290+ -/
291+
292+ example (P Q R : Prop ) (h₁ : P → Q) (h₂ : Q → R) (p : P) : R :=
293+ by apply h₂; exact h₁ p
294+
295+
296+ /-
297+ ## Exercise Block B02: Graph of Implications (Continued)
298+ -/
299+
300+ -- Use only `suffices` to work backwards from the goal:
301+ example (A B C D E F G H I : Prop )
302+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
303+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
304+ (q : H → G) (r : H → I) (a : A) : I := by
305+ sorry
306+
307+ -- Use only `refine` to work backwards from the goal:
308+ example (A B C D E F G H I : Prop )
309+ (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
310+ (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
311+ (q : H → G) (r : H → I) (a : A) : I := by
312+ sorry
313+
314+ -- Combine all of `clear`, `exact`, `have`, `suffices`, `refine`, and `apply`
139315example (A B C D E F G H I : Prop )
140316 (f : A → B) (g : C → B) (h : A → D) (i : B → E) (j : C → F)
141317 (k : E → D) (l : E → F) (m : G → D) (n : H → E) (p : F → I)
0 commit comments