How can I write an operation gcd(x : Integer, y : Integer) : Integer
which returns the greatest common divisor of two positive integers (the largest integer which divides both of them exactly) in ocl
?
Asked
Active
Viewed 84 times
0

any
- 325
- 5
- 17
1 Answers
0
Here is a simple solution for this (certainly not effective, but it works):
let divs : Sequence(Integer) = if x < y then Sequence{1..y} else Sequence{1..x} endif
in divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()
What is simply done is that a sequence of each potentials candidates is generated, then, from this sequence, only the ones that divide x
and y
are selected and stored in a new sequence (which is ordered). Finally, the last number from this filtered sequence is your greatest common divisor.
Now in details:
- we produce a sequence with
Sequence{a..b}
- this sequence is goes from
1
to the higher number betweenx
andy
(if x < y then Sequence{1..y} else Sequence{1..x}
) - this sequence is stored in a immutable variable
divs
(let divs : Sequence(Integer) = ... in ...
) - from
divs
, we select only the numberz
which is a divisor forx
andz
(divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)
- finally, we only take the last element from the new sequence (
select(...)->last()
)
If the last()
function does not exist in your env (don't know why, but some OCL implementations bring their own functions), you can use:
->sortedBy(i | -i)->at(1)
instead of last()
, which reverse the sequence and take the first element.
EDIT>
You can also reduce the expression this way:
let divs : Sequence(Integer) = Sequence{1..x.max(y)}
in divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()
or, by removing the use of divs
Sequence{1..x.max(y)}->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()

Vincent Aranega
- 1,441
- 10
- 21
-
Is it support in standard OCL? what is the set to result or return? – any Jun 17 '16 at 08:59
-
I checked, `last()` is standard OCL (specification, p.170). It was the only point I was not sure about. Everything else is obviously standard. This expression does not work for you? – Vincent Aranega Jun 17 '16 at 09:02
-
Bytheway, you can reduce the expression (see my edit), and everything is still standard OCL. – Vincent Aranega Jun 17 '16 at 09:06