Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import Bool ZAxioms ZMulOrder ZPow ZDivFloor ZSgnAbs ZParity NZLog.
Derived properties of bitwise operations
Module Type ZBitsProp (Import A : ZAxiomsSig') (Import B : ZMulOrderProp A) (Import C : ZParityProp A B) (Import D : ZSgnAbsProp A B) (Import E : ZPowProp A B C D) (Import F : ZDivProp A B D) (Import G : NZLog2Prop A A A B E). Include BoolEqualityFacts A. Ltac order_nz := try apply pow_nonzero; order'. Ltac order_pos' := try apply abs_nonneg; order_pos. Hint Rewrite div_0_l mod_0_l div_1_r mod_1_r : nz.
Some properties of power and division
forall a b c : t, a ~= 0 -> 0 <= c <= b -> a ^ (b - c) == a ^ b / a ^ cforall a b c : t, a ~= 0 -> 0 <= c <= b -> a ^ (b - c) == a ^ b / a ^ ca, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ (b - c) == a ^ b / a ^ ca, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ (b - c) == a ^ (b - c + c) / a ^ ca, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ (b - c) == a ^ (b - c) * a ^ c / a ^ ca, b, c:tHa:a ~= 0H:0 <= cH':c <= b0 <= b - ca, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ (b - c) == a ^ (b - c)a, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ c ~= 0a, b, c:tHa:a ~= 0H:0 <= cH':c <= b0 <= b - ca, b, c:tHa:a ~= 0H:0 <= cH':c <= ba ^ c ~= 0a, b, c:tHa:a ~= 0H:0 <= cH':c <= b0 <= b - cnow apply le_0_sub. Qed.a, b, c:tHa:a ~= 0H:0 <= cH':c <= b0 <= b - cforall a b c : t, b ~= 0 -> 0 <= c -> a mod b == 0 -> (a / b) ^ c == a ^ c / b ^ cforall a b c : t, b ~= 0 -> 0 <= c -> a mod b == 0 -> (a / b) ^ c == a ^ c / b ^ ca, b, c:tHb:b ~= 0Hc:0 <= cH:a mod b == 0(a / b) ^ c == a ^ c / b ^ ca, b, c:tHb:b ~= 0Hc:0 <= cH:a mod b == 0(a / b) ^ c == (b * (a / b) + a mod b) ^ c / b ^ ca, b, c:tHb:b ~= 0Hc:0 <= cH:a mod b == 0(a / b) ^ c == (a / b) ^ ca, b, c:tHb:b ~= 0Hc:0 <= cH:a mod b == 0b ^ c ~= 0now apply pow_nonzero. Qed.a, b, c:tHb:b ~= 0Hc:0 <= cH:a mod b == 0b ^ c ~= 0
An injection from bits true and false to numbers 1 and 0.
We declare it as a (local) coercion for shorter statements.
Definition b2z (b:bool) := if b then 1 else 0. Coercion b2z : bool >-> t. Instance b2z_wd : Proper (Logic.eq ==> eq) b2z := _.a:texists (a' : t) (b : bool), a == 2 * a' + ba:texists (a' : t) (b : bool), a == 2 * a' + ba, a':tH:a == 2 * a'exists (a'0 : t) (b : bool), a == 2 * a'0 + ba, a':tH:a == 2 * a' + 1exists (a'0 : t) (b : bool), a == 2 * a'0 + ba, a':tH:a == 2 * a'exists b : bool, a == 2 * a' + ba, a':tH:a == 2 * a' + 1exists (a'0 : t) (b : bool), a == 2 * a'0 + ba, a':tH:a == 2 * a'a == 2 * a' + falsea, a':tH:a == 2 * a' + 1exists (a'0 : t) (b : bool), a == 2 * a'0 + ba, a':tH:a == 2 * a' + 1exists (a'0 : t) (b : bool), a == 2 * a'0 + ba, a':tH:a == 2 * a' + 1exists b : bool, a == 2 * a' + bnow simpl. Qed.a, a':tH:a == 2 * a' + 1a == 2 * a' + true
We can compact testbit_odd_0 testbit_even_0
testbit_even_succ testbit_odd_succ in only two lemmas.
a:tb:bool(2 * a + b).[0] = ba:tb:bool(2 * a + b).[0] = ba:t(2 * a + 1).[0] = truea:t(2 * a).[0] = falseapply testbit_even_0. Qed.a:t(2 * a).[0] = falsea:tb:booln:t0 <= n -> (2 * a + b).[S n] = a.[n]a:tb:booln:t0 <= n -> (2 * a + b).[S n] = a.[n]a, n:t0 <= n -> (2 * a + 1).[S n] = a.[n]a, n:t0 <= n -> (2 * a).[S n] = a.[n]now apply testbit_even_succ. Qed.a, n:t0 <= n -> (2 * a).[S n] = a.[n]
Alternative characterisations of testbit
This concise equation could have been taken as specification
for testbit in the interface, but it would have been hard to
implement with little initial knowledge about div and mod
a, n:t0 <= n -> a.[n] == (a / 2 ^ n) mod 2a, n:t0 <= n -> a.[n] == (a / 2 ^ n) mod 2a, n:tHn:0 <= na.[n] == (a / 2 ^ n) mod 2n:tHn:0 <= nforall a : t, a.[n] == (a / 2 ^ n) mod 2n:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => forall a : t, a.[n0] == (a / 2 ^ n0) mod 2)n:tHn:0 <= nforall a : t, a.[0] == (a / 2 ^ 0) mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= nforall a : t, a.[0] == (a / 2 ^ 0) mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na:ta.[0] == (a / 2 ^ 0) mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na:ta.[0] == a mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na, a':tb:boolH:a == 2 * a' + ba.[0] == a mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na, a':tb:boolH:a == 2 * a' + b(2 * a' + b).[0] == a mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na, a':tb:boolH:a == 2 * a' + bb == a mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na, a':tb:boolH:a == 2 * a' + b0 <= b < 2 \/ 2 < b <= 0n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= na, a':tb:boolH:a == 2 * a' + b0 <= b < 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= nforall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2forall m : t, 0 <= m -> (forall a : t, a.[m] == (a / 2 ^ m) mod 2) -> forall a : t, a.[S m] == (a / 2 ^ S m) mod 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a:ta.[S n] == (a / 2 ^ S n) mod 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + ba.[S n] == (a / 2 ^ S n) mod 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + b(2 * a' + b).[S n] == (a / 2 ^ S n) mod 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + b(a' / 2 ^ n) mod 2 == (a / 2 ^ S n) mod 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + ba' / 2 ^ n == a / 2 ^ S nn:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + ba' / 2 ^ n == a / 2 / 2 ^ nn:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + ba' == a / 2n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + b0 <= b < 2 \/ 2 < b <= 0destruct b; split; simpl; order'. Qed.n:tHn:0 <= nIH:forall a0 : t, a0.[n] == (a0 / 2 ^ n) mod 2a, a':tb:boolH:a == 2 * a' + b0 <= b < 2
This characterisation that uses only basic operations and
power was initially taken as specification for testbit.
We describe a as having a low part and a high part, with
the corresponding bit in the middle. This characterisation
is moderatly complex to implement, but also moderately
usable...
a, n:t0 <= n -> exists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ na, n:t0 <= n -> exists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ na, n:tHn:0 <= nexists l h : t, 0 <= l < 2 ^ n /\ a == l + (a.[n] + 2 * h) * 2 ^ na, n:tHn:0 <= nexists h : t, 0 <= a mod 2 ^ n < 2 ^ n /\ a == a mod 2 ^ n + (a.[n] + 2 * h) * 2 ^ na, n:tHn:0 <= n0 <= a mod 2 ^ n < 2 ^ n /\ a == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ na, n:tHn:0 <= n0 <= a mod 2 ^ n < 2 ^ na, n:tHn:0 <= na == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ na, n:tHn:0 <= na == a mod 2 ^ n + (a.[n] + 2 * (a / 2 ^ n / 2)) * 2 ^ na, n:tHn:0 <= na == 2 ^ n * (2 * (a / 2 ^ n / 2) + a.[n]) + a mod 2 ^ na, n:tHn:0 <= n2 ^ n * (a / 2 ^ n) + a mod 2 ^ n == 2 ^ n * (2 * (a / 2 ^ n / 2) + a.[n]) + a mod 2 ^ na, n:tHn:0 <= na / 2 ^ n == 2 * (a / 2 ^ n / 2) + a.[n]a, n:tHn:0 <= na / 2 ^ n == 2 * (a / 2 ^ n / 2) + (a / 2 ^ n) mod 2order'. Qed.a, n:tHn:0 <= n2 ~= 0forall a n : t, 0 <= n -> a.[n] = true <-> (a / 2 ^ n) mod 2 == 1forall a n : t, 0 <= n -> a.[n] = true <-> (a / 2 ^ n) mod 2 == 1a, n:tHn:0 <= na.[n] = true <-> (a / 2 ^ n) mod 2 == 1destruct a.[n]; split; simpl; now try order'. Qed.a, n:tHn:0 <= na.[n] = true <-> a.[n] == 1forall a n : t, 0 <= n -> a.[n] = false <-> (a / 2 ^ n) mod 2 == 0forall a n : t, 0 <= n -> a.[n] = false <-> (a / 2 ^ n) mod 2 == 0a, n:tHn:0 <= na.[n] = false <-> (a / 2 ^ n) mod 2 == 0destruct a.[n]; split; simpl; now try order'. Qed.a, n:tHn:0 <= na.[n] = false <-> a.[n] == 0forall a n : t, 0 <= n -> a.[n] = ((a / 2 ^ n) mod 2 =? 1)forall a n : t, 0 <= n -> a.[n] = ((a / 2 ^ n) mod 2 =? 1)a, n:tHn:0 <= na.[n] = ((a / 2 ^ n) mod 2 =? 1)now rewrite testbit_true, eqb_eq. Qed.a, n:tHn:0 <= na.[n] = true <-> ((a / 2 ^ n) mod 2 =? 1) = true
Results about the injection b2z
forall a0 b0 : bool, a0 == b0 -> a0 = b0intros [|] [|]; simpl; trivial; order'. Qed.forall a0 b0 : bool, a0 == b0 -> a0 = b0forall (a0 : bool) (a : t), (a0 + 2 * a) / 2 == aforall (a0 : bool) (a : t), (a0 + 2 * a) / 2 == aa0:boola:t(a0 + 2 * a) / 2 == anow rewrite div_small, add_0_l by (destruct a0; split; simpl; order'). Qed.a0:boola:ta0 / 2 + a == aforall (a0 : bool) (a : t), (a0 + 2 * a).[0] = a0forall (a0 : bool) (a : t), (a0 + 2 * a).[0] = a0a0:boola:t(a0 + 2 * a).[0] = a0a0:boola:t(a0 + 2 * a).[0] == a0a0:boola:t((a0 + 2 * a) / 2 ^ 0) mod 2 == a0a0:boola:t(a0 + 2 * a) mod 2 == a0now rewrite mod_small by (destruct a0; split; simpl; order'). Qed.a0:boola:ta0 mod 2 == a0forall a0 : bool, a0 / 2 == 0forall a0 : bool, a0 / 2 == 0a0:boola0 / 2 == 0now nzsimpl. Qed.a0:boola0 / 2 == (a0 + 2 * 0) / 2forall a0 : bool, a0.[0] = a0forall a0 : bool, a0.[0] = a0a0:boola0.[0] = a0now nzsimpl. Qed.a0:boola0.[0] = (a0 + 2 * 0).[0]
The specification of testbit by low and high parts is complete
forall (a n : t) (a0 : bool) (l h : t), 0 <= l < 2 ^ n -> a == l + (a0 + 2 * h) * 2 ^ n -> a.[n] = a0forall (a n : t) (a0 : bool) (l h : t), 0 <= l < 2 ^ n -> a == l + (a0 + 2 * h) * 2 ^ n -> a.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ na.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ n0 <= na, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nHn:n < 00 <= na, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 0EQ:a == l + (a0 + 2 * h) * 2 ^ nHn:n < 00 <= na, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na.[n] = a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na.[n] == a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= n(a / 2 ^ n) mod 2 == a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na0 == (a / 2 ^ n) mod 2a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= n0 <= a0 < 2 \/ 2 < a0 <= 0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na / 2 ^ n == 2 * h + a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na / 2 ^ n == 2 * h + a0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= n2 * h + a0 == a / 2 ^ na, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= n0 <= l < 2 ^ n \/ 2 ^ n < l <= 0a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na == 2 ^ n * (2 * h + a0) + lnow rewrite add_comm, (add_comm _ a0), mul_comm. Qed.a, n:ta0:booll, h:tHl:0 <= l < 2 ^ nEQ:a == l + (a0 + 2 * h) * 2 ^ nH:0 <= na == 2 ^ n * (2 * h + a0) + l
All bits of number 0 are 0
forall n : t, 0.[n] = falseforall n : t, 0.[n] = falsen:t0.[n] = falsen:tH:0 <= n0.[n] = falsen:tH:n < 00.[n] = falsen:tH:0 <= n(0 / 2 ^ n) mod 2 == 0n:tH:n < 00.[n] = falsenow apply testbit_neg_r. Qed.n:tH:n < 00.[n] = false
For negative numbers, we are actually doing two's complement
forall a n : t, 0 <= n -> (- a).[n] = negb (P a).[n]forall a n : t, 0 <= n -> (- a).[n] = negb (P a).[n]a, n:tHn:0 <= n(- a).[n] = negb (P a).[n]a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] = negb (P a).[n]a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] = negb (P a).[n]a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(P a).[n] = negb (- a).[n]a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n0 <= 2 ^ n - l - 1 < 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n0 <= 2 ^ n - l - 1a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n - l - 1 < 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n0 < S (2 ^ n - l - 1)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n - l - 1 < 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n0 < 2 ^ n - la, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n - l - 1 < 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n - l - 1 < 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nS (2 ^ n - l - 1) <= 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n - l <= 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n <= 2 ^ n + la, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n2 ^ n + 0 <= 2 ^ n + la, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == 2 ^ n - l - 1 + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nP a == P (2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ na == 2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n- a == - (2 ^ n - l + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n- a == - 2 ^ n + l + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n- a == l + (- 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ nl + ((- a).[n] + 2 * h) * 2 ^ n == l + (- 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n((- a).[n] + 2 * h) * 2 ^ n == - 2 ^ n + - ((negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n((- a).[n] + 2 * h) * 2 ^ n == - (2 ^ n + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n((- a).[n] + 2 * h) * 2 ^ n == - (1 * 2 ^ n + (negb (- a).[n] + 2 * (- h - 1)) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n((- a).[n] + 2 * h) * 2 ^ n == - ((1 + (negb (- a).[n] + 2 * (- h - 1))) * 2 ^ n)a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n((- a).[n] + 2 * h) * 2 ^ n == - (1 + (negb (- a).[n] + 2 * (- h - 1))) * 2 ^ na, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == - (1 + (negb (- a).[n] + 2 * (- h - 1)))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + - (2 * (- h - 1)))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * - (- h - 1))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * (h + 1))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + 2 * (1 + h))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + (- negb (- a).[n] + (2 * 1 + 2 * h))a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] + 2 * h == -1 + - negb (- a).[n] + 2 * 1 + 2 * ha, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] == -1 + - negb (- a).[n] + 2 * 1a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] == -1 + - negb (- a).[n] + 2a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + ((- a).[n] + 2 * h) * 2 ^ n(- a).[n] == 1 - negb (- a).[n]a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + (true + 2 * h) * 2 ^ n1 == 1 - 0a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + (false + 2 * h) * 2 ^ n0 == 1 - 1now nzsimpl'. Qed.a, n:tHn:0 <= nl, h:tHl:0 <= l < 2 ^ nEQ:- a == l + (false + 2 * h) * 2 ^ n0 == 1 - 1
All bits of number (-1) are 1
forall n : t, 0 <= n -> (-1).[n] = trueforall n : t, 0 <= n -> (-1).[n] = truenow rewrite bits_opp, one_succ, pred_succ, bits_0. Qed.n:tH:0 <= n(-1).[n] = true
Various ways to refer to the lowest bit of a number
forall a : t, a.[0] = odd aforall a : t, a.[0] = odd aa:ta.[0] = odd aa:todd a = a.[0]a, a':tb:boolEQ:a == 2 * a' + bodd a = a.[0]destruct b; simpl; apply odd_1 || apply odd_0. Qed.a, a':tb:boolEQ:a == 2 * a' + bodd b = bforall a : t, a.[0] = (a mod 2 =? 1)forall a : t, a.[0] = (a mod 2 =? 1)a:ta.[0] = (a mod 2 =? 1)now nzsimpl. Qed.a:t((a / 2 ^ 0) mod 2 =? 1) = (a mod 2 =? 1)forall a : t, a.[0] == a mod 2forall a : t, a.[0] == a mod 2a:ta.[0] == a mod 2now nzsimpl. Qed.a:t(a / 2 ^ 0) mod 2 == a mod 2
Hence testing a bit is equivalent to shifting and testing parity
forall a n : t, a.[n] = odd (a >> n)forall a n : t, a.[n] = odd (a >> n)now rewrite <- bit0_odd, shiftr_spec, add_0_l. Qed.a, n:ta.[n] = odd (a >> n)
log2 gives the highest nonzero bit of positive numbers
forall a : t, 0 < a -> a.[log2 a] = trueforall a : t, 0 < a -> a.[log2 a] = truea:tHa:0 < aa.[log2 a] = truea:tHa:0 < aHa':0 <= log2 aa.[log2 a] = truea:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 aa.[log2 a] = truea:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a(2 ^ log2 a + r).[log2 a] = truea:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a((r + 2 ^ log2 a) / 2 ^ log2 a) mod 2 == 1a:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a((r + 1 * 2 ^ log2 a) / 2 ^ log2 a) mod 2 == 1a:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a(r / 2 ^ log2 a + 1) mod 2 == 1a:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a(0 + 1) mod 2 == 1a:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a1 mod 2 == 1split; order'. Qed.a:tHa:0 < aHa':0 <= log2 ar:tEQ:a == 2 ^ log2 a + rHr:0 <= r < 2 ^ log2 a0 <= 1 < 2forall a n : t, 0 <= a -> log2 a < n -> a.[n] = falseforall a n : t, 0 <= a -> log2 a < n -> a.[n] = falsea, n:tHa:0 <= aH:log2 a < na.[n] = falsea, n:tHa:0 <= aH:log2 a < n0 <= na, n:tHa:0 <= aH:log2 a < nHn:0 <= na.[n] = falsea, n:tHa:0 <= aH:log2 a < n0 <= log2 aa, n:tHa:0 <= aH:log2 a < nlog2 a <= na, n:tHa:0 <= aH:log2 a < nHn:0 <= na.[n] = falsea, n:tHa:0 <= aH:log2 a < nlog2 a <= na, n:tHa:0 <= aH:log2 a < nHn:0 <= na.[n] = falsea, n:tHa:0 <= aH:log2 a < nHn:0 <= na.[n] = falsea, n:tHa:0 <= aH:log2 a < nHn:0 <= n(a / 2 ^ n) mod 2 == 0a, n:tHa:0 <= aH:log2 a < nHn:0 <= n0 mod 2 == 0a, n:tHa:0 <= aH:log2 a < nHn:0 <= n0 <= a < 2 ^ na, n:tHa:0 <= aH:log2 a < nHn:0 <= n0 <= a < 2 ^ na, n:tHa:0 <= aH:log2 a < nHn:0 <= n0 <= aa, n:tHa:0 <= aH:log2 a < nHn:0 <= na < 2 ^ na, n:tHa:0 <= aH:log2 a < nHn:0 <= na < 2 ^ nnow rewrite log2_pow2. Qed.a, n:tHa:0 <= aH:log2 a < nHn:0 <= nlog2 a < log2 (2 ^ n)
Hence the number of bits of a is 1+log2 a
(see Pos.size_nat and Pos.size).
For negative numbers, things are the other ways around:
log2 gives the highest zero bit (for numbers below -1).
forall a : t, a < -1 -> a.[log2 (P (- a))] = falseforall a : t, a < -1 -> a.[log2 (P (- a))] = falsea:tHa:a < -1a.[log2 (P (- a))] = falsea:tHa:a < -1(- - a).[log2 (P (- a))] = falsea:tHa:a < -1negb (P (- a)).[log2 (P (- a))] = falsea:tHa:a < -10 <= log2 (P (- a))a:tHa:a < -1(P (- a)).[log2 (P (- a))] = truea:tHa:a < -10 <= log2 (P (- a))a:tHa:a < -10 < P (- a)a:tHa:a < -10 <= log2 (P (- a))a:tHa:- -1 < - a0 < P (- a)a:tHa:a < -10 <= log2 (P (- a))a:tHa:1 < - a0 < P (- a)a:tHa:a < -10 <= log2 (P (- a))a:tHa:1 < - aS 0 < - aa:tHa:a < -10 <= log2 (P (- a))apply log2_nonneg. Qed.a:tHa:a < -10 <= log2 (P (- a))forall a n : t, a < 0 -> log2 (P (- a)) < n -> a.[n] = trueforall a n : t, a < 0 -> log2 (P (- a)) < n -> a.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < na.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < n0 <= na, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= na.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < n0 <= log2 (P (- a))a, n:tHa:a < 0H:log2 (P (- a)) < nlog2 (P (- a)) <= na, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= na.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < nlog2 (P (- a)) <= na, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= na.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= na.[n] = truea, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= n(P (- a)).[n] = falsenow rewrite <- opp_succ, opp_nonneg_nonpos, le_succ_l. Qed.a, n:tHa:a < 0H:log2 (P (- a)) < nHn:0 <= n0 <= P (- a)
Accessing a high enough bit of a number gives its sign
forall a n : t, log2 (abs a) < n -> 0 <= a <-> a.[n] = falseforall a n : t, log2 (abs a) < n -> 0 <= a <-> a.[n] = falsea, n:tHn:log2 (abs a) < n0 <= a <-> a.[n] = falsea, n:tHn:log2 (abs a) < nH:0 <= aa.[n] = falsea, n:tHn:log2 (abs a) < nH:a.[n] = false0 <= aa, n:tHn:log2 a < nH:0 <= aa.[n] = falsea, n:tHn:log2 (abs a) < nH:a.[n] = false0 <= aa, n:tHn:log2 (abs a) < nH:a.[n] = false0 <= aa, n:tHn:log2 (abs a) < nH:a.[n] = falseH0:a < 00 <= aa, n:tHn:log2 (- a) < nH:a.[n] = falseH0:a < 00 <= aa, n:tHn:log2 (- a) < nH:a.[n] = falseH0:a < 0log2 (P (- a)) < na, n:tHn:log2 (- a) < nH:a.[n] = falseH0:a < 0log2 (P (- a)) <= log2 (- a)apply le_pred_l. Qed.a, n:tHn:log2 (- a) < nH:a.[n] = falseH0:a < 0P (- a) <= - aforall a : t, 0 <= a <-> a.[S (log2 (abs a))] = falseforall a : t, 0 <= a <-> a.[S (log2 (abs a))] = falsea:t0 <= a <-> a.[S (log2 (abs a))] = falseapply lt_succ_diag_r. Qed.a:tlog2 (abs a) < S (log2 (abs a))forall a : t, 0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)forall a : t, 0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)a:t0 <= a <-> (exists k : t, forall m : t, k < m -> a.[m] = false)a:t0 <= a -> exists k : t, forall m : t, k < m -> a.[m] = falsea:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= aa:tHa:0 <= aexists k : t, forall m : t, k < m -> a.[m] = falsea:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= aa:tHa:0 <= aforall m : t, log2 a < m -> a.[m] = falsea:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= aa:tHa:0 <= am:tHm:log2 a < ma.[m] = falsea:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= aa:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> 0 <= aa, k:tHk:forall m : t, k < m -> a.[m] = false0 <= aa, k:tHk:forall m : t, k < m -> a.[m] = falseH:k <= log2 (abs a)0 <= aa, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < k0 <= aa, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < k0 <= aa, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < klog2 (abs a) < S ka, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < ka.[S k] = falsea, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < ka.[S k] = falseapply lt_succ_diag_r. Qed.a, k:tHk:forall m : t, k < m -> a.[m] = falseH:log2 (abs a) < kk < S kforall a n : t, log2 (abs a) < n -> a < 0 <-> a.[n] = trueforall a n : t, log2 (abs a) < n -> a < 0 <-> a.[n] = truenow rewrite lt_nge, <- not_false_iff_true, (bits_iff_nonneg a n). Qed.a, n:tHn:log2 (abs a) < na < 0 <-> a.[n] = trueforall a : t, a < 0 <-> a.[S (log2 (abs a))] = trueforall a : t, a < 0 <-> a.[S (log2 (abs a))] = truea:ta < 0 <-> a.[S (log2 (abs a))] = trueapply lt_succ_diag_r. Qed.a:tlog2 (abs a) < S (log2 (abs a))forall a : t, a < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)forall a : t, a < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)a:ta < 0 <-> (exists k : t, forall m : t, k < m -> a.[m] = true)a:ta < 0 -> exists k : t, forall m : t, k < m -> a.[m] = truea:t(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0a:tHa:a < 0exists k : t, forall m : t, k < m -> a.[m] = truea:t(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0a:tHa:a < 0forall m : t, log2 (P (- a)) < m -> a.[m] = truea:t(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0a:tHa:a < 0m:tHm:log2 (P (- a)) < ma.[m] = truea:t(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0a:t(exists k : t, forall m : t, k < m -> a.[m] = true) -> a < 0a, k:tHk:forall m : t, k < m -> a.[m] = truea < 0a, k:tHk:forall m : t, k < m -> a.[m] = trueH:k <= log2 (abs a)a < 0a, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < ka < 0a, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < ka < 0a, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < klog2 (abs a) < S ka, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < ka.[S k] = truea, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < ka.[S k] = trueapply lt_succ_diag_r. Qed.a, k:tHk:forall m : t, k < m -> a.[m] = trueH:log2 (abs a) < kk < S k
Testing bits after division or multiplication by a power of two
forall a n : t, 0 <= n -> (a / 2).[n] = a.[S n]forall a n : t, 0 <= n -> (a / 2).[n] = a.[S n]a, n:tHn:0 <= n(a / 2).[n] = a.[S n]a, n:tHn:0 <= n(a / 2).[n] = true <-> a.[S n] = truea, n:tHn:0 <= n(a / 2 / 2 ^ n) mod 2 == 1 <-> (a / 2 ^ S n) mod 2 == 1now rewrite div_div by order_pos. Qed.a, n:tHn:0 <= n(a / 2 / 2 ^ n) mod 2 == 1 <-> (a / (2 * 2 ^ n)) mod 2 == 1forall a n m : t, 0 <= n -> 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]forall a n m : t, 0 <= n -> 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]a, n, m:tHn:0 <= n0 <= m -> (a / 2 ^ n).[m] = a.[m + n]n:tHn:0 <= nforall a m : t, 0 <= m -> (a / 2 ^ n).[m] = a.[m + n]n:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => forall a m : t, 0 <= m -> (a / 2 ^ n0).[m] = a.[m + n0])n:tHn:0 <= nforall a m : t, 0 <= m -> (a / 2 ^ 0).[m] = a.[m + 0]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]n:tHn:0 <= nforall a m : t, 0 <= m -> (a / 2 ^ 0).[m] = a.[m + 0]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]n:tHn:0 <= na, m:tHm:0 <= m(a / 2 ^ 0).[m] = a.[m + 0]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]forall m : t, 0 <= m -> (forall a m0 : t, 0 <= m0 -> (a / 2 ^ m).[m0] = a.[m0 + m]) -> forall a m0 : t, 0 <= m0 -> (a / 2 ^ S m).[m0] = a.[m0 + S m]n:tHn:0 <= nIH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]a, m:tHm:0 <= m(a / 2 ^ S n).[m] = a.[m + S n]n:tHn:0 <= nIH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]a, m:tHm:0 <= m(a / (2 * 2 ^ n)).[m] = a.[S (m + n)]now rewrite IH, div2_bits by order_pos. Qed.n:tHn:0 <= nIH:forall a0 m0 : t, 0 <= m0 -> (a0 / 2 ^ n).[m0] = a0.[m0 + n]a, m:tHm:0 <= m(a / 2 / 2 ^ n).[m] = a.[S (m + n)]forall a n : t, (2 * a).[S n] = a.[n]forall a n : t, (2 * a).[S n] = a.[n]a, n:t(2 * a).[S n] = a.[n]a, n:tHn:0 <= n(2 * a).[S n] = a.[n]a, n:tHn:n < 0(2 * a).[S n] = a.[n]a, n:tHn:n < 0(2 * a).[S n] = a.[n]a, n:tHn:n < 0(2 * a).[S n] = falsea, n:tHn:S n <= 0(2 * a).[S n] = falsea, n:tHn:S n < 0(2 * a).[S n] = falsea, n:tHn:S n == 0(2 * a).[S n] = falsenow rewrite Hn, bit0_odd, odd_mul, odd_2. Qed.a, n:tHn:S n == 0(2 * a).[S n] = falseforall a n : t, (2 * a).[n] = a.[P n]forall a n : t, (2 * a).[n] = a.[P n]a, n:t(2 * a).[n] = a.[P n]apply double_bits_succ. Qed.a, n:t(2 * a).[S (P n)] = a.[P n]forall a n m : t, 0 <= n -> (a * 2 ^ n).[n + m] = a.[m]forall a n m : t, 0 <= n -> (a * 2 ^ n).[n + m] = a.[m]a, n, m:tHn:0 <= n(a * 2 ^ n).[n + m] = a.[m]n:tHn:0 <= nforall a m : t, (a * 2 ^ n).[n + m] = a.[m]n:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => forall a m : t, (a * 2 ^ n0).[n0 + m] = a.[m])n:tHn:0 <= nforall a m : t, (a * 2 ^ 0).[0 + m] = a.[m]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]n:tHn:0 <= nforall a m : t, (a * 2 ^ 0).[0 + m] = a.[m]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]n:tHn:0 <= na, m:t(a * 2 ^ 0).[0 + m] = a.[m]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]n:tHn:0 <= nforall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]forall m : t, 0 <= m -> (forall a m0 : t, (a * 2 ^ m).[m + m0] = a.[m0]) -> forall a m0 : t, (a * 2 ^ S m).[S m + m0] = a.[m0]n:tHn:0 <= nIH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]a, m:t(a * 2 ^ S n).[S n + m] = a.[m]n:tHn:0 <= nIH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]a, m:t(a * (2 * 2 ^ n)).[S (n + m)] = a.[m]now rewrite double_bits_succ. Qed.n:tHn:0 <= nIH:forall a0 m0 : t, (a0 * 2 ^ n).[n + m0] = a0.[m0]a, m:t(2 * (a * 2 ^ n)).[S (n + m)] = a.[m]forall a n m : t, 0 <= n -> (a * 2 ^ n).[m] = a.[m - n]forall a n m : t, 0 <= n -> (a * 2 ^ n).[m] = a.[m - n]a, n, m:tH:0 <= n(a * 2 ^ n).[m] = a.[m - n]a, n, m:tH:0 <= n(a * 2 ^ n).[m + n - n] = a.[m - n]now apply mul_pow2_bits_add. Qed.a, n, m:tH:0 <= n(a * 2 ^ n).[n + (m - n)] = a.[m - n]forall a n m : t, m < n -> (a * 2 ^ n).[m] = falseforall a n m : t, m < n -> (a * 2 ^ n).[m] = falsea, n, m:tH:m < n(a * 2 ^ n).[m] = falsea, n, m:tH:m < nH0:0 <= n(a * 2 ^ n).[m] = falsea, n, m:tH:m < nH0:n < 0(a * 2 ^ n).[m] = falsea, n, m:tH:m < nH0:0 <= na.[m - n] = falsea, n, m:tH:m < nH0:n < 0(a * 2 ^ n).[m] = falsea, n, m:tH:m < nH0:0 <= nm - n < 0a, n, m:tH:m < nH0:n < 0(a * 2 ^ n).[m] = falsenow rewrite pow_neg_r, mul_0_r, bits_0. Qed.a, n, m:tH:m < nH0:n < 0(a * 2 ^ n).[m] = false
Selecting the low part of a number can be done by a modulo
forall a n m : t, 0 <= n <= m -> (a mod 2 ^ n).[m] = falseforall a n m : t, 0 <= n <= m -> (a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= m(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= m0 < 2 ^ na, n, m:tHn:0 <= nH:n <= mLE:0 <= a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= mLE:0 <= a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= mLE:0 < a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= mLE:0 == a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= mLE:0 < a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ nlog2 (a mod 2 ^ n) < ma, n, m:tHn:0 <= nH:n <= mLE:0 == a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsea, n, m:tHn:0 <= nH:n <= mLE:0 < a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ nlog2 (a mod 2 ^ n) < na, n, m:tHn:0 <= nH:n <= mLE:0 == a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falsenow rewrite <- LE, bits_0. Qed.a, n, m:tHn:0 <= nH:n <= mLE:0 == a mod 2 ^ nLT:a mod 2 ^ n < 2 ^ n(a mod 2 ^ n).[m] = falseforall a n m : t, m < n -> (a mod 2 ^ n).[m] = a.[m]forall a n m : t, m < n -> (a mod 2 ^ n).[m] = a.[m]a, n, m:tH:m < n(a mod 2 ^ n).[m] = a.[m]a, n, m:tH:m < nHm:0 <= m(a mod 2 ^ n).[m] = a.[m]a, n, m:tH:m < nHm:0 <= m((a mod 2 ^ n / 2 ^ m) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m((a mod 2 ^ n / 2 ^ m + 2 ^ P (n - m) * (a / 2 ^ n) * 2) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m(((a mod 2 ^ n + 2 ^ P (n - m) * (a / 2 ^ n) * 2 * 2 ^ m) / 2 ^ m) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m(((a mod 2 ^ n + 2 ^ (n - m) * (a / 2 ^ n) * 2 ^ m) / 2 ^ m) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m0 <= P (n - m)a, n, m:tH:m < nHm:0 <= m(((a mod 2 ^ n + 2 ^ n * (a / 2 ^ n)) / 2 ^ m) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m0 <= n - ma, n, m:tH:m < nHm:0 <= m0 <= P (n - m)a, n, m:tH:m < nHm:0 <= m((a / 2 ^ m) mod 2 =? 1) = a.[m]a, n, m:tH:m < nHm:0 <= m0 <= n - ma, n, m:tH:m < nHm:0 <= m0 <= P (n - m)a, n, m:tH:m < nHm:0 <= ma.[m] = ((a / 2 ^ m) mod 2 =? 1)a, n, m:tH:m < nHm:0 <= m0 <= n - ma, n, m:tH:m < nHm:0 <= m0 <= P (n - m)a, n, m:tH:m < nHm:0 <= m0 <= n - ma, n, m:tH:m < nHm:0 <= m0 <= P (n - m)now apply lt_le_pred, lt_0_sub. Qed.a, n, m:tH:m < nHm:0 <= m0 <= P (n - m)
We now prove that having the same bits implies equality.
For that we use a notion of equality over functional
streams of bits.
Definition eqf (f g:t -> bool) := forall n:t, f n = g n.Equivalence eqfsplit; congruence. Qed. Local Infix "===" := eqf (at level 70, no associativity).Equivalence eqfProper (eq ==> eqf) testbitProper (eq ==> eqf) testbitnow rewrite Ha. Qed.a, a':tHa:a == a'n:ta.[n] = a'.[n]
Only zero corresponds to the always-false stream.
forall a : t, (forall n : t, a.[n] = false) -> a == 0forall a : t, (forall n : t, a.[n] = false) -> a == 0a:tH:forall n : t, a.[n] = falsea == 0a:tH:forall n : t, a.[n] = falseHa:a < 0a == 0a:tH:forall n : t, a.[n] = falseHa:0 < aa == 0a:tH:forall n : t, a.[n] = falseHa:a.[S (log2 (P (- a)))] = truea == 0a:tH:forall n : t, a.[n] = falseHa:a < 0log2 (P (- a)) < S (log2 (P (- a)))a:tH:forall n : t, a.[n] = falseHa:0 < aa == 0a:tH:forall n : t, a.[n] = falseHa:a < 0log2 (P (- a)) < S (log2 (P (- a)))a:tH:forall n : t, a.[n] = falseHa:0 < aa == 0a:tH:forall n : t, a.[n] = falseHa:0 < aa == 0now rewrite H in Ha. Qed.a:tH:forall n : t, a.[n] = falseHa:a.[log2 a] = truea == 0
If two numbers produce the same stream of bits, they are equal.
forall a b : t, testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bforall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nforall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => forall a b : t, 0 <= a < 2 ^ n0 -> testbit a === testbit b -> a == b)n:tHn:0 <= nforall a b : t, 0 <= a < 2 ^ 0 -> testbit a === testbit b -> a == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nforall a b : t, 0 <= a < 2 ^ 0 -> testbit a === testbit b -> a == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= a < 2 ^ 0H:testbit a === testbit ba == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= a <= 0H:testbit a === testbit ba == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= a <= 0H:testbit a === testbit bHa':a == 0a == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= 0 <= 0H:testbit 0 === testbit bHa':a == 00 == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= 0 <= 0H:testbit 0 === testbit bHa':a == 0b == 0n:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= 0 <= 0H:testbit 0 === testbit bHa':a == 0forall n0 : t, b.[n0] = falsen:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= na, b:tHa:0 <= 0 <= 0H:testbit 0 === testbit bHa':a == 0m:tb.[m] = falsen:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> testbit a === testbit b -> a == b) -> forall a b : t, 0 <= a < 2 ^ S m -> testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit b2 * (a / 2) + a mod 2 == 2 * (b / 2) + b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit b2 * (a / 2) == 2 * (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba / 2 == b / 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit b0 <= a / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit b0 <= a / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit b0 < 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba < 2 * 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit ba < 2 * 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit btestbit (a / 2) === testbit (b / 2)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:t(a / 2).[m] = (b / 2).[m]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:tH0:0 <= m(a / 2).[m] = (b / 2).[m]n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:tH0:m < 0(a / 2).[m] = (b / 2).[m]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:tH0:0 <= ma.[S m] = b.[S m]n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:tH0:m < 0(a / 2).[m] = (b / 2).[m]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tHa:0 <= aHa':a < 2 ^ S nH:testbit a === testbit bm:tH0:m < 0(a / 2).[m] = (b / 2).[m]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> testbit a === testbit b -> a == bforall a b : t, testbit a === testbit b -> a == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit ba == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:0 <= aa == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0a == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:0 <= a0 <= a < 2 ^ aAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0a == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:0 <= aa < 2 ^ aAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0a == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0a == bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0- S a == - S bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 00 <= - S aAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S a- S a == - S bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0- - S a <= - 0AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S a- S a == - S bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S a- S a == - S bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S a0 <= - S a < 2 ^ (- S a)AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S atestbit (- S a) === testbit (- S b)AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S a- S a < 2 ^ (- S a)AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S atestbit (- S a) === testbit (- S b)AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S atestbit (- S a) === testbit (- S b)AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S am:t(- S a).[m] = (- S b).[m]AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S am:tH1:0 <= m(- S a).[m] = (- S b).[m]AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S am:tH1:m < 0(- S a).[m] = (- S b).[m]now rewrite 2 testbit_neg_r. Qed.AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> testbit a0 === testbit b0 -> a0 == b0a, b:tH:testbit a === testbit bHa:a < 0H0:0 <= - S am:tH1:m < 0(- S a).[m] = (- S b).[m]forall a b : t, testbit a === testbit b <-> a == bforall a b : t, testbit a === testbit b <-> a == ba, b:ttestbit a === testbit b -> a == ba, b:ta == b -> testbit a === testbit bintros EQ; now rewrite EQ. Qed.a, b:ta == b -> testbit a === testbit b
In fact, checking the bits at positive indexes is enough.
forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == bforall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == ba, b:tH:forall n : t, 0 <= n -> a.[n] = b.[n]a == ba, b:tH:forall n : t, 0 <= n -> a.[n] = b.[n]testbit a === testbit ba, b:tH:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]n:ta.[n] = b.[n]a, b:tH:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]n:tH0:0 <= na.[n] = b.[n]a, b:tH:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]n:tH0:n < 0a.[n] = b.[n]now rewrite 2 testbit_neg_r. Qed.a, b:tH:forall n0 : t, 0 <= n0 -> a.[n0] = b.[n0]n:tH0:n < 0a.[n] = b.[n]forall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) <-> a == bforall a b : t, (forall n : t, 0 <= n -> a.[n] = b.[n]) <-> a == ba, b:t(forall n : t, 0 <= n -> a.[n] = b.[n]) -> a == ba, b:ta == b -> forall n : t, 0 <= n -> a.[n] = b.[n]intros EQ n Hn; now rewrite EQ. Qed. Ltac bitwise := apply bits_inj'; intros ?m ?Hm; autorewrite with bitwise. Hint Rewrite lxor_spec lor_spec land_spec ldiff_spec bits_0 : bitwise.a, b:ta == b -> forall n : t, 0 <= n -> a.[n] = b.[n]
The streams of bits that correspond to a numbers are
exactly the ones which are stationary after some point.
forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists n : t, forall m : t, 0 <= m -> f m = n.[m]) <-> (exists k : t, forall m : t, k <= m -> f m = f k)f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists n : t, forall m : t, 0 <= m -> f m = n.[m]) -> exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:0 <= aexists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:0 <= aforall m : t, S (log2 a) <= m -> f m = f (S (log2 a))f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:0 <= am:tHm:S (log2 a) <= mf m = f (S (log2 a))f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:0 <= am:tHm:log2 a < mf m = f (S (log2 a))f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:0 <= am:tHm:log2 a < m0 <= S (log2 a)f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:0 <= am:tHm:log2 a < m0 <= mf:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:0 <= am:tHm:log2 a < m0 <= mf:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0exists k : t, forall m : t, k <= m -> f m = f kf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m : t, 0 <= m -> f m = a.[m]H0:a < 0forall m : t, S (log2 (P (- a))) <= m -> f m = f (S (log2 (P (- a))))f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:a < 0m:tHm:S (log2 (P (- a))) <= mf m = f (S (log2 (P (- a))))f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:a < 0m:tHm:log2 (P (- a)) < mf m = f (S (log2 (P (- a))))f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:a < 0m:tHm:log2 (P (- a)) < m0 <= S (log2 (P (- a)))f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:a < 0m:tHm:log2 (P (- a)) < m0 <= mf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fa:tH:forall m0 : t, 0 <= m0 -> f m0 = a.[m0]H0:a < 0m:tHm:log2 (P (- a)) < m0 <= mf:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) f(exists k : t, forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0exists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = trueexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = trueforall m : t, 0 <= m -> f m = (-1).[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = truem:tHm:0 <= mf m = (-1).[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = truem:tHm:0 <= mf k = truef:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = truem:tHm:0 <= mf 0 = f kf:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLT:k < 0H0:f 0 = falseforall m : t, 0 <= m -> f m = 0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = falsem:tHm:0 <= mf m = 0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = falsem:tHm:0 <= mf k = falsef:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m0 : t, k <= m0 -> f m0 = f kLT:k < 0H0:f 0 = falsem:tHm:0 <= mf 0 = f kf:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fk:tHk:forall m : t, k <= m -> f m = f kLE:0 <= kexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m](* compat : solve_proper fails here *)k:tLE:0 <= kProper (eq ==> iff) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kSymmetric eqk:tLE:0 <= kProper (eq ==> Basics.impl) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kProper (eq ==> Basics.impl) (fun k0 : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k0 <= m -> f m = f k0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]Proper (eq ==> Basics.impl) (fun k : t => forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, k <= m -> f m = f k) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m])k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k, k':tHk:k == k'IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fH:forall m : t, k' <= m -> f m = f k'exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k, k':tHk:k == k'IH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fH:forall m : t, k' <= m -> f m = f k'forall m : t, k <= m -> f m = f kk:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0](* /compat *)k:tLE:0 <= kforall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m : t, 0 <= m -> f m = f 0) -> exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = f 0exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = trueexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = trueforall m : t, 0 <= m -> f m = (-1).[m]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m0 : t, 0 <= m0 -> f m0 = truem:tHm:0 <= mf m = (-1).[m]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = falseexists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m : t, 0 <= m -> f m = falseforall m : t, 0 <= m -> f m = 0.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kf:t -> boolHf:Proper (eq ==> Logic.eq) fH0:forall m0 : t, 0 <= m0 -> f m0 = falsem:tHm:0 <= mf m = 0.[m]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kforall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]forall m : t, 0 <= m -> (forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, m <= m0 -> f m0 = f m) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]) -> forall f : t -> bool, Proper (eq ==> Logic.eq) f -> (forall m0 : t, S m <= m0 -> f m0 = f (S m)) -> exists n : t, forall m0 : t, 0 <= m0 -> f m0 = n.[m0]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)exists n : t, forall m : t, 0 <= m -> f m = n.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)Proper (eq ==> Logic.eq) (fun m : t => f (S m))k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)forall m : t, k <= m -> f (S m) = f (S k)k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n : t, forall m : t, 0 <= m -> f0 m = n.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)forall m : t, k <= m -> f (S m) = f (S k)k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n : t, forall m0 : t, 0 <= m0 -> f0 m0 = n.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)m:tHm:k <= mf (S m) = f (S k)k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n : t, forall m0 : t, 0 <= m0 -> f0 m0 = n.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)m:tHm:k <= mS k <= S mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]exists n0 : t, forall m : t, 0 <= m -> f m = n0.[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m : t, k <= m -> f0 m = f0 k) -> exists n0 : t, forall m : t, 0 <= m -> f0 m = n0.[m]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m : t, S k <= m -> f m = f (S k)n:tHn:forall m : t, 0 <= m -> f (S m) = n.[m]forall m : t, 0 <= m -> f m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 <= mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < mn.[P m] = ((f 0 + 2 * n) / 2).[P m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m2 ~= 0k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 < m0 <= P mk:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf m = (f 0 + 2 * n).[m]k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == mf 0 = (f 0 + 2 * n).[0]apply add_b2z_double_bit0. Qed.k:tLE:0 <= kIH:forall f0 : t -> bool, Proper (eq ==> Logic.eq) f0 -> (forall m0 : t, k <= m0 -> f0 m0 = f0 k) -> exists n0 : t, forall m0 : t, 0 <= m0 -> f0 m0 = n0.[m0]f:t -> boolHf:Proper (eq ==> Logic.eq) fHk:forall m0 : t, S k <= m0 -> f m0 = f (S k)n:tHn:forall m0 : t, 0 <= m0 -> f (S m0) = n.[m0]m:tHm:0 == m(f 0 + 2 * n).[0] = f 0
First, a unified specification for shiftl : the shiftl_spec
below (combined with testbit_neg_r) is equivalent to
shiftl_spec_low and shiftl_spec_high.
forall a n m : t, 0 <= m -> (a << n).[m] = a.[m - n]forall a n m : t, 0 <= m -> (a << n).[m] = a.[m - n]a, n, m:tH:0 <= m(a << n).[m] = a.[m - n]a, n, m:tH:0 <= mH0:n <= m(a << n).[m] = a.[m - n]a, n, m:tH:0 <= mH0:m < n(a << n).[m] = a.[m - n]a, n, m:tH:0 <= mH0:m < n(a << n).[m] = a.[m - n]now apply lt_sub_0. Qed.a, n, m:tH:0 <= mH0:m < nm - n < 0
A shiftl by a negative number is a shiftr, and vice-versa
forall a n : t, a >> (- n) == a << nforall a n : t, a >> (- n) == a << na, n:ta >> (- n) == a << nnow rewrite shiftr_spec, shiftl_spec, add_opp_r. Qed.a, n, m:tHm:0 <= m(a >> (- n)).[m] = (a << n).[m]forall a n : t, a << (- n) == a >> nforall a n : t, a << (- n) == a >> na, n:ta << (- n) == a >> nnow rewrite shiftr_spec, shiftl_spec, sub_opp_r. Qed.a, n, m:tHm:0 <= m(a << (- n)).[m] = (a >> n).[m]
Shifts correspond to multiplication or division by a power of two
forall a n : t, 0 <= n -> a >> n == a / 2 ^ nforall a n : t, 0 <= n -> a >> n == a / 2 ^ na, n:tH:0 <= na >> n == a / 2 ^ nnow rewrite shiftr_spec, div_pow2_bits. Qed.a, n:tH:0 <= nm:tHm:0 <= m(a >> n).[m] = (a / 2 ^ n).[m]forall a n : t, n <= 0 -> a >> n == a * 2 ^ (- n)forall a n : t, n <= 0 -> a >> n == a * 2 ^ (- n)a, n:tH:n <= 0a >> n == a * 2 ^ (- n)a, n:tH:n <= 0m:tHm:0 <= m(a >> n).[m] = (a * 2 ^ (- n)).[m]a, n:tH:n <= 0m:tHm:0 <= ma.[m + n] = a.[m - - n]a, n:tH:n <= 0m:tHm:0 <= m0 <= - nnow apply opp_nonneg_nonpos. Qed.a, n:tH:n <= 0m:tHm:0 <= m0 <= - nforall a n : t, 0 <= n -> a << n == a * 2 ^ nforall a n : t, 0 <= n -> a << n == a * 2 ^ na, n:tH:0 <= na << n == a * 2 ^ nnow rewrite shiftl_spec, mul_pow2_bits. Qed.a, n:tH:0 <= nm:tHm:0 <= m(a << n).[m] = (a * 2 ^ n).[m]forall a n : t, n <= 0 -> a << n == a / 2 ^ (- n)forall a n : t, n <= 0 -> a << n == a / 2 ^ (- n)a, n:tH:n <= 0a << n == a / 2 ^ (- n)a, n:tH:n <= 0m:tHm:0 <= m(a << n).[m] = (a / 2 ^ (- n)).[m]a, n:tH:n <= 0m:tHm:0 <= ma.[m - n] = a.[m + - n]a, n:tH:n <= 0m:tHm:0 <= m0 <= - nnow apply opp_nonneg_nonpos. Qed.a, n:tH:n <= 0m:tHm:0 <= m0 <= - n
Shifts are morphisms
Proper (eq ==> eq ==> eq) shiftrProper (eq ==> eq ==> eq) shiftra, a':tHa:a == a'n, n':tHn:n == n'a >> n == a' >> n'a, a':tHa:a == a'n, n':tHn:n == n'H:n <= 0H':n' <= 0a >> n == a' >> n'a, a':tHa:a == a'n, n':tHn:n == n'H:0 <= nH':0 <= n'a >> n == a' >> n'now rewrite 2 shiftr_div_pow2, Ha, Hn. Qed.a, a':tHa:a == a'n, n':tHn:n == n'H:0 <= nH':0 <= n'a >> n == a' >> n'Proper (eq ==> eq ==> eq) shiftlProper (eq ==> eq ==> eq) shiftlnow rewrite <- 2 shiftr_opp_r, Ha, Hn. Qed.a, a':tHa:a == a'n, n':tHn:n == n'a << n == a' << n'
We could also have specified shiftl with an addition on the left.
forall a n m : t, 0 <= n -> (a << n).[m + n] = a.[m]forall a n m : t, 0 <= n -> (a << n).[m + n] = a.[m]now rewrite shiftl_mul_pow2, mul_pow2_bits, add_simpl_r. Qed.a, n, m:tH:0 <= n(a << n).[m + n] = a.[m]
Chaining several shifts. The only case for which
there isn't any simple expression is a true shiftr
followed by a true shiftl.
forall a n m : t, 0 <= n -> (a << n) << m == a << (n + m)forall a n m : t, 0 <= n -> (a << n) << m == a << (n + m)a, n, p:tHn:0 <= n(a << n) << p == a << (n + p)a, n, p:tHn:0 <= nm:tHm:0 <= m((a << n) << p).[m] = (a << (n + p)).[m]a, n, p:tHn:0 <= nm:tHm:0 <= m(a << n).[m - p] = a.[m - (n + p)]a, n, p:tHn:0 <= nm:tHm:0 <= m(a << n).[m - p] = a.[m - p - n]a, n, p:tHn:0 <= nm:tHm:0 <= mH:0 <= m - p(a << n).[m - p] = a.[m - p - n]a, n, p:tHn:0 <= nm:tHm:0 <= mH:m - p < 0(a << n).[m - p] = a.[m - p - n]a, n, p:tHn:0 <= nm:tHm:0 <= mH:m - p < 0(a << n).[m - p] = a.[m - p - n]a, n, p:tHn:0 <= nm:tHm:0 <= mH:m - p < 0m - p - n < 0now apply lt_le_trans with 0. Qed.a, n, p:tHn:0 <= nm:tHm:0 <= mH:m - p < 0m - p < nforall a n m : t, 0 <= n -> (a << n) >> m == a << (n - m)forall a n m : t, 0 <= n -> (a << n) >> m == a << (n - m)now rewrite <- shiftl_opp_r, shiftl_shiftl, add_opp_r. Qed.a, n, m:tH:0 <= n(a << n) >> m == a << (n - m)forall a n m : t, 0 <= n -> (a << n) >> m == a >> (m - n)forall a n m : t, 0 <= n -> (a << n) >> m == a >> (m - n)now rewrite <- 2 shiftl_opp_r, shiftl_shiftl, opp_sub_distr, add_comm. Qed.a, n, m:tH:0 <= n(a << n) >> m == a >> (m - n)forall a n m : t, 0 <= m -> (a >> n) >> m == a >> (n + m)forall a n m : t, 0 <= m -> (a >> n) >> m == a >> (n + m)a, n, p:tHn:0 <= p(a >> n) >> p == a >> (n + p)a, n, p:tHn:0 <= pm:tHm:0 <= m((a >> n) >> p).[m] = (a >> (n + p)).[m]a, n, p:tHn:0 <= pm:tHm:0 <= ma.[m + p + n] = a.[m + (n + p)]a, n, p:tHn:0 <= pm:tHm:0 <= m0 <= m + pnow apply add_nonneg_nonneg. Qed.a, n, p:tHn:0 <= pm:tHm:0 <= m0 <= m + p
shifts and constants
forall n : t, 1 << n == 2 ^ nforall n : t, 1 << n == 2 ^ nn:t1 << n == 2 ^ nn:tH:0 <= n1 << n == 2 ^ nn:tH:n < 01 << n == 2 ^ nn:tH:n < 01 << n == 2 ^ nn:tH:n < 01 < 2 ^ (- n)n:tH:n < 01 < 2n:tH:n < 00 < - nnow apply opp_pos_neg. Qed.n:tH:n < 00 < - nforall a : t, a << 0 == aforall a : t, a << 0 == aa:ta << 0 == anow nzsimpl. Qed.a:ta * 2 ^ 0 == aforall a : t, a >> 0 == aforall a : t, a >> 0 == anow rewrite <- shiftl_opp_r, opp_0, shiftl_0_r. Qed.a:ta >> 0 == aforall n : t, 0 << n == 0forall n : t, 0 << n == 0n:t0 << n == 0n:tH:0 <= n0 << n == 0n:tH:n <= 00 << n == 0n:tH:0 <= n0 * 2 ^ n == 0n:tH:n <= 00 << n == 0n:tH:n <= 00 << n == 0n:tH:n <= 00 / 2 ^ (- n) == 0nzsimpl; order_nz. Qed.n:tH:0 <= - n0 / 2 ^ (- n) == 0forall n : t, 0 >> n == 0forall n : t, 0 >> n == 0now rewrite <- shiftl_opp_r, shiftl_0_l. Qed.n:t0 >> n == 0forall a n : t, 0 <= n -> a << n == 0 <-> a == 0forall a n : t, 0 <= n -> a << n == 0 <-> a == 0a, n:tHn:0 <= na << n == 0 <-> a == 0a, n:tHn:0 <= na * 2 ^ n == 0 <-> a == 0a, n:tHn:0 <= na == 0 \/ 2 ^ n == 0 <-> a == 0a, n:tHn:0 <= na == 0 \/ 2 ^ n == 0 -> a == 0a, n:tHn:0 <= na == 0 -> a == 0 \/ 2 ^ n == 0a, n:tHn:0 <= nH:2 ^ n == 0a == 0a, n:tHn:0 <= na == 0 -> a == 0 \/ 2 ^ n == 0a, n:tHn:0 <= na == 0 -> a == 0 \/ 2 ^ n == 0now left. Qed.a, n:tHn:0 <= nH:a == 0a == 0 \/ 2 ^ n == 0forall a n : t, a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < nforall a n : t, a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:ta >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= na >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= n0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 -> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0H:0 <= aa == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0H:2 ^ n < aH':a <= 0a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0H:2 ^ n < aH':a <= 0a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:a < 0a == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0 <-> 0 == 0 \/ 0 < 0 /\ log2 0 < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0 -> 0 == 0 \/ 0 < 0 /\ log2 0 < na, n:tHn:0 <= nEQ:a == 00 == 0 \/ 0 < 0 /\ log2 0 < n -> 0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0a, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 == 0 \/ 0 < 0 /\ log2 0 < n -> 0 <= 0 < 2 ^ n \/ 2 ^ n < 0 <= 0a, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nEQ:a == 00 <= 0 < 2 ^ na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < a0 <= a < 2 ^ n \/ 2 ^ n < a <= 0 -> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aa == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aH:0 <= aH':a < 2 ^ n0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aH:2 ^ n < aH':a <= 00 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aa == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aH:0 <= aH':a < 2 ^ nlog2 a < na, n:tHn:0 <= nLT:0 < aH:2 ^ n < aH':a <= 00 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aa == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aH:2 ^ n < aH':a <= 00 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aa == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aa == 0 \/ 0 < a /\ log2 a < n -> 0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT:0 < aH:a == 00 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:0 <= nLT, H:0 < aH':log2 a < n0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT, H:0 < aH':log2 a < n0 <= a < 2 ^ n \/ 2 ^ n < a <= 0a, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT, H:0 < aH':log2 a < n0 <= a < 2 ^ na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT, H:0 < aH':log2 a < n0 <= aa, n:tHn:0 <= nLT, H:0 < aH':log2 a < na < 2 ^ na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:0 <= nLT, H:0 < aH':log2 a < na < 2 ^ na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a >> n == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a * 2 ^ (- n) == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0a == 0 \/ 2 ^ (- n) == 0 <-> a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0H:a == 0a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0H:2 ^ (- n) == 0a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0H:a == 0a == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:0 < a /\ log2 a < na == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:2 ^ (- n) == 0a == 0 \/ 0 < a /\ log2 a < na, n:tHn:n < 0H:a == 0a == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:0 < a /\ log2 a < na == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:a == 0a == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:0 < a /\ log2 a < na == 0 \/ 2 ^ (- n) == 0a, n:tHn:n < 0H:0 < a /\ log2 a < na == 0 \/ 2 ^ (- n) == 0generalize (log2_nonneg a); order. Qed.a, n:tHn:n < 0H:0 < aH0:log2 a < na == 0 \/ 2 ^ (- n) == 0forall a n : t, 0 <= a -> log2 a < n -> a >> n == 0forall a n : t, 0 <= a -> log2 a < n -> a >> n == 0a, n:tHa:0 <= aH:log2 a < na >> n == 0a, n:tHa:0 <= aH:log2 a < na == 0 \/ 0 < a /\ log2 a < na, n:tHa:0 < aH:log2 a < na == 0 \/ 0 < a /\ log2 a < na, n:tHa:0 == aH:log2 a < na == 0 \/ 0 < a /\ log2 a < na, n:tHa:0 < aH:log2 a < n0 < a /\ log2 a < na, n:tHa:0 == aH:log2 a < na == 0 \/ 0 < a /\ log2 a < nnow left. Qed.a, n:tHa:0 == aH:log2 a < na == 0 \/ 0 < a /\ log2 a < n
Properties of div2.
forall a : t, div2 a == a / 2forall a : t, div2 a == a / 2a:tdiv2 a == a / 2a:ta / 2 ^ 1 == a / 2a:t0 <= 1order'. Qed.a:t0 <= 1Proper (eq ==> eq) div2Proper (eq ==> eq) div2now rewrite 2 div2_div, Ha. Qed.a, a':tHa:a == a'div2 a == div2 a'forall a : t, a == 2 * div2 a + odd aforall a : t, a == 2 * div2 a + odd aa:ta == 2 * div2 a + odd aa:ta == 2 * (a / 2) + a mod 2order'. Qed.a:t2 ~= 0
Properties of lxor and others, directly deduced
from properties of xorb and others.
Proper (eq ==> eq ==> eq) lxorProper (eq ==> eq ==> eq) lxora, a':tHa:a == a'b, b':tHb:b == b'lxor a b == lxor a' b'now rewrite Ha, Hb. Qed.a, a':tHa:a == a'b, b':tHb:b == b'm:tHm:0 <= mxorb a.[m] b.[m] = xorb a'.[m] b'.[m]Proper (eq ==> eq ==> eq) landProper (eq ==> eq ==> eq) landa, a':tHa:a == a'b, b':tHb:b == b'land a b == land a' b'now rewrite Ha, Hb. Qed.a, a':tHa:a == a'b, b':tHb:b == b'm:tHm:0 <= ma.[m] && b.[m] = a'.[m] && b'.[m]Proper (eq ==> eq ==> eq) lorProper (eq ==> eq ==> eq) lora, a':tHa:a == a'b, b':tHb:b == b'lor a b == lor a' b'now rewrite Ha, Hb. Qed.a, a':tHa:a == a'b, b':tHb:b == b'm:tHm:0 <= ma.[m] || b.[m] = a'.[m] || b'.[m]Proper (eq ==> eq ==> eq) ldiffProper (eq ==> eq ==> eq) ldiffa, a':tHa:a == a'b, b':tHb:b == b'ldiff a b == ldiff a' b'now rewrite Ha, Hb. Qed.a, a':tHa:a == a'b, b':tHb:b == b'm:tHm:0 <= ma.[m] && negb b.[m] = a'.[m] && negb b'.[m]forall a a' : t, lxor a a' == 0 -> a == a'forall a a' : t, lxor a a' == 0 -> a == a'a, a':tH:lxor a a' == 0a == a'a, a':tH:lxor a a' == 0m:tHm:0 <= ma.[m] = a'.[m]now rewrite <- lxor_spec, H, bits_0. Qed.a, a':tH:lxor a a' == 0m:tHm:0 <= mxorb a.[m] a'.[m] = falseforall a : t, lxor a a == 0forall a : t, lxor a a == 0a:tlxor a a == 0apply xorb_nilpotent. Qed.a, m:tHm:0 <= mxorb a.[m] a.[m] = falseforall a a' : t, lxor a a' == 0 <-> a == a'forall a a' : t, lxor a a' == 0 <-> a == a'a, a':tlxor a a' == 0 -> a == a'a, a':ta == a' -> lxor a a' == 0intros EQ; rewrite EQ; apply lxor_nilpotent. Qed.a, a':ta == a' -> lxor a a' == 0forall a : t, lxor 0 a == aforall a : t, lxor 0 a == aa:tlxor 0 a == aapply xorb_false_l. Qed.a, m:tHm:0 <= mxorb false a.[m] = a.[m]forall a : t, lxor a 0 == aforall a : t, lxor a 0 == aa:tlxor a 0 == aapply xorb_false_r. Qed.a, m:tHm:0 <= mxorb a.[m] false = a.[m]forall a b : t, lxor a b == lxor b aforall a b : t, lxor a b == lxor b aa, b:tlxor a b == lxor b aapply xorb_comm. Qed.a, b, m:tHm:0 <= mxorb a.[m] b.[m] = xorb b.[m] a.[m]forall a b c : t, lxor (lxor a b) c == lxor a (lxor b c)forall a b c : t, lxor (lxor a b) c == lxor a (lxor b c)a, b, c:tlxor (lxor a b) c == lxor a (lxor b c)apply xorb_assoc. Qed.a, b, c, m:tHm:0 <= mxorb (xorb a.[m] b.[m]) c.[m] = xorb a.[m] (xorb b.[m] c.[m])forall a : t, lor 0 a == aforall a : t, lor 0 a == aa:tlor 0 a == atrivial. Qed.a, m:tHm:0 <= mfalse || a.[m] = a.[m]forall a : t, lor a 0 == aforall a : t, lor a 0 == aa:tlor a 0 == aapply orb_false_r. Qed.a, m:tHm:0 <= ma.[m] || false = a.[m]forall a b : t, lor a b == lor b aforall a b : t, lor a b == lor b aa, b:tlor a b == lor b aapply orb_comm. Qed.a, b, m:tHm:0 <= ma.[m] || b.[m] = b.[m] || a.[m]forall a b c : t, lor a (lor b c) == lor (lor a b) cforall a b c : t, lor a (lor b c) == lor (lor a b) ca, b, c:tlor a (lor b c) == lor (lor a b) capply orb_assoc. Qed.a, b, c, m:tHm:0 <= ma.[m] || (b.[m] || c.[m]) = a.[m] || b.[m] || c.[m]forall a : t, lor a a == aforall a : t, lor a a == aa:tlor a a == aapply orb_diag. Qed.a, m:tHm:0 <= ma.[m] || a.[m] = a.[m]forall a b : t, lor a b == 0 -> a == 0forall a b : t, lor a b == 0 -> a == 0a, b:tH:lor a b == 0a == 0a, b:tH:lor a b == 0m:tHm:0 <= ma.[m] = falsenow rewrite <- lor_spec, H, bits_0. Qed.a, b:tH:lor a b == 0m:tHm:0 <= ma.[m] || b.[m] = falseforall a b : t, lor a b == 0 <-> a == 0 /\ b == 0forall a b : t, lor a b == 0 <-> a == 0 /\ b == 0a, b:tlor a b == 0 <-> a == 0 /\ b == 0a, b:tlor a b == 0 -> a == 0 /\ b == 0a, b:ta == 0 /\ b == 0 -> lor a b == 0a, b:tH:lor a b == 0a == 0a, b:tH:lor a b == 0b == 0a, b:ta == 0 /\ b == 0 -> lor a b == 0a, b:tH:lor a b == 0b == 0a, b:ta == 0 /\ b == 0 -> lor a b == 0a, b:tH:lor b a == 0b == 0a, b:ta == 0 /\ b == 0 -> lor a b == 0a, b:ta == 0 /\ b == 0 -> lor a b == 0now rewrite EQ, lor_0_l. Qed.a, b:tEQ:a == 0EQ':b == 0lor a b == 0forall a : t, land 0 a == 0forall a : t, land 0 a == 0a:tland 0 a == 0trivial. Qed.a, m:tHm:0 <= mfalse && a.[m] = falseforall a : t, land a 0 == 0forall a : t, land a 0 == 0a:tland a 0 == 0apply andb_false_r. Qed.a, m:tHm:0 <= ma.[m] && false = falseforall a b : t, land a b == land b aforall a b : t, land a b == land b aa, b:tland a b == land b aapply andb_comm. Qed.a, b, m:tHm:0 <= ma.[m] && b.[m] = b.[m] && a.[m]forall a b c : t, land a (land b c) == land (land a b) cforall a b c : t, land a (land b c) == land (land a b) ca, b, c:tland a (land b c) == land (land a b) capply andb_assoc. Qed.a, b, c, m:tHm:0 <= ma.[m] && (b.[m] && c.[m]) = a.[m] && b.[m] && c.[m]forall a : t, land a a == aforall a : t, land a a == aa:tland a a == aapply andb_diag. Qed.a, m:tHm:0 <= ma.[m] && a.[m] = a.[m]forall a : t, ldiff 0 a == 0forall a : t, ldiff 0 a == 0a:tldiff 0 a == 0trivial. Qed.a, m:tHm:0 <= mfalse && negb a.[m] = falseforall a : t, ldiff a 0 == aforall a : t, ldiff a 0 == aa:tldiff a 0 == anow rewrite andb_true_r. Qed.a, m:tHm:0 <= ma.[m] && negb false = a.[m]forall a : t, ldiff a a == 0forall a : t, ldiff a a == 0a:tldiff a a == 0apply andb_negb_r. Qed.a, m:tHm:0 <= ma.[m] && negb a.[m] = falseforall a b c : t, lor (land a b) c == land (lor a c) (lor b c)forall a b c : t, lor (land a b) c == land (lor a c) (lor b c)a, b, c:tlor (land a b) c == land (lor a c) (lor b c)apply orb_andb_distrib_l. Qed.a, b, c, m:tHm:0 <= ma.[m] && b.[m] || c.[m] = (a.[m] || c.[m]) && (b.[m] || c.[m])forall a b c : t, lor a (land b c) == land (lor a b) (lor a c)forall a b c : t, lor a (land b c) == land (lor a b) (lor a c)a, b, c:tlor a (land b c) == land (lor a b) (lor a c)apply orb_andb_distrib_r. Qed.a, b, c, m:tHm:0 <= ma.[m] || b.[m] && c.[m] = (a.[m] || b.[m]) && (a.[m] || c.[m])forall a b c : t, land (lor a b) c == lor (land a c) (land b c)forall a b c : t, land (lor a b) c == lor (land a c) (land b c)a, b, c:tland (lor a b) c == lor (land a c) (land b c)apply andb_orb_distrib_l. Qed.a, b, c, m:tHm:0 <= m(a.[m] || b.[m]) && c.[m] = a.[m] && c.[m] || b.[m] && c.[m]forall a b c : t, land a (lor b c) == lor (land a b) (land a c)forall a b c : t, land a (lor b c) == lor (land a b) (land a c)a, b, c:tland a (lor b c) == lor (land a b) (land a c)apply andb_orb_distrib_r. Qed.a, b, c, m:tHm:0 <= ma.[m] && (b.[m] || c.[m]) = a.[m] && b.[m] || a.[m] && c.[m]forall a b c : t, ldiff (ldiff a b) c == ldiff a (lor b c)forall a b c : t, ldiff (ldiff a b) c == ldiff a (lor b c)a, b, c:tldiff (ldiff a b) c == ldiff a (lor b c)now rewrite negb_orb, andb_assoc. Qed.a, b, c, m:tHm:0 <= ma.[m] && negb b.[m] && negb c.[m] = a.[m] && negb (b.[m] || c.[m])forall a b : t, lor (ldiff a b) (land a b) == aforall a b : t, lor (ldiff a b) (land a b) == aa, b:tlor (ldiff a b) (land a b) == anow rewrite <- andb_orb_distrib_r, orb_comm, orb_negb_r, andb_true_r. Qed.a, b, m:tHm:0 <= ma.[m] && negb b.[m] || a.[m] && b.[m] = a.[m]forall a b : t, land (ldiff a b) b == 0forall a b : t, land (ldiff a b) b == 0a, b:tland (ldiff a b) b == 0now rewrite <-andb_assoc, (andb_comm (negb _)), andb_negb_r, andb_false_r. Qed.a, b, m:tHm:0 <= ma.[m] && negb b.[m] && b.[m] = false
Properties of setbit and clearbit
Definition setbit a n := lor a (1 << n). Definition clearbit a n := ldiff a (1 << n).forall a n : t, setbit a n == lor a (2 ^ n)forall a n : t, setbit a n == lor a (2 ^ n)a, n:tsetbit a n == lor a (2 ^ n)now rewrite shiftl_1_l. Qed.a, n:tlor a (1 << n) == lor a (2 ^ n)forall a n : t, clearbit a n == ldiff a (2 ^ n)forall a n : t, clearbit a n == ldiff a (2 ^ n)a, n:tclearbit a n == ldiff a (2 ^ n)now rewrite shiftl_1_l. Qed.a, n:tldiff a (1 << n) == ldiff a (2 ^ n)Proper (eq ==> eq ==> eq) setbitProper (eq ==> eq ==> eq) setbitsolve_proper. Qed.Proper (eq ==> eq ==> eq) (fun a n : t => lor a (1 << n))Proper (eq ==> eq ==> eq) clearbitProper (eq ==> eq ==> eq) clearbitsolve_proper. Qed.Proper (eq ==> eq ==> eq) (fun a n : t => ldiff a (1 << n))forall n : t, 0 <= n -> (2 ^ n).[n] = trueforall n : t, 0 <= n -> (2 ^ n).[n] = truen:tH:0 <= n(2 ^ n).[n] = truenow rewrite mul_pow2_bits, sub_diag, bit0_odd, odd_1. Qed.n:tH:0 <= n(1 * 2 ^ n).[n] = trueforall n m : t, n ~= m -> (2 ^ n).[m] = falseforall n m : t, n ~= m -> (2 ^ n).[m] = falsen, m:tH:n ~= m(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= n(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= m(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= m1.[m - n] = falsen, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= m(1 / 2).[P (m - n)] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= m0 <= P (m - n)n, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= m0 <= P (m - n)n, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falsen, m:tH:n ~= mH0:0 <= nH1:n <= mn < mn, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falserewrite <- (mul_1_l (2^n)), mul_pow2_bits_low; trivial. Qed.n, m:tH:n ~= mH0:0 <= nH1:m < n(2 ^ n).[m] = falseforall n m : t, 0 <= n -> (2 ^ n).[m] = (n =? m)forall n m : t, 0 <= n -> (2 ^ n).[m] = (n =? m)n, m:tHn:0 <= n(2 ^ n).[m] = (n =? m)n, m:tHn:0 <= n(2 ^ n).[m] = true <-> (n =? m) = truen, m:tHn:0 <= n(2 ^ n).[m] = true <-> n == mn, m:tHn:0 <= n(2 ^ n).[m] = true -> n == mn, m:tHn:0 <= nn == m -> (2 ^ n).[m] = truen, m:tHn:0 <= nH:n == m(2 ^ n).[m] = true -> n == mn, m:tHn:0 <= nH:n ~= m(2 ^ n).[m] = true -> n == mn, m:tHn:0 <= nn == m -> (2 ^ n).[m] = truen, m:tHn:0 <= nH:n ~= m(2 ^ n).[m] = true -> n == mn, m:tHn:0 <= nn == m -> (2 ^ n).[m] = truen, m:tHn:0 <= nn == m -> (2 ^ n).[m] = truen, m:tHn:0 <= nEQ:n == m(2 ^ n).[m] = trueapply pow2_bits_true; order. Qed.n, m:tHn:0 <= nEQ:n == m(2 ^ m).[m] = trueforall a n m : t, 0 <= n -> (setbit a n).[m] = (n =? m) || a.[m]forall a n m : t, 0 <= n -> (setbit a n).[m] = (n =? m) || a.[m]now rewrite setbit_spec', lor_spec, pow2_bits_eqb, orb_comm. Qed.a, n, m:tH:0 <= n(setbit a n).[m] = (n =? m) || a.[m]forall a n m : t, 0 <= n -> (setbit a n).[m] = true <-> n == m \/ a.[m] = trueforall a n m : t, 0 <= n -> (setbit a n).[m] = true <-> n == m \/ a.[m] = truenow rewrite setbit_eqb, orb_true_iff, eqb_eq. Qed.a, n, m:tH:0 <= n(setbit a n).[m] = true <-> n == m \/ a.[m] = trueforall a n : t, 0 <= n -> (setbit a n).[n] = trueforall a n : t, 0 <= n -> (setbit a n).[n] = truea, n:tH:0 <= n(setbit a n).[n] = truenow left. Qed.a, n:tH:0 <= nn == n \/ a.[n] = trueforall a n m : t, 0 <= n -> n ~= m -> (setbit a n).[m] = a.[m]forall a n m : t, 0 <= n -> n ~= m -> (setbit a n).[m] = a.[m]a, n, m:tHn:0 <= nH:n ~= m(setbit a n).[m] = a.[m]a, n, m:tHn:0 <= nH:n ~= m(n =? m) || a.[m] = a.[m]a, n, m:tHn:0 <= nH:(n =? m) <> true(n =? m) || a.[m] = a.[m]now rewrite H. Qed.a, n, m:tHn:0 <= nH:(n =? m) = false(n =? m) || a.[m] = a.[m]forall a n m : t, (clearbit a n).[m] = a.[m] && negb (n =? m)forall a n m : t, (clearbit a n).[m] = a.[m] && negb (n =? m)a, n, m:t(clearbit a n).[m] = a.[m] && negb (n =? m)a, n, m:tH:0 <= m(clearbit a n).[m] = a.[m] && negb (n =? m)a, n, m:tH:0 <= ma.[m] && negb (2 ^ n).[m] = a.[m] && negb (n =? m)a, n, m:tH:0 <= mnegb (2 ^ n).[m] = negb (n =? m)a, n, m:tH:0 <= m(2 ^ n).[m] = (n =? m)a, n, m:tH:0 <= mHn:0 <= n(2 ^ n).[m] = (n =? m)a, n, m:tH:0 <= mHn:n < 0(2 ^ n).[m] = (n =? m)a, n, m:tH:0 <= mHn:n < 0(2 ^ n).[m] = (n =? m)rewrite pow_neg_r, bits_0, <- not_true_iff_false, eqb_eq; order. Qed.a, n, m:tH:0 <= mHn:n < 0(n =? m) = (2 ^ n).[m]forall a n m : t, (clearbit a n).[m] = true <-> a.[m] = true /\ n ~= mforall a n m : t, (clearbit a n).[m] = true <-> a.[m] = true /\ n ~= ma, n, m:t(clearbit a n).[m] = true <-> a.[m] = true /\ n ~= mnow rewrite negb_true_iff, not_true_iff_false. Qed.a, n, m:ta.[m] = true /\ negb (n =? m) = true <-> a.[m] = true /\ (n =? m) <> trueforall a n : t, (clearbit a n).[n] = falseforall a n : t, (clearbit a n).[n] = falsea, n:t(clearbit a n).[n] = falseapply andb_false_r. Qed.a, n:ta.[n] && negb true = falseforall a n m : t, n ~= m -> (clearbit a n).[m] = a.[m]forall a n m : t, n ~= m -> (clearbit a n).[m] = a.[m]a, n, m:tH:n ~= m(clearbit a n).[m] = a.[m]a, n, m:tH:n ~= ma.[m] && negb (n =? m) = a.[m]a, n, m:tH:(n =? m) <> truea.[m] && negb (n =? m) = a.[m]a, n, m:tH:(n =? m) = falsea.[m] && negb (n =? m) = a.[m]apply andb_true_r. Qed.a, n, m:tH:(n =? m) = falsea.[m] && negb false = a.[m]
Shifts of bitwise operations
forall a b n : t, lxor a b << n == lxor (a << n) (b << n)forall a b n : t, lxor a b << n == lxor (a << n) (b << n)a, b, n:tlxor a b << n == lxor (a << n) (b << n)now rewrite !shiftl_spec, lxor_spec. Qed.a, b, n, m:tHm:0 <= m(lxor a b << n).[m] = xorb (a << n).[m] (b << n).[m]forall a b n : t, lxor a b >> n == lxor (a >> n) (b >> n)forall a b n : t, lxor a b >> n == lxor (a >> n) (b >> n)a, b, n:tlxor a b >> n == lxor (a >> n) (b >> n)now rewrite !shiftr_spec, lxor_spec. Qed.a, b, n, m:tHm:0 <= m(lxor a b >> n).[m] = xorb (a >> n).[m] (b >> n).[m]forall a b n : t, land a b << n == land (a << n) (b << n)forall a b n : t, land a b << n == land (a << n) (b << n)a, b, n:tland a b << n == land (a << n) (b << n)now rewrite !shiftl_spec, land_spec. Qed.a, b, n, m:tHm:0 <= m(land a b << n).[m] = (a << n).[m] && (b << n).[m]forall a b n : t, land a b >> n == land (a >> n) (b >> n)forall a b n : t, land a b >> n == land (a >> n) (b >> n)a, b, n:tland a b >> n == land (a >> n) (b >> n)now rewrite !shiftr_spec, land_spec. Qed.a, b, n, m:tHm:0 <= m(land a b >> n).[m] = (a >> n).[m] && (b >> n).[m]forall a b n : t, lor a b << n == lor (a << n) (b << n)forall a b n : t, lor a b << n == lor (a << n) (b << n)a, b, n:tlor a b << n == lor (a << n) (b << n)now rewrite !shiftl_spec, lor_spec. Qed.a, b, n, m:tHm:0 <= m(lor a b << n).[m] = (a << n).[m] || (b << n).[m]forall a b n : t, lor a b >> n == lor (a >> n) (b >> n)forall a b n : t, lor a b >> n == lor (a >> n) (b >> n)a, b, n:tlor a b >> n == lor (a >> n) (b >> n)now rewrite !shiftr_spec, lor_spec. Qed.a, b, n, m:tHm:0 <= m(lor a b >> n).[m] = (a >> n).[m] || (b >> n).[m]forall a b n : t, ldiff a b << n == ldiff (a << n) (b << n)forall a b n : t, ldiff a b << n == ldiff (a << n) (b << n)a, b, n:tldiff a b << n == ldiff (a << n) (b << n)now rewrite !shiftl_spec, ldiff_spec. Qed.a, b, n, m:tHm:0 <= m(ldiff a b << n).[m] = (a << n).[m] && negb (b << n).[m]forall a b n : t, ldiff a b >> n == ldiff (a >> n) (b >> n)forall a b n : t, ldiff a b >> n == ldiff (a >> n) (b >> n)a, b, n:tldiff a b >> n == ldiff (a >> n) (b >> n)now rewrite !shiftr_spec, ldiff_spec. Qed.a, b, n, m:tHm:0 <= m(ldiff a b >> n).[m] = (a >> n).[m] && negb (b >> n).[m]
For integers, we do have a binary complement function
Definition lnot a := P (-a).Proper (eq ==> eq) lnotProper (eq ==> eq) lnotsolve_proper. Qed.Proper (eq ==> eq) (fun a : t => P (- a))forall a n : t, 0 <= n -> (lnot a).[n] = negb a.[n]forall a n : t, 0 <= n -> (lnot a).[n] = negb a.[n]a, n:tH:0 <= n(lnot a).[n] = negb a.[n]a, n:tH:0 <= n(P (- a)).[n] = negb a.[n]rewrite bits_opp, negb_involutive; trivial. Qed.a, n:tH:0 <= n(P (- a)).[n] = negb (- - a).[n]forall a : t, lnot (lnot a) == aforall a : t, lnot (lnot a) == aa:tlnot (lnot a) == anow rewrite 2 lnot_spec, negb_involutive. Qed.a, m:tHm:0 <= m(lnot (lnot a)).[m] = a.[m]lnot 0 == -1lnot 0 == -1now rewrite opp_0, <- sub_1_r, sub_0_l. Qed.P (- 0) == -1lnot (-1) == 0lnot (-1) == 0now rewrite opp_involutive, one_succ, pred_succ. Qed.P (- -1) == 0
Complement and other operations
forall a : t, lor a (-1) == -1forall a : t, lor a (-1) == -1a:tlor a (-1) == -1now rewrite bits_m1, orb_true_r. Qed.a, m:tHm:0 <= ma.[m] || (-1).[m] = (-1).[m]forall a : t, lor (-1) a == -1forall a : t, lor (-1) a == -1now rewrite lor_comm, lor_m1_r. Qed.a:tlor (-1) a == -1forall a : t, land a (-1) == aforall a : t, land a (-1) == aa:tland a (-1) == anow rewrite bits_m1, andb_true_r. Qed.a, m:tHm:0 <= ma.[m] && (-1).[m] = a.[m]forall a : t, land (-1) a == aforall a : t, land (-1) a == anow rewrite land_comm, land_m1_r. Qed.a:tland (-1) a == aforall a : t, ldiff a (-1) == 0forall a : t, ldiff a (-1) == 0a:tldiff a (-1) == 0now rewrite bits_m1, andb_false_r. Qed.a, m:tHm:0 <= ma.[m] && negb (-1).[m] = falseforall a : t, ldiff (-1) a == lnot aforall a : t, ldiff (-1) a == lnot aa:tldiff (-1) a == lnot anow rewrite lnot_spec, bits_m1. Qed.a, m:tHm:0 <= m(-1).[m] && negb a.[m] = (lnot a).[m]forall a : t, lor a (lnot a) == -1forall a : t, lor a (lnot a) == -1a:tlor a (lnot a) == -1a, m:tHm:0 <= ma.[m] || (lnot a).[m] = (-1).[m]now destruct a.[m]. Qed.a, m:tHm:0 <= ma.[m] || negb a.[m] = trueforall a : t, a + lnot a == -1forall a : t, a + lnot a == -1a:ta + lnot a == -1now rewrite add_pred_r, add_opp_r, sub_diag, one_succ, opp_succ, opp_0. Qed.a:ta + P (- a) == -1forall a b : t, ldiff a b == land a (lnot b)forall a b : t, ldiff a b == land a (lnot b)a, b:tldiff a b == land a (lnot b)now rewrite lnot_spec. Qed.a, b, m:tHm:0 <= ma.[m] && negb b.[m] = a.[m] && (lnot b).[m]forall a : t, land a (lnot a) == 0forall a : t, land a (lnot a) == 0now rewrite <- ldiff_land, ldiff_diag. Qed.a:tland a (lnot a) == 0forall a b : t, lnot (lor a b) == land (lnot a) (lnot b)forall a b : t, lnot (lor a b) == land (lnot a) (lnot b)a, b:tlnot (lor a b) == land (lnot a) (lnot b)now rewrite !lnot_spec, lor_spec, negb_orb. Qed.a, b, m:tHm:0 <= m(lnot (lor a b)).[m] = (lnot a).[m] && (lnot b).[m]forall a b : t, lnot (land a b) == lor (lnot a) (lnot b)forall a b : t, lnot (land a b) == lor (lnot a) (lnot b)a, b:tlnot (land a b) == lor (lnot a) (lnot b)now rewrite !lnot_spec, land_spec, negb_andb. Qed.a, b, m:tHm:0 <= m(lnot (land a b)).[m] = (lnot a).[m] || (lnot b).[m]forall a b : t, lnot (ldiff a b) == lor (lnot a) bforall a b : t, lnot (ldiff a b) == lor (lnot a) ba, b:tlnot (ldiff a b) == lor (lnot a) bnow rewrite !lnot_spec, ldiff_spec, negb_andb, negb_involutive. Qed.a, b, m:tHm:0 <= m(lnot (ldiff a b)).[m] = (lnot a).[m] || b.[m]forall a b : t, lxor (lnot a) (lnot b) == lxor a bforall a b : t, lxor (lnot a) (lnot b) == lxor a ba, b:tlxor (lnot a) (lnot b) == lxor a bnow rewrite !lnot_spec, xorb_negb_negb. Qed.a, b, m:tHm:0 <= mxorb (lnot a).[m] (lnot b).[m] = xorb a.[m] b.[m]forall a b : t, lnot (lxor a b) == lxor (lnot a) bforall a b : t, lnot (lxor a b) == lxor (lnot a) ba, b:tlnot (lxor a b) == lxor (lnot a) bnow rewrite !lnot_spec, !lxor_spec, negb_xorb_l. Qed.a, b, m:tHm:0 <= m(lnot (lxor a b)).[m] = xorb (lnot a).[m] b.[m]forall a b : t, lnot (lxor a b) == lxor a (lnot b)forall a b : t, lnot (lxor a b) == lxor a (lnot b)a, b:tlnot (lxor a b) == lxor a (lnot b)now rewrite !lnot_spec, !lxor_spec, negb_xorb_r. Qed.a, b, m:tHm:0 <= m(lnot (lxor a b)).[m] = xorb a.[m] (lnot b).[m]forall a : t, lxor a (-1) == lnot aforall a : t, lxor a (-1) == lnot anow rewrite <- (lxor_0_r (lnot a)), <- lnot_m1, lxor_lnot_lnot. Qed.a:tlxor a (-1) == lnot aforall a : t, lxor (-1) a == lnot aforall a : t, lxor (-1) a == lnot anow rewrite lxor_comm, lxor_m1_r. Qed.a:tlxor (-1) a == lnot aforall a b : t, land a b == 0 -> lxor a b == lor a bforall a b : t, land a b == 0 -> lxor a b == lor a ba, b:tH:land a b == 0lxor a b == lor a ba, b:tH:land a b == 0m:tHm:0 <= mxorb a.[m] b.[m] = a.[m] || b.[m]now destruct a.[m], b.[m]. Qed.a, b:tH:land a b == 0m:tHm:0 <= mH0:a.[m] && b.[m] = falsexorb a.[m] b.[m] = a.[m] || b.[m]forall a n : t, 0 <= n -> lnot (a >> n) == lnot a >> nforall a n : t, 0 <= n -> lnot (a >> n) == lnot a >> na, n:tHn:0 <= nlnot (a >> n) == lnot a >> nnow rewrite lnot_spec, 2 shiftr_spec, lnot_spec by order_pos. Qed.a, n:tHn:0 <= nm:tHm:0 <= m(lnot (a >> n)).[m] = (lnot a >> n).[m]
(ones n) is 2^n-1, the number with n digits 1
Definition ones n := P (1<<n).Proper (eq ==> eq) onesProper (eq ==> eq) onessolve_proper. Qed.Proper (eq ==> eq) (fun n : t => P (1 << n))forall n : t, ones n == P (2 ^ n)forall n : t, ones n == P (2 ^ n)n:tones n == P (2 ^ n)n:tP (1 << n) == P (2 ^ n)n:tH:0 <= nP (1 << n) == P (2 ^ n)n:tH:n < 0P (1 << n) == P (2 ^ n)n:tH:n < 0P (1 << n) == P (2 ^ n)n:tH:n < 01 << n == 2 ^ nn:tH:n < 01 << n == 0n:tH:n < 01 >> (- n) == 0n:tH:n < 01 == 0 \/ 0 < 1 /\ log2 1 < - nn:tH:n < 00 < 1n:tH:n < 0log2 1 < - nn:tH:n < 0log2 1 < - nnow apply opp_pos_neg. Qed.n:tH:n < 00 < - nforall n m : t, 0 <= n -> 0 <= m -> ones (m + n) == 2 ^ m * ones n + ones mforall n m : t, 0 <= n -> 0 <= m -> ones (m + n) == 2 ^ m * ones n + ones mn, m:tHn:0 <= nHm:0 <= mones (m + n) == 2 ^ m * ones n + ones mn, m:tHn:0 <= nHm:0 <= mP (2 ^ (m + n)) == 2 ^ m * P (2 ^ n) + P (2 ^ m)n, m:tHn:0 <= nHm:0 <= m2 ^ (m + n) - 1 == 2 ^ (m + n) - 2 ^ m + (2 ^ m - 1)reflexivity. Qed.n, m:tHn:0 <= nHm:0 <= m2 ^ (m + n) - 1 == 2 ^ (m + n) - 1forall n m : t, 0 <= m <= n -> ones n / 2 ^ m == ones (n - m)forall n m : t, 0 <= m <= n -> ones n / 2 ^ m == ones (n - m)n, m:tHm:0 <= mH:m <= nones n / 2 ^ m == ones (n - m)n, m:tHm:0 <= mH:m <= nones (n - m) == ones n / 2 ^ mn, m:tHm:0 <= mH:m <= n0 <= ones m < 2 ^ m \/ 2 ^ m < ones m <= 0n, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= ones m < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= P (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= P (2 ^ m)n, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 < 2 ^ mn, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones (n - m + m) == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones (m + (n - m)) == 2 ^ m * ones (n - m) + ones mnow apply le_0_sub. Qed.n, m:tHm:0 <= mH:m <= n0 <= n - mforall n m : t, 0 <= m <= n -> ones n mod 2 ^ m == ones mforall n m : t, 0 <= m <= n -> ones n mod 2 ^ m == ones mn, m:tHm:0 <= mH:m <= nones n mod 2 ^ m == ones mn, m:tHm:0 <= mH:m <= nones m == ones n mod 2 ^ mn, m:tHm:0 <= mH:m <= n0 <= ones m < 2 ^ m \/ 2 ^ m < ones m <= 0n, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= ones m < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= P (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 <= P (2 ^ m)n, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= n0 < 2 ^ mn, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nP (2 ^ m) < 2 ^ mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones n == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones (n - m + m) == 2 ^ m * ones (n - m) + ones mn, m:tHm:0 <= mH:m <= nones (m + (n - m)) == 2 ^ m * ones (n - m) + ones mnow apply le_0_sub. Qed.n, m:tHm:0 <= mH:m <= n0 <= n - mforall n m : t, 0 <= m < n -> (ones n).[m] = trueforall n m : t, 0 <= m < n -> (ones n).[m] = truen, m:tHm:0 <= mH:m < n(ones n).[m] = truen, m:tHm:0 <= mH:m < n(ones n / 2 ^ m) mod 2 == 1n, m:tHm:0 <= mH:m < nones (n - m) mod 2 == 1n, m:tHm:0 <= mH:m < nones (n - m) mod 2 ^ 1 == 1n, m:tHm:0 <= mH:m < nones 1 == 1n, m:tHm:0 <= mH:m < n0 <= 1 <= n - mn, m:tHm:0 <= mH:m < nP (2 ^ 1) == 1n, m:tHm:0 <= mH:m < n0 <= 1 <= n - mn, m:tHm:0 <= mH:m < n0 <= 1 <= n - mn, m:tHm:0 <= mH:m < n0 <= 1n, m:tHm:0 <= mH:m < n1 <= n - mn, m:tHm:0 <= mH:m < n1 <= n - mn, m:tHm:0 <= mH:m < n1 + m <= nnow apply le_succ_l. Qed.n, m:tHm:0 <= mH:m < nS m <= nforall n m : t, 0 <= n <= m -> (ones n).[m] = falseforall n m : t, 0 <= n <= m -> (ones n).[m] = falsen, m:tHn:0 <= nH:n <= m(ones n).[m] = falsen, m:tHn:0 < nH:n <= m(ones n).[m] = falsen, m:tHn:0 == nH:n <= m(ones n).[m] = falsen, m:tHn:0 < nH:n <= m0 <= P (2 ^ n)n, m:tHn:0 < nH:n <= mlog2 (P (2 ^ n)) < mn, m:tHn:0 == nH:n <= m(ones n).[m] = falsen, m:tHn:0 < nH:n <= mlog2 (P (2 ^ n)) < mn, m:tHn:0 == nH:n <= m(ones n).[m] = falsen, m:tHn:0 < nH:n <= mP n < mn, m:tHn:0 == nH:n <= m(ones n).[m] = falsen, m:tHn:0 == nH:n <= m(ones n).[m] = falsenow rewrite <- Hn, pow_0_r, one_succ, pred_succ, bits_0. Qed.n, m:tHn:0 == nH:n <= m(P (2 ^ n)).[m] = falseforall n m : t, 0 <= n -> (ones n).[m] = true <-> 0 <= m < nforall n m : t, 0 <= n -> (ones n).[m] = true <-> 0 <= m < nn, m:tHn:0 <= n(ones n).[m] = true <-> 0 <= m < nn, m:tHn:0 <= n(ones n).[m] = true -> 0 <= m < nn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = true0 <= m < nn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:m < 00 <= m < nn, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= m0 <= m < nn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= m0 <= m < nn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= mm < nn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= m~ n <= mn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= mH':n <= mFalsen, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:false = trueHm:0 <= mH':n <= mFalsen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= mH':n <= m0 <= n <= mn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = truen, m:tHn:0 <= nH:(ones n).[m] = trueHm:0 <= mH':n <= m0 <= n <= mn, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = trueapply ones_spec_low. Qed.n, m:tHn:0 <= n0 <= m < n -> (ones n).[m] = trueforall a n : t, 0 <= a -> log2 a < n -> lor a (ones n) == ones nforall a n : t, 0 <= a -> log2 a < n -> lor a (ones n) == ones na, n:tHa:0 <= aH:log2 a < nlor a (ones n) == ones na, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= ma.[m] || (ones n).[m] = (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= ma.[m] || (ones n).[m] = (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] || (ones n).[m] = (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= mlog2 a < ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= na, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] || (ones n).[m] = (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= na, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] || (ones n).[m] = (ones n).[m]rewrite ones_spec_low, orb_true_r; try split; trivial. Qed.a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] || (ones n).[m] = (ones n).[m]forall a n : t, 0 <= n -> land a (ones n) == a mod 2 ^ nforall a n : t, 0 <= n -> land a (ones n) == a mod 2 ^ na, n:tHn:0 <= nland a (ones n) == a mod 2 ^ na, n:tHn:0 <= nm:tHm:0 <= ma.[m] && (ones n).[m] = (a mod 2 ^ n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= ma.[m] && (ones n).[m] = (a mod 2 ^ n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && (ones n).[m] = (a mod 2 ^ n).[m]rewrite ones_spec_low, mod_pow2_bits_low, andb_true_r; try split; trivial. Qed.a, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && (ones n).[m] = (a mod 2 ^ n).[m]forall a n : t, 0 <= a -> log2 a < n -> land a (ones n) == aforall a n : t, 0 <= a -> log2 a < n -> land a (ones n) == aa, n:tHa:0 <= aH:log2 a < nland a (ones n) == aa, n:tHa:0 <= aH:log2 a < nHn:0 <= nland a (ones n) == aa, n:tHa:0 <= aH:log2 a < nHn:0 <= na mod 2 ^ n == aa, n:tHa:0 <= aH:log2 a < nHn:0 <= n0 <= a < 2 ^ na, n:tHa:0 <= aH:log2 a < nHn:0 <= na < 2 ^ nnow rewrite log2_pow2. Qed.a, n:tHa:0 <= aH:log2 a < nHn:0 <= nlog2 a < log2 (2 ^ n)forall a n : t, 0 <= n -> ldiff a (ones n) == (a >> n) << nforall a n : t, 0 <= n -> ldiff a (ones n) == (a >> n) << na, n:tHn:0 <= nldiff a (ones n) == (a >> n) << na, n:tHn:0 <= nm:tHm:0 <= ma.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= ma.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= ma.[m] && negb false = a.[m - n + n]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= m - na, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= n <= ma, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= ma.[m] && negb false = a.[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= m - na, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= n <= ma, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= m - na, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= n <= ma, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]a, n:tHn:0 <= nm:tHm:0 <= mH:n <= m0 <= n <= ma, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]rewrite ones_spec_low, shiftl_spec_low, andb_false_r; try split; trivial. Qed.a, n:tHn:0 <= nm:tHm:0 <= mH:m < na.[m] && negb (ones n).[m] = ((a >> n) << n).[m]forall a n : t, 0 <= a -> log2 a < n -> ldiff a (ones n) == 0forall a n : t, 0 <= a -> log2 a < n -> ldiff a (ones n) == 0a, n:tHa:0 <= aH:log2 a < nldiff a (ones n) == 0a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= ma.[m] && negb (ones n).[m] = falsea, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= ma.[m] && negb (ones n).[m] = falsea, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] && negb (ones n).[m] = falsea, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= mlog2 a < ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= n <= ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] && negb (ones n).[m] = falsea, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= n <= ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] && negb (ones n).[m] = falsea, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= na, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] && negb (ones n).[m] = falserewrite ones_spec_low, andb_false_r; try split; trivial. Qed.a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < na.[m] && negb (ones n).[m] = falseforall a n : t, 0 <= a -> log2 a < n -> ldiff (ones n) a == lxor a (ones n)forall a n : t, 0 <= a -> log2 a < n -> ldiff (ones n) a == lxor a (ones n)a, n:tHa:0 <= aH:log2 a < nldiff (ones n) a == lxor a (ones n)a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= m(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < n(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= mlog2 a < ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= n <= ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < n(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= n <= ma, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < n(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:n <= m0 <= na, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < n(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]rewrite ones_spec_low, xorb_true_r; try split; trivial. Qed.a, n:tHa:0 <= aH:log2 a < nm:tHm:0 <= mH0:m < n(ones n).[m] && negb a.[m] = xorb a.[m] (ones n).[m]
Bitwise operations and sign
forall a n : t, 0 <= a << n <-> 0 <= aforall a n : t, 0 <= a << n <-> 0 <= aa, n:t0 <= a << n <-> 0 <= a(* 0<=n *)a, n:tHn:0 <= n0 <= a << n <-> 0 <= aa, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= n(exists k : t, forall m : t, k < m -> (a << n).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false)a, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m : t, k < m -> (a << n).[m] = falseexists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m : t, k < m -> (a << n).[m] = falseforall m : t, k - n < m -> a.[m] = falsea, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> (a << n).[m0] = falsem:tHm:k - n < ma.[m] = falsea, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> (a << n).[m0] = falsem:tHm:k - n < mH:0 <= ma.[m] = falsea, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> (a << n).[m0] = falsem:tHm:k - n < mH:0 <= m(a << n).[m + n] = falsea, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> (a << n).[m0] = falsem:tHm:k - n < mH:0 <= mk < m + na, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m : t, k < m -> a.[m] = falseforall m : t, k + n < m -> (a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < m(a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= m(a << n).[m] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= ma.[m - n] = falsea, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:0 <= nk:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= mk < m - na, n:tHn:n <= 00 <= a << n <-> 0 <= a(* n<=0*)a, n:tHn:n <= 00 <= a << n <-> 0 <= aa, n:tHn:n <= 0(exists k : t, forall m : t, k < m -> (a >> (- n)).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false)a, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseexists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:0 <= kexists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:0 <= kforall m : t, k - n < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:0 <= km:tHm:k - n < ma.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:0 <= km:tHm:k < m + na.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:0 <= km:tHm:k < m + n(a >> (- n)).[m + n] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:0 <= km:tHm:k < m + n0 <= m + na, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:0 <= km:tHm:k < m + n0 <= m + na, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0a >> (- n) == 0a, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a >> (- n) == 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0forall n0 : t, 0 <= n0 -> (a >> (- n)).[n0] = 0.[n0]a, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a >> (- n) == 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:k < 0m:tHm:0 <= m(a >> (- n)).[m] = 0.[m]a, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a >> (- n) == 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> (a >> (- n)).[m0] = falseH:k < 0m:tHm:0 <= m(a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a >> (- n) == 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a >> (- n) == 0exists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a == 0 \/ 0 < a /\ log2 a < - nexists k0 : t, forall m : t, k0 < m -> a.[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> (a >> (- n)).[m] = falseH:k < 0EQ:a == 0 \/ 0 < a /\ log2 a < - n0 <= aa, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseexists k0 : t, forall m : t, k0 < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m : t, k < m -> a.[m] = falseforall m : t, k + n < m -> (a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < m(a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= m(a >> (- n)).[m] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= ma.[m + - n] = falsea, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= mk < m + - nnow apply lt_add_lt_sub_r. Qed.a, n:tHn:n <= 0k:tHk:forall m0 : t, k < m0 -> a.[m0] = falsem:tHm:k + n < mH:0 <= mk < m - nforall a n : t, a << n < 0 <-> a < 0forall a n : t, a << n < 0 <-> a < 0now rewrite 2 lt_nge, shiftl_nonneg. Qed.a, n:ta << n < 0 <-> a < 0forall a n : t, 0 <= a >> n <-> 0 <= aforall a n : t, 0 <= a >> n <-> 0 <= aa, n:t0 <= a >> n <-> 0 <= aapply shiftl_nonneg. Qed.a, n:t0 <= a << (- n) <-> 0 <= aforall a n : t, a >> n < 0 <-> a < 0forall a n : t, a >> n < 0 <-> a < 0now rewrite 2 lt_nge, shiftr_nonneg. Qed.a, n:ta >> n < 0 <-> a < 0forall a : t, 0 <= div2 a <-> 0 <= aforall a : t, 0 <= div2 a <-> 0 <= aa:t0 <= div2 a <-> 0 <= aapply shiftr_nonneg. Qed.a:t0 <= a >> 1 <-> 0 <= aforall a : t, div2 a < 0 <-> a < 0forall a : t, div2 a < 0 <-> a < 0now rewrite 2 lt_nge, div2_nonneg. Qed.a:tdiv2 a < 0 <-> a < 0forall a b : t, 0 <= lor a b <-> 0 <= a /\ 0 <= bforall a b : t, 0 <= lor a b <-> 0 <= a /\ 0 <= ba, b:t0 <= lor a b <-> 0 <= a /\ 0 <= ba, b:t(exists k : t, forall m : t, k < m -> (lor a b).[m] = false) <-> (exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false)a, b:t(exists k : t, forall m : t, k < m -> (lor a b).[m] = false) -> (exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false)a, b:t(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = falsea, b, k:tHk:forall m : t, k < m -> (lor a b).[m] = false(exists k0 : t, forall m : t, k0 < m -> a.[m] = false) /\ (exists k0 : t, forall m : t, k0 < m -> b.[m] = false)a, b:t(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = falsea, b:t(exists k : t, forall m : t, k < m -> a.[m] = false) /\ (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lor a b).[m] = falsedestruct (le_ge_cases k k'); [ exists k' | exists k ]; intros m Hm; rewrite lor_spec, Hk, Hk'; trivial; order. Qed.a, b, k:tHk:forall m : t, k < m -> a.[m] = falsek':tHk':forall m : t, k' < m -> b.[m] = falseexists k0 : t, forall m : t, k0 < m -> (lor a b).[m] = falseforall a b : t, lor a b < 0 <-> a < 0 \/ b < 0forall a b : t, lor a b < 0 <-> a < 0 \/ b < 0a, b:tlor a b < 0 <-> a < 0 \/ b < 0a, b:t~ (0 <= a /\ 0 <= b) <-> ~ 0 <= a \/ ~ 0 <= ba, b:t~ (0 <= a /\ 0 <= b) -> ~ 0 <= a \/ ~ 0 <= ba, b:t~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)a, b:tdecidable (0 <= a)a, b:t~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)now intros [H|H] (H',H''). Qed.a, b:t~ 0 <= a \/ ~ 0 <= b -> ~ (0 <= a /\ 0 <= b)forall a : t, 0 <= lnot a <-> a < 0forall a : t, 0 <= lnot a <-> a < 0now rewrite <- opp_succ, opp_nonneg_nonpos, le_succ_l. Qed.a:t0 <= P (- a) <-> a < 0forall a : t, lnot a < 0 <-> 0 <= aforall a : t, lnot a < 0 <-> 0 <= anow rewrite le_ngt, lt_nge, lnot_nonneg. Qed.a:tlnot a < 0 <-> 0 <= aforall a b : t, 0 <= land a b <-> 0 <= a \/ 0 <= bforall a b : t, 0 <= land a b <-> 0 <= a \/ 0 <= bnow rewrite <- (lnot_involutive (land a b)), lnot_land, lnot_nonneg, lor_neg, !lnot_neg. Qed.a, b:t0 <= land a b <-> 0 <= a \/ 0 <= bforall a b : t, land a b < 0 <-> a < 0 /\ b < 0forall a b : t, land a b < 0 <-> a < 0 /\ b < 0now rewrite <- (lnot_involutive (land a b)), lnot_land, lnot_neg, lor_nonneg, !lnot_nonneg. Qed.a, b:tland a b < 0 <-> a < 0 /\ b < 0forall a b : t, 0 <= ldiff a b <-> 0 <= a \/ b < 0forall a b : t, 0 <= ldiff a b <-> 0 <= a \/ b < 0now rewrite ldiff_land, land_nonneg, lnot_nonneg. Qed.a, b:t0 <= ldiff a b <-> 0 <= a \/ b < 0forall a b : t, ldiff a b < 0 <-> a < 0 <= bforall a b : t, ldiff a b < 0 <-> a < 0 <= bnow rewrite ldiff_land, land_neg, lnot_neg. Qed.a, b:tldiff a b < 0 <-> a < 0 <= bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)a, b:t0 <= a -> 0 <= b -> 0 <= lxor a bH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)a, b:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> (exists k : t, forall m : t, k < m -> b.[m] = false) -> exists k : t, forall m : t, k < m -> (lxor a b).[m] = falseH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)a, b, k:tHk:forall m : t, k < m -> a.[m] = falsek':tHk':forall m : t, k' < m -> b.[m] = falseexists k0 : t, forall m : t, k0 < m -> (lxor a b).[m] = falseH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bforall a b : t, 0 <= a -> b < 0 -> lxor a b < 0H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0a, b:t0 <= a -> b < 0 -> lxor a b < 0H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0a, b:t(exists k : t, forall m : t, k < m -> a.[m] = false) -> (exists k : t, forall m : t, k < m -> b.[m] = true) -> exists k : t, forall m : t, k < m -> (lxor a b).[m] = trueH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0a, b, k:tHk:forall m : t, k < m -> a.[m] = falsek':tHk':forall m : t, k' < m -> b.[m] = trueexists k0 : t, forall m : t, k0 < m -> (lxor a b).[m] = trueH:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a b : t, 0 <= a -> 0 <= b -> 0 <= lxor a bH':forall a b : t, 0 <= a -> b < 0 -> lxor a b < 0forall a b : t, 0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= lxor a b <-> (0 <= a <-> 0 <= b)H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= lxor a b -> 0 <= a <-> 0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= a <-> 0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= a -> 0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= b -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHa:0 <= a0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= b -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHa:0 <= aHb:b < 00 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= b -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHa:0 <= aHb:b < 0lxor a b < 0 -> 0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= b -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a b0 <= b -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHb:0 <= b0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHb:0 <= bHa:a < 00 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHb:0 <= bHa:a < 0lxor b a < 0 -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tHab:0 <= lxor a bHb:0 <= bHa:a < 0lxor a b < 0 -> 0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:t0 <= a <-> 0 <= b -> 0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= b0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:0 <= a0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 00 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:0 <= a0 <= bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 00 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 00 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:0 <= b0 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:b < 00 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:0 <= b0 <= aH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:b < 00 <= lxor a bH:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:b < 00 <= lxor a bapply H; now apply lnot_nonneg. Qed.H:forall a0 b0 : t, 0 <= a0 -> 0 <= b0 -> 0 <= lxor a0 b0H':forall a0 b0 : t, 0 <= a0 -> b0 < 0 -> lxor a0 b0 < 0a, b:tE:0 <= a <-> 0 <= bHa:a < 0Hb:b < 00 <= lxor (lnot a) (lnot b)
Bitwise operations and log2
forall a n : t, a.[n] = true -> (forall m : t, n < m -> a.[m] = false) -> log2 a == nforall a n : t, a.[n] = true -> (forall m : t, n < m -> a.[m] = false) -> log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falselog2 a == n(* a < 0 *)a, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = truelog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:n <= klog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:a.[S k] = trueH0:n <= klog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:false = trueH0:n <= klog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:a.[S k] = trueH0:n <= kn < S ka, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:a.[S k] = trueH0:n <= kn < S ka, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':a.[S n] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':true = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nlog2 a == na, n:tH:a.[n] = trueH':a.[S n] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nk < S na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':a.[S n] = falseHa:a < 0k:tHk:forall m : t, k < m -> a.[m] = trueH0:k < nk < S na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == n(* a = 0 *)a, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:a == 0log2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == n(* 0 < a *)a, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < alog2 a == na, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < aLT:n < log2 aFalsea, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < aLT:log2 a < nFalsea, n:tH:a.[n] = trueH':a.[log2 a] = falseHa:0 < aLT:n < log2 aFalsea, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < aLT:log2 a < nFalsenow rewrite bits_above_log2 in H by order. Qed.a, n:tH:a.[n] = trueH':forall m : t, n < m -> a.[m] = falseHa:0 < aLT:log2 a < nFalseforall a n : t, 0 < a -> log2 (a >> n) == max 0 (log2 a - n)forall a n : t, 0 < a -> log2 (a >> n) == max 0 (log2 a - n)a, n:tHa:0 < alog2 (a >> n) == max 0 (log2 a - n)a, n:tHa:0 < aH:0 <= log2 a - nlog2 (a >> n) == log2 a - na, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - n(a >> n).[log2 a - n] = truea, n:tHa:0 < aH:0 <= log2 a - nforall m : t, log2 a - n < m -> (a >> n).[m] = falsea, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - nforall m : t, log2 a - n < m -> (a >> n).[m] = falsea, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - nm:tHm:log2 a - n < m(a >> n).[m] = falsea, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - nm:tHm:log2 a - n < mH0:0 <= m(a >> n).[m] = falsea, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - nm:tHm:log2 a - n < mH0:0 <= ma.[m + n] = falsea, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:0 <= log2 a - nm:tHm:log2 a - n < mH0:0 <= mlog2 a < m + na, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:log2 a - n < 0log2 (a >> n) == 0a, n:tHa:0 < aH:log2 a < nlog2 (a >> n) == 0a, n:tHa:0 < aH:log2 a < na >> n <= 0a, n:tHa:0 < aH:log2 a < na >> n == 0a, n:tHa:0 < aH:log2 a < na == 0 \/ 0 < a /\ log2 a < nnow split. Qed.a, n:tHa:0 < aH:log2 a < n0 < a /\ log2 a < nforall a n : t, 0 < a -> 0 <= n -> log2 (a << n) == log2 a + nforall a n : t, 0 < a -> 0 <= n -> log2 (a << n) == log2 a + na, n:tHa:0 < aHn:0 <= nlog2 (a << n) == log2 a + nnow apply log2_mul_pow2. Qed.a, n:tHa:0 < aHn:0 <= nlog2 (a * 2 ^ n) == n + log2 aforall a n : t, 0 < a -> log2 (a << n) == max 0 (log2 a + n)forall a n : t, 0 < a -> log2 (a << n) == max 0 (log2 a + n)a, n:tHa:0 < alog2 (a << n) == max 0 (log2 a + n)destruct (le_gt_cases 0 (log2 a + n)); [rewrite 2 max_r | rewrite 2 max_l]; rewrite ?sub_opp_r; try order. Qed.a, n:tHa:0 < amax 0 (log2 a - - n) == max 0 (log2 a + n)forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)forall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 <= aH:a <= blog2 (lor a b) == log2 bAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 < aH:a <= blog2 (lor a b) == log2 bAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 < aH:a <= b(lor a b).[log2 b] = truea, b:tHa:0 < aH:a <= bforall m : t, log2 b < m -> (lor a b).[m] = falseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 < aH:a <= bforall m : t, log2 b < m -> (lor a b).[m] = falseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 < aH:a <= bm:tHm:log2 b < m(lor a b).[m] = falseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)a, b:tHa:0 < aH:a <= bm:tHm:log2 b < mH':log2 a <= log2 b(lor a b).[m] = falseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)(* main *)AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lor a b) == log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= blog2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (lor a b) == log2 bAUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lor a b) == max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lor a b) == log2 anow apply AUX. Qed.AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lor a0 b0) == log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lor b a) == log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)forall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= blog2 (land a b) <= log2 aAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= b~ log2 a < log2 (land a b)AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)FalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 <= land a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 < land a bFalsea, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 == land a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 < land a b(land a b).[log2 (land a b)] = true -> Falsea, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 == land a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 (land a b)H:0 == land a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 a < log2 0H:0 == land a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)(* main *)AUX:forall a b : t, 0 <= a -> a <= b -> log2 (land a b) <= log2 aforall a b : t, 0 <= a -> 0 <= b -> log2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= blog2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (land a b) <= log2 aAUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (land a b) <= min (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (land a b) <= log2 bnow apply AUX. Qed.AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (land a0 b0) <= log2 a0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (land b a) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)forall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= blog2 (lxor a b) <= log2 bAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= b~ log2 b < log2 (lxor a b)AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)FalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 <= lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a bFalsea, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a b(lxor a b).[log2 (lxor a b)] = true -> Falsea, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a bxorb false false = true -> Falsea, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a blog2 a < log2 (lxor a b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a blog2 a < log2 (lxor a b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 < lxor a blog2 a <= log2 ba, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 (lxor a b)H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)a, b:tHa:0 <= aHb:a <= bLT:log2 b < log2 0H:0 == lxor a bFalseAUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)(* main *)AUX:forall a b : t, 0 <= a -> a <= b -> log2 (lxor a b) <= log2 bforall a b : t, 0 <= a -> 0 <= b -> log2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= blog2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:a <= blog2 (lxor a b) <= log2 bAUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lxor a b) <= max (log2 a) (log2 b)AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lxor a b) <= log2 anow apply AUX. Qed.AUX:forall a0 b0 : t, 0 <= a0 -> a0 <= b0 -> log2 (lxor a0 b0) <= log2 b0a, b:tHa:0 <= aHb:0 <= bH:b <= alog2 (lxor b a) <= log2 a
Bitwise operations and arithmetical operations
Notation xor3 a b c := (xorb (xorb a b) c). Notation lxor3 a b c := (lxor (lxor a b) c). Notation nextcarry a b c := ((a&&b) || (c && (a||b))). Notation lnextcarry a b c := (lor (land a b) (land c (lor a b))).forall a b : t, (a + b).[0] = xorb a.[0] b.[0]forall a b : t, (a + b).[0] = xorb a.[0] b.[0]now rewrite !bit0_odd, odd_add. Qed.a, b:t(a + b).[0] = xorb a.[0] b.[0]forall a b c : t, (a + b + c).[0] = xor3 a.[0] b.[0] c.[0]forall a b c : t, (a + b + c).[0] = xor3 a.[0] b.[0] c.[0]now rewrite !add_bit0. Qed.a, b, c:t(a + b + c).[0] = xor3 a.[0] b.[0] c.[0]forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0H:1 + 1 == 2forall a0 b0 c0 : bool, (a0 + b0 + c0) / 2 == nextcarry a0 b0 c0H:1 + 1 == 2(2 + 1) / 2 == 1H:1 + 1 == 21 == (2 + 1) / 2H:1 + 1 == 20 <= 1 < 2 \/ 2 < 1 <= 0H:1 + 1 == 22 + 1 == 2 * 1 + 1now nzsimpl'. Qed.H:1 + 1 == 22 + 1 == 2 * 1 + 1forall (a b : t) (c0 : bool), (a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0forall (a b : t) (c0 : bool), (a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0a, b:tc0:bool(a + b + c0) / 2 == a / 2 + b / 2 + nextcarry a.[0] b.[0] c0a, b:tc0:bool(a + b + c0) / 2 == a / 2 + b / 2 + (a.[0] + b.[0] + c0) / 2a, b:tc0:bool(a + b + c0) / 2 == (a.[0] + b.[0] + c0) / 2 + (a / 2 + b / 2)a, b:tc0:bool(a + b + c0) / 2 == (a.[0] + b.[0] + c0 + (a / 2 + b / 2) * 2) / 2a, b:tc0:boola + b + c0 == a.[0] + b.[0] + c0 + (a / 2 + b / 2) * 2a, b:tc0:boola + b + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)a, b:tc0:bool2 * div2 a + a.[0] + b + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)a, b:tc0:bool2 * div2 a + a.[0] + (2 * div2 b + b.[0]) + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)a, b:tc0:bool2 * div2 a + 2 * div2 b + (a.[0] + b.[0]) + c0 == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)apply add_comm. Qed.a, b:tc0:bool2 * div2 a + 2 * div2 b + (a.[0] + b.[0] + c0) == a.[0] + b.[0] + c0 + (2 * div2 a + 2 * div2 b)
The main result concerning addition: we express the bits of the sum
in term of bits of a and b and of some carry stream which is also
recursively determined by another equation.
forall n : t, 0 <= n -> forall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0forall n : t, 0 <= n -> forall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall (a b : t) (c0 : bool), - 2 ^ n <= a < 2 ^ n -> - 2 ^ n <= b < 2 ^ n -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => forall (a b : t) (c0 : bool), - 2 ^ n0 <= a < 2 ^ n0 -> - 2 ^ n0 <= b < 2 ^ n0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0)n:tHn:0 <= nforall (a b : t) (c0 : bool), - 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* base *)n:tHn:0 <= nforall (a b : t) (c0 : bool), - 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:bool- 2 ^ 0 <= a < 2 ^ 0 -> - 2 ^ 0 <= b < 2 ^ 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:bool-1 <= a <= 0 -> -1 <= b <= 0 -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 <= aHa2:a <= 0Hb1:-1 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* base, a = 0, b = 0 *)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:0 <= bHb2:b <= 0a + b + c0 == lxor3 a b c0 /\ c0 / 2 == lnextcarry a b c0 /\ c0.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:0 <= bHb2:b <= 00 + 0 + c0 == lxor3 0 0 c0 /\ c0 / 2 == lnextcarry 0 0 c0 /\ c0.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:0 <= bHb2:b <= 0c0 == c0 /\ c0 / 2 == 0 /\ c0.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* base, a = 0, b = -1 *)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0a + b + c0 == lxor3 a b (- c0) /\ - c0 / 2 == lnextcarry a b (- c0) /\ (- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 00 + -1 + c0 == lxor3 0 (-1) (- c0) /\ - c0 / 2 == lnextcarry 0 (-1) (- c0) /\ (- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 00 + -1 + c0 == lxor3 0 (-1) (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 / 2 == lnextcarry 0 (-1) (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0-1 + c0 == lnot (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 / 2 == lnextcarry 0 (-1) (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0-1 + c0 == P (- - c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 / 2 == lnextcarry 0 (-1) (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 / 2 == lnextcarry 0 (-1) (- c0)n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 / 2 == - c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 == - c0 / 2n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 00 <= c0 < 2 \/ 2 < c0 <= 0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 == 2 * - c0 + c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0- c0 == 2 * - c0 + c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:0 <= aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* base, a = -1, b = 0 *)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0a + b + c0 == lxor3 a b (- c0) /\ - c0 / 2 == lnextcarry a b (- c0) /\ (- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0-1 + 0 + c0 == lxor3 (-1) 0 (- c0) /\ - c0 / 2 == lnextcarry (-1) 0 (- c0) /\ (- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0-1 + 0 + c0 == lxor3 (-1) 0 (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 / 2 == lnextcarry (-1) 0 (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0-1 + c0 == lnot (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 / 2 == lnextcarry (-1) 0 (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0-1 + c0 == P (- - c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 / 2 == lnextcarry (-1) 0 (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 / 2 == lnextcarry (-1) 0 (- c0)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 / 2 == - c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 == - c0 / 2n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 00 <= c0 < 2 \/ 2 < c0 <= 0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 == 2 * - c0 + c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0- c0 == 2 * - c0 + c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:0 <= bHb2:b <= 0(- c0).[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* base, a = -1, b = -1 *)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0a + b + c0 == lxor3 a b (c0 + 2 * -1) /\ (c0 + 2 * -1) / 2 == lnextcarry a b (c0 + 2 * -1) /\ (c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0-1 + -1 + c0 == lxor3 (-1) (-1) (c0 + 2 * -1) /\ (c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1) /\ (c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0-1 + -1 + c0 == lxor3 (-1) (-1) (c0 + 2 * -1)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0-1 + -1 + c0 == c0 + 2 * -1n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1) / 2 == lnextcarry (-1) (-1) (c0 + 2 * -1)n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1) / 2 == -1n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa1:-1 == aHa2:a <= 0Hb1:-1 == bHb2:b <= 0(c0 + 2 * -1).[0] = c0n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* step *)n:tHn:0 <= nforall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0forall m : t, 0 <= m -> (forall (a b : t) (c0 : bool), - 2 ^ m <= a < 2 ^ m -> - 2 ^ m <= b < 2 ^ m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0) -> forall (a b : t) (c0 : bool), - 2 ^ S m <= a < 2 ^ S m -> - 2 ^ S m <= b < 2 ^ S m -> exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nIH:forall (a0 b0 : t) (c1 : bool), - 2 ^ n <= a0 < 2 ^ n -> - 2 ^ n <= b0 < 2 ^ n -> exists c : t, a0 + b0 + c1 == lxor3 a0 b0 c /\ c / 2 == lnextcarry a0 b0 c /\ c.[0] = c1a, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nexists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= nIH:forall (a0 b0 : t) (c2 : bool), - 2 ^ n <= a0 < 2 ^ n -> - 2 ^ n <= b0 < 2 ^ n -> exists c : t, a0 + b0 + c2 == lxor3 a0 b0 c /\ c / 2 == lnextcarry a0 b0 c /\ c.[0] = c2a, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolexists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= a / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= a / 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool0 < 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool2 * - 2 ^ n <= an:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool2 * - 2 ^ n <= an:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool0 < 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola < 2 * 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boola < 2 * 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool- 2 ^ n <= b / 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool0 < 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool2 * - 2 ^ n <= bn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool2 * - 2 ^ n <= bn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb / 2 < 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:bool0 < 2n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb < 2 * 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolb < 2 * 2 ^ nn:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1exists c2 : t, a + b + c0 == lxor3 a b c2 /\ c2 / 2 == lnextcarry a b c2 /\ c2.[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1a + b + c0 == lxor3 a b (c0 + 2 * c) /\ (c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c) /\ (c0 + 2 * c).[0] = c0(* step, add *)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1a + b + c0 == lxor3 a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 < m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P m((a + b + c0) / 2).[P m] = (lxor3 (a / 2) (b / 2) ((c0 + 2 * c) / 2)).[P m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P m(a + b + c0) / 2 == lxor3 (a / 2) (b / 2) ((c0 + 2 * c) / 2)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P m(a + b + c0) / 2 == a / 2 + b / 2 + c1n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[m] = xor3 a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == m(a + b + c0).[0] = xor3 a.[0] b.[0] (c0 + 2 * c).[0]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0(* step, carry *)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c) / 2 == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1c == lnextcarry a b (c0 + 2 * c)n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 < mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P m(lnextcarry (a / 2) (b / 2) c).[P m] = nextcarry (a / 2).[P m] (b / 2).[P m] ((c0 + 2 * c) / 2).[P m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 <= P mnextcarry (a / 2).[P m] (b / 2).[P m] c.[P m] = nextcarry (a / 2).[P m] (b / 2).[P m] ((c0 + 2 * c) / 2).[P m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[m] = nextcarry a.[m] b.[m] (c0 + 2 * c).[m]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1m:tHm:0 == mc.[0] = nextcarry a.[0] b.[0] (c0 + 2 * c).[0]n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0(* step, carry0 *) apply add_b2z_double_bit0. Qed.n:tHn:0 <= na, b:tc0:boolHa:- 2 ^ S n <= a < 2 ^ S nHb:- 2 ^ S n <= b < 2 ^ S nc1:=nextcarry a.[0] b.[0] c0:boolc:tIH1:a / 2 + b / 2 + c1 == lxor3 (a / 2) (b / 2) cIH2:c / 2 == lnextcarry (a / 2) (b / 2) cHc:c.[0] = c1(c0 + 2 * c).[0] = c0forall (a b : t) (c0 : bool), exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0forall (a b : t) (c0 : bool), exists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0a, b:tc0:boolexists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0a, b:tc0:booln:=max (abs a) (abs b):texists c : t, a + b + c0 == lxor3 a b c /\ c / 2 == lnextcarry a b c /\ c.[0] = c0(* positivity *)a, b:tc0:booln:=max (abs a) (abs b):t0 <= na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t0 <= max (abs a) (abs b)a, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ n(* bound for a *)a, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs a < 2 ^ abs aa, b:tc0:booln:=max (abs a) (abs b):t2 ^ abs a <= 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t2 ^ abs a <= 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t0 < 2a, b:tc0:booln:=max (abs a) (abs b):tabs a <= na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs a <= na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs a <= max (abs a) (abs b)a, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHa:abs a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHa:- 2 ^ n < a < 2 ^ n- 2 ^ n <= a < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ n(* bound for b *)a, b:tc0:booln:=max (abs a) (abs b):t- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs b < 2 ^ abs ba, b:tc0:booln:=max (abs a) (abs b):t2 ^ abs b <= 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t2 ^ abs b <= 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):t0 < 2a, b:tc0:booln:=max (abs a) (abs b):tabs b <= na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs b <= na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tabs b <= max (abs a) (abs b)a, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ na, b:tc0:booln:=max (abs a) (abs b):tHb:abs b < 2 ^ n- 2 ^ n <= b < 2 ^ ndestruct Hb; split; order. Qed.a, b:tc0:booln:=max (abs a) (abs b):tHb:- 2 ^ n < b < 2 ^ n- 2 ^ n <= b < 2 ^ n
Particular case : the second bit of an addition
forall a b : t, (a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])forall a b : t, (a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b:t(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b, c:tEQ1:a + b + false == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = false(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = false(a + b).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = false(lxor3 a b c).[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsexor3 a.[1] b.[1] c.[1] = xor3 a.[1] b.[1] (a.[0] && b.[0])a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsec.[1] = a.[0] && b.[0]a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = false(lnextcarry a b c).[0] = a.[0] && b.[0]a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsenextcarry a.[0] b.[0] c.[0] = a.[0] && b.[0]a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsenextcarry a.[0] b.[0] false = a.[0] && b.[0]apply orb_false_r. Qed.a, b, c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsea.[0] && b.[0] || false = a.[0] && b.[0]
In an addition, there will be no carries iff there is
no common bits in the numbers to add
forall a b c : t, c / 2 == lnextcarry a b c -> c.[0] = false -> c == 0 <-> land a b == 0forall a b c : t, c / 2 == lnextcarry a b c -> c.[0] = false -> c == 0 <-> land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falsec == 0 <-> land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falsec == 0 -> land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseland a b == 0 -> c == 0a, b, c:tH:0 / 2 == lnextcarry a b 0H':0.[0] = falseEQ:c == 0land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseland a b == 0 -> c == 0a, b, c:tH:0 == lnextcarry a b 0H':0.[0] = falseEQ:c == 0land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseland a b == 0 -> c == 0a, b, c:tH:lnextcarry a b 0 == 0H':0.[0] = falseEQ:c == 0land a b == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseland a b == 0 -> c == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseland a b == 0 -> c == 0a, b, c:tH:c / 2 == lnextcarry a b cH':c.[0] = falseEQ:land a b == 0c == 0a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0c == 0a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0forall n : t, 0 <= n -> c.[n] = 0.[n]a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nc.[n] = 0.[n]a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nc.[n] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nProper (eq ==> iff) (fun n0 : t => c.[n0] = false)a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nc.[0] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nforall m : t, 0 <= m -> c.[m] = false -> c.[S m] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nc.[0] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nforall m : t, 0 <= m -> c.[m] = false -> c.[S m] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nforall m : t, 0 <= m -> c.[m] = false -> c.[S m] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0forall m : t, 0 <= m -> c.[m] = false -> c.[S m] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nIH:c.[n] = falsec.[S n] = falsea, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nIH:c.[n] = false(land c (lor a b)).[n] = falsenow rewrite IH. Qed.a, b, c:tH:c / 2 == land c (lor a b)H':c.[0] = falseEQ:land a b == 0n:tHn:0 <= nIH:c.[n] = falsec.[n] && (a.[n] || b.[n]) = false
When there is no common bits, the addition is just a xor
forall a b : t, land a b == 0 -> a + b == lxor a bforall a b : t, land a b == 0 -> a + b == lxor a ba, b:tH:land a b == 0a + b == lxor a ba, b:tH:land a b == 0c:tEQ1:a + b + false == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsea + b == lxor a ba, b:tH:land a b == 0c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falsea + b == lxor a ba, b:tH:land a b == 0c:tEQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falselxor3 a b c == lxor a ba, b, c:tH:c == 0EQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falselxor3 a b c == lxor a bnow rewrite lxor_0_r. Qed.a, b, c:tH:c == 0EQ1:a + b == lxor3 a b cEQ2:c / 2 == lnextcarry a b cHc:c.[0] = falselxor3 a b 0 == lxor a b
A null ldiff implies being smaller
forall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bforall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nforall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bProper (eq ==> iff) (fun n : t => forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= b)forall a b : t, 0 <= a < 2 ^ 0 -> 0 <= b -> ldiff a b == 0 -> a <= bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bforall a b : t, 0 <= a < 2 ^ 0 -> 0 <= b -> ldiff a b == 0 -> a <= bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= ba, b:tHa:0 <= a < 2 ^ 0Hb:0 <= ba <= bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= ba, b:tHa:0 <= a <= 0Hb:0 <= ba <= bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bforall m : t, 0 <= m -> (forall a b : t, 0 <= a < 2 ^ m -> 0 <= b -> ldiff a b == 0 -> a <= b) -> forall a b : t, 0 <= a < 2 ^ S m -> 0 <= b -> ldiff a b == 0 -> a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a <= bAUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 02 * (a / 2) + a mod 2 <= 2 * (b / 2) + b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 02 * (a / 2) <= 2 * (b / 2)n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a / 2 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= a / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= a / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a / 2 < 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a < 2 * 2 ^ nn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 00 <= b / 2n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a / 2) (b / 2) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0ldiff (a >> 1) (b >> 1) == 0n:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a mod 2 <= b mod 2AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:ldiff a b == 0NEQ:2 ~= 0a.[0] <= b.[0]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:testbit (ldiff a b) === testbit 0NEQ:2 ~= 0a.[0] <= b.[0]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:(ldiff a b).[0] = 0.[0]NEQ:2 ~= 0a.[0] <= b.[0]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bn:tHn:0 <= nIH:forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHa:0 <= aHa':a < 2 ^ S nHb:0 <= bH:a.[0] && negb b.[0] = falseNEQ:2 ~= 0a.[0] <= b.[0]AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= b(* main *)AUX:forall n : t, 0 <= n -> forall a b : t, 0 <= a < 2 ^ n -> 0 <= b -> ldiff a b == 0 -> a <= bforall a b : t, 0 <= b -> ldiff a b == 0 -> 0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 00 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 00 <= aAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha':a < 0FalseAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha':a < 00 < 0AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha':a < 0ldiff a b < 0AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha':a < 0a < 0 <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= a0 <= a <= bAUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= aa <= bapply pow_gt_lin_r; order'. Qed.AUX:forall n : t, 0 <= n -> forall a0 b0 : t, 0 <= a0 < 2 ^ n -> 0 <= b0 -> ldiff a0 b0 == 0 -> a0 <= b0a, b:tHb:0 <= bHd:ldiff a b == 0Ha:0 <= aa < 2 ^ a
Subtraction can be a ldiff when the opposite ldiff is null.
forall a b : t, ldiff b a == 0 -> a - b == ldiff a bforall a b : t, ldiff b a == 0 -> a - b == ldiff a ba, b:tH:ldiff b a == 0a - b == ldiff a ba, b:tH:ldiff b a == 0a - b + b == ldiff a b + ba, b:tH:ldiff b a == 0a == ldiff a b + ba, b:tH:ldiff b a == 0ldiff a b + b == aa, b:tH:ldiff b a == 0lxor (ldiff a b) b == aa, b:tH:ldiff b a == 0land (ldiff a b) b == 0a, b:tH:ldiff b a == 0m:tHm:0 <= mxorb (a.[m] && negb b.[m]) b.[m] = a.[m]a, b:tH:ldiff b a == 0land (ldiff a b) b == 0a, b:tH:testbit (ldiff b a) === testbit 0m:tHm:0 <= mxorb (a.[m] && negb b.[m]) b.[m] = a.[m]a, b:tH:ldiff b a == 0land (ldiff a b) b == 0a, b, m:tH:(ldiff b a).[m] = 0.[m]Hm:0 <= mxorb (a.[m] && negb b.[m]) b.[m] = a.[m]a, b:tH:ldiff b a == 0land (ldiff a b) b == 0a, b, m:tH:b.[m] && negb a.[m] = falseHm:0 <= mxorb (a.[m] && negb b.[m]) b.[m] = a.[m]a, b:tH:ldiff b a == 0land (ldiff a b) b == 0apply land_ldiff. Qed.a, b:tH:ldiff b a == 0land (ldiff a b) b == 0
Adding numbers with no common bits cannot lead to a much bigger number
forall a b n : t, land a b == 0 -> a < 2 ^ n -> b < 2 ^ n -> a + b < 2 ^ nforall a b n : t, land a b == 0 -> a < 2 ^ n -> b < 2 ^ n -> a + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ na + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':a <= 0a + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aa + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':a <= 0a + b <= 0 + ba, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':a <= 00 + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aa + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':a <= 00 + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aa + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aa + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':b <= 0a + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < ba + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':b <= 0a + b <= a + 0a, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':b <= 0a + 0 < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < ba + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':b <= 0a + 0 < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < ba + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < ba + b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < blxor a b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < bH0:0 < lxor a blxor a b < 2 ^ na, b, n:tH:land a b == 0Ha:a < 2 ^ nHb:b < 2 ^ nHa':0 < aHb':0 < bH0:0 < lxor a blog2 (lxor a b) < na, b, n:tH:land a b == 0Ha:log2 a < nHb:b < 2 ^ nHa':0 < aHb':0 < bH0:0 < lxor a blog2 (lxor a b) < na, b, n:tH:land a b == 0Ha:log2 a < nHb:log2 b < nHa':0 < aHb':0 < bH0:0 < lxor a blog2 (lxor a b) < na, b, n:tH:land a b == 0Ha:log2 a < nHb:log2 b < nHa':0 < aHb':0 < bH0:0 < lxor a blog2 (lxor a b) <= max (log2 a) (log2 b)a, b, n:tH:land a b == 0Ha:log2 a < nHb:log2 b < nHa':0 < aHb':0 < bH0:0 < lxor a bmax (log2 a) (log2 b) < ndestruct (le_ge_cases (log2 a) (log2 b)); [rewrite max_r|rewrite max_l]; order. Qed.a, b, n:tH:land a b == 0Ha:log2 a < nHb:log2 b < nHa':0 < aHb':0 < bH0:0 < lxor a bmax (log2 a) (log2 b) < nforall a b n : t, 0 <= n -> land a b == 0 -> a mod 2 ^ n + b mod 2 ^ n < 2 ^ nforall a b n : t, 0 <= n -> land a b == 0 -> a mod 2 ^ n + b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n + b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0land (a mod 2 ^ n) (b mod 2 ^ n) == 0a, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0m:tHm:0 <= m(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = falsea, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0m:tHm:0 <= mH0:n <= m(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = falsea, b, n:tHn:0 <= nH:land a b == 0m:tHm:0 <= mH0:m < n(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = falsea, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0m:tHm:0 <= mH0:m < n(a mod 2 ^ n).[m] && (b mod 2 ^ n).[m] = falsea, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0a mod 2 ^ n < 2 ^ na, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ napply mod_pos_bound; order_pos. Qed. End ZBitsProp.a, b, n:tHn:0 <= nH:land a b == 0b mod 2 ^ n < 2 ^ n