From 06ad54dec40fbf0bbee97243be5ceab57517eadb Mon Sep 17 00:00:00 2001 From: Heiko Becker <hbecker@mpi-sws.org> Date: Tue, 12 May 2020 13:38:58 +0200 Subject: [PATCH] Fix bug in FMA evaluation, add some small lemmas --- hol4/CertificateCheckerScript.sml | 8 + hol4/CommandsScript.sml | 1 + hol4/ErrorBoundsScript.sml | 16 +- hol4/ErrorValidationScript.sml | 154 +++++++++-------- hol4/ExpressionsScript.sml | 2 +- hol4/FPRangeValidatorScript.sml | 37 ++-- hol4/IEEE_connectionScript.sml | 247 +++++++++++++++++++++------ hol4/IntervalValidationScript.sml | 167 +++++++++--------- hol4/RealIntervalInferenceScript.sml | 2 +- hol4/TypeValidatorScript.sml | 31 ++++ 10 files changed, 428 insertions(+), 237 deletions(-) diff --git a/hol4/CertificateCheckerScript.sml b/hol4/CertificateCheckerScript.sml index 70de241d..96783cbe 100644 --- a/hol4/CertificateCheckerScript.sml +++ b/hol4/CertificateCheckerScript.sml @@ -150,4 +150,12 @@ Proof \\ fs[] QED +Theorem CertificateCheckerCmd_Gamma_is_getValidMapCmd: + CertificateCheckerCmd f A P dVars = SOME Gamma ⇒ + getValidMapCmd dVars f FloverMapTree_empty = Succes Gamma +Proof + fs[CertificateCheckerCmd_def] + \\ rpt (TOP_CASE_TAC \\ fs[]) +QED + val _ = export_theory(); diff --git a/hol4/CommandsScript.sml b/hol4/CommandsScript.sml index c7b2e9e5..b1c23388 100644 --- a/hol4/CommandsScript.sml +++ b/hol4/CommandsScript.sml @@ -30,6 +30,7 @@ val toREvalCmd_def = Define ` val (bstep_rules, bstep_ind, bstep_cases) = Hol_reln ` (!m m' x e s E v res Gamma. eval_expr E Gamma e v m /\ + Gamma (Var x) = SOME m ∧ bstep s (updEnv x v E) Gamma res m' ==> bstep (Let m x e s) E Gamma res m') /\ (!m e E v Gamma. diff --git a/hol4/ErrorBoundsScript.sml b/hol4/ErrorBoundsScript.sml index 4d9da554..e129830a 100644 --- a/hol4/ErrorBoundsScript.sml +++ b/hol4/ErrorBoundsScript.sml @@ -293,8 +293,8 @@ Proof QED val float_fma_tac = - `e1R + e2R * e3R + -((e1F + e2F * e3F) * (1 + deltaF)) = - (e1R + e2R * e3R + -(e1F + e2F * e3F)) + (- (e1F + e2F * e3F) * deltaF)` + `e1R * e2R + e3R + -((1 + deltaF) * (e1F * e2F + e3F)) = + (e1R * e2R + e3R + -(e1F * e2F + e3F)) + (- (e1F * e2F + e3F) * deltaF)` by REAL_ASM_ARITH_TAC \\ simp[] \\ triangle_tac @@ -324,8 +324,8 @@ Theorem fma_abs_err_bounded: abs (e2R - e2F) <= err2 /\ abs (e3R - e3F) <= err3 ==> abs (vR - vF) <= - abs ((e1R - e1F) + (e2R * e3R - e2F * e3F)) + - computeError (e1F + e2F * e3F) m + abs ((e1R * e2R - e1F * e2F) + (e3R - e3F)) + + computeError (e1F * e2F + e3F) m Proof rpt strip_tac \\ fs[toREval_def] \\ inversion `eval_expr E1 _ (Fma _ _ _) _ _` eval_expr_cases @@ -350,15 +350,15 @@ Proof \\ Cases_on `mF` \\ fs[computeError_def, perturb_def] \\ rewrite_tac[real_sub] - >- (`e1R + e2R * e3R + - (e1F + e2F * e3F) = - e1R + - e1F + (e2R * e3R + - (e2F * e3F))` + >- (`e1R * e2R + e3R + - (e1F * e2F + e3F) = + (e1R * e2R + - (e1F * e2F) + (e3R + - e3F))` by REAL_ASM_ARITH_TAC \\ simp[]) >- (float_fma_tac) >- (float_fma_tac) >- (float_fma_tac) - \\ `e1R + e2R * e3R + -(e1F + e2F * e3F + deltaF) = - (e1R + e2R * e3R + - (e1F + e2F * e3F)) + - deltaF` + \\ `e1R * e2R + e3R + -(e1F * e2F + e3F + deltaF) = + (e1R * e2R + e3R + - (e1F * e2F + e3F)) + - deltaF` by REAL_ASM_ARITH_TAC \\ simp[] \\ triangle_tac diff --git a/hol4/ErrorValidationScript.sml b/hol4/ErrorValidationScript.sml index c0ba05f0..5cef7fa1 100644 --- a/hol4/ErrorValidationScript.sml +++ b/hol4/ErrorValidationScript.sml @@ -98,10 +98,10 @@ val validErrorbound_def = Define ` upperBoundE1 = maxAbs ive1; upperBoundE2 = maxAbs ive2; upperBoundE3 = maxAbs ive3; - errIntv_prod = multInterval errIve2 errIve3; - mult_error_bound = (upperBoundE2 * err3 + upperBoundE3 * err2 + err2 * err3); - mAbs = maxAbs (addInterval errIve1 errIntv_prod) in - err1 + mult_error_bound + computeError mAbs m <= err + errIntv_prod = multInterval errIve1 errIve2; + mult_error_bound = (upperBoundE1 * err2 + upperBoundE2 * err1 + err1 * err2); + mAbs = maxAbs (addInterval errIntv_prod errIve3 ) in + mult_error_bound + err3 + computeError mAbs m <= err |_, _, _ => F else F) | Downcast m1 e1 => @@ -2100,35 +2100,36 @@ val validErrorboundCorrectDiv = store_thm ("validErrorboundCorrectDiv", \\ assume_tac (REWRITE_RULE [contained_def] interval_division_valid) \\ fs[contained_def, widenInterval_def, noDivzero_def]); -val validErrorboundCorrectFma = store_thm ("validErrorboundCorrectFma", - ``!(E1 E2:env) (A:analysisResult) (e1:real expr) (e2:real expr) (e3: real expr) - (nR nR1 nR2 nR3 nF nF1 nF2 nF3:real) (e err1 err2 err3:real) - (alo ahi e1lo e1hi e2lo e2hi e3lo e3hi :real) dVars m m1 m2 m3 Gamma. - eval_Real E1 Gamma e1 nR1 /\ - eval_Real E1 Gamma e2 nR2 /\ - eval_Real E1 Gamma e3 nR3 /\ - eval_Real E1 Gamma (Fma e1 e2 e3) nR /\ - eval_Fin E2 Gamma e1 nF1 m1 /\ - eval_Fin E2 Gamma e2 nF2 m2 /\ - eval_Fin E2 Gamma e3 nF3 m3 /\ - eval_expr (updEnv 3 nF3 (updEnv 2 nF2 (updEnv 1 nF1 emptyEnv))) - (updDefVars (Fma (Var 1) (Var 2) (Var 3)) m - (updDefVars (Var 3) m3 - (updDefVars (Var 2) m2 (updDefVars (Var 1) m1 (toRExpMap Gamma))))) - (Fma (Var 1) (Var 2) (Var 3)) nF m /\ - validErrorbound (Fma e1 e2 e3) Gamma A dVars /\ - (e1lo <= nR1 /\ nR1 <= e1hi) /\ - (e2lo <= nR2 /\ nR2 <= e2hi) /\ - (e3lo <= nR3 /\ nR3 <= e3hi) /\ - FloverMapTree_find e1 A = SOME ((e1lo, e1hi), err1) /\ - FloverMapTree_find e2 A = SOME ((e2lo, e2hi), err2) /\ - FloverMapTree_find e3 A = SOME ((e3lo, e3hi), err3) /\ - FloverMapTree_find (Fma e1 e2 e3) A = SOME ((alo, ahi), e) /\ - FloverMapTree_find (Fma e1 e2 e3) Gamma = SOME m /\ - abs (nR1 - nF1) <= err1 /\ - abs (nR2 - nF2) <= err2 /\ - abs (nR3 - nF3) <= err3 ==> - abs (nR - nF) <= e``, +Theorem validErrorboundCorrectFma: + !(E1 E2:env) (A:analysisResult) (e1:real expr) (e2:real expr) (e3: real expr) + (nR nR1 nR2 nR3 nF nF1 nF2 nF3:real) (e err1 err2 err3:real) + (alo ahi e1lo e1hi e2lo e2hi e3lo e3hi :real) dVars m m1 m2 m3 Gamma. + eval_Real E1 Gamma e1 nR1 /\ + eval_Real E1 Gamma e2 nR2 /\ + eval_Real E1 Gamma e3 nR3 /\ + eval_Real E1 Gamma (Fma e1 e2 e3) nR /\ + eval_Fin E2 Gamma e1 nF1 m1 /\ + eval_Fin E2 Gamma e2 nF2 m2 /\ + eval_Fin E2 Gamma e3 nF3 m3 /\ + eval_expr (updEnv 3 nF3 (updEnv 2 nF2 (updEnv 1 nF1 emptyEnv))) + (updDefVars (Fma (Var 1) (Var 2) (Var 3)) m + (updDefVars (Var 3) m3 + (updDefVars (Var 2) m2 (updDefVars (Var 1) m1 (toRExpMap Gamma))))) + (Fma (Var 1) (Var 2) (Var 3)) nF m /\ + validErrorbound (Fma e1 e2 e3) Gamma A dVars /\ + (e1lo <= nR1 /\ nR1 <= e1hi) /\ + (e2lo <= nR2 /\ nR2 <= e2hi) /\ + (e3lo <= nR3 /\ nR3 <= e3hi) /\ + FloverMapTree_find e1 A = SOME ((e1lo, e1hi), err1) /\ + FloverMapTree_find e2 A = SOME ((e2lo, e2hi), err2) /\ + FloverMapTree_find e3 A = SOME ((e3lo, e3hi), err3) /\ + FloverMapTree_find (Fma e1 e2 e3) A = SOME ((alo, ahi), e) /\ + FloverMapTree_find (Fma e1 e2 e3) Gamma = SOME m /\ + abs (nR1 - nF1) <= err1 /\ + abs (nR2 - nF2) <= err2 /\ + abs (nR3 - nF3) <= err3 ==> + abs (nR - nF) <= e +Proof fs [toREval_def] \\ rpt strip_tac \\ simp[Once toREval_def] \\ Flover_compute ``validErrorbound`` \\ fs [] \\ rveq @@ -2142,8 +2143,8 @@ val validErrorboundCorrectFma = store_thm ("validErrorboundCorrectFma", by (irule err_always_positive \\ rpt (asm_exists_tac \\ fs[])) \\ irule REAL_LE_TRANS - \\ qexists_tac `abs ((nR1 - nF1) + (nR2 * nR3 - nF2 * nF3)) + - computeError (nF1 + nF2 * nF3) m` + \\ qexists_tac `abs ((nR1 * nR2 - nF1 * nF2) + (nR3 - nF3)) + + computeError (nF1 * nF2 + nF3) m` \\ conj_tac >- (irule fma_abs_err_bounded \\ rpt conj_tac \\ rpt (find_exists_tac \\ fs[toREval_def])) @@ -2153,6 +2154,10 @@ val validErrorboundCorrectFma = store_thm ("validErrorboundCorrectFma", >- (irule triangle_trans \\ fs[REAL_ABS_TRIANGLE] \\ irule REAL_LE_ADD2 \\ fs[] \\ irule multiplicationErrorBounded \\ fs[]) + \\ `contained nF1 (widenInterval (e1lo,e1hi) err1)` + by (irule distance_gives_iv + \\ qexists_tac `nR1` \\ conj_tac + \\ simp[contained_def, IVlo_def, IVhi_def]) \\ `contained nF2 (widenInterval (e2lo,e2hi) err2)` by (irule distance_gives_iv \\ qexists_tac `nR2` \\ conj_tac @@ -2161,22 +2166,19 @@ val validErrorboundCorrectFma = store_thm ("validErrorboundCorrectFma", by (irule distance_gives_iv \\ qexists_tac `nR3` \\ conj_tac \\ simp[contained_def, IVlo_def, IVhi_def]) - \\ `contained (nF2 * nF3) - (multInterval (widenInterval (e2lo, e2hi) err2) - (widenInterval (e3lo, e3hi) err3))` + \\ `contained (nF1 * nF2) + (multInterval (widenInterval (e1lo, e1hi) err1) + (widenInterval (e2lo, e2hi) err2))` by (irule (ONCE_REWRITE_RULE [validIntervalMult_def] interval_multiplication_valid) \\ conj_tac \\ simp[]) - \\ `contained nF1 (widenInterval (e1lo,e1hi) err1)` - by (irule distance_gives_iv - \\ qexists_tac `nR1` \\ conj_tac - \\ simp[contained_def]) \\ qmatch_abbrev_tac `_ <= computeError (maxAbs iv) _` \\ PairCases_on `iv` \\ irule computeError_up \\ unabbrev_all_tac \\ fs[maxAbs_def] \\ irule maxAbs \\ assume_tac (REWRITE_RULE [validIntervalAdd_def, contained_def] interval_addition_valid) - \\ fs[contained_def, widenInterval_def, IVlo_def, IVhi_def, noDivzero_def]); + \\ fs[contained_def, widenInterval_def, IVlo_def, IVhi_def, noDivzero_def] +QED val validErrorboundCorrectRounding = store_thm ("validErrorboundCorrectRounding", ``!(E1 E2:env) (A:analysisResult) (e:real expr) @@ -2543,21 +2545,21 @@ val validErrorbound_sound = store_thm ("validErrorbound_sound", \\ irule Var_load \\ fs[updDefVars_def, updEnv_def])); -val validErrorboundCmd_gives_eval = store_thm ( - "validErrorboundCmd_gives_eval", - ``!(f:real cmd) (A:analysisResult) (E1 E2:env) - (outVars fVars dVars:num_set) (vR elo ehi err:real) - (m:mType) Gamma. - validTypesCmd f Gamma /\ - approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 /\ - ssa f (union fVars dVars) outVars /\ - ((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars) /\ - bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ - validErrorboundCmd f Gamma A dVars /\ - validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ - FloverMapTree_find (getRetExp f) A = SOME ((elo,ehi),err) ==> - ?vF m. - bstep f E2 (toRExpMap Gamma) vF m``, +Theorem validErrorboundCmd_gives_eval: + !(f:real cmd) (A:analysisResult) (E1 E2:env) + (outVars fVars dVars:num_set) (vR elo ehi err:real) + (m:mType) Gamma. + validTypesCmd f Gamma /\ + approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 /\ + ssa f (union fVars dVars) outVars /\ + ((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars) /\ + bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ + validErrorboundCmd f Gamma A dVars /\ + validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ + FloverMapTree_find (getRetExp f) A = SOME ((elo,ehi),err) ==> + ?vF m. + bstep f E2 (toRExpMap Gamma) vF m +Proof Induct_on `f` \\ rpt strip_tac \\ Flover_compute ``validErrorboundCmd`` \\ rveq \\ fs[Once toREvalCmd_def] @@ -2618,7 +2620,7 @@ val validErrorboundCmd_gives_eval = store_thm ( \\ fs[Once toREvalCmd_def]) \\ qexistsl_tac [`vF_res`, `m_res`] \\ fs[bstep_cases] - \\ qexists_tac `vF` \\ rveq \\ fs[]) + \\ qexists_tac `vF` \\ rveq \\ fs[toRExpMap_def]) >- (fs[getRetExp_def] \\ inversion `ssa _ _ _` ssa_cases \\ inversion `bstep _ _ _ _ _` bstep_cases @@ -2628,21 +2630,23 @@ val validErrorboundCmd_gives_eval = store_thm ( by (irule (REWRITE_RULE [eval_Fin_def] validErrorbound_sound) \\ fs[validTypesCmd_def, validRangesCmd_def, freeVars_def] \\ rpt (find_exists_tac \\ fs[])) - \\ qexistsl_tac [`vF`, `m`] \\ fs[])); + \\ qexistsl_tac [`vF`, `m`] \\ fs[]) +QED -val validErrorboundCmd_sound = store_thm ("validErrorboundCmd_sound", - ``!(f:real cmd) (A:analysisResult) (E1 E2:env) - (outVars fVars dVars:num_set) (vR vF elo ehi err:real) (m:mType) Gamma. - validTypesCmd f Gamma /\ - approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 /\ - ssa f (union fVars dVars) outVars /\ - ((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars) /\ - bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ - bstep f E2 (toRExpMap Gamma) vF m /\ - validErrorboundCmd f Gamma A dVars /\ - validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ - FloverMapTree_find (getRetExp f) A = SOME ((elo,ehi),err) ==> - abs (vR - vF) <= err``, +Theorem validErrorboundCmd_sound: + !(f:real cmd) (A:analysisResult) (E1 E2:env) + (outVars fVars dVars:num_set) (vR vF elo ehi err:real) (m:mType) Gamma. + validTypesCmd f Gamma /\ + approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 /\ + ssa f (union fVars dVars) outVars /\ + ((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars) /\ + bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ + bstep f E2 (toRExpMap Gamma) vF m /\ + validErrorboundCmd f Gamma A dVars /\ + validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ + FloverMapTree_find (getRetExp f) A = SOME ((elo,ehi),err) ==> + abs (vR - vF) <= err +Proof Induct_on `f` \\ rpt strip_tac \\ Flover_compute ``validErrorboundCmd`` \\ rveq \\ fs[Once toREvalCmd_def] @@ -2668,7 +2672,6 @@ val validErrorboundCmd_sound = store_thm ("validErrorboundCmd_sound", >- (fs[Once toREvalCmd_def]) >- (irule approxEnvUpdBound \\ rpt conj_tac \\ fs[] - >- (fs[Once validTypesCmd_def] \\ fs[toRExpMap_def]) >- (Cases_on `lookup n (union fVars dVars)` \\ fs [domain_lookup]) \\ qspecl_then [`e`, `E1`, `E2`, `A`, `vr`, `err_e`, `FST (iv_e)`, @@ -2688,6 +2691,7 @@ val validErrorboundCmd_sound = store_thm ("validErrorboundCmd_sound", destruct validErrorbound_sound \\ fs[freeVars_def, getRetExp_def, Once validTypesCmd_def, Once validRangesCmd_def] \\ first_x_assum irule \\ fs[] - \\ find_exists_tac \\ fs[])); + \\ find_exists_tac \\ fs[]) +QED val _ = export_theory(); diff --git a/hol4/ExpressionsScript.sml b/hol4/ExpressionsScript.sml index fa5d871d..549eeeb5 100644 --- a/hol4/ExpressionsScript.sml +++ b/hol4/ExpressionsScript.sml @@ -57,7 +57,7 @@ val _ = Datatype ` Errors are added on the exprression evaluation level later **) val evalFma_def = Define ` - evalFma v1 v2 v3 = evalBinop Plus v1 (evalBinop Mult v2 v3)`; + evalFma v1 v2 v3 = evalBinop Plus (evalBinop Mult v1 v2) v3`; val toREval_def = Define ` (toREval (Var n) = Var n) /\ diff --git a/hol4/FPRangeValidatorScript.sml b/hol4/FPRangeValidatorScript.sml index 6a0614c1..ba69e2d4 100644 --- a/hol4/FPRangeValidatorScript.sml +++ b/hol4/FPRangeValidatorScript.sml @@ -167,22 +167,22 @@ val FPRangeValidator_sound = store_thm ( \\ fs[] \\ rveq \\ fs[]) \\ solve_tac); -val FPRangeValidatorCmd_sound = store_thm ( - "FPRangeValidatorCmd_sound", - ``!f E1 E2 Gamma v vR m A fVars dVars outVars. - approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 ∧ - ssa f (union fVars dVars) outVars /\ - bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR m /\ - bstep f E2 (toRExpMap Gamma) v m ∧ - validTypesCmd f Gamma /\ - validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ - validErrorboundCmd f Gamma A dVars ∧ - FPRangeValidatorCmd f A Gamma dVars ∧ - domain (freeVars f) DIFF domain dVars ⊆ domain fVars ∧ - (!(v:num). v IN domain dVars ==> - (?vF m. E2 v = SOME vF /\ FloverMapTree_find (Var v) Gamma = SOME m - /\ validFloatValue vF m)) ==> - validFloatValue v m``, +Theorem FPRangeValidatorCmd_sound: + !f E1 E2 Gamma v vR m A fVars dVars outVars. + approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 ∧ + ssa f (union fVars dVars) outVars /\ + bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR m /\ + bstep f E2 (toRExpMap Gamma) v m ∧ + validTypesCmd f Gamma /\ + validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\ + validErrorboundCmd f Gamma A dVars ∧ + FPRangeValidatorCmd f A Gamma dVars ∧ + domain (freeVars f) DIFF domain dVars ⊆ domain fVars ∧ + (!(v:num). v IN domain dVars ==> + (?vF m. E2 v = SOME vF /\ FloverMapTree_find (Var v) Gamma = SOME m + /\ validFloatValue vF m)) ==> + validFloatValue v m +Proof Induct \\ simp[Once toREvalCmd_def, Once FPRangeValidatorCmd_def, Once freeVars_def] @@ -224,8 +224,6 @@ val FPRangeValidatorCmd_sound = store_thm ( impl_subgoal_tac) >- (fs[] \\ rpt conj_tac >- (irule approxEnvUpdBound \\ fs[lookup_NONE_domain] - \\ conj_tac - >- (fs[Once validTypesCmd_def, toRExpMap_def]) \\ first_x_assum (qspecl_then [`vF`, `m`] irule) \\ qexists_tac `m` \\ fs[]) >- (irule ssa_equal_set @@ -285,6 +283,7 @@ val FPRangeValidatorCmd_sound = store_thm ( \\ rpt (inversion `bstep (Ret _) _ _ _ _` bstep_cases) \\ drule FPRangeValidator_sound \\ rpt (disch_then drule) - \\ fs[Once validTypesCmd_def, Once validRangesCmd_def]); + \\ fs[Once validTypesCmd_def, Once validRangesCmd_def] +QED val _ = export_theory(); diff --git a/hol4/IEEE_connectionScript.sml b/hol4/IEEE_connectionScript.sml index 7bca265d..e36395ae 100644 --- a/hol4/IEEE_connectionScript.sml +++ b/hol4/IEEE_connectionScript.sml @@ -41,8 +41,9 @@ val eval_expr_float_def = Define ` | Div => SOME (fp64_div dmode v1 v2)) | _, _ => NONE)) /\ (eval_expr_float (Fma e1 e2 e3) E = - (case (eval_expr_float e1 E), (eval_expr_float e2 E), (eval_expr_float e2 E) of - | _, _, _ => NONE)) /\ + (case (eval_expr_float e1 E), (eval_expr_float e2 E), (eval_expr_float e3 E) of + | SOME v1, SOME v2, SOME v3 => SOME (fp64_mul_add roundTiesToEven v1 v2 v3) + | _, _, _ => NONE)) /\ (eval_expr_float (Downcast m e) E = NONE)`; val bstep_float_def = Define ` @@ -93,7 +94,7 @@ val eval_expr_valid_def = Define ` in optionLift e3_res (\ v3. let v3_real = float_to_real (fp64_to_float v3) in - F) + normal_or_zero (evalFma v1_real v2_real v3_real)) T) T) T)) /\ @@ -530,29 +531,30 @@ val typing_cmd_64bit = store_thm ( \\ rpt strip_tac \\ fs[] \\ res_tac); -val eval_expr_gives_IEEE = store_thm ("eval_expr_gives_IEEE", - ``!(e:word64 expr) E1 E2 E2_real Gamma vR A fVars dVars. - (!x. (toREnv E2) x = E2_real x) /\ - validTypes (toRExp e) Gamma /\ - approxEnv E1 (toRExpMap Gamma) A fVars dVars E2_real /\ - validRanges (toRExp e) A E1 (toRTMap (toRExpMap Gamma)) /\ - validErrorbound (toRExp e) Gamma A dVars /\ - FPRangeValidator (toRExp e) A Gamma dVars /\ - eval_expr (toREnv E2) (toRExpMap Gamma) (toRExp e) vR M64 /\ - domain (usedVars (toRExp e)) DIFF domain dVars ⊆ domain fVars ∧ - is64BitEval (toRExp e) /\ - is64BitEnv Gamma /\ - noDowncast (toRExp e) /\ - eval_expr_valid e E2 /\ - (∀v. - v ∈ domain dVars ⇒ - ∃vF m. - (E2_real v = SOME vF ∧ FloverMapTree_find (Var v) Gamma = SOME m ∧ - validFloatValue vF m)) ==> - ?v. - eval_expr_float e E2 = SOME v /\ - eval_expr (toREnv E2) (toRExpMap Gamma) (toRExp e) - (float_to_real (fp64_to_float v)) M64``, +Theorem eval_expr_gives_IEEE: + !(e:word64 expr) E1 E2 E2_real Gamma vR A fVars dVars. + (!x. (toREnv E2) x = E2_real x) /\ + validTypes (toRExp e) Gamma /\ + approxEnv E1 (toRExpMap Gamma) A fVars dVars E2_real /\ + validRanges (toRExp e) A E1 (toRTMap (toRExpMap Gamma)) /\ + validErrorbound (toRExp e) Gamma A dVars /\ + FPRangeValidator (toRExp e) A Gamma dVars /\ + eval_expr (toREnv E2) (toRExpMap Gamma) (toRExp e) vR M64 /\ + domain (usedVars (toRExp e)) DIFF domain dVars ⊆ domain fVars ∧ + is64BitEval (toRExp e) /\ + is64BitEnv Gamma /\ + noDowncast (toRExp e) /\ + eval_expr_valid e E2 /\ + (∀v. + v ∈ domain dVars ⇒ + ∃vF m. + (E2_real v = SOME vF ∧ FloverMapTree_find (Var v) Gamma = SOME m ∧ + validFloatValue vF m)) ==> + ?v. + eval_expr_float e E2 = SOME v /\ + eval_expr (toREnv E2) (toRExpMap Gamma) (toRExp e) + (float_to_real (fp64_to_float v)) M64 +Proof Induct_on `e` \\ rewrite_tac[toRExp_def] \\ rpt strip_tac \\ inversion `eval_expr _ _ _ _ _` eval_expr_cases \\ once_rewrite_tac [eval_expr_float_def] @@ -1059,34 +1061,168 @@ val eval_expr_gives_IEEE = store_thm ("eval_expr_gives_IEEE", \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) Gamma = _`) \\ rw_thm_asm `domain (usedVars _) DIFF _ SUBSET _` usedVars_def \\ fs[domain_union, DIFF_DEF, SUBSET_DEF]) - \\ fs[optionLift_def])); + \\ rename1 ‘eval_expr_float e1 E2 = SOME vF1’ + \\ rename1 ‘eval_expr_float e2 E2 = SOME vF2’ + \\ rename1 ‘eval_expr_float e3 E2 = SOME vF3’ + \\ `validFloatValue + (evalFma (float_to_real (fp64_to_float vF1)) + (float_to_real (fp64_to_float vF2)) + (float_to_real (fp64_to_float vF3))) M64` + by (drule FPRangeValidator_sound + \\ disch_then + (qspecl_then + [`(Fma (toRExp e1) (toRExp e2) (toRExp e3))`, + `evalFma (float_to_real (fp64_to_float vF1)) + (float_to_real (fp64_to_float vF2)) + (float_to_real (fp64_to_float vF3))`, + `M64`] irule) + \\ fs[] + \\ qexistsl_tac [`e1`, `e2`, ‘e3’] \\ fs[] + \\ rpt conj_tac + >- (simp[Once validTypes_def] \\ first_x_assum MATCH_ACCEPT_TAC) + >- (simp[Once validRanges_def] \\ find_exists_tac \\ fs[] + \\ fs[] \\ rveq \\ fs[]) + \\ irule eval_eq_env + \\ find_exists_tac \\ fs[eval_expr_cases] + \\ qexistsl_tac [`M64`, `M64`, ‘M64’, `float_to_real (fp64_to_float vF1)`, + `float_to_real (fp64_to_float vF2)`, + `float_to_real (fp64_to_float vF3)`, `0:real`] + \\ fs[perturb_def, evalFma_def, mTypeToR_pos]) + \\ `validFloatValue (float_to_real (fp64_to_float vF1)) M64` + by (drule FPRangeValidator_sound + \\ disch_then + (qspecl_then + [`toRExp e1`, `float_to_real (fp64_to_float vF1)`, + `M64`] irule) + \\ fs[] + \\ qexistsl_tac [`e1`] \\ fs[] + \\ rpt conj_tac + >- (rw_thm_asm `domain (usedVars _) DIFF _ SUBSET _` usedVars_def + \\ fs[domain_union, DIFF_DEF, SUBSET_DEF, Once usedVars_def]) + >- (rw_thm_asm `FPRangeValidator _ _ _ _` FPRangeValidator_def + \\ fs[] \\ rveq + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) A = _` + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) Gamma = _`) + >- (Flover_compute ``validErrorbound``) + \\ irule eval_eq_env + \\ find_exists_tac \\ fs[]) + \\ `validFloatValue (float_to_real (fp64_to_float vF2)) M64` + by (drule FPRangeValidator_sound + \\ disch_then + (qspecl_then + [`toRExp e2`, `float_to_real (fp64_to_float vF2)`, + `M64`] irule) + \\ fs[] + \\ qexists_tac `e2` \\ fs[] + \\ rpt conj_tac + >- (rw_thm_asm `domain (usedVars _) DIFF _ SUBSET _` usedVars_def + \\ fs[domain_union, DIFF_DEF, SUBSET_DEF]) + >- (rw_thm_asm `FPRangeValidator _ _ _ _` FPRangeValidator_def + \\ fs[] \\ rveq + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) A = _` + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) Gamma = _`) + >- (Flover_compute ``validErrorbound``) + \\ irule eval_eq_env + \\ find_exists_tac \\ fs[]) + \\ `validFloatValue (float_to_real (fp64_to_float vF3)) M64` + by (drule FPRangeValidator_sound + \\ disch_then + (qspecl_then + [`toRExp e3`, `float_to_real (fp64_to_float vF3)`, + `M64`] irule) + \\ fs[] + \\ qexists_tac `e3` \\ fs[] + \\ rpt conj_tac + >- (rw_thm_asm `domain (usedVars _) DIFF _ SUBSET _` usedVars_def + \\ fs[domain_union, DIFF_DEF, SUBSET_DEF]) + >- (rw_thm_asm `FPRangeValidator _ _ _ _` FPRangeValidator_def + \\ fs[] \\ rveq + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) A = _` + \\ rw_asm_star `FloverMapTree_find (Fma _ _ _) Gamma = _`) + >- (Flover_compute ``validErrorbound``) + \\ irule eval_eq_env + \\ find_exists_tac \\ fs[]) + \\ fs[optionLift_def, normal_or_zero_def] + \\ simp[Once eval_expr_cases, PULL_EXISTS] + \\ rewrite_tac [CONJ_ASSOC] + \\ ntac 3 (once_rewrite_tac [CONJ_COMM] \\ asm_exists_tac \\ fs[]) + \\ fs[evalFma_def, evalBinop_def, fp64_mul_add_def, fp64_to_float_float_to_fp64] + >- ( + `normal (evalFma (float_to_real (fp64_to_float vF1)) + (float_to_real (fp64_to_float vF2)) + (float_to_real (fp64_to_float vF3))) M64` + by ( + rw_thm_asm `validFloatValue (_ + _) _` validFloatValue_def + \\ fs[normal_def, denormal_def, evalFma_def, evalBinop_def] + >- ( + `abs (float_to_real (fp64_to_float vF1) * + float_to_real (fp64_to_float vF2) + float_to_real (fp64_to_float vF3)) < + abs (float_to_real (fp64_to_float vF1) * + float_to_real (fp64_to_float vF2) + float_to_real (fp64_to_float vF3))` + suffices_by (fs[]) + \\ irule REAL_LTE_TRANS + \\ asm_exists_tac \\ fs[]) + \\ qpat_x_assum `_ + _ = 0` (fn thm => fs[thm]) + \\ fs[maxValue_def, maxExponent_def]) + \\ Q.ISPECL_THEN [`(fp64_to_float vF1):(52,11) float`, + `(fp64_to_float vF2):(52,11) float`, + `(fp64_to_float vF3):(52,11) float`] + impl_subgoal_tac + float_mul_add_relative + >- (rpt conj_tac + \\ fs[validFloatValue_def, + normalTranslatedValue_implies_finiteness, + denormalTranslatedValue_implies_finiteness, + normalValue_implies_normalization, + GSYM float_is_zero_to_real, float_is_finite, evalFma_def, evalBinop_def]) + \\ fs[dmode_def] + \\ fs[perturb_def] + \\ qexistsl_tac [`e`] + \\ pop_assum (rewrite_tac o single) + \\ fs[perturb_def, evalBinop_def] + \\ fs[mTypeToR_def]) + (* result = 0 *) + >- (IMP_RES_TAC validValue_gives_float_value + \\ fs[REAL_LNEG_UNIQ, evalFma_def, evalBinop_def] + \\ fs[fp64_add_def, dmode_def, fp64_mul_def, fp64_to_float_float_to_fp64] + \\ fs[float_mul_add_def, float_round_with_flags_def] + \\ qexistsl_tac [`0:real`] + \\ fs[perturb_def, mTypeToR_pos, evalBinop_def] + \\ fs[float_is_nan_def, float_is_infinite_def] + \\ `2 * abs (0:real) <= ulp (:52 #11)` + by (fs[REAL_ABS_0, ulp_def, ULP_def, REAL_OF_NUM_POW] + \\ once_rewrite_tac [real_div] + \\ irule REAL_LE_MUL \\ fs[] + \\ irule REAL_LE_INV \\ fs[]) + \\ fs[float_to_real_round_zero_is_zero])) +QED -val bstep_gives_IEEE = store_thm ( - "bstep_gives_IEEE", - ``!(f:word64 cmd) E1 E2 E2_real Gamma vR vF A fVars dVars outVars. - (!x. (toREnv E2) x = E2_real x) /\ - approxEnv E1 (toRExpMap Gamma) A fVars dVars E2_real /\ - ssa (toRCmd f) (union fVars dVars) outVars /\ - validTypesCmd (toRCmd f) Gamma /\ - validRangesCmd (toRCmd f) A E1 (toRTMap (toRExpMap Gamma)) /\ - validErrorboundCmd (toRCmd f) Gamma A dVars /\ - FPRangeValidatorCmd (toRCmd f) A Gamma dVars /\ - bstep (toREvalCmd (toRCmd f)) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ - bstep (toRCmd f) (toREnv E2) (toRExpMap Gamma) vF M64 /\ - domain (freeVars (toRCmd f)) DIFF domain dVars ⊆ domain fVars ∧ - is64BitBstep (toRCmd f) /\ - is64BitEnv Gamma /\ - noDowncastFun (toRCmd f) /\ - bstep_valid f E2 /\ - (∀v. - v ∈ domain dVars ⇒ - ∃vF m. - (E2_real v = SOME vF ∧ FloverMapTree_find (Var v) Gamma = SOME m ∧ - validFloatValue vF m)) ==> - ?v. - bstep_float f E2 = SOME v /\ - bstep (toRCmd f) (toREnv E2) (toRExpMap Gamma) - (float_to_real (fp64_to_float v)) M64``, +Theorem bstep_gives_IEEE: + !(f:word64 cmd) E1 E2 E2_real Gamma vR vF A fVars dVars outVars. + (!x. (toREnv E2) x = E2_real x) /\ + approxEnv E1 (toRExpMap Gamma) A fVars dVars E2_real /\ + ssa (toRCmd f) (union fVars dVars) outVars /\ + validTypesCmd (toRCmd f) Gamma /\ + validRangesCmd (toRCmd f) A E1 (toRTMap (toRExpMap Gamma)) /\ + validErrorboundCmd (toRCmd f) Gamma A dVars /\ + FPRangeValidatorCmd (toRCmd f) A Gamma dVars /\ + bstep (toREvalCmd (toRCmd f)) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\ + bstep (toRCmd f) (toREnv E2) (toRExpMap Gamma) vF M64 /\ + domain (freeVars (toRCmd f)) DIFF domain dVars ⊆ domain fVars ∧ + is64BitBstep (toRCmd f) /\ + is64BitEnv Gamma /\ + noDowncastFun (toRCmd f) /\ + bstep_valid f E2 /\ + (∀v. + v ∈ domain dVars ⇒ + ∃vF m. + (E2_real v = SOME vF ∧ FloverMapTree_find (Var v) Gamma = SOME m ∧ + validFloatValue vF m)) ==> + ?v. + bstep_float f E2 = SOME v /\ + bstep (toRCmd f) (toREnv E2) (toRExpMap Gamma) + (float_to_real (fp64_to_float v)) M64 +Proof Induct_on `f` \\ simp [toRCmd_def, Once toREvalCmd_def, is64BitBstep_def, noDowncastFun_def, bstep_valid_def] @@ -1245,7 +1381,7 @@ val bstep_gives_IEEE = store_thm ( \\ irule eval_eq_env \\ asm_exists_tac \\ fs[])) \\ fs[] - \\ irule let_b \\ find_exists_tac + \\ irule let_b \\ fs[toRExpMap_def] \\ find_exists_tac \\ fs[] \\ irule bstep_eq_env \\ find_exists_tac \\ fs[] \\ strip_tac \\ fs[toREnv_def, updEnv_def, updFlEnv_def] @@ -1256,7 +1392,8 @@ val bstep_gives_IEEE = store_thm ( >- (find_exists_tac \\ fs[]) \\ qexistsl_tac [`A`, `E1`, `dVars`, `fVars`] \\ rpt conj_tac - \\ fs[freeVars_def, Once FPRangeValidatorCmd_def, validRangesCmd_def])); + \\ fs[freeVars_def, Once FPRangeValidatorCmd_def, validRangesCmd_def]) +QED val found_tac = TRY (last_x_assum irule \\ find_exists_tac \\ fs[] \\ FAIL_TAC "") \\ first_x_assum irule \\ find_exists_tac \\ fs[]; diff --git a/hol4/IntervalValidationScript.sml b/hol4/IntervalValidationScript.sml index 6f707a89..f718ca03 100644 --- a/hol4/IntervalValidationScript.sml +++ b/hol4/IntervalValidationScript.sml @@ -87,7 +87,7 @@ val validIntervalbounds_def = Define ` case FloverMapTree_find f1 absenv, FloverMapTree_find f2 absenv, FloverMapTree_find f3 absenv of | SOME (iv1, _), SOME (iv2, _), SOME (iv3, _) => - let new_iv = addInterval iv1 (multInterval iv2 iv3) in + let new_iv = addInterval (multInterval iv1 iv2) iv3 in isSupersetInterval new_iv intv | _, _, _ => F else F)) @@ -120,16 +120,17 @@ val real_prove = \\ rpt (qpat_x_assum `_ ==> ! x. _` kall_tac) \\ REAL_ASM_ARITH_TAC; -val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound", - ``!(f:real expr) (A:analysisResult) (P:precond) (fVars:num_set) - (dVars:num_set) E Gamma. - validIntervalbounds f A P dVars /\ (* The checker succeeded *) - (* All defined vars have already been analyzed *) - dVars_range_valid dVars E A /\ - (((domain (usedVars f)) DIFF (domain dVars)) SUBSET (domain fVars)) /\ - fVars_P_sound fVars E P /\ - validTypes f Gamma ==> - validRanges f A E (toRTMap (toRExpMap Gamma))``, +Theorem validIntervalbounds_sound: + !(f:real expr) (A:analysisResult) (P:precond) (fVars:num_set) + (dVars:num_set) E Gamma. + validIntervalbounds f A P dVars /\ (* The checker succeeded *) + (* All defined vars have already been analyzed *) + dVars_range_valid dVars E A /\ + (((domain (usedVars f)) DIFF (domain dVars)) SUBSET (domain fVars)) /\ + fVars_P_sound fVars E P /\ + validTypes f Gamma ==> + validRanges f A E (toRTMap (toRExpMap Gamma)) +Proof Induct_on `f` \\ once_rewrite_tac [usedVars_def, toREval_def] \\ rpt strip_tac \\ rveq \\ Flover_compute ``validIntervalbounds`` \\ rveq @@ -295,7 +296,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound", \\ rename1 `FloverMapTree_find f1 A = SOME (iv_f1, err1)` \\ rename1 `FloverMapTree_find f2 A = SOME (iv_f2, err2)` \\ rename1 `FloverMapTree_find f3 A = SOME (iv_f3, err3)` - \\ qspecl_then [`iv_f2`, `iv_f3`, `vR2`, `vR3`] + \\ qspecl_then [`iv_f1`, `iv_f2`, `vR1`, `vR2`] destruct (REWRITE_RULE [validIntervalAdd_def, @@ -303,7 +304,7 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound", absIntvUpd_def, contained_def] interval_multiplication_valid) \\ fs[] - \\ qspecl_then [`iv_f1`, `multInterval iv_f2 iv_f3`, `vR1`, `vR2 * vR3`] + \\ qspecl_then [`multInterval iv_f1 iv_f2`, `iv_f3`, `vR1 * vR2`, `vR3`] destruct (REWRITE_RULE [validIntervalAdd_def, @@ -328,65 +329,73 @@ val validIntervalbounds_sound = store_thm ("validIntervalbounds_sound", \\ fs[Downcast_dist', toREval_def, isSupersetInterval_def] \\ `FST iv = FST intv` by (metis_tac [REAL_LE_ANTISYM]) \\ `SND iv = SND intv` by (metis_tac [REAL_LE_ANTISYM]) - \\ fs[])); + \\ fs[]) +QED -val validIntervalboundsCmd_sound = store_thm ( - "validIntervalboundsCmd_sound", - ``!f A E fVars dVars outVars P Gamma. - ssa f (union fVars dVars) outVars /\ - dVars_range_valid dVars E A /\ - fVars_P_sound fVars E P /\ - (((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars)) /\ - validIntervalboundsCmd f A P dVars /\ - validTypesCmd f Gamma ==> - validRangesCmd f A E (toRTMap (toRExpMap Gamma))``, +Theorem validIntervalboundsCmd_sound: + ∀ f A E fVars dVars outVars P Gamma. + ssa f (union fVars dVars) outVars /\ + dVars_range_valid dVars E A /\ + fVars_P_sound fVars E P /\ + (((domain (freeVars f)) DIFF (domain dVars)) SUBSET (domain fVars)) /\ + validIntervalboundsCmd f A P dVars /\ + validTypesCmd f Gamma ==> + validRangesCmd f A E (toRTMap (toRExpMap Gamma)) +Proof Induct_on `f` \\ once_rewrite_tac [toREvalCmd_def, getRetExp_def, validTypesCmd_def] \\ rpt strip_tac \\ Flover_compute ``validIntervalboundsCmd`` - >- (inversion `ssa _ _ _` ssa_cases \\ rveq - \\ drule validIntervalbounds_sound - \\ rpt (disch_then drule) - \\ disch_then (qspecl_then [`fVars`, `Gamma`] destruct) - >- (fs [SUBSET_DEF, domain_union] - \\ rpt strip_tac \\ res_tac) - \\ IMP_RES_TAC validRanges_single - \\ rename1 `FloverMapTree_find e A = SOME (iv_e, err_e)` - \\ first_x_assum - (qspecl_then [`A`, `updEnv n vR E`, `fVars`, `insert n () dVars`, - `outVars`, `P`, `Gamma`] - destruct) - >- (fs [domain_insert] - \\ rpt conj_tac - >- (irule ssa_equal_set - \\ qexists_tac `(insert n () (union fVars dVars))` - \\ fs [domain_union, domain_insert] - \\ once_rewrite_tac [UNION_COMM] - \\ fs [INSERT_UNION_EQ, UNION_COMM]) - >- (fs[dVars_range_valid_def] - \\ rpt strip_tac \\ fs[updEnv_def] - >- (rveq \\ fs[]) - \\ rename1 `v2 IN domain dVars` - \\ Cases_on `v2 = n` \\ fs[] - \\ rveq \\ fs [domain_union]) - >- (fs[fVars_P_sound_def] - \\ rpt strip_tac \\ fs[updEnv_def] - \\ rename1 `v2 IN domain fVars` - \\ Cases_on `v2 = n` \\ rveq \\ fs[domain_union]) - \\ fs [domain_insert, SUBSET_DEF] - \\ rpt strip_tac - \\ first_x_assum match_mp_tac - \\ once_rewrite_tac [freeVars_def, domain_union] - \\ fs [domain_union]) - \\ simp[Once validRangesCmd_def] - \\ conj_tac - >- (rpt strip_tac - \\ `vR = vR'` by (metis_tac [meps_0_deterministic]) - \\ rveq \\ fs[]) - \\ IMP_RES_TAC validRangesCmd_single - \\ fs[getRetExp_def] - \\ find_exists_tac \\ simp[Once toREvalCmd_def] - \\ irule let_b \\ find_exists_tac \\ fs[]) + >- ( + inversion `ssa _ _ _` ssa_cases \\ rveq + \\ drule validIntervalbounds_sound + \\ rpt (disch_then drule) + \\ disch_then (qspecl_then [`fVars`, `Gamma`] destruct) + >- ( + fs [SUBSET_DEF, domain_union] + \\ rpt strip_tac \\ res_tac) + \\ imp_res_tac validRanges_single + \\ rename1 `FloverMapTree_find e A = SOME (iv_e, err_e)` + \\ first_x_assum + (qspecl_then [`A`, `updEnv n vR E`, `fVars`, `insert n () dVars`, + `outVars`, `P`, `Gamma`] + destruct) + >- ( + fs [domain_insert] + \\ rpt conj_tac + >- ( + irule ssa_equal_set + \\ qexists_tac `(insert n () (union fVars dVars))` + \\ fs [domain_union, domain_insert] + \\ once_rewrite_tac [UNION_COMM] + \\ fs [INSERT_UNION_EQ, UNION_COMM]) + >- ( + fs[dVars_range_valid_def] + \\ rpt strip_tac \\ fs[updEnv_def] + >- (rveq \\ fs[]) + \\ rename1 `v2 IN domain dVars` + \\ Cases_on `v2 = n` \\ fs[] + \\ rveq \\ fs [domain_union]) + >- ( + fs[fVars_P_sound_def] + \\ rpt strip_tac \\ fs[updEnv_def] + \\ rename1 `v2 IN domain fVars` + \\ Cases_on `v2 = n` \\ rveq \\ fs[domain_union]) + \\ fs [domain_insert, SUBSET_DEF] + \\ rpt strip_tac + \\ first_x_assum match_mp_tac + \\ once_rewrite_tac [freeVars_def, domain_union] + \\ fs [domain_union]) + \\ simp[Once validRangesCmd_def] + \\ conj_tac + >- ( + rpt strip_tac + \\ `vR = vR'` by (metis_tac [meps_0_deterministic]) + \\ rveq \\ fs[]) + \\ imp_res_tac validRangesCmd_single + \\ fs[getRetExp_def] + \\ find_exists_tac \\ simp[Once toREvalCmd_def] + \\ irule let_b \\ fs[toRTMap_def, toRExpMap_def] \\ find_exists_tac \\ fs[]) \\ inversion `ssa _ _ _` ssa_cases \\ drule validIntervalbounds_sound \\ rpt (disch_then drule) @@ -395,17 +404,19 @@ val validIntervalboundsCmd_sound = store_thm ( \\ simp[Once validRangesCmd_def] \\ IMP_RES_TAC validRanges_single \\ simp[Once getRetExp_def, Once toREvalCmd_def] - \\ fs[] \\ find_exists_tac \\ fs[ret_b]); + \\ fs[] \\ find_exists_tac \\ fs[ret_b] +QED -val validIntervalbounds_validates_iv = store_thm ("validIntervalbounds_validates_iv", - ``!(f:real expr) (A:analysisResult) (P:precond) (dVars:num_set). - (!v. v IN domain dVars ==> - ? iv err. FloverMapTree_find (Var v) A = SOME (iv,err) /\ - valid iv) /\ - validIntervalbounds f A P dVars ==> - ? iv err. - FloverMapTree_find f A = SOME (iv, err) /\ - valid iv``, +Theorem validIntervalbounds_validates_iv: + !(f:real expr) (A:analysisResult) (P:precond) (dVars:num_set). + (!v. v IN domain dVars ==> + ? iv err. FloverMapTree_find (Var v) A = SOME (iv,err) /\ + valid iv) /\ + validIntervalbounds f A P dVars ==> + ? iv err. + FloverMapTree_find f A = SOME (iv, err) /\ + valid iv +Proof Induct_on `f` \\ rpt strip_tac \\ Flover_compute ``validIntervalbounds`` @@ -481,7 +492,7 @@ val validIntervalbounds_validates_iv = store_thm ("validIntervalbounds_validates \\ rename1 `FloverMapTree_find f2 A = SOME (iv_f2, err_f2)` \\ rename1 `FloverMapTree_find f3 A = SOME (iv_f3, err_f3)` \\ fs[] - \\ `valid (addInterval iv_f1 (multInterval iv_f2 iv_f3))` + \\ `valid (addInterval (multInterval iv_f1 iv_f2) iv_f3)` by (irule iv_add_preserves_valid \\ fs[] \\ irule iv_mult_preserves_valid \\ fs[]) \\ fs[valid_def, isSupersetInterval_def] diff --git a/hol4/RealIntervalInferenceScript.sml b/hol4/RealIntervalInferenceScript.sml index ab9d3520..aea0e78c 100644 --- a/hol4/RealIntervalInferenceScript.sml +++ b/hol4/RealIntervalInferenceScript.sml @@ -67,7 +67,7 @@ Definition inferIntervalbounds_def: iv_e1 <- FloverMapTree_find e1 recRes3; iv_e2 <- FloverMapTree_find e2 recRes3; iv_e3 <- FloverMapTree_find e3 recRes3; - SOME (FloverMapTree_insert e (addInterval iv_e1 (multInterval iv_e2 iv_e3)) recRes3); + SOME (FloverMapTree_insert e (addInterval (multInterval iv_e1 iv_e2) iv_e3) recRes3); od)) End diff --git a/hol4/TypeValidatorScript.sml b/hol4/TypeValidatorScript.sml index 67783c06..a42f5903 100644 --- a/hol4/TypeValidatorScript.sml +++ b/hol4/TypeValidatorScript.sml @@ -860,4 +860,35 @@ val getValidMapCmd_correct = store_thm ( \\ rpt strip_tac \\ fs[bstep_cases] \\ first_x_assum irule \\ ntac 2 (find_exists_tac \\ fs[])); +Theorem validTypes_defined_usedVars: + ∀ e Gamma. + validTypes e Gamma ⇒ + ∀ x. x IN domain (usedVars e) ⇒ + ∃ m. FloverMapTree_find (Var x) Gamma = SOME m +Proof + ho_match_mp_tac (fetch "-" "validTypes_ind") + \\ rpt strip_tac + \\ qpat_x_assum ‘validTypes _ _’ mp_tac \\ simp[Once validTypes_def] + \\ every_case_tac + \\ qpat_x_assum ‘_ IN domain (usedVars _)’ mp_tac + \\ simp[Once usedVars_def] + \\ rpt strip_tac \\ rveq \\ fs[domain_union] +QED + +Theorem validTypesCmd_freevars: + ∀ e Gamma. + validTypesCmd e Gamma ⇒ + ∀ x. x IN domain (freeVars e) ⇒ + ∃ m. FloverMapTree_find (Var x) Gamma = SOME m +Proof + ho_match_mp_tac (fetch "-" "validTypesCmd_ind") + \\ rpt strip_tac + \\ qpat_x_assum ‘validTypesCmd _ _’ mp_tac \\ simp[Once validTypesCmd_def] + \\ every_case_tac + \\ qpat_x_assum ‘_ IN domain (freeVars _)’ mp_tac + \\ simp[Once freeVars_def, domain_union] + \\ rpt strip_tac \\ rveq \\ fs[domain_union] + \\ imp_res_tac validTypes_defined_usedVars \\ fs[] +QED + val _ = export_theory(); -- GitLab