reserve x,y,z for boolean object;
reserve i,j,k for Nat;
reserve n for non zero Nat;
reserve x,y,z1,z2 for Tuple of n, BOOLEAN;

theorem Th19:
  for z1,z2 being Tuple of n,BOOLEAN, d1,d2 being Element of
BOOLEAN holds z1^<*d1*> + z2^<*d2*> = (z1+z2)^<*d1 'xor' d2 'xor' add_ovfl(z1,
  z2)*>
proof
  let z1,z2 be Tuple of n,BOOLEAN, d1,d2 be Element of BOOLEAN;
  for i st i in Seg (n+1) holds ((z1+z2)^<*d1 'xor' d2 'xor' add_ovfl(z1,
z2)*>)/.i = ((z1^<*d1*>)/.i) 'xor' ((z2^<*d2*>)/.i) 'xor' (carry(z1^<*d1*>,z2^
  <*d2*>)/.i)
  proof
A1: Seg (n+1) = Seg (n) \/ {. n+1 .} by FINSEQ_1:9;
    let i such that
A2: i in Seg (n+1);
    per cases by A2,A1,XBOOLE_0:def 3;
    suppose
A3:   i in Seg n;
      hence ((z1+z2)^<*d1 'xor' d2 'xor' add_ovfl(z1,z2)*>)/.i = (z1+z2)/.i
       by Th1
        .= (z1/.i) 'xor' (z2/.i) 'xor' (carry(z1,z2)/.i) by A3,Def5
        .= ((z1^<*d1*>)/.i) 'xor' (z2/.i) 'xor' (carry(z1,z2)/.i) by A3,Th1
        .= ((z1^<*d1*>)/.i) 'xor' ((z2^<*d2*>)/.i) 'xor' (carry(z1,z2)/.i)
      by A3,Th1
        .= ((z1^<*d1*>)/.i) 'xor' ((z2^<*d2*>)/.i) 'xor' (carry(z1^<*d1*>,z2
      ^<*d2*>)/.i) by A3,Th17;
    end;
    suppose
      i in {. n+1 .};
      then
A4:   i=n+1 by TARSKI:def 1;
      hence (((z1+z2)^<*d1 'xor' d2 'xor' add_ovfl(z1,z2)*>)/.i) = d1 'xor' d2
      'xor' add_ovfl(z1,z2) by Th2
        .= d1 'xor' d2 'xor' (carry(z1^<*d1*>,z2^<*d2*>)/.i) by A4,Th18
        .= d1 'xor' ((z2^<*d2*>)/.i) 'xor' (carry(z1^<*d1*>,z2^<*d2*>)/.i)
      by A4,Th2
        .= ((z1^<*d1*>)/.i) 'xor' ((z2^<*d2*>)/.i) 'xor' (carry(z1^<*d1*>,z2
      ^<*d2*>)/.i) by A4,Th2;
    end;
  end;
  hence thesis by Def5;
end;
