Zulip Chat Archive

Stream: lean4

Topic: Feeding instances to QQ


Patrick Massot (May 03 2023 at 20:21):

How do you make QQ aware of an instance you just synthesized? The MWE below depends on mathlib but I hope it's enough to make the question clear:

import Mathlib.Tactic.NormNum.Core

open Qq Lean Meta Mathlib Meta NormNum

example (e : Expr) : MetaM Unit :=
do let α : Q(Type)  inferType e
   let   synthInstance q(LinearOrderedField $α)
   have al := ( mkOfNat α  <| mkRawNatLit 0).1
   have ar := ( mkOfNat α  <| mkRawNatLit 1).1
   let al_pos : Q(Prop) := q($al < $ar)
   pure ()

This fails at q($al < $ar) with message failed to synthesize instance LT «$α», q isn't seeing the linear ordered field instance.

Patrick Massot (May 03 2023 at 20:26):

Note it may be that I'm completely misunderstanding how QQ should be used.

Tomas Skrivan (May 03 2023 at 20:27):

What about adding have inst := $sa to the term where you want the instance to be available?

Adam Topaz (May 03 2023 at 20:29):

Yeah, you could do something like this:

example (e : Expr) : MetaM Unit :=
do let α : Q(Type)  inferType e
   let  : Q(LinearOrderedField $α) :=  synthInstance q(LinearOrderedField $α)
   have al := ( mkOfNat α  <| mkRawNatLit 0).1
   have ar := ( mkOfNat α  <| mkRawNatLit 1).1
   let al_pos : Q(Prop) := q(letI : LinearOrderedField $α := $ ; $al < $ar)
   pure ()

But I hope there's a better way without a let

Adam Topaz (May 03 2023 at 20:29):

Oh actually it just works:

example (e : Expr) : MetaM Unit :=
do let α : Q(Type)  inferType e
   let  : Q(LinearOrderedField $α) :=  synthInstance q(LinearOrderedField $α)
   have al := ( mkOfNat α  <| mkRawNatLit 0).1
   have ar := ( mkOfNat α  <| mkRawNatLit 1).1
   let al_pos : Q(Prop) := q($al < $ar)
   pure ()

Adam Topaz (May 03 2023 at 20:30):

And I guess you could clean it up even more:

example (e : Expr) : MetaM Unit :=
do let α : Q(Type)  inferType e
   let  : Q(LinearOrderedField $α) :=  synthInstance q(LinearOrderedField $α)
   have al : Q($α) := q(0)
   have ar : Q($α) := q(1)
   let al_pos : Q(Prop) := q($al < $ar)
   pure ()

Patrick Massot (May 03 2023 at 20:31):

Oh I see, I simply needed to tell Lean that is also in the QQ world with a type ascription.

Patrick Massot (May 03 2023 at 20:33):

Thanks Tomas and Adam!

Eric Wieser (May 03 2023 at 22:03):

I think if you use docs4#Qq.synthInstanceQ then you can skip adding some of the ascriptions here

Eric Wieser (May 03 2023 at 22:03):

Oh, I guess Qq doesn't get shown in doc-gen

Henrik Böving (May 03 2023 at 22:04):

Indeed, although that could be done

Alex Keizer (May 03 2023 at 22:11):

I'm not so sure that synthInstanceQ removes the need for type ascription. In my experience, Qq refuses to reflect let-bindings without type ascription, even if the type is completely unambiguous

Eric Wieser (May 03 2023 at 22:20):

I just tested, replacing synthInstance in the original mwe with synthInstanceQ solves the problem

Moritz Doll (May 25 2023 at 20:06):

Henrik Böving said:

Indeed, although that could be done

I would be happy if this was the case.


Last updated: Dec 20 2023 at 11:08 UTC