Zulip Chat Archive

Stream: general

Topic: fin_random instance


Fabian Glöckle (May 12 2022 at 15:57):

The following code runs successfully, but fails if 1000 is replaced by 10000:

import system.random.basic

meta def rnd_comp (g : Type) [random_gen g] : list (fin 1000)  nat  rand_g g (list (fin 1000))
| l 0 := return l
| l (n+1) := have h : 0 < 1000 := by obviously, do x  rand.random (fin 1000), (rnd_comp (x::l) n)

meta def trace_rnd : tactic (list nat) :=
do
  g  tactic.mk_generator,
  res  tactic.run_rand $ rnd_comp std_gen [] 30,
  return (list.map (λ (x : fin 1000), x) res)

#eval trace_rnd >>= tactic.trace

In the latter case, the random (fin 10000) instance from docs#fin_random is no longer found, despite h : 0 < 10000 being available in the context.
As I do not know how type class resolution works, I thought I'll better report this. (I can, however, easily work around it.)

Reid Barton (May 12 2022 at 16:18):

What you need is fact (0 < 10000) in the type class context. I'm not sure how to cajole the equation compiler into doing it right.

Reid Barton (May 12 2022 at 16:19):

There is a global instance docs#succ_pos'' that in principle should provide fact (0 < 10000) but I guess the elaborator gives up before doing enough unfolding to see this

Fabian Glöckle (May 12 2022 at 16:24):

I don't know how to get the fact, but the hypothesis is there:

failed to synthesize type class instance for
g : Type,
_inst_1 : random_gen g,
rnd_comp : list (fin 10000)    rand_g g (list (fin 10000)),
l : list (fin 10000),
n : ,
h : 0 < 10000
 random (fin 10000)

Fabian Glöckle (May 12 2022 at 16:25):

Oh, I see.
So the fact comes from docs#succ_pos'', not from the local context

Mario Carneiro (May 12 2022 at 16:25):

you can also use nat.succ 9999 instead of 10000

Fabian Glöckle (May 12 2022 at 16:27):

Mario Carneiro said:

you can also use nat.succ 9999 instead of 10000

yes, that works :D

Fabian Glöckle (May 12 2022 at 16:27):

thank you both!

Mario Carneiro (May 12 2022 at 16:29):

meta def rnd_comp (g : Type) [random_gen g] : list (fin 10000)  nat  rand_g g (list (fin 10000))
| l 0 := return l
| l (n+1) := do
  x  by haveI := fact.mk (by norm_num : 0 < 10000); exact rand.random (fin 10000),
  rnd_comp (x::l) n

Fabian Glöckle (May 12 2022 at 16:31):

very elegant :+1: thanks!


Last updated: Dec 20 2023 at 11:08 UTC