After some experimentation and search, I came up with the following definition:
emcd' :: Integer -> Integer -> (Integer,Integer,Integer)
emcd' a 0 = (a, 1, 0)
emcd' a b =
let (g, t, s) = emcd' b r
in (g, s, t - (q * s))
where
(q, r) = divMod a b
I'd evaluate emcd' 56 15
up to the innermost level, for example, as:
emcd' 56 15
= let (g, t, s) = emcd' 15 11 in (
let (g, t, s) = emcd' 11 4 in (
let (g, t, s) = emcd' 4 3 in (
let (g, t, s) = emcd' 3 1 in (
let (g, t, s) = emcd' 1 0 in (
(1, 1, 0)
) in (g, s, t - (3 * s))
) in (g, s, t - (1 * s))
) in (g, s, t - (2 * s))
) in (g, s, t - (1 * s))
) in (g, s, t - (3 * s))
- Is my evaluation going in the right direction ?
EDIT:
From Will Ness's comments, I am updating the evaluation.
The general direction is correct but it contains the recursive calls which had already been performed and thus mustn't be there. Instead, it's
In what follows I derive the following pseudocode (where
a where { ... }
stands forlet { ... } in a
):The two indeed are equivalent, but it's more readable with the
where
pseudocode, I think.Restructuring the definition a little bit, it becomes
We then write, in pseudocode with
where
instead oflet
, using the basic cut-and-paste substitutions,and now we've hit the base case:
Hopefully there's no cut-and-paste errors here. The general idea is just to make the straightforward substitutions in a purely mechanical manner.
side note:
(g,t,s)=foo a b
===g==gcd a b && g==t*a+s*b
.