Basic Bignum Lemmas #
Fundamental theorems about bignum operations, ported from s2n-bignum/common/bignum.ml
Main Theorems #
high_low_digits- Decomposition: n = 2^(64*i) * highdigits n i + lowdigits n ihighdigits_clauses- Recursive characterization of highdigitslowdigits_clauses- Recursive characterization of lowdigitsbigdigitsum_works- Sum of digits equals the number (when bounded)
References #
Source: s2n-bignum/common/bignum.ml (lines 79-150)
Fundamental decomposition theorem: any number can be split into high and low parts.
Corresponds to HOL Light theorem:
let HIGH_LOW_DIGITS = prove
(`(!n i. 2 EXP (64 * i) * highdigits n i + lowdigits n i = n) /\
(!n i. lowdigits n i + 2 EXP (64 * i) * highdigits n i = n) /\
(!n i. highdigits n i * 2 EXP (64 * i) + lowdigits n i = n) /\
(!n i. lowdigits n i + highdigits n i * 2 EXP (64 * i) = n)`, ...);;
Source: s2n-bignum/common/bignum.ml:79-85
Recursive characterization of highdigits. This is the second clause of HOL
Light's HIGHDIGITS_CLAUSES. The first clause (highdigits n 0 = n) is in
Defs.lean as highdigits_zero.
Corresponds to HOL Light theorem:
let HIGHDIGITS_CLAUSES = prove
(`(!n. highdigits n 0 = n) /\ -- clause 1
(!n i. highdigits n (i + 1) = highdigits n i DIV 2 EXP 64)`, ...);; -- clause 2
Source: s2n-bignum/common/bignum.ml:87-91 (HIGHDIGITS_CLAUSES, clause 2)
Step theorem: relating highdigits at position i with i+1 and the digit at i.
This is a key decomposition theorem: highdigits at position i equals the highdigits at i+1 (shifted left by 64 bits) plus the digit at position i.
Corresponds to HOL Light theorem:
let HIGHDIGITS_STEP = prove
(`!n i. highdigits n i = 2 EXP 64 * highdigits n (i + 1) + bigdigit n i`,
REWRITE_TAC[highdigits; bigdigit; LEFT_ADD_DISTRIB; MULT_CLAUSES] THEN
REWRITE_TAC[EXP_ADD; GSYM DIV_DIV] THEN ARITH_TAC);;
Source: s2n-bignum/common/bignum.ml:93-96
Recursive characterization of lowdigits. This is the second clause of HOL
Light's LOWDIGITS_CLAUSES. Corresponds to HOL Light theorem:
let LOWDIGITS_CLAUSES = prove
(`(!n. lowdigits n 0 = 0) /\
(!n i. lowdigits n (i + 1) =
2 EXP (64 * i) * bigdigit n i + lowdigits n i)`, ...);;
Source: s2n-bignum/common/bignum.ml:98-103
highdigits equals 0 iff n is bounded.
Corresponds to HOL Light theorem:
let HIGHDIGITS_EQ_0 = prove
(`!n i. highdigits n i = 0 <=> n < 2 EXP (64 * i)`, ...);;
Source: s2n-bignum/common/bignum.ml:105-107
If n is bounded, then highdigits n i = 0.
Corresponds to HOL Light theorem:
let HIGHDIGITS_ZERO = prove
(`!n i. n < 2 EXP (64 * i) ==> highdigits n i = 0`, ...);;
Source: s2n-bignum/common/bignum.ml:113-115
If n is bounded, the top digit equals highdigits at position k-1.
Corresponds to HOL Light theorem:
let HIGHDIGITS_TOP = prove
(`!n k. n < 2 EXP (64 * k) ==> highdigits n (k - 1) = bigdigit n (k - 1)`,
REPEAT STRIP_TAC THEN REWRITE_TAC[highdigits; bigdigit] THEN
CONV_TAC SYM_CONV THEN MATCH_MP_TAC MOD_LT THEN
SIMP_TAC[RDIV_LT_EQ; EXP_EQ_0; ARITH_EQ; GSYM EXP_ADD] THEN
TRANS_TAC LTE_TRANS `2 EXP (64 * k)` THEN
ASM_REWRITE_TAC[LE_EXP] THEN ARITH_TAC);;
Source: s2n-bignum/common/bignum.ml:131-137
highdigits of 0 is always 0.
Corresponds to HOL Light theorem:
let HIGHDIGITS_TRIVIAL = prove
(`!n. highdigits 0 n = 0`,
REWRITE_TAC[highdigits; DIV_0]);;
Source: s2n-bignum/common/bignum.ml:117-119
Compositionality of highdigits: taking highdigits twice is equivalent to adding indices.
Corresponds to HOL Light theorem:
let HIGHDIGITS_HIGHDIGITS = prove
(`!n i j. highdigits (highdigits n i) j = highdigits n (i + j)`,
REPEAT GEN_TAC THEN REWRITE_TAC[highdigits] THEN
REWRITE_TAC[LEFT_ADD_DISTRIB; EXP_ADD; DIV_DIV]);;
Source: s2n-bignum/common/bignum.ml:169-172
The first lowdigit equals the 0-th bigdigit.
Corresponds to HOL Light theorem:
let LOWDIGITS_1 = prove
(`!n. lowdigits n 1 = bigdigit n 0`,
SUBST1_TAC(ARITH_RULE `1 = 0 + 1`) THEN
REWRITE_TAC[LOWDIGITS_CLAUSES; LOWDIGITS_0] THEN
REWRITE_TAC[MULT_CLAUSES; EXP; ADD_CLAUSES]);;
Source: s2n-bignum/common/bignum.ml:125-129
lowdigits of 0 is always 0.
Corresponds to HOL Light theorem:
let LOWDIGITS_TRIVIAL = prove
(`!n. lowdigits 0 n = 0`,
REWRITE_TAC[lowdigits; MOD_0]);;
Source: s2n-bignum/common/bignum.ml:151-153
lowdigits equals n iff n is bounded.
This is the bidirectional version of lowdigits_of_lt.
Corresponds to HOL Light theorem:
let LOWDIGITS_EQ_SELF = prove
(`!n i. lowdigits n i = n <=> n < 2 EXP (64 * i)`,
SIMP_TAC[lowdigits; MOD_EQ_SELF; EXP_EQ_0; ARITH_EQ]);;
Source: s2n-bignum/common/bignum.ml:143-145
lowdigits is always less than or equal to the original number.
Corresponds to HOL Light theorem:
let LOWDIGITS_LE = prove
(`!n i. lowdigits n i <= n`,
REWRITE_TAC[lowdigits; MOD_LE]);;
Source: s2n-bignum/common/bignum.ml:155-157
Compositionality of lowdigits: taking lowdigits twice equals taking the minimum.
Corresponds to HOL Light theorem:
let LOWDIGITS_LOWDIGITS = prove
(`!n i j. lowdigits (lowdigits n i) j = lowdigits n (MIN i j)`,
REPEAT GEN_TAC THEN REWRITE_TAC[lowdigits; MOD_MOD_EXP_MIN] THEN
AP_TERM_TAC THEN AP_TERM_TAC THEN ARITH_TAC);;
Source: s2n-bignum/common/bignum.ml:159-162
If n is bounded by 2^(64*k), then the sum of its digits equals n.
Corresponds to HOL Light theorem:
let BIGDIGITSUM_WORKS = prove
(`!n k. n < 2 EXP (64 * k)
==> nsum {i | i < k} (\i. 2 EXP (64 * i) * bigdigit n i) = n`, ...);;
Source: s2n-bignum/common/bignum.ml:19-22
Note: We use Finset.sum instead of HOL Light's nsum.
If a number is less than 2^(64*i), then its i-th bigdigit is 0.
Corresponds to HOL Light theorem:
let BIGDIGIT_ZERO = prove
(`!n i. n < 2 EXP (64 * i) ==> bigdigit n i = 0`, ...);;
Source: s2n-bignum/common/bignum.ml:37-39
bigdigit is unaffected by adding a high-order term.
If we add a term 2^(64*n) * b to a, the digits below position n remain unchanged.
Corresponds to HOL Light theorem:
let BIGDIGIT_ADD_LEFT =
prove(`forall a n b i.
i < n ==> bigdigit (a + 2 EXP (64 * n) * b) i = bigdigit a i`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[bigdigit] THEN
SUBGOAL_THEN `2 EXP (64 * n) = 2 EXP (64 * i) * (2 EXP (64 * (n-i)))` SUBST_ALL_TAC THENL [
REWRITE_TAC[GSYM EXP_ADD] THEN
REWRITE_TAC[GSYM LEFT_ADD_DISTRIB] THEN
AP_TERM_TAC THEN AP_TERM_TAC THEN ASM_ARITH_TAC;
REWRITE_TAC[GSYM MULT_ASSOC] THEN
IMP_REWRITE_TAC[DIV_MULT_ADD; EXP_2_NE_0] THEN
SUBGOAL_THEN
`2 EXP (64*(n-i)) = 2 EXP 64 * (2 EXP (64*(n-i-1)))`
SUBST_ALL_TAC THENL [
REWRITE_TAC[GSYM EXP_ADD] THEN
AP_TERM_TAC THEN ASM_ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[GSYM MULT_ASSOC] THEN
IMP_REWRITE_TAC[MOD_MULT_ADD; EXP_2_NE_0]]);;
Source: s2n-bignum/common/bignum.ml:41-62
Successor digit extraction: extracting digit (i+1) from a 2-word number.
When a number is written as t + 2^64 * n where t < 2^64,
the digit at position (i+1) equals the digit at position i of n.
Corresponds to HOL Light theorem:
let BIGDIGIT_SUC = prove(`forall n i t.
t < 2 EXP 64 ==> bigdigit (t + 2 EXP 64 * n) (SUC i) = bigdigit n i`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[bigdigit;ARITH_RULE`SUC i = 1 + i`;LEFT_ADD_DISTRIB;EXP_ADD;GSYM DIV_DIV;
ARITH_RULE`64 * 1 = 64`] THEN
IMP_REWRITE_TAC[DIV_MULT_ADD;EXP_2_NE_0;SPECL [`t:num`;`2 EXP 64`] DIV_LT] THEN
REWRITE_TAC[ADD]);;
Source: s2n-bignum/common/bignum.ml:64-71
Compositionality: bigdigit of highdigits shifts indices.
Extracting digit j from highdigits at position i is the same as extracting digit (i+j) from the original number.
Corresponds to HOL Light theorem:
let BIGDIGIT_HIGHDIGITS = prove
(`!n i j. bigdigit (highdigits n i) j = bigdigit n (i + j)`,
REPEAT GEN_TAC THEN REWRITE_TAC[bigdigit; highdigits] THEN
REWRITE_TAC[LEFT_ADD_DISTRIB; EXP_ADD; DIV_DIV]);;
Source: s2n-bignum/common/bignum.ml:164-167
Extracting digits from lowdigits: only digits below position i are preserved.
Corresponds to HOL Light theorem:
let BIGDIGIT_LOWDIGITS = prove
(`!n i j. bigdigit (lowdigits n i) j = if j < i then bigdigit n j else 0`,
REPEAT GEN_TAC THEN REWRITE_TAC[bigdigit; lowdigits] THEN
COND_CASES_TAC THENL
[REWRITE_TAC[DIV_MOD; GSYM EXP_ADD; MOD_MOD_EXP_MIN] THEN
ASM_SIMP_TAC[ARITH_RULE
`j < i ==> MIN (64 * i) (64 * j + 64) = 64 * j + 64`];
MATCH_MP_TAC(MESON[MOD_0] `x = 0 ==> x MOD n = 0`) THEN
SIMP_TAC[DIV_EQ_0; EXP_EQ_0; ARITH_EQ] THEN
TRANS_TAC LTE_TRANS `2 EXP (64 * i)` THEN
REWRITE_TAC[MOD_LT_EQ; EXP_EQ_0; ARITH_EQ; LE_EXP] THEN ASM_ARITH_TAC]);;
Source: s2n-bignum/common/bignum.ml:174-184