Zulip Chat Archive

Stream: metaprogramming / tactics

Topic: A simple result that `omega` fails to prove


Geoffrey Irving (Dec 25 2023 at 10:42):

import Mathlib.Data.Nat.Order.Basic

-- A true lemma
lemma right {t i : } (t0 : t  0) (h : i < 64) : i + t - 64 < t := by
  simp only [add_comm _ t, tsub_tsub_eq_add_tsub_of_le h.le, imp_false, not_le]
  apply Nat.sub_lt (Nat.pos_of_ne_zero t0) (Nat.sub_pos_of_lt h)

-- `omega` fails to prove it
lemma wrong {t i : } (t0 : t  0) (h : i < 64) : i + t - 64 < t := by omega

Result:

omega did not find a contradiction:
[1, 0, 0]  (-∞, 63]
[1]  [0, 63]

This happened to be the first thing I tried omega on. :)

Geoffrey Irving (Dec 25 2023 at 10:47):

Is omega missing that 0 < t?

Geoffrey Irving (Dec 25 2023 at 10:51):

Ah, possibly it thinks it can cancel the ts from both sides, which doesn't work since the subtraction saturates at 0.

Geoffrey Irving (Dec 25 2023 at 11:41):

I should say, I've since tried on a lot of other cases, and it's extremely useful! :heart:

Kevin Buzzard (Dec 25 2023 at 11:52):

What happens if you explicitly add 0 < t to the local context?

Geoffrey Irving (Dec 25 2023 at 11:53):

^ Then it works.

Kevin Buzzard (Dec 25 2023 at 11:54):

Maybe open an issue then? I think Scott is on holiday for a while.

Geoffrey Irving (Dec 25 2023 at 11:58):

https://github.com/leanprover/std4/issues/482

Mirek Olšák (Jan 03 2024 at 11:24):

Ideally, one would expect a tactic that can deal with non-equalities / proving equality. So for example it could prove

example (a : ) : 3*a > 4  3*a  11  a  2  a = 3

only that it goes beyond simple linear programming, rather something on top of that to case split a ≠ 2 as a < 2 ∨ a > 2 which goes towards SMT-solving (extension of SAT solving). It should be doable but it is not trivial.

Damiano Testa (Jan 03 2024 at 11:41):

This is not related to the issue just mentioned, but it seems that omega may not be ignoring mdata correctly:

import Mathlib.Tactic

example : 0 = 0 := by
  have : 0 = 0 := by omega -- works
  omega -- fails

Eric Rodriguez (Jan 03 2024 at 11:45):

is there any way to clear all mdata in the context? I've had many, many omega failures and maybe this is the root issue

Damiano Testa (Jan 03 2024 at 11:45):

It should be easy to write a clear_mdata tactic, but I think that it would be somewhat a hack, since mdata stores information that is actually useful for something.

Eric Rodriguez (Jan 03 2024 at 11:46):

it'd be useful for debugging at least!

Mario Carneiro (Jan 03 2024 at 11:58):

Eric Rodriguez said:

is there any way to clear all mdata in the context? I've had many, many omega failures and maybe this is the root issue

Please report these as issues so we can track and fix them

Eric Rodriguez (Jan 03 2024 at 12:00):

https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/.60omega.60.20did.20not.20find.20a.20contradiction/near/410345497

my whinging is here, will open the Std issues in a sec

Mirek Olšák (Jan 03 2024 at 12:03):

Oh, I realized that omega can deal with (a < 2 or a > 2), so the only trick is to replace non-equality with disjunction of two strict inequalities, I guess

Mario Carneiro (Jan 03 2024 at 12:06):

Since Scott wrote most of the code, it would be best to whinge while he's not on holiday :)

Eric Rodriguez (Jan 03 2024 at 12:07):

std4#499, std4#500 - some nice presents for when they're back :)

Mirek Olšák (Jan 03 2024 at 12:15):

