Zulip Chat Archive

Stream: general

Topic: conditional mk_instance


Floris van Doorn (Jul 20 2020 at 19:36):

I'm trying to write a small metaprogram that finds an instance of tgt : expr, and being able to use an instance of cond : expr.

For example, I might want to find an "instance" of semigroup α → has_mul α.

Here is what I tried, but the printed expressions look very wrong.

  • Am I doing something wrong?
  • Is there a better way of doing this?
import algebra.group.defs tactic.core
open tactic
universe variable u

open tactic
/- finds an instance of an implication `cond → tgt`.
  Returns a pair of a local constant `e` of type `cond`, and an instance of `tgt` that can mention `e`. -/
meta def mk_conditional_instance (cond tgt : expr) : tactic (expr × expr) := do
f  mk_meta_var cond,
e  assertv `c cond f, swap,
reset_instance_cache,
inst  mk_instance tgt,
trace $ pformat!"({e} : {infer_type e})",
trace $ format!"raw local type of {e}: {e.local_type.to_raw_fmt}",
trace $ pformat!"({inst} : {infer_type inst})",
trace $ pformat!"({inst.bind_lambda e} : {infer_type $ inst.bind_lambda e})",
type_check inst,
return (e, inst)

set_option pp.implicit true
example {α : Type u} : unit :=
by do e  get_local `α,
  (f, inst)  mk_conditional_instance
    ((expr.const `semigroup [level.param `u]).app e)
    ((expr.const `has_mul [level.param `u]).app e),
  g  mk_mapp `has_mul.mul [e, inst],
  trace pformat!"({g} : {infer_type g})",
  trace pformat!"({g.bind_lambda f} : {infer_type $ g.bind_lambda f})"

Floris van Doorn (Jul 20 2020 at 19:41):

I get expressions that look like

(λ (c : 1), @semigroup.to_has_mul α c : 1  has_mul α)

Here 1 is const 1 [], which is the local_type of the local constant e.

Floris van Doorn (Jul 20 2020 at 19:42):

1 should be semigroup α, which is what I get if I run infer_type e (but not if I run infer_type `inst.bind_lambda e)

Jannis Limperg (Jul 20 2020 at 19:43):

local_type is useless precisely because of this issue. (The docs for expr mention this.) You need to use infer_type to get the type of a local const or mvar.

Floris van Doorn (Jul 20 2020 at 19:45):

But bind_lambda puts this useless field in my expression. What should I be using instead of bind_lambda?

Floris van Doorn (Jul 20 2020 at 19:49):

I don't know if my expression is incorrect, or that this is still an issue of "the pretty printer is showing the wrong thing". I suspect the former.

Rob Lewis (Jul 20 2020 at 20:03):

There's docs#tactic.lambdas which I believe is a tactic mode version of bind_lambda

Floris van Doorn (Jul 20 2020 at 20:07):

That looks a lot better. I will try that. Thanks!

Floris van Doorn (Jul 20 2020 at 20:14):

That indeed solved my problem.

Jannis Limperg (Jul 20 2020 at 21:29):

Ah that's what those variants are for! Thanks Rob, now I can kill my workaround for this issue.


Last updated: Dec 20 2023 at 11:08 UTC