Zulip Chat Archive

Stream: new members

Topic: nat inequalities


Scott Olson (Sep 25 2018 at 12:30):

What is the most efficient way to solve situations like this? I get a bit lost in all the details of lt, le, negations, and symmetries...

x : ,
is_lt : x < 2,
h_zero : ¬x = 0,
h_one : ¬x = 1
 false

Kevin Buzzard (Sep 25 2018 at 12:34):

I am really bad at questions like this still, and I've been playing with Lean for a year. People come up with all sorts of tricks using tactics like cc or finish or a clever application of dec_trivial or whatever, which I never seem to spot.

Reid Barton (Sep 25 2018 at 12:37):

Depending on how you obtained the hypotheses h_zero and h_one, it might have been more efficient to use cases on x earlier

Scott Olson (Sep 25 2018 at 12:43):

I'm interested in the nat inequalites problem in general, but this came up while trying to match exhaustively on a fin 2. (It's a contrived example, I suppose, but I also run into fin troubles fairly often.)

The trouble there is I'm not sure how to make the pattern compiler understand I don't need any cases beyond 0 and 1, and if I do fill in the catch-all case, I wouldn't automatically even have x != 0 and x != 1 with which to prove this.

Scott Olson (Sep 25 2018 at 12:49):

Ohhh, I think I finally understood the useful way to match on them. If I use a ⟨n+2, is_lt⟩ pattern, I get the is_lt : n + 2 < 2 contradiction.

Reid Barton (Sep 25 2018 at 12:50):

Yes exactly

Reid Barton (Sep 25 2018 at 12:50):

Now you need to prove that's false, probably something like (made up names) not_lt_of_ge (le_add_self _ _)

Reid Barton (Sep 25 2018 at 12:51):

and then combine that with absurd is_lt ...

Reid Barton (Sep 25 2018 at 12:54):

For your original question you could do cases on x, handle the first case with h_zero, then cases again and handle the first case with h_one, then you'd be at proving n + 2 < 2 -> false again. But those two cases steps are just repeating some case analysis that you've already done, it sounds like (that's why you have h_zero and h_one in the first place).

Scott Olson (Sep 25 2018 at 12:54):

Yep, that makes sense. At that point I would just be going the long way around to do the same thing.

Chris Hughes (Sep 25 2018 at 13:03):

example : ∀ x : ℕ, x < 2 → x ≠ 0 → x ≠ 1 → false := dec_trivial

Reid Barton (Sep 25 2018 at 13:05):

Aha! sneaky...

Reid Barton (Sep 25 2018 at 13:08):

So I guess revert x, exact dec_trivial should work for the original question. That's a good trick, changing the goal to something with a bounded quantifier

Scott Olson (Sep 25 2018 at 13:09):

Interesting, I was having trouble making that work in context, didn't realize I needed revert x

Scott Olson (Sep 25 2018 at 13:10):

Does that work because \all n < k, p n has a decidable instance or something tricky like that?

Scott Olson (Sep 25 2018 at 13:12):

Heh, yeah, I see instances like decidable (∀ (n_1 : ℕ) (h : n_1 < n), P n_1 h)

Reid Barton (Sep 25 2018 at 13:12):

Yes exactly

Scott Olson (Sep 25 2018 at 13:13):

Which is from mathlib, actually, so good thing I finally started using mathlib today...

Scott Olson (Sep 25 2018 at 13:34):

Thanks for all the help. For the record, this is the exercise I gave myself, and it looks pretty minimal now:

def fin2_equiv_bool : fin 2  bool := {
    to_fun := λ x, x = 1,

    inv_fun := λ b, cond b 1 0,

    left_inv := λ x,
        match x with
        | 0, _⟩ := rfl
        | 1, _⟩ := rfl
        | n+2, is_lt := absurd is_lt (not_lt_of_le (nat.le_add_left _ _))
        end,

    right_inv := λ b, by cases b; refl,
}

Scott Olson (Sep 25 2018 at 13:35):

Although now that we mentioned dec_trivial, it occurs to me I noticed \all x : fin n, p x is decidable...

Kenny Lau (Sep 25 2018 at 13:36):

import data.equiv.basic data.fin

def fin2_equiv_bool : fin 2  bool := {
    to_fun := λ x, x = 1,
    inv_fun := λ b, cond b 1 0,
    left_inv := by unfold function.left_inverse; exact dec_trivial,
    right_inv := by unfold function.right_inverse function.left_inverse; exact dec_trivial,
}

Scott Olson (Sep 25 2018 at 13:37):

Thanks! The unfold is the only step I was missing in my attempt

Kenny Lau (Sep 25 2018 at 13:40):

import data.equiv.basic data.fin

def fin2_equiv_bool : fin 2  bool :=
{ to_fun := λ x, x = 1,
  inv_fun := λ b, cond b 1 0,
  left_inv := show  x, _ = x, from dec_trivial,
  right_inv := show  b, _ = b, from dec_trivial }

Scott Olson (Sep 25 2018 at 13:46):

It seems like the last part of these is failing for me because there's no instance of decidable for \all b : bool, p b

Kenny Lau (Sep 25 2018 at 13:47):

did you follow the imports?

Scott Olson (Sep 25 2018 at 13:48):

data.equiv.basic doesn't exist for me, I just have data.equiv in mathlib

Scott Olson (Sep 25 2018 at 13:48):

I do have data.fin

Scott Olson (Sep 25 2018 at 13:49):

I'll double-check my mathlib dependency... I just added it with leanpkg add leanprover/mathlib earlier today

Scott Olson (Sep 25 2018 at 13:51):

I see, i think it gave me the branch named lean-3.4.1 instead of master

Simon Hudon (Sep 25 2018 at 18:52):

Does linarith work for your kind of inequality?


Last updated: Dec 20 2023 at 11:08 UTC