Ok, I will wait with my question about a counterexample too. Now, to my understanding, the issues here are more about user experience that any algorithmic difficulty. For example, the power question is about general coefficient evaluation.

Eric Rodriguez (Jan 03 2024 at 12:20):

I do think there's other stuff going on:

import Std.Tactic.Omega

example (x : Nat) (h : x ^ 2 = 4) : x = 2 := by
  change 1 * x * x = 4 at h -- this line doesn't matter
  omega

Mirek Olšák (Jan 03 2024 at 12:24):

But what does this has anything to do with linear inequalities? It feels a bit like complaining that omega doesn't know that (sin x)^2 is the same as 1-(cos x)^2

Mirek Olšák (Jan 03 2024 at 12:27):

If we had a tactic that could deal with non-linear (in)equalities, like SMT-NIA, then understanding constant powers should be expected. On the other hand, non-linear problems are algorithmically much harder.

Eric Rodriguez (Jan 03 2024 at 12:33):

ah, my apologies! I thought that omega was a full decision procedure, not a linear one

Eric Rodriguez (Jan 03 2024 at 12:34):

(now that I think about it, a non-linear decision procedure is provably impossible...)

Yaël Dillies (Jan 03 2024 at 12:34):

I thought omega was supposed to be complete?

Mirek Olšák (Jan 03 2024 at 12:35):

It is complete within the realm of linear inequalities over integers (which is an NP-complete problem afaik)

Mirek Olšák (Jan 03 2024 at 12:36):

non-linear problems (Diophantine equations) are generally undecidable

Alex J. Best (Jan 03 2024 at 12:37):

Omega is a decision procedure for Presburger arithmetic, which means in a complete implementation it can decide any first order sentence using addition on the naturals, this means that you can't deal with things like n^2 only things like 4*n + 5*m for fixed constants (as these can be expressed via a longer formula using only addition), hence the linear part.

Mario Carneiro (Jan 03 2024 at 12:37):

over real closed fields it is decidable again, but with double-exponential performance

Yaël Dillies (Jan 03 2024 at 12:38):

Uh, I thought Presburger arithmetic included multiplication. But of course that's bogus.

Mario Carneiro (Jan 03 2024 at 12:38):

I've long wanted to get an implementation of CAD in lean, but last I checked it was waiting on a bunch of results on permanents needed for a computable algebraic numbers implementation

Eric Rodriguez (Jan 03 2024 at 12:39):

and C\mathbb{C} is undecidable again because we get e2πite^{2\pi it} which can let us emulate integers

Mario Carneiro (Jan 03 2024 at 12:39):

Do we have algebraic numbers in mathlib yet? Surely we do

Eric Rodriguez (Jan 03 2024 at 12:40):

docs#IsAlgebraic

Mario Carneiro (Jan 03 2024 at 12:41):

I see that but it's a proposition

Kevin Buzzard (Jan 03 2024 at 12:41):

Yaël Dillies said:

Uh, I thought Presburger arithmetic included multiplication. But of course that's bogus.

Multiplication by constants but not by variables.

Mirek Olšák (Jan 03 2024 at 12:41):

Eric Rodriguez said:

and C\mathbb{C} is undecidable again because we get e2πite^{2\pi it} which can let us emulate integers

Algebraically closed fields are decidable too, I believe the complexity should be the same as with real (sure not harder)

Eric Rodriguez (Jan 03 2024 at 12:41):

docs#Algebraic.cardinal_mk_of_infinite uses the subtype so I don't think there's anything else

Mario Carneiro (Jan 03 2024 at 12:41):

is there a type of algebraic numbers over Q\mathbb{Q} or as elements of C\mathbb{C}

Yaël Dillies (Jan 03 2024 at 12:43):

Eric Rodriguez said:

and C is undecidable again because we get e2πite^{2π it} which can let us emulate integers

But only integers with addition, right? You don't get multiplication because that would correspond to exponentiation.

