reserve A for preIfWhileAlgebra;
reserve A for Euclidean preIfWhileAlgebra;
reserve X for non empty countable set;
reserve T for Subset of Funcs(X, INT);
reserve f for Euclidean ExecutionFunction of A, Funcs(X, INT), T;
reserve A for Euclidean preIfWhileAlgebra,
  X for non empty countable set,
   z for (Element of X),
  s,s9 for (Element of Funcs(X, INT)),
  T for Subset of Funcs(X, INT),
  f for Euclidean ExecutionFunction of A, Funcs(X, INT), T,
  v for INT-Variable of A,f,
  t for INT-Expression of A,f;
reserve i for Integer;
reserve b for (Element of X),
  g for Euclidean ExecutionFunction of A, Funcs(X, INT), Funcs(X, INT)\(b,0);

theorem :: Euclid algorithm 2
  for x,y,z being Variable of g st ex d being Function st d.b = 0 & d.x
  = 1 & d.y = 2 & d.z = 3 for s being Element of Funcs(X, INT) for n,m being
Element of NAT st n = s.x & m = s.y & n > 0 holds g.(s, while(y gt 0, z:=(.x-.y
  )\; if-then(z lt 0, z*=-1)\; x:=y\; y:=z ) ).x = n gcd m
proof
  set h = g;
  set S = Funcs(X, INT);
  set T = S\(b,0);
A1: h complies_with_if_wrt T by AOFA_000:def 32;
  let x,y,z be Variable of h;
  given d being Function such that
A2: d.b = 0 and
A3: d.x = 1 and
A4: d.y = 2 and
A5: d.z = 3;
  set C = y gt 0;
  let s be Element of Funcs(X, INT);
A6: y <> z by A4,A5;
  reconsider s1 = h.(s, C) as Element of S;
A7: s1.x = s.x by A2,A3,Th38;
A8: s1.y = s.y by A2,A4,Th38;
A9: s.y <= 0 implies s1.b = 0 by Th38;
  defpred R[Element of S] means $1.x > 0 & $1.y > 0;
  let n,m be Element of NAT;
  defpred P[Element of S] means n gcd m divides $1.x & n gcd m divides $1.y &
$1.x > 0 & $1.y >= 0 & for c being Nat st c divides $1.x & c divides $1.y holds
  c divides n gcd m;
  set J = if-then(z lt 0, z*=-1);
  set I = z:=(.x-.y)\; J\; x:=y\; y:=z;
  assume that
A10: n = s.x and
A11: m = s.y and
A12: n > 0;
  s.y > 0 implies s1.b = 1 by Th38;
  then s1 in T iff R[s1] by A10,A12,A9,Th2,Th38;
  then
A13: h iteration_terminates_for I\;C, h.(s,C) by A2,A3,A4,A5,A10,A11,A12,A7,A8
,Lm2;
A14: z <> x by A3,A5;
A15: x <> y by A3,A4;
A16: now
    let s be Element of S;
    set s1 = h.(s, z:=(.x-.y));
    set s2 = h.(s1, z lt 0);
    set q = h.(s1, J);
    set qz = h.(s2, z*=-1);
A17: (s2.z)*(-1) = -(s2.z);
    set s3 = h.(q, x:=y);
    set s4 = h.(s3, y:=z);
A18: h.(s, I) = h.(h.(s, z:=(.x-.y)\; J\; x:=y), y:=z) by AOFA_000:def 29
      .= h.(h.(h.(s, z:=(.x-.y)\; J), x:=y), y:=z) by AOFA_000:def 29
      .= s4 by AOFA_000:def 29;
    s2.b = 1 implies s2 in T;
    then
A19: s2.b = 1 implies q = qz by A1;
A20: (.x).s = s.x by Th22;
A21: qz.y = s2.y by A6,Th31;
A22: (.y).s = s.y by Th22;
    (.x-.y).s = ((.x).s)-((.y).s) by Def11;
    then
A23: s1.z = (s.x)-(s.y) by A20,A22,Th26;
A24: s1.z < 0 implies s2.b = 1 by Th38;
A25: s2.z = s1.z by A2,A5,Th38;
A26: qz.z = (s2.z)*(-1) by Th31;
A27: s3.z = q.z by A14,Th27;
A28: s4.y = s3.z by Th27;
    s2.b = 0 implies s2 nin T by Th2;
    then
A29: s2.b = 0 implies q = s2 by A1,AOFA_000:80;
A30: s1.z >= 0 implies s2.b = 0 by Th38;
A31: s1.y = s.y by A6,Th26;
A32: s3.x = q.y by Th27;
    s2.y = s1.y by A2,A4,Th38;
    hence h.(s, I).x = s.y & h.(s, I).y = |.s.x-s.y.| by A15,A29,A19,A25,A24
,A30,A21,A26,A17,A18,A31,A23,A32,A27,A28,Th27,ABSVALUE:def 1;
  end;
A33: for s being Element of S st P[s] & s in T & R[s] holds P[h.(s,I)]
  proof
    let s be Element of S;
    reconsider s99 = h.(s, I) as Element of S;
A34: |.n gcd m.| = n gcd m by ABSVALUE:def 1;
A35: s99.y = |.s.x-s.y.| by A16;
    assume
A36: P[s];
    then reconsider n9 = s.x, m9 = s.y as Element of NAT by INT_1:3;
    assume that
    s in T and
A37: R[s];
    n gcd m divides n9-m9 by A36,PREPOWER:94;
    hence
    n gcd m divides h.(s,I).x & n gcd m divides h.(s,I).y & h.(s,I).x > 0
    & h.(s,I).y >= 0 by A16,A36,A37,A35,A34,INT_2:16;
    let c be Nat;
    reconsider c9 = c as Element of NAT by ORDINAL1:def 12;
    assume that
A38: c divides h.(s,I).x and
A39: c divides h.(s,I).y;
A40: |.c.| = c by ABSVALUE:def 1;
A41: s99.x = s.y by A16;
    c9 divides |.n9-m9.| by A16,A39;
    then
A42: c divides n9-m9 by A40,INT_2:16;
    c qua Integer divides m9 by A16,A38;
    then c divides (n9-m9)+m9 by A42,WSIERP_1:4;
    hence thesis by A36,A41,A38;
  end;
A43: for s being Element of S st P[s] holds P[h.(s,C) qua Element of S] & (h
  .(s,C) in T iff R[h.(s,C) qua Element of S])
  proof
    let s be Element of S;
    assume
A44: P[s];
    reconsider s9 = h.(s,C) as Element of S;
A45: s9.y = s.y by A2,A4,Th38;
    s9.x = s.x by A2,A3,Th38;
    hence P[h.(s,C) qua Element of S] by A44,A45;
A46: s.y <= 0 implies s9.b = 0 by Th38;
    s.y > 0 implies s9.b = 1 by Th38;
    hence thesis by A44,A46,Th2,Th38;
  end;
  reconsider fin = h.(s, while(C,I)) as Element of S;
A47: P[s] by A10,A11,A12,NAT_D:def 5;
A48: P[h.(s,while(C,I)) qua Element of S] & not R[h.(s,while(C,I)) qua
  Element of S] from AOFA_000:sch 5(A47,A13,A33,A43);
  then reconsider fn = fin.x as Element of NAT by INT_1:3;
A49: fn divides 0 by NAT_D:6;
  fin.y = 0 by A48;
  then fn divides n gcd m by A48,A49;
  hence thesis by A48,NAT_D:5;
end;
