Zulip Chat Archive

Stream: mathlib4

Topic: writing a positivity extension


Jireh Loreaux (Nov 10 2023 at 21:09):

I'm trying to write a positivity extension for docs#StarOrderedRing to make use of things like docs#mul_star_self_nonneg and docs#conjugate_nonneg. By cargo cult coding from the basic positivity extensions, I can make the former work fairly easily. However, when I try to generalize to make it handle multiple forms simultaneously by matching on the expression, I get errors. What am I doing wrong here in the second attempt?

import Mathlib

namespace Mathlib.Meta.Positivity
open Lean Meta Expr Qq

/-- The `positivity` extension which identifies expressions of the form `star a * a`. -/
@[positivity _ * _, Mul.mul _ _] def evalStarMul : PositivityExt where eval {u α}   e := do
  let _a  synthInstanceQ q(NonUnitalSemiring $α)
  let _a'  synthInstanceQ q(StarOrderedRing $α)
  assumeInstancesCommute
  let .app (.app (f : Q($α  $α  $α)) (.app (s : Q($α  $α)) (a : Q($α)))) (b : Q($α))  withReducible (whnf e)
    | throwError "not *"
  let _e_eq : $e =Q $f ($s $a) $b := ⟨⟩
  let _f_eq  withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u.succ) f q(HMul.hMul)
  let _s_eq  withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u.succ) s q(Star.star)
  let _a_eq_b  withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u) a b
  pure (.nonnegative q(star_mul_self_nonneg $a))

example (a : ) : 0  star a * a := by
  positivity -- works! yay!

@[positivity _ * _, Mul.mul _ _] def evalStarMul' : PositivityExt where eval {u α}   e := do
  let e : Q($α)  whnfR e
  let _inst₁  synthInstanceQ q(NonUnitalSemiring $α)
  let _inst₂  synthInstanceQ q(StarOrderedRing $α)
  assumeInstancesCommute
  match e with
  | ~q((star $a) * $b) =>
    let _a_eq_b  withDefault <| withNewMCtxDepth <| assertDefEqQ (u := u) a b
    let _e_eq : $e =Q (star $a) * $a := ⟨⟩
    pure (.nonnegative q(star_mul_self_nonneg $a))
    /-
    type mismatch
      star_mul_self_nonneg «$a»
    has type
      0 ≤ star «$a» * «$a» : Prop
    but is expected to have type
      0 ≤ $e✝ : Prop
    -/

Jireh Loreaux (Nov 10 2023 at 21:13):

Separate but connected question: is it possible to make positivity attributes scoped? when I tried to do that I got "invalid attribute positivity, must be global"

Yaël Dillies (Nov 10 2023 at 21:16):

It was the case in Lean 3. Not anymore :sad:

Jireh Loreaux (Nov 10 2023 at 21:29):

nevermind, this is just because I called it e again in the first let so the original was inaccessible. Ignore the noise.

Jireh Loreaux (Nov 10 2023 at 21:40):

Why can't it be scoped anymore?

Yaël Dillies (Nov 10 2023 at 21:41):

No clue. Probably it simply hasn't been implemented?

Mario Carneiro (Nov 10 2023 at 21:41):

scoped extensions have to be implemented individually, it's just a matter of implementation work

Mario Carneiro (Nov 10 2023 at 21:41):

it's also a bit slower/more complicated than global-only attributes

Scott Morrison (Nov 11 2023 at 00:21):

See Std.Tactic.LabelAttr for a minimal example of how to set up removable attributes.

(These label attributes are for cases where we're not doing any work when adding the attribute: we just need to know if it is there or not.)

Someone needs to add this functionality to the positivity attribute.

Frédéric Dupuis (Nov 11 2023 at 01:05):

(deleted)


Last updated: Dec 20 2023 at 11:08 UTC