Mario Carneiro (Jan 03 2024 at 12:43):

AlgebraicCard.lean's module doc references Liouville.is_transcendental but I don't think docs#Liouville.is_transcendental exists

Yaël Dillies (Jan 03 2024 at 12:44):

docs#Liouville.transcendental it seems

Mario Carneiro (Jan 03 2024 at 12:45):

and I see it uses Transcendental ℤ (x : ℝ) in the statement, which is ¬IsAlgebraic ℤ (x : ℝ), so I guess that's all there is

Mario Carneiro (Jan 03 2024 at 12:45):

Do we know the algebraic numbers are closed under addition and such?

Mario Carneiro (Jan 03 2024 at 12:46):

there are some basic results in the Algebraic file but not addition or ringness

Yaël Dillies (Jan 03 2024 at 12:46):

docs#IsAlgebraic.add is not there, it seems

Mario Carneiro (Jan 03 2024 at 12:48):

Eric Rodriguez said:

and C\mathbb{C} is undecidable again because we get e2πite^{2\pi it} which can let us emulate integers

This by the way is the proof that although you can decide polynomial equations and inequalities using R\mathbb{R} and C\mathbb{C}, once you add exponentials or trig functions it becomes undecidable.

Damiano Testa (Jan 03 2024 at 12:53):

Eric Rodriguez said:

it'd be useful for debugging at least!

Here is a very simple-minded implementation of clear_mdata:

import Mathlib.Lean.Meta
import Std.Tactic.Omega

open Lean.Elab.Tactic in
/-- removes the first layer of `mdata` from the main goal. -/
elab (name := tacClearMData) "clear_mdata" : tactic => do
  let goal  getMainGoal
  replaceMainGoal [ goal.change ( goal.getType'')]

example : 0 = 0 := by
  have : 0 = 0 := by omega -- works
  --omega  -- fails
  clear_mdata
  omega -- works

Geoffrey Irving (Jan 04 2024 at 21:33):

Is this the mdata thing again, or something else?

import Std.Tactic.Omega
import Mathlib.Data.Nat.Basic

theorem good {n : } (h : n  62) : 64 - (62 - n) = n + 2 := by
  omega

lemma bad {X : Type} {x : X} {f : X  } : 64 - (62 - f x) = f x + 2 := by
  replace h : f x  62 := sorry
  -- Works
  --   `exact good h`
  -- Fails with
  --   `omega did not find a contradiction:`
  --   `[1] ∈ [0, 62]`
  omega

Damiano Testa (Jan 04 2024 at 21:36):

Likely: using clear_mdata before the failing omega, makes the omega call work.

Geoffrey Irving (Jan 04 2024 at 21:44):

Is there a bug already filed about the mdata issue? I don't see one: https://github.com/leanprover/std4/issues?q=is%3Aissue+omega+mdata

Damiano Testa (Jan 04 2024 at 21:49):

I didn't file any bug. If someone did, it might be @Eric Rodriguez , but I do not know if he got around to it.

Geoffrey Irving (Jan 04 2024 at 21:52):

mdata bug: https://github.com/leanprover/std4/issues/509

Eric Rodriguez (Jan 04 2024 at 21:54):

I didn't file one for mdata, just for powers and for constants on the right

Damiano Testa (Jan 04 2024 at 21:58):

Btw, the mdata issue is very simple: if, inside a proof, you use a have or let, this changes the goal to a DefEq expression that begins with a "metadata" field. If a tactic like omega does some matching on the goal and does not "see through" mdata, it will fail to identify what the target really is.

Damiano Testa (Jan 04 2024 at 22:00):

The solution is typically to add a ← whnf or a consumeMData or something similar. I just do not have the time to figure out where it should go...

Kim Morrison (Jan 05 2024 at 02:09):

Fixed in std4#510.

Geoffrey Irving (Jan 05 2024 at 07:37):

Thank you!


Last updated: May 02 2025 at 03:31 UTC