Zulip Chat Archive

Stream: metaprogramming / tactics

Topic: Qq/positivity confusion


Moritz Doll (Feb 18 2024 at 03:23):

I've tried to write a positivity extension with Qq and I ran into a weird problem:

import Mathlib.Algebra.Order.Group.PosPart

namespace Mathlib.Meta.Positivity

open Qq Lean Meta LinearOrder

@[positivity PosPart.pos _]
def evalPosPart : PositivityExt where eval {u α}   e := do
  match e with
  | ~q(@PosPart.pos _ $inst1 $a) =>
    let instαLattice  synthInstanceQ q(Lattice $α)
    let instαAddGroup  synthInstanceQ q(AddGroup $α)
    assertInstancesCommute
    return .nonnegative q(@posPart_nonneg $α $instαLattice $instαAddGroup $a)
  | _ => throwError "not PosPart.pos"

example {α : Type*} [Lattice α] [AddGroup α] (a : α) : 0  a := by positivity

end Mathlib.Meta.Positivity

The return fails with error:

type mismatch
  posPart_nonneg «$a»
has type
  0  «$a»⁺ : Prop
but is expected to have type
  0  «$e» : Prop

even though the matching ensures that these two are equal. I don't know how to use the matching hypothesis to make Qq happy and I haven't seen a similar issue in any of the other positivity extensions

Yaël Dillies (Feb 18 2024 at 09:29):

You're using the wrong function?

Yaël Dillies (Feb 18 2024 at 09:29):

See #10256

Yaël Dillies (Feb 18 2024 at 09:30):

Anyway, I have those extensions written. I can PR them

Eric Wieser (Feb 18 2024 at 10:20):

set_option autoImplicit false makes the error clearer (you're missing the import of PositivityExt)

Eric Wieser (Feb 18 2024 at 10:26):

To decode Yael's comment, you should be using posPart not PosPart.pos

Eric Wieser (Feb 18 2024 at 10:26):

So this works:

@[positivity posPart _]
def evalPosPart : PositivityExt where eval {u α}   e := do
  match e with
  | ~q(@posPart _ $inst1 $inst2 $a) =>
    assertInstancesCommute
    return .nonnegative q(posPart_nonneg $a)
  | _ => throwError "not PosPart.pos"

Yaël Dillies (Feb 18 2024 at 10:27):

#10681

Yaël Dillies (Feb 18 2024 at 10:28):

There is a bug here: core q(inferInstance) q(inferInstance) a fails instead of returning none when no 0 ≤ a or 0 < a assumption is in context.

Moritz Doll (Feb 18 2024 at 12:19):

Thanks you. That was very silly of me.

Moritz Doll (Feb 18 2024 at 12:20):

Yael there are at least two instance where positivity should be able to replace explicit calls to posPart_nonneg and a third one where one needs a positivity-extension for integrals (I wrote a PR for that)

Yaël Dillies (Feb 18 2024 at 14:38):

You mean two occurrences in mathlib? I didn't know posPart was used at all yet.

Moritz Doll (Feb 18 2024 at 14:43):

yes, in MeasureTheory.Decomposition.Jordan and Probability.Martingale.Upcrossing

Moritz Doll (Feb 18 2024 at 14:46):

this is how I found posPart in the first place: I was search&replacing integral_nonneg and Upcrossing had these posPart_nonneg that we not used by positivity.


Last updated: May 02 2025 at 03:31 UTC