From 58de5a60d856197e2d926c24101f2c8e8f67fade Mon Sep 17 00:00:00 2001 From: Heiko Becker <hbecker@mpi-sws.org> Date: Fri, 5 Mar 2021 16:02:46 +0100 Subject: [PATCH] Rework an error bound proof --- hol4/ErrorBoundsScript.sml | 251 +++++++------------------------------ 1 file changed, 47 insertions(+), 204 deletions(-) diff --git a/hol4/ErrorBoundsScript.sml b/hol4/ErrorBoundsScript.sml index 18aa186b..f9b2a3ac 100644 --- a/hol4/ErrorBoundsScript.sml +++ b/hol4/ErrorBoundsScript.sml @@ -441,7 +441,7 @@ Proof QED Theorem nonzerop_EQ1_I'[simp]: - 0 < r ==> (nonzerop r = 1) + 0 < r ⇒ (nonzerop r = 1) Proof rw[nonzerop_def] QED @@ -449,93 +449,34 @@ QED Theorem err_prop_inversion_pos: ∀ (nF:real) (nR:real) (err:real) (elo:real) (ehi:real). 0 < elo - err ∧ 0 < elo ∧ - abs (nR - nF) <= err ∧ - elo <= nR ∧ nR <= ehi ∧ - elo - err <= nF ∧ nF <= ehi + err ∧ - 0 <= err ⇒ - abs (inv nR - inv nF) <= err * inv ((elo - err) * (elo - err)) + abs (nR - nF) ≤ err ∧ + elo ≤ nR ∧ nR ≤ ehi ∧ + elo - err ≤ nF ∧ nF ≤ ehi + err ∧ + 0 ≤ err ⇒ + abs (inv nR - inv nF) ≤ err * inv ((elo - err) * (elo - err)) Proof rpt strip_tac - \\ `! (x:real). ((abs x = x) /\ 0 < x) \/ ((abs x = - x) /\ x <= 0)` - by (REAL_ASM_ARITH_TAC) - \\ qpat_x_assum `!x. (A /\ B) \/ C` (qspecl_then [`nR - nF` ] assume_tac) - \\ fs[] - >- ( - `nF <= nR` by REAL_ASM_ARITH_TAC - \\ `0 < nF` by REAL_ASM_ARITH_TAC - \\ `0 < nR` by REAL_ASM_ARITH_TAC - \\ `inv nR <= inv nF` by fs [REAL_INV_LE_ANTIMONO] - \\ `inv nR - inv nF <= 0` by REAL_ASM_ARITH_TAC - \\ `0 <= - (inv nR - inv nF) ` by REAL_ASM_ARITH_TAC - \\ `abs (- (inv nR - inv nF)) = - (inv nR - inv nF)` by fs [ABS_REFL] - \\ `abs (inv nR - inv nF) = - (inv nR - inv nF)` by metis_tac[ABS_NEG] - \\ simp[real_sub, REAL_NEG_ADD] - \\ rpt (qpat_x_assum `abs v = v'` kall_tac) - \\ `- (inv nR) = inv (- nR)` - by (fs [real_div] \\ irule REAL_NEG_INV \\ REAL_ASM_ARITH_TAC) - \\ simp[] - \\ qspec_then `inv (-nR) + inv (nR - err)` match_mp_tac real_le_trans2 \\ conj_tac - >- (match_mp_tac REAL_LE_LADD_IMP - \\ ‘0 < nR - err ∧ nR - err ≤ nF’ by REAL_ASM_ARITH_TAC - \\ simp[]) - \\ `- nR <> 0 /\ nR - err <> 0` by REAL_ASM_ARITH_TAC - \\ ‘(nR - err + -nR) / (-nR * (nR - err)) ≤ err * (1 / (elo + -err) pow 2)’ - suffices_by (rewrite_tac[REAL_INV_1OVER] \\ fs[REAL_ADD_RAT]) - \\ `nR - err + - nR = - err` by REAL_ASM_ARITH_TAC - \\ pop_assum (rewrite_tac o single) - \\ qspec_then `nR` (fn thm => fs [real_div, GSYM thm]) REAL_NEG_LMUL - \\ `nR * (nR - err) <> 0` by fs[REAL_ENTIRE] - \\ ‘err * inv (nR * (nR − err)) ≤ err * inv ((elo + -err) pow 2)’ - by ( - match_mp_tac REAL_LE_LMUL_IMP \\ conj_tac \\ simp[] - \\ rpt (qpat_x_assum `T` kall_tac) - \\ `0 < elo + - err` by REAL_ASM_ARITH_TAC - \\ `0 < (elo + - err) * (elo + - err)` by fs[REAL_LT_MUL] - \\ match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac - >- (match_mp_tac REAL_LT_MUL \\ REAL_ASM_ARITH_TAC) - \\ conj_tac - >- (fs[POW_2]) - \\ once_rewrite_tac [POW_2] \\ irule REAL_LE_MUL2 \\ REAL_ASM_ARITH_TAC) - \\ fs[REAL_INV_MUL'] \\ pop_assum mp_tac \\ fs[]) - >- (fs[] - \\ `nR <= nF` by REAL_ASM_ARITH_TAC - \\ `0 < nF` by REAL_ASM_ARITH_TAC - \\ `0 < nR` by REAL_ASM_ARITH_TAC - \\ `inv nF <= inv nR` by fs [REAL_INV_LE_ANTIMONO] - \\ `0 <= inv nR - inv nF` by REAL_ASM_ARITH_TAC \\ qpat_x_assum `inv nF <= inv nR` kall_tac - \\ `abs (inv nR - inv nF) = inv nR - inv nF` by fs[ABS_REFL] \\ qpat_x_assum `0 <= inv a - b` kall_tac - \\ simp [real_sub, REAL_NEG_ADD] - \\ rpt (qpat_x_assum `abs x = y` kall_tac) - \\ qspec_then `inv nR + - (inv (nR + err))` match_mp_tac real_le_trans2 \\ conj_tac - >- (match_mp_tac REAL_LE_LADD_IMP - \\ `0 < nR + err /\ nF <= nR + err` by REAL_ASM_ARITH_TAC - \\ fs[GSYM REAL_INV_1OVER, REAL_INV_LE_ANTIMONO]) - >- (`- nR <> 0 /\ nR - err <> 0` by REAL_ASM_ARITH_TAC - \\ `- (inv (nR + err)) = inv (- (nR + err))` - by (fs [real_div] \\ match_mp_tac REAL_NEG_INV \\ REAL_ASM_ARITH_TAC) - \\ pop_assum (rewrite_tac o single) - \\ `- (nR + err) <> 0` by REAL_ASM_ARITH_TAC - \\ `nR <> 0` by REAL_ASM_ARITH_TAC - \\ rewrite_tac[REAL_INV_1OVER] - \\ ‘1 / - (nR + err) = -1 / (nR + err)’ by (fs[neg_rat]) - \\ pop_assum (rewrite_tac o single) - \\ ‘1 / nR + -1 / (nR + err) = (-(nR + err) + nR) / (nR * -(nR + err))’ - by (fs[REAL_ADD_RAT, real_div, REAL_MUL_LNEG, REAL_MUL_RNEG] - \\ rewrite_tac[GSYM REAL_MUL_RNEG, REAL_NEG_ADD, REAL_NEG_NEG]) - \\ pop_assum (rewrite_tac o single) - (* Goal: (-(nR + err) + nR) / (nR * -(nR + err)) ≤ err * (1 / (elo + -err) pow 2) *) - \\ `- (nR + err) + nR = - err` by REAL_ASM_ARITH_TAC - \\ pop_assum (rewrite_tac o single) - \\ rewrite_tac[real_div, GSYM REAL_NEG_LMUL, REAL_NEG_RMUL] - \\ match_mp_tac REAL_LE_LMUL_IMP \\ conj_tac \\ simp[] - \\ fs [REAL_NEG_INV, REAL_NEG_RMUL, REAL_NEG_NEG] - (* Goal: inv (nR * (nR + err)) ≤ inv ((elo + -err) pow 2)) *) - \\ match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac - >- (match_mp_tac REAL_LT_MUL \\ REAL_ASM_ARITH_TAC) - \\ conj_tac \\ once_rewrite_tac [POW_2] - >- (match_mp_tac REAL_LT_MUL - \\ REAL_ASM_ARITH_TAC) - \\ match_mp_tac REAL_LE_MUL2 \\ REAL_ASM_ARITH_TAC)) + \\ ‘nR ≠0’ by REAL_ASM_ARITH_TAC + \\ ‘-nF ≠0’ by REAL_ASM_ARITH_TAC + \\ ‘inv nR - inv nF = - ((nR - nF) / (nR * nF))’ + by (gs[real_div, real_sub] \\ rewrite_tac[realTheory.REAL_LDISTRIB, REAL_NEG_ADD] + \\ rewrite_tac [GSYM REAL_MUL_ASSOC] + \\ gs[REAL_MUL_LINV] \\ REAL_ASM_ARITH_TAC) + \\ pop_assum $ gs o single + \\ gs[real_div, Once REAL_ABS_MUL] + \\ irule REAL_LE_TRANS \\ qexists_tac ‘abs (inv nF * inv nR) * err’ + \\ conj_tac \\ gs[] \\ irule REAL_LE_LMUL_IMP \\ gs[] + \\ ‘abs (inv nF * inv nR) = inv (abs (nF * nR))’ by gs[GSYM REAL_INV_MUL, ABS_INV] + \\ pop_assum $ rewrite_tac o single + \\ irule REAL_INV_LE_ANTIMONO_IMPR \\ rewrite_tac [POW_2] \\ rpt conj_tac + >- gs[] + >- (irule REAL_LT_MUL \\ gs[]) + \\ rewrite_tac [ABS_MUL] + \\ irule REAL_LE_MUL2 \\ gs[] + \\ rpt conj_tac + >- (irule REAL_LE_TRANS \\ qexists_tac ‘nF’ \\ gs[ABS_LE]) + >- (irule REAL_LE_TRANS \\ qexists_tac ‘elo’ \\ conj_tac \\ REAL_ASM_ARITH_TAC) + \\ REAL_ASM_ARITH_TAC QED Theorem err_prop_inversion_neg: @@ -550,124 +491,26 @@ Theorem err_prop_inversion_neg: abs (inv nR - inv nF) <= err * inv ((ehi + err) * (ehi + err)) Proof rpt strip_tac - \\ `! (x:real). ((abs x = x) /\ 0 < x) \/ ((abs x = - x) /\ x <= 0)` by REAL_ASM_ARITH_TAC - \\ qpat_x_assum `!x. (A /\ B) \/ C` (fn thm => qspecl_then [`nR - nF` ] DISJ_CASES_TAC thm) - >- (fs [] - \\ `nF <= nR` by REAL_ASM_ARITH_TAC - \\ `0 < -nF /\ nF <> 0` by REAL_ASM_ARITH_TAC - \\ `0 < -nR /\ nR <> 0` by REAL_ASM_ARITH_TAC - \\ `inv (- nF) <= inv (- nR)` - by (match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac - \\ REAL_ASM_ARITH_TAC) - \\ `inv (- nF) - inv (- nR) <= 0` by REAL_ASM_ARITH_TAC - \\ `0 <= - (inv (- nF) - inv (-nR)) ` by REAL_ASM_ARITH_TAC - \\ `abs (- (inv (- nF) - inv (- nR))) = - (inv (- nF) - inv (- nR))` by fs [ABS_REFL] - \\ `abs (inv (- nF) - inv (- nR)) = - (inv (- nF) - inv (- nR))` by metis_tac[ABS_NEG] - \\ `inv (- nF) - inv (- nR) = inv nR - inv nF` - by (fs[GSYM REAL_NEG_INV, real_sub] \\ REAL_ASM_ARITH_TAC) - \\ `abs (inv nR - inv nF) = - (inv nR - inv nF)` by fs[] - \\ simp[real_sub, REAL_NEG_ADD] - \\ rpt (qpat_x_assum `abs v = v'` kall_tac) - \\ `- (1 / nR) = 1 / - nR` - by (fs [real_div] \\ match_mp_tac REAL_NEG_INV \\ REAL_ASM_ARITH_TAC) - \\ simp[] - \\ qspec_then `1 / -nR + 1 / (nR - err)` match_mp_tac real_le_trans2 \\ conj_tac - >- (once_rewrite_tac [REAL_INV_1OVER] - \\ pop_assum (rewrite_tac o single) - \\ match_mp_tac REAL_LE_LADD_IMP - \\ simp[GSYM REAL_INV_1OVER] - \\ `nR - err <= nF` by REAL_ASM_ARITH_TAC - \\ `- nF <= - (nR - err)` by REAL_ASM_ARITH_TAC - \\ `inv (- (nR - err)) <= inv (- nF)` by (match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac \\ REAL_ASM_ARITH_TAC) - \\ `0 <> nR - err` by REAL_ASM_ARITH_TAC - \\ qpat_abbrev_tac `nRerr = nR - err` - \\ once_rewrite_tac [GSYM REAL_LE_NEG] - \\ `- inv (nRerr) = inv (- nRerr)` by (match_mp_tac REAL_NEG_INV \\ simp[]) - \\ `- inv (nF) = inv (- nF)` by (match_mp_tac REAL_NEG_INV \\ simp []) - \\ qpat_x_assum `-(inv nRerr) = v` (fn thm => once_rewrite_tac [thm]) - \\ qpat_x_assum `-(inv nF) = v` (fn thm => once_rewrite_tac [thm]) - \\ simp[]) - >- (`- nR <> 0 /\ nR - err <> 0` by REAL_ASM_ARITH_TAC - \\ ‘1 / -nR + 1 / (nR - err) = (1 * (nR - err) + -nR * 1) / (-nR * (nR - err))’ - by (fs [REAL_ADD_RAT]) - \\ pop_assum (rewrite_tac o single) - \\ rewrite_tac [REAL_MUL_LID, REAL_MUL_RID] - \\ `nR - err + - nR = - err` by REAL_ASM_ARITH_TAC - \\ pop_assum (rewrite_tac o single) - \\ rewrite_tac [GSYM REAL_NEG_LMUL, real_div] - \\ `nR <> 0` by REAL_ASM_ARITH_TAC - \\ `nR * (nR - err) <> 0` by fs[REAL_ENTIRE] - \\ fs [GSYM REAL_NEG_INV, GSYM REAL_NEG_LMUL, GSYM REAL_NEG_RMUL] - \\ match_mp_tac REAL_LE_LMUL_IMP \\ conj_tac \\ simp[] - \\ rpt (qpat_x_assum `T` kall_tac) - \\ `0 < - (ehi + err)` by REAL_ASM_ARITH_TAC - \\ `0 < - (ehi + err) * -(ehi + err)` by (match_mp_tac REAL_LT_MUL \\ fs[]) - \\ `0 < (ehi + err) * (ehi + err)` by REAL_ASM_ARITH_TAC - \\ `0 < - nR * - (nR - err)` by (match_mp_tac REAL_LT_MUL \\ REAL_ASM_ARITH_TAC) - \\ `0 < nR * (nR - err)` by REAL_ASM_ARITH_TAC - \\ match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac \\ TRY (REAL_ASM_ARITH_TAC) - \\ conj_tac \\ once_rewrite_tac [POW_2] \\ TRY (REAL_ASM_ARITH_TAC) - \\ qspec_then `(ehi + err) * (nR - err)` match_mp_tac real_le_trans2 - \\ conj_tac - >- (match_mp_tac REAL_MUL_LE_COMPAT_NEG_L \\ conj_tac \\ REAL_ASM_ARITH_TAC) - >- (`- (nR * (nR - err)) <= - ((ehi + err) * (nR - err))` - by (once_rewrite_tac [REAL_NEG_RMUL] \\ match_mp_tac REAL_LE_RMUL_IMP \\ REAL_ASM_ARITH_TAC) - \\ REAL_ASM_ARITH_TAC))) - \\ fs [] - \\ `nR <= nF` by REAL_ASM_ARITH_TAC - \\ `0 < -nF /\ nF <> 0` by REAL_ASM_ARITH_TAC - \\ `0 < -nR /\ nR <> 0` by REAL_ASM_ARITH_TAC - \\ `inv (- nR) <= inv (- nF)` - by (match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac - \\ REAL_ASM_ARITH_TAC) - \\ `inv (- nR) - inv (- nF) <= 0` by REAL_ASM_ARITH_TAC - \\ `0 <= - (inv (- nR) - inv (-nR)) ` by REAL_ASM_ARITH_TAC - \\ `abs (- (inv (- nR) - inv (- nF))) = - (inv (- nR) - inv (- nF))` by fs [ABS_REFL] - \\ `abs (inv (- nR) - inv (- nF)) = - (inv (- nR) - inv (- nF))` by metis_tac[ABS_NEG] - \\ `inv (- nR) - inv (- nF) = inv nF - inv nR` by (fs[GSYM REAL_NEG_INV, real_sub] \\ REAL_ASM_ARITH_TAC) - \\ `abs (inv nF - inv nR) = - (inv (- nR) - inv (- nF))` by fs[] - \\ `abs (inv nR - inv nF) = - (inv (- nR) - inv (- nF))` by fs[ABS_SUB] - \\ simp[real_sub, REAL_NEG_ADD] - \\ rpt (qpat_x_assum `abs v = v'` kall_tac) - \\ `- (1 / nF) = 1 / - nF` by (fs [real_div] \\ match_mp_tac REAL_NEG_INV \\ REAL_ASM_ARITH_TAC) - \\ simp[] - \\ qspec_then `1 / -(nR + err) + 1 / nR` match_mp_tac real_le_trans2 \\ conj_tac - >- (once_rewrite_tac [REAL_ADD_COMM] \\ rewrite_tac [REAL_INV_1OVER] - \\ pop_assum (rewrite_tac o single) - \\ match_mp_tac REAL_LE_LADD_IMP - \\ `0 < - (nR + err) /\ nF <= nR + err` by REAL_ASM_ARITH_TAC - \\ simp [REAL_LE_NEG, REAL_INV_LE_ANTIMONO, REAL_MUL_LNEG]) - >- (`- nR <> 0 /\ nR - err <> 0` by REAL_ASM_ARITH_TAC - \\ `- (nR + err) <> 0` by REAL_ASM_ARITH_TAC - \\ ‘1 / - (nR + err) + 1 / nR = (1 * nR + - (nR + err) * 1) / (- (nR + err) * nR)’ - by (fs[REAL_ADD_RAT]) - \\ pop_assum (rewrite_tac o single) - \\ rewrite_tac [REAL_MUL_RID, REAL_MUL_LID, real_div, GSYM REAL_NEG_RMUL, GSYM REAL_NEG_LMUL] - \\ `nR + - (nR + err) = - err` by REAL_ASM_ARITH_TAC - \\ pop_assum (rewrite_tac o single) - \\ `inv (- ((nR + err) * nR)) = - (inv ((nR + err) * nR))` - by (match_mp_tac (GSYM REAL_NEG_INV) \\ fs[] \\ REAL_ASM_ARITH_TAC) - \\ pop_assum (rewrite_tac o single) - \\ simp[GSYM REAL_NEG_RMUL, GSYM REAL_NEG_LMUL, REAL_NEG_NEG] - \\ match_mp_tac REAL_LE_LMUL_IMP \\ conj_tac \\ simp[] - \\ `0 < - (ehi + err)` by REAL_ASM_ARITH_TAC - \\ `0 < - (ehi + err) * -(ehi + err)` by (match_mp_tac REAL_LT_MUL \\ fs[]) - \\ `0 < (ehi + err) * (ehi + err)` by REAL_ASM_ARITH_TAC - \\ `0 < - nR * - (nR + err)` by (match_mp_tac REAL_LT_MUL \\ REAL_ASM_ARITH_TAC) - \\ `0 < nR * (nR + err)` by REAL_ASM_ARITH_TAC - \\ asm_rewrite_tac[GSYM REAL_NEG_RMUL] - \\ once_rewrite_tac [REAL_MUL_COMM] - \\ asm_rewrite_tac[REAL_NEG_INV, REAL_NEGNEG, GSYM REAL_INV_1OVER] - \\ match_mp_tac REAL_INV_LE_ANTIMONO_IMPR \\ conj_tac - \\ once_rewrite_tac [POW_2] \\ TRY (REAL_ASM_ARITH_TAC) - \\ conj_tac \\ TRY(REAL_ASM_ARITH_TAC) - \\ qspec_then `(nR + err) * (ehi + err)` match_mp_tac real_le_trans2 - \\ conj_tac - >- (once_rewrite_tac [REAL_MUL_COMM] - \\ match_mp_tac REAL_MUL_LE_COMPAT_NEG_L \\ conj_tac \\ REAL_ASM_ARITH_TAC) - \\ `- (nR * (nR + err)) <= - ((ehi + err) * (nR + err))` - by (once_rewrite_tac [REAL_NEG_RMUL] \\ match_mp_tac REAL_LE_RMUL_IMP \\ REAL_ASM_ARITH_TAC) - \\ REAL_ASM_ARITH_TAC) + \\ ‘0 < (-ehi) + -err’ by REAL_ASM_ARITH_TAC + \\ qspecl_then [‘-nF’, ‘-nR’, ‘err’, ‘-ehi’, ‘-elo’] mp_tac err_prop_inversion_pos + \\ impl_tac + >- ( + rpt conj_tac \\ TRY (gs[real_sub] \\ NO_TAC) + >- (gs[real_sub] \\ REAL_ASM_ARITH_TAC) + \\ REAL_ASM_ARITH_TAC) + \\ strip_tac + \\ ‘nR ≠0 ∧ nF ≠0’ by REAL_ASM_ARITH_TAC + \\ ‘abs (inv nR - inv nF) = abs (inv (-nR) - inv (- nF))’ + by (gs[GSYM REAL_NEG_INV, real_sub] \\ REAL_ASM_ARITH_TAC) + \\ pop_assum $ rewrite_tac o single + \\ irule REAL_LE_TRANS \\ asm_exists_tac \\ gs[] + \\ irule REAL_LE_LMUL_IMP \\ gs[] + \\ irule REAL_INV_LE_ANTIMONO_IMPR \\ rpt conj_tac + >- (rewrite_tac[REAL_POW_POS] \\ DISJ2_TAC \\ DISJ1_TAC \\ gs[real_sub]) + >- (rewrite_tac[REAL_POW_POS] \\ DISJ2_TAC \\ DISJ2_TAC \\ gs[]) + \\ ‘-ehi - err = -1 * (ehi + err)’ by REAL_ASM_ARITH_TAC + \\ pop_assum $ rewrite_tac o single + \\ rewrite_tac [POW_MUL] \\ gs[POW_MINUS1] QED val _ = export_theory(); -- GitLab