public class Euclid {

  /*@ axiom (\forall int i, j; (i >= 0 && j >= i && j != 0) ==> i % j == i);
      axiom (\forall int m, n, d; d > 0 && m >= 0 && n > 0 && m % d == 0 &&
             n % d == 0 ==> (m % n) % d == 0);
      axiom (\forall int m, n, d; d > 0 && m >= 0 && n > 0 && n % d == 0 &&
             (m % n) % d == 0 ==> m % d == 0);
   */

  /*@ requires m >= 0 && n >= 0;
      requires m > 0 || n > 0;
      ensures (\forall int d; (d > 0 && m % d == 0 && n % d == 0) ==>
               d <= \result);
      ensures m % \result == 0;
      ensures n % \result == 0;
      ensures \result > 0;
  */
  public static int gcd(int m, int n) {
    if (n == 0) return m;
    else return gcd(n, m % n);
  }
}
