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 PNats:
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