Zulip Chat Archive

Stream: general

Topic: Proof of argument decrease for num.gcd


Seul Baek (Jun 07 2018 at 13:28):

I'm trying to define gcd for num. I've already defined num.mod and proved related lemmas (which you can check at https://github.com/skbaek/qelim/blob/master/src/common/num.lean), and here's my first attempt using those preliminary definitions :

def gcd : num → num → num
| 0       y := y
| (pos x) y :=
  have y % pos x < pos x, from mod_lt _ $ pos_pos _,
  gcd (y % pos x) (pos x)

I get an error message saying that Lean failed to prove recursive application is decreasing. Apparently Lean is not using the proof of argument decrease provided by have. I'm not sure why this happens, since the definition of nat.gcd is almost identical. Any ideas?

Gabriel Ebner (Jun 07 2018 at 13:36):

The error message shows what you need to prove: in this case, it's num.sizeof (y % pos x) < pos_num.sizeof x + 1 (didn't clone the repo).

Gabriel Ebner (Jun 07 2018 at 13:38):

The default termination measure for well-founded recursion in the equation compiler is lexicographic ordering of the sizeof values of the arguments. You should probably define has_sizeof for num in a sensible way (i.e. the nat value). Check out #eval sizeof (1000:num)

Gabriel Ebner (Jun 07 2018 at 13:40):

Note that #eval sizeof is broken for nested and mutual inductives. https://github.com/leanprover/lean/issues/1518

Seul Baek (Jun 07 2018 at 14:17):

That worked. Thank you!

Mario Carneiro (Jun 12 2018 at 16:12):

@Seul Baek The latest mathlib update includes div and gcd for num and znum. It is implemented in binary, rather than by repeated subtraction, so it should be exponentially faster than the transcribed nat definition, which is what it looks like you did. I think gcd should have something like O((log n)^2) performance in the kernel now

Seul Baek (Jun 14 2018 at 23:12):

@Mario Carneiro Thank you for the notice. This is very good news - I was only thinking about faster subtraction using binary representations.


Last updated: Dec 20 2023 at 11:08 UTC