Zulip Chat Archive

Stream: new members

Topic: more induction related questions


Robert hackman (Aug 24 2023 at 10:49):

Hi,
so I'm still working on the induction examples. This time with unequal signs.

mve:

example (n : ):  k in Finset.Ico 1 n.succ, ((k - 1 )^2 :  ) < ((Nat.zero + 1) ^ (3: ) : ) / 3 := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    rw[ih]
    rw[succ_eq_add_one]

There is an error at rw[ih] which says that it can't find the target expression. Although it's clearly there, but it's embedded in Rat.blt so maybe that's the problem. If the rewrite is successfull I want to finish the goal by using Nat.succ_lt_succ`. Is that a viable way to go? regards

Kevin Buzzard (Aug 24 2023 at 11:00):

Natural subtraction is pathological like natural division so you can't expect things to be easy. Also you're making your life more difficult by insisting on summing from 1 to n and then taking away 1, instead of summing from 0 to n-1. As I said several times last week when I was in a field and unable to post code, you should coerce into the rationals immediately if you want these things to be as easy as they are on paper. In particular I'm very strongly of the opinion that this goal should look like

example (n : ):  k in Finset.Ico 1 n.succ, ((k : ) - 1 )^2 ...

As for your current problem, the rw tactic will only consume equalities and iff statements. Think about what the rw tactic does to understand why. In particular it will not consume a statement of the from X < Y (which is what you're feeding it with ih) so you need to rethink your mathematical proof.

Kevin Buzzard (Aug 24 2023 at 11:02):

Oh, it's probably also worth remarking that your example is of course not at all true: if n is huge then a sum of a bunch of squares is clearly going to be > 1/3.

Robert hackman (Aug 24 2023 at 11:24):

Ok so about the whole type thing, I'm not yet thinkting in those dimension but I adapted my code.
I can't sum from 0 to n-1 because the statement is not true for 0.

The logic error was a stupid mistake, this is the correct version where it's not ... < ((Nat.zero + 1) ^ 3 ... but ... < ((n + 1) ^ 3 ...
example (n : ℕ): ∑ k in Finset.Ico 1 n.succ, (((k : ℚ) - 1 )^2) < ((n + 1) ^ (3: ℕ) : ℚ) / 3 := by

So I will start to sarch for something that does rewrites for lt

Kevin Buzzard (Aug 24 2023 at 12:12):

You can sum k from 0 to <n instead of summing k-1 from 1 to <n+1, this doesn't change anything, this is just a change of variables

Robert hackman (Aug 24 2023 at 21:56):

ah uff sure, sorry

Robert hackman (Sep 01 2023 at 11:02):

So I've really really tried but am not getting anywhere. So I understand why rewrite doesn't work, instead I think I have to prove thorugh manual calc or some unequality theorem that the replaced(or rewritten) version is true. I've tried to use add_lt_add_right but since I'm trying to prove induction, a+b<c doesn't work because the c is c(n+1) for the goal and c(n) for the induciton hypothisis. I'm probably on the completely wrong track. Any help or tips would be greatly appreciated!

Kevin Buzzard (Sep 01 2023 at 13:30):

Can you please post a #mwe containing your current work (click on the link to see the details of what this is)? That is the best way to ask questions here.

Kevin Buzzard (Sep 01 2023 at 13:31):

"can someone help me fill in this sorry in this fully working code" is a better question than "help me I am stuck"

Moritz Firsching (Sep 01 2023 at 13:44):

The statement in the example does not seem to be true:

example (n : ):  k in Finset.Ico 1 n.succ, ((k - 1 )^2 :  ) < ((Nat.zero + 1) ^ (3: ) : ) / 3

You can check the left hand side and the right hand side:

def n := 2
#eval  k in Finset.Ico 1 n.succ, ((k - 1)^2 :  ) -- gives`1`
#eval ((Nat.zero + 1) ^ (3: ) : ) / 3 --gives (1: Rat)/3

Kevin Buzzard (Sep 01 2023 at 14:13):

By the way Robert, Lean does not do maths for you -- Lean checks your maths. So is your question "I can't get Lean to understand a maths proof I know" or is it "I don't know how to prove this theorem myself"?

Robert hackman (Sep 01 2023 at 17:58):

This is the mwe, the first one is obv. false, this one should be correct.

import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Data.Num.Lemmas
import Mathlib.Data.Nat.Basic
import Mathlib.Tactic.Ring
import Mathlib.Tactic.FieldSimp
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Nat.Interval
import Mathlib.Order.LocallyFinite

open Num
open BigOperators
open Finset
open Nat
example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      rw[add_lt_add_right ih]

      sorry
      -- rw[ih]
      -- rw[add_lt_add_right]
      -- sorry
    case succ.hab => sorry

Robert hackman (Sep 01 2023 at 18:01):

Kevin Buzzard said:

By the way Robert, Lean does not do maths for you -- Lean checks your maths. So is your question "I can't get Lean to understand a maths proof I know" or is it "I don't know how to prove this theorem myself"?

I do understand this basic induciton, but fail to translate it into the language, any other humiliations you want me to admit? I've put many many hours into the lang and am starting to make sense of the syntax/ logic, please don't let me down lol.

Mario Carneiro (Sep 01 2023 at 18:02):

Could you explain the proof strategy to us informally?

Mario Carneiro (Sep 01 2023 at 18:05):

The error I get on that MWE is that add_lt_add_right ih is a proof of a < statement and rw takes equality statements

Mario Carneiro (Sep 01 2023 at 18:09):

calc is probably the clearest way to go about this:

    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
        _ < ((Nat.succ n + 1) ^ 3) / 3 := ?_
      sorry

Mario Carneiro (Sep 01 2023 at 18:10):

or if you like golfing:

    case succ =>
      apply (add_lt_add_right ih _).trans
      sorry

Robert hackman (Sep 01 2023 at 18:11):

This is very informal though, as thought.
First you show that the sum of k=1 to n +1 (k-1)^2 <... can be written as k=1 to n (k-1)^2 + (n+1-1)^2 <..., then you replace k=1 to n (k-1)^2part of above equation with the ih and prove that thourgh simplifcation until you have smth like n > 0. That's the paper way I guess.

Robert hackman (Sep 01 2023 at 18:14):

thank you so much for the help!

Robert hackman (Sep 01 2023 at 18:15):

Really good to know that the add_lt_add_right was the right choice at least I just didn't know how to use it

Kevin Buzzard (Sep 01 2023 at 18:31):

Yeah, rw eats a list of proofs but each proof must be either an iff or an equality: its job is to replace X by Y so X had better be equal to Y.

Kyle Miller (Sep 01 2023 at 18:35):

I'm not sure which import you need precisely, but with the whole kitchen sink import Mathlib.Tactic you can replace add_lt_add_right ih _ with by gcongr. It sort of does rewrites with inequalities (or more accurately, it knows the names of lemmas like add_lt_add_right so you don't have to)

Mario Carneiro (Sep 01 2023 at 18:37):

It also reminds me that generalized rewriting came up a lot in iris-lean, there is a rw' tactic which allows you to rewrite with any kind of transitive relation using a gcongr-like traversal

Mario Carneiro (Sep 01 2023 at 18:38):

it would be nice if simp supported other relations, it has basically all the tools it needs to do so

Kevin Buzzard (Sep 01 2023 at 18:45):

gsimp

Robert hackman (Sep 05 2023 at 10:47):

Ok, I spend another 10 hours and didn't move a cm lol.
So up front here is my mve:

import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Data.Num.Lemmas
import Mathlib.Data.Nat.Basic
import Mathlib.Tactic.Ring
import Mathlib.Tactic.FieldSimp
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Nat.Interval
import Mathlib.Order.LocallyFinite

open Num
open BigOperators
open Finset
open Nat

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      calc
        n * 27 < n * 36 + 12 := by ring_nf
    case succ.hab =>
      sorry

basically I'm currently completely overwhelemed trying to proof 12 + ↑n * 27 < 24 + ↑n * 36(without using gsimp...).
There are many tactics that proof variations of a + b < a + c(or theorems with iff exists) but none for rings (at least I couldn't find them). My idea now was to isolate and simplify until I get some sporadic enlightment or something like that but I'm also failing on that, so any suggestions would be welcome. regards

Yaël Dillies (Sep 05 2023 at 10:49):

There are many tactics that proof variations of a + b < a + c (or theorems with iff exists) but none for rings

Have you tried the lemmas you found which you thought were not for rings?

Robert hackman (Sep 05 2023 at 10:58):

yeah I tried many but none worked, I also understand (now...) why they don't work. Edit: I found a few lemmas it was more that I couldn't figure out how to transfrom the term..

Kevin Buzzard (Sep 05 2023 at 17:35):

The code is full of errors for me. Can you make it error-free by sorrying all the problems rather than just letting them error?

Kevin Buzzard (Sep 05 2023 at 17:46):

OK so it wasn't too bad to fix the errors: here's one way of finishing the proof.

import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Tactic.FieldSimp

open BigOperators
open Nat

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      norm_cast
      linarith
    case succ.hab =>
      simp

(note that you don't need all those imports)

Robert hackman (Sep 06 2023 at 08:56):

Thank you so much. What's confusing to me is that without norm_cast, linarith throws linarith failed to find a contradiction, but if I understand correctly, norm_cast is really only mutating types, that's why I thought the term's pattern wasn't "compatible"(without understanding why...) with linarith

Alex J. Best (Sep 06 2023 at 11:56):

Well the fact that 12 + q * 27 < 24 + q * 36 isn't true for all rational numbers q. So without the norm_cast step (which essentially makes the argument that 12 + n * 27 < 24 + n * 36 for natural numbers interpreted as rationals if and only if the same inequality over the naturals) linarith doesn't know how to conclude as it doesn't work out that the casts of n must be nonnegative. After norm_cast the correcponding goal is more suitable for linarith
One could argue that linarith should know that a natural number treated as a rational is nonnegative, but it seems it currently doesn't.

Robert hackman (Sep 07 2023 at 17:25):

Yeah that makes sense, thx!

Robert hackman (Sep 08 2023 at 10:21):

So I want do finish the example with a manual more insightful proof than linarith (for learning purposes). Apperantly, when just simplifying one can use iff to proof the simplification. Why is that? I thought everyhting would need to be proofed or that just axioms applying?
Now I'm stuck at -9 < 12/n since it's a type missmatch which I don't want to resolve. Instead I want to proof at that point that this Prop is true since it cannot be 12/n cannot get negative, how would I do that?

Here is my mve:

import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Data.Num.Lemmas
import Mathlib.Data.Nat.Basic
import Mathlib.Tactic.Ring
import Mathlib.Tactic.FieldSimp
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Nat.Interval
import Mathlib.Order.LocallyFinite

open Num
open BigOperators
open Finset
open Nat

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      -- norm_cast
      calc
        -- 12 + ↑n * 27 < 24 + ↑n * 36 -- - 12
        27 * n < 12 + n * 36  -- /n
        27 < 12/n + 36  -- -36
        (-9: ) < 12/n  -- /12

    case succ.hab =>
      simp

Kevin Buzzard (Sep 08 2023 at 13:45):

Can you post code with sorrys (and comments saying "this is the sorry I am stuck on") rather than errors, which are very confusing?

Robert hackman (Sep 09 2023 at 13:37):

Sure, I hope that’s more understandable

import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Data.Num.Lemmas
import Mathlib.Data.Nat.Basic
import Mathlib.Tactic.Ring
import Mathlib.Tactic.FieldSimp
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Nat.Interval
import Mathlib.Order.LocallyFinite

open Num
open BigOperators
open Finset
open Nat

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      -- norm_cast
      calc
        -- 12 + ↑n * 27 < 24 + ↑n * 36 -- - 12
        27 * n < 12 + n * 36  -- /n
        27 < 12/n + 36 := by sorry -- -substract 36 and proof of that the natural right side cannot be smaller than the negative left side
       --  (-9: ℚ) < 12/n ↔ -- /12

    case succ.hab =>
      simp

Alex J. Best (Sep 09 2023 at 13:46):

It looks like the division operation here is the division of natural numbers (where 1 / 2 = 0 as it outputs a natural number).
That's probably not what you want (its not a very well behaved function).
use 12/(n : ℚ) so that lean treats your numbers as rationals before dividing

Alex J. Best (Sep 09 2023 at 13:48):

You also have a bunch of errors earlier and later in the snippet which I think just confuse things (and leans error reporting).
Try and focus on one sorry at a time, maybe stating things as separate lemmas if needed.

Alex J. Best (Sep 09 2023 at 13:50):

You'll also probably need to split into cases based on whether n is zero or not, as that will likely be a requirement to apply many lemmas about divisibility

Robert hackman (Sep 09 2023 at 17:17):

Regarding the bunch of errors, there's that expected := (at line case succ.hab) error that I really don't understand. Even when I'm finishing the last line in succ n ihin the scope of the calc with sorry it's still there. I can't really get rid of it. Up to just now I thought that when I'm prooving the code in the (last)calc section, it would go away but not event than apperantly, I relly can't get rid of it if I'm using the calc mode

Robert hackman (Sep 09 2023 at 17:40):

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      -- norm_cast
      -- linarith
      calc
        12 + n * 27 < 24 + n * 36 := by linarith
    case succ.hab =>
      simp

for example throws the error expected := , at line case succ.hab and this version:

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top]
    rw[ succ_eq_add_one]
    case succ =>
      calc
         k in Finset.Ico 0 n.succ, ((k + 1 : ) - 1) ^ 2 + ((Nat.succ n : ) + 1 - 1) ^ 2
        _ < ((n + 1) ^ 3) / 3 + ((Nat.succ n : ) + 1 - 1) ^ 2 := add_lt_add_right ih _
      field_simp
      rw[div_lt_div_iff]
      case calc.step.b0 =>
        norm_num
      case calc.step.d0 =>
        norm_num
      ring_nf
      simp
      -- norm_cast
      -- linarith
      calc
        12 + n * 27
        _ < 24 + n * 36 := by linarith
    case succ.hab =>
      simp

throws invalid 'calc' step, failed to synthesize Trans instance Trans LT.lt LT.lt ?m.1047at the second calc statement although it's technically the same (I think)

Kevin Buzzard (Sep 09 2023 at 17:54):

I think you don't have the right syntax for calc. Search for examples in the source code.

Kevin Buzzard (Sep 09 2023 at 18:04):

Here's an example from mathematics in Lean:

theorem my_lemma4 :
     {x y ε : }, 0 < ε  ε  1  |x| < ε  |y| < ε  |x * y| < ε := by
  intro x y ε epos ele1 xlt ylt
  calc
    |x * y| = |x| * |y| := sorry
    _  |x| * ε := sorry
    _ < 1 * ε := sorry
    _ = ε := sorry

Note that the first line is an equality, not a number.

Robert hackman (Sep 10 2023 at 09:07):

So I'm just very confused at that point.
I want to simplify by transforming both sides of the equasion, for example substracting 12, then dividing both sides by n and then 12.
I spend some time now reading thorugh docs and am still not certain which way to read it.
So I will just assume now that when stating an in- or equality that it always refers to the left side of the equasion and that all of what I wrote above is wrong.

But how do I go about transforming both sides then?

Damiano Testa (Sep 10 2023 at 09:44):

Are you referring to your latest post? This seems to work and maybe it is useful.

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top (Nat.zero_le ..)]
    rw[ Nat.succ_eq_add_one]
    have := _root_.add_lt_add_right ih (((Nat.succ n : ) + 1 - 1) ^ 2)
    apply this.trans_le
    field_simp
    apply div_le_div ?_ ?_ zero_lt_three rfl.le
    · positivity
    · ring_nf
      apply add_le_add_right
      apply add_le_add_right
      apply add_le_add
      · norm_num
      · norm_cast
        apply Nat.mul_le_mul rfl.le (by decide)

Robert hackman (Sep 10 2023 at 10:39):

Damiano Testa said:

Are you referring to your latest post? This seems to work and maybe it is useful.

example (n : ):  k in Finset.Ico 0 n.succ, (((k + 1 : ) - 1 )^2) < (((n + 1) ^ (3: ) : ) / 3 : ) := by
  induction n with
  | zero =>
    simp
  | succ n ih =>
    rw[Finset.sum_Ico_succ_top (Nat.zero_le ..)]
    rw[ Nat.succ_eq_add_one]
    have := _root_.add_lt_add_right ih (((Nat.succ n : ) + 1 - 1) ^ 2)
    apply this.trans_le
    field_simp
    apply div_le_div ?_ ?_ zero_lt_three rfl.le
    · positivity
    · ring_nf
      apply add_le_add_right
      apply add_le_add_right
      apply add_le_add
      · norm_num
      · norm_cast
        apply Nat.mul_le_mul rfl.le (by decide)

thank you, this is super interesting! Will take me some time to fully understand it

Robert hackman (Sep 12 2023 at 10:06):

oh this is so cool thanks again, that was exactly what I was looking for!

Robert hackman (Sep 17 2023 at 10:59):

(deleted)

Robert hackman (Sep 22 2023 at 10:27):

So I really wanted to have the n > 0part explicetly in the paramters instead of putting +1 all over the goal, that's what I came up with (works..)
But the one thing I don't understand about my code and @Damiano Testa example is the apply add_le_add_right/ add_le_add/ mul_le_mul part. Not because I don't understand the hypothesis but because after applying it, the common parts of the equation are just cut away, but the theorem or the tactitc doesn't state that in anyway, why is it transformed in that way then?

example (n : ) (h: n  1):  k in Finset.Ico 1 n, ((k - 1 : ) ^ 2) < ((n ^ (3: ) : ) / 3 : ) := by
  cases' h
  case refl =>
    simp
  case step n h =>
    induction n, h using le_induction with
    | base =>
      simp
      norm_num
    | succ n h ih =>
      rw[ succ_eq_add_one]
      have succ_zero_le_succ_one: 1  Nat.succ (n) := by
        apply succ_le_succ (Nat.zero_le n)
      rw[Finset.sum_Ico_succ_top (succ_zero_le_succ_one ..)]

      have := _root_.add_lt_add_right ih (((Nat.succ n : ) - 1) ^ 2)
      apply this.trans_le

      field_simp
      rw[div_le_div_iff (by norm_num) (by norm_num)]
      ring_nf
      apply add_le_add_right
      apply add_le_add_right
      apply _root_.add_le_add
      · norm_num
      · norm_cast
        apply mul_le_mul rfl.le (by decide)
        norm_num
        apply Nat.zero_le

Damiano Testa (Sep 22 2023 at 11:29):

I'm on mobile, so I what I is ever more subject to error than normal. The lemmas add_le_add/... prove an inequality of the form a+b ≤ c+d from inequalities of the form a ≤ c and b ≤ d. However, depending on the exact form of add_le_add that you use, say a=c in your case, some of the required inequalities are just true because they are equalities (really, someone proved this once and then you can use the more specialised result).

This is indicated but the right/left suffix that you see in the name of the lemma.

Damiano Testa (Sep 22 2023 at 11:30):

So, in such situations, if you use the more specialised lemma, some of the proof obligations are already done for you.

Robert hackman (Sep 23 2023 at 09:31):

Ok that explains why there are "missing"/ non explicit proofs, but I still don't understand why, when the hypothysis is applied, it also substitutes a. Every time add_le_add_right is applied, the goal is simpliefied through the removal of the equal parts on both sides. Is "apply" doing that?

Ruben Van de Velde (Sep 23 2023 at 09:40):

Is the question about the code you pasted yesterday? Which line exactly is confusing?

Robert hackman (Sep 23 2023 at 09:42):

yep the last example I posted (since there is no line numeration), this is the part I'm talking about(below ring_nf):

...
 apply add_le_add_right
      apply add_le_add_right
      apply _root_.add_le_add
      · norm_num
...

Ruben Van de Velde (Sep 23 2023 at 09:45):

So if you look at the definition of add_le_add_right:

#check add_le_add_right
-- add_le_add_right.{u_1} {α : Type u_1} [inst✝ : Add α] [inst✝¹ : LE α]
--   [i : CovariantClass α α (Function.swap fun x x_1 ↦ x + x_1) fun x x_1 ↦ x ≤ x_1] {b c : α}
--   (bc : b ≤ c) (a : α) :
--   b + a ≤ c + a

then you see it states that, under various assumptions that happen to be true for the natural numbers, if b ≤ c, then also b + a ≤ c + a. (In particular, this is because naturals are nonnegative.)

Ruben Van de Velde (Sep 23 2023 at 09:47):

What the apply tactic does is say: "I'm trying to prove an assertion P and I have a lemma that says that Q implies P. Thanks to that lemma, it's sufficient to prove Q, so change my current goal to Q"

Ruben Van de Velde (Sep 23 2023 at 09:47):

Does that clarify a bit?

Robert hackman (Sep 23 2023 at 09:52):

ok, I think I'm a bit at loss :D
But I'm correct in the assumption that the substraction of a(referring to a in add_le_add_right) is done through the apply tactic to get closer to the goal? :melting_face:

Kevin Buzzard (Sep 23 2023 at 11:05):

No subtraction ever occurs. Cancellation occurs, which is something different.

Kevin Buzzard (Sep 23 2023 at 11:06):

One way of proving cancellation is using subtraction, but that is not what is being used here, because subtraction on the naturals is poorly behaved.


Last updated: Dec 20 2023 at 11:08 UTC