Zulip Chat Archive
Stream: mathlib4
Topic: Omega with PNat
Vasilii Nesterov (Feb 01 2025 at 11:02):
Hi! I've written a simple wrapper around omega
that can solve goals involving PNat
s:
import Mathlib.Data.PNat.Basic
lemma PNat.sub_coe' (a b : PNat) : ((a - b : PNat) : Nat) = a.val - 1 - b.val + 1 := by
cases a
cases b
simp only [PNat.mk_coe, PNat.sub_coe, ← PNat.coe_lt_coe]
split_ifs <;> omega
open Qq in
elab "omega_preprocess_pnat" : tactic =>
Lean.Elab.Tactic.withMainContext do
let goal ← Lean.Elab.Tactic.getMainGoal
let ctx ← Lean.MonadLCtx.getLCtx
let result : Lean.MVarId ← ctx.foldlM (init := goal) fun g decl => do
let declExpr := decl.toExpr
let declType ← Lean.Meta.inferType declExpr
let isPNat ← Lean.Meta.isExprDefEq declType q(PNat)
if isPNat then
let p : Lean.Expr := Lean.Expr.app q(PNat.pos) declExpr
let mvarIdNew ← g.define .anonymous (← Lean.Meta.inferType p) p
let (_, mvarIdNew) ← mvarIdNew.intro1P
return mvarIdNew
else
return g
Lean.Elab.Tactic.setGoals [result]
syntax "omega_pnat" : tactic
macro_rules
| `(tactic| omega_pnat) => `(tactic|
omega_preprocess_pnat;
simp only [← PNat.coe_inj, ← PNat.coe_le_coe, ← PNat.coe_lt_coe, PNat.sub_coe', PNat.add_coe, PNat.mul_coe, PNat.val_ofNat] at *;
omega
)
example (a b : PNat) (h : a < b) : 1 < b := by
omega_pnat
Would it be worth PRing it in some form?
Vasilii Nesterov (Feb 01 2025 at 11:03):
It just translates PNat
arithmetic (+
, -
, *
) into Nat
.
Kevin Buzzard (Feb 01 2025 at 11:05):
Definitely! I don't see any harm in a tactic with a niche but genuine use case.
Is another perhaps more useful approch to write a nify
tactic, which takes goals or hypotheses involving pnats and changes them into equivalent goals involving nats? We have zify
, qify
etc, so that would fit into the general mathlib pattern. And then maybe nify; omega
would be the way to solve many pnat goals.
Kim Morrison (Feb 03 2025 at 00:30):
Yes, both routes are great.
Junyan Xu (Feb 03 2025 at 01:11):
Maybe something similar can be done for docs#ENat, WithBot Nat
(docs#Polynomial.degree), WithBot ENat
(docs#Order.krullDim) ...
Vasilii Nesterov (Feb 03 2025 at 09:19):
Yes, I am working on this.
Vasilii Nesterov (Feb 09 2025 at 20:21):
The PR for ENat
and PNat
is ready: #21602
Kim Morrison (Feb 10 2025 at 00:55):
@Vasily Nesterov, would it be possible to refactor this to provide a enat_to_nat
tactic (cases, simplify inequalities, translate), and then enat_omega
is just enat_to_nat; omega
? I think there would also be independent uses for enat_to_nat
.
Kim Morrison (Feb 10 2025 at 00:55):
(Similarly for pnat
.)
Vasilii Nesterov (Feb 10 2025 at 17:23):
How about pnat_to_nat x y z
syntax for a tactic that translates variables x
, y
, z
from the context from PNat
to Nat
and pushes the translation as far as possible?
Vasilii Nesterov (Feb 10 2025 at 17:35):
And similar tactic for ENat
(in which case multiple goals might be created).
Kevin Buzzard (Feb 10 2025 at 18:28):
zify
, qify
and rify
don't use this approach and people don't seem to be complaining that they want this fine-grained control.
Kim Morrison (Feb 10 2025 at 23:36):
I'd be content with one that just aggressively translates all relevant hypotheses. I think an optional at x y z
syntax can't hurt if you want to implement it.
Last updated: May 02 2025 at 03:31 UTC