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
  for x,y,m being Variable of g st ex d being Function st d.b = 0 & d.x
= 1 & d.y = 2 & d.m = 3 holds y:=1\; while(m gt 0, if-then(m is_odd, y*=x)\; m
  /=2\; x*=x ) is_terminating_wrt g, {s: s.m >= 0}
proof
  set S = Funcs(X, INT);
  set T = S\(b,0);
  let x,y,m be Variable of g;
  set P = {s: s.m >= 0};
  given d being Function such that
A1: d.b = 0 and
A2: d.x = 1 and
A3: d.y = 2 and
A4: d.m = 3;
  set C = m gt 0;
A5: y:=1 is_terminating_wrt g, P by AOFA_000:107;
  deffunc F(Element of S) = In($1.m, NAT);
  defpred R[Element of S] means $1.m > 0;
  set I = if-then(m is_odd, y*=x);
  set J = I\; m/=2\; x*=x;
A6: g complies_with_if_wrt T by AOFA_000:def 32;
A7: P is_invariant_wrt C,g
  proof
    let s;
    assume s in P;
    then
A8: ex s9 st s = s9 & s9.m >= 0;
    g.(s, C).m = s.m by A1,A4,Th38;
    hence g.(s, C) in P by A8;
  end;
A9: for s st s in P & g.(g.(s,J),C) in T holds g.(s,J) in P
  proof
    let s such that
    s in P;
    assume g.(g.(s,J),C) in T;
    then g.(s,J).m > 0 by Th40;
    hence thesis;
  end;
A10: m <> y by A3,A4;
A11: P is_invariant_wrt y:=1, g
  proof
    let s;
    assume s in P;
    then
A12: ex s9 st s = s9 & s9.m >= 0;
    g.(s, y:=1).m = s.m by A10,Th25;
    hence g.(s, y:=1) in P by A12;
  end;
A13: m <> x by A2,A4;
A14: for s st g.(s,C) in P holds g iteration_terminates_for J\;C, g.(s,C)
  proof
A15: for s being Element of S st R[s] holds (R[g.(s,J\;C)] iff g.(s,J\;C)
    in T) & F(g.(s,J\;C)) < F(s)
    proof
      let s be Element of S such that
A16:  s.m > 0;
A17:  F(s) = s.m by A16,INT_1:3,SUBSET_1:def 8;
      set q1 = g.(s,I);
      set q0 = g.(s, m is_odd);
      set sJ = g.(s,J);
      set sC = g.(sJ,C);
A18:  g.(s,J\;C) = sC by AOFA_000:def 29;
A19:  sJ.m <= 0 implies sC.b = 0 by Th38;
      sJ.m > 0 implies sC.b = 1 by Th38;
      hence R[g.(s,J\;C)] iff g.(s,J\;C) in T by A19,A18,Th2,Th38;
      set q2 = g.(q1,m/=2);
      set q3 = g.(q2,x*=x);
A20:  q1 = g.(q0, y*=x) or q1 = g.(q0, EmptyIns A) by A6;
      q2 = g.(s,I\;m/=2) by AOFA_000:def 29;
      then q3 = g.(s,J) by AOFA_000:def 29;
      then
A21:  sJ.m = q2.m by A13,Th33
        .= (q1.m) div 2 by Th45
        .= (q0.m) div 2 by A10,A20,Th33,AOFA_000:def 28
        .= (s.m) div 2 by A1,A4,Th49;
A22:  sC.m = sJ.m by A1,A4,Th38;
      then sC.m in NAT by A16,A21,INT_1:3,61;
      then F(sC) = sC.m by SUBSET_1:def 8;
      hence thesis by A16,A22,A18,A21,A17,INT_1:56;
    end;
    let s0 be Element of S such that
    g.(s0,C) in P;
    set s1 = g.(s0,C);
A23: s0.m <= 0 implies s1.b = 0 by Th38;
    s0.m > 0 implies s1.b = 1 by Th38;
    then
A24: g.(s0,C) in T iff R[g.(s0,C)] by A23,Th2,Th38;
    thus g iteration_terminates_for J\;C, g.(s0,C) from AOFA_000:sch 3(A24,A15
    );
  end;
  J is_terminating_wrt g,P by AOFA_000:107;
  then while(m gt 0, if-then(m is_odd, y*=x)\; m/=2\; x*=x )
  is_terminating_wrt g, P by A7,A9,A14,AOFA_000:104,118;
  hence thesis by A5,A11,AOFA_000:111;
end;
