prioritize_num();;

let EGCD_INVARIANT = thm `;
  !m n d. d divides egcd(m,n) <=> d divides m /\ d divides n
  proof
    let m n be num;
    (!m'' n'.
         m'' + n' < m + n
         ==> (!d. d divides egcd (m'',n') <=>
             d divides m'' /\ d divides n'))
    ==> (!d. d divides egcd (m,n) <=> d divides m /\ d divides n) [1]
    proof
      assume !m'' n'.
                 m'' + n' < m + n
                 ==> (!d. d divides egcd (m'',n') <=>
                      d divides m'' /\ d divides n') [2];
      !d. d divides
          (if m = 0
           then n
           else 
          if n = 0
          then m
          else if m <= n then egcd (m,n - m) else egcd (m - n,n)) <=>
          d divides m /\ d divides n [3]
      proof
        let d be num;
        m = 0 ==> (d divides n <=> d divides m /\ d divides n) [4]
          by DIVIDES_0;
        ~(m = 0)
        ==> (d divides
             (if n = 0
              then m
              else 
             if m <= n then egcd (m,n - m) else egcd (m - n,n)) <=>
             d divides m /\ d divides n) [5]
        proof
          assume ~(m = 0) [6];
          n = 0 ==> (d divides m <=> d divides m /\ d divides n) [7]
            by DIVIDES_0;
          ~(n = 0)
          ==> (d divides
               (if m <= n then egcd (m,n - m) else egcd (m - n,n)) <=>
               d divides m /\ d divides n) [8]
          proof
            assume ~(n = 0) [9];
            m <= n
            ==> (d divides egcd (m,n - m) <=>
                 d divides m /\ d divides n) [10]
            proof
              assume m <= n;
              m + (n - m) < m + n by ARITH_TAC,6;
            qed by #;
            ~(m <= n)
            ==> (d divides egcd (m - n,n) <=>
                 d divides m /\ d divides n) [11]
            proof
              assume ~(m <= n);
              (m - n) + n < m + n by ARITH_TAC,9;
              d divides egcd (m - n,n) <=> d divides m - n /\ d divides n
                by 2;
              ... <=> d divides (m - n) + n /\ d divides n by DIVIDES_ADD;
::                                                                       #1
:: 1: inference error
            qed by 2,DIVIDES_SUB;
::                              #1
          qed by COND_CASES_TAC from 10,11;
        qed by COND_CASES_TAC from 7,8;
      qed by COND_CASES_TAC from 4,5;
    qed by ONCE_REWRITE_TAC[egcd] from 3;
  qed by WF_INDUCT_TAC (parse_term "m + n") from 1;
::                                                #1
`;;
