diff options
Diffstat (limited to '')
| -rw-r--r-- | backends/hol4/primitivesScript.sml | 551 | 
1 files changed, 222 insertions, 329 deletions
diff --git a/backends/hol4/primitivesScript.sml b/backends/hol4/primitivesScript.sml index 2df3375a..9da8505d 100644 --- a/backends/hol4/primitivesScript.sml +++ b/backends/hol4/primitivesScript.sml @@ -534,34 +534,35 @@ fun prove_arith_op_eq (asms, g) =        | _ => failwith "Unexpected"      val x = (snd o dest_comb) x_to_int;      val y = (snd o dest_comb) y_to_int; +    val rw_thms = int_rem_def :: List.concat [all_rem_defs, all_add_defs, all_sub_defs, all_mul_defs, all_div_defs, all_mk_int_defs, all_to_int_bounds_lemmas, all_conversion_id_lemmas];      fun inst_first_lem arg lems = -      MAP_FIRST (fn th => (ASSUME_TAC (SPEC arg th) handle HOL_ERR _ => FAIL_TAC "")) lems; +      map_first (fn th => (assume_tac (SPEC arg th) handle HOL_ERR _ => fail_tac "")) lems;    in      (rpt gen_tac >> -     rpt DISCH_TAC >> -     ASSUME_TAC usize_bounds >> (* Only useful for usize of course *) -     ASSUME_TAC isize_bounds >> (* Only useful for isize of course *) -     rw (int_rem_def :: List.concat [all_rem_defs, all_add_defs, all_sub_defs, all_mul_defs, all_div_defs, all_mk_int_defs, all_to_int_bounds_lemmas, all_conversion_id_lemmas]) >> -     fs (int_rem_def :: List.concat [all_rem_defs, all_add_defs, all_sub_defs, all_mul_defs, all_div_defs, all_mk_int_defs, all_to_int_bounds_lemmas, all_conversion_id_lemmas]) >> +     rpt disch_tac >> +     assume_tac usize_bounds >> (* Only useful for usize of course *) +     assume_tac isize_bounds >> (* Only useful for isize of course *) +     rw rw_thms >> +     fs rw_thms >>       inst_first_lem x all_to_int_bounds_lemmas >>       inst_first_lem y all_to_int_bounds_lemmas >> -     gs [NOT_LE_EQ_GT, NOT_LT_EQ_GE, NOT_GE_EQ_LT, NOT_GT_EQ_LE, GE_EQ_LE, GT_EQ_LT] >> -     TRY COOPER_TAC >> -     FIRST [ +     gs [not_le_eq_gt, not_lt_eq_ge, not_ge_eq_lt, not_gt_eq_le, ge_eq_le, gt_eq_lt] >> +     try_tac cooper_tac >> +     first_tac [         (* For division *) -       qspecl_then [‘^x_to_int’, ‘^y_to_int’] ASSUME_TAC POS_DIV_POS_IS_POS >> -       qspecl_then [‘^x_to_int’, ‘^y_to_int’] ASSUME_TAC POS_DIV_POS_LE_INIT >> -       COOPER_TAC, +       qspecl_assume [‘^x_to_int’, ‘^y_to_int’] pos_div_pos_is_pos >> +       qspecl_assume [‘^x_to_int’, ‘^y_to_int’] pos_div_pos_le_init >> +       cooper_tac,         (* For remainder *)         dep_rewrite.DEP_PURE_ONCE_REWRITE_TAC all_conversion_id_lemmas >> fs [] >> -       qspecl_then [‘^x_to_int’, ‘^y_to_int’] ASSUME_TAC POS_MOD_POS_IS_POS >> -       qspecl_then [‘^x_to_int’, ‘^y_to_int’] ASSUME_TAC POS_MOD_POS_LE_INIT >> -       COOPER_TAC, +       qspecl_assume [‘^x_to_int’, ‘^y_to_int’] pos_mod_pos_is_pos >> +       qspecl_assume [‘^x_to_int’, ‘^y_to_int’] pos_mod_pos_le_init >> +       cooper_tac,         dep_rewrite.DEP_PURE_ONCE_REWRITE_TAC all_conversion_id_lemmas >> fs []       ]) (asms, g)    end -Theorem U8_ADD_EQ: +Theorem u8_add_eq:    !x y.      u8_to_int x + u8_to_int y <= u8_max ==>      ?z. u8_add x y = Return z /\ u8_to_int z = u8_to_int x + u8_to_int y @@ -569,7 +570,7 @@ Proof    prove_arith_op_eq  QED -Theorem U16_ADD_EQ: +Theorem u16_add_eq:    !(x y).      u16_to_int x + u16_to_int y <= u16_max ==>      ?(z). u16_add x y = Return z /\ u16_to_int z = u16_to_int x + u16_to_int y @@ -577,7 +578,7 @@ Proof    prove_arith_op_eq  QED -Theorem U32_ADD_EQ: +Theorem u32_add_eq:    !x y.      u32_to_int x + u32_to_int y <= u32_max ==>      ?z. u32_add x y = Return z /\ u32_to_int z = u32_to_int x + u32_to_int y @@ -585,7 +586,7 @@ Proof    prove_arith_op_eq  QED -Theorem U64_ADD_EQ: +Theorem u64_add_eq:    !x y.      u64_to_int x + u64_to_int y <= u64_max ==>      ?z. u64_add x y = Return z /\ u64_to_int z = u64_to_int x + u64_to_int y @@ -593,7 +594,7 @@ Proof    prove_arith_op_eq  QED -Theorem U128_ADD_EQ: +Theorem u128_add_eq:    !x y.      u128_to_int x + u128_to_int y <= u128_max ==>      ?z. u128_add x y = Return z /\ u128_to_int z = u128_to_int x + u128_to_int y @@ -601,7 +602,7 @@ Proof    prove_arith_op_eq  QED -Theorem USIZE_ADD_EQ: +Theorem usize_add_eq:    !x y.      (usize_to_int x + usize_to_int y <= u16_max) \/ (usize_to_int x + usize_to_int y <= usize_max) ==>      ?z. usize_add x y = Return z /\ usize_to_int z = usize_to_int x + usize_to_int y @@ -609,7 +610,7 @@ Proof    prove_arith_op_eq  QED -Theorem I8_ADD_EQ: +Theorem i8_add_eq:    !x y.      i8_min <= i8_to_int x + i8_to_int y ==>      i8_to_int x + i8_to_int y <= i8_max ==> @@ -618,7 +619,7 @@ Proof    prove_arith_op_eq  QED -Theorem I16_ADD_EQ: +Theorem i16_add_eq:    !x y.      i16_min <= i16_to_int x + i16_to_int y ==>      i16_to_int x + i16_to_int y <= i16_max ==> @@ -627,7 +628,7 @@ Proof    prove_arith_op_eq  QED -Theorem I32_ADD_EQ: +Theorem i32_add_eq:    !x y.      i32_min <= i32_to_int x + i32_to_int y ==>      i32_to_int x + i32_to_int y <= i32_max ==> @@ -636,7 +637,7 @@ Proof    prove_arith_op_eq  QED -Theorem I64_ADD_EQ: +Theorem i64_add_eq:    !x y.      i64_min <= i64_to_int x + i64_to_int y ==>      i64_to_int x + i64_to_int y <= i64_max ==> @@ -645,7 +646,7 @@ Proof    prove_arith_op_eq  QED -Theorem I128_ADD_EQ: +Theorem i128_add_eq:    !x y.      i128_min <= i128_to_int x + i128_to_int y ==>      i128_to_int x + i128_to_int y <= i128_max ==> @@ -654,7 +655,7 @@ Proof    prove_arith_op_eq  QED -Theorem ISIZE_ADD_EQ: +Theorem isize_add_eq:    !x y.      (i16_min <= isize_to_int x + isize_to_int y \/ isize_min <= isize_to_int x + isize_to_int y) ==>      (isize_to_int x + isize_to_int y <= i16_max \/ isize_to_int x + isize_to_int y <= isize_max) ==> @@ -664,21 +665,21 @@ Proof  QED  val all_add_eqs = [ -  ISIZE_ADD_EQ, -  I8_ADD_EQ, -  I16_ADD_EQ, -  I32_ADD_EQ, -  I64_ADD_EQ, -  I128_ADD_EQ, -  USIZE_ADD_EQ, -  U8_ADD_EQ, -  U16_ADD_EQ, -  U32_ADD_EQ, -  U64_ADD_EQ, -  U128_ADD_EQ +  isize_add_eq, +  i8_add_eq, +  i16_add_eq, +  i32_add_eq, +  i64_add_eq, +  i128_add_eq, +  usize_add_eq, +  u8_add_eq, +  u16_add_eq, +  u32_add_eq, +  u64_add_eq, +  u128_add_eq  ] -Theorem U8_SUB_EQ: +Theorem u8_sub_eq:    !x y.      0 <= u8_to_int x - u8_to_int y ==>      ?z. u8_sub x y = Return z /\ u8_to_int z = u8_to_int x - u8_to_int y @@ -686,7 +687,7 @@ Proof    prove_arith_op_eq  QED -Theorem U16_SUB_EQ: +Theorem u16_sub_eq:    !x y.      0 <= u16_to_int x - u16_to_int y ==>      ?z. u16_sub x y = Return z /\ u16_to_int z = u16_to_int x - u16_to_int y @@ -694,7 +695,7 @@ Proof    prove_arith_op_eq  QED -Theorem U32_SUB_EQ: +Theorem u32_sub_eq:    !x y.      0 <= u32_to_int x - u32_to_int y ==>      ?z. u32_sub x y = Return z /\ u32_to_int z = u32_to_int x - u32_to_int y @@ -702,7 +703,7 @@ Proof    prove_arith_op_eq  QED -Theorem U64_SUB_EQ: +Theorem u64_sub_eq:    !x y.      0 <= u64_to_int x - u64_to_int y ==>      ?z. u64_sub x y = Return z /\ u64_to_int z = u64_to_int x - u64_to_int y @@ -710,7 +711,7 @@ Proof    prove_arith_op_eq  QED -Theorem U128_SUB_EQ: +Theorem u128_sub_eq:    !x y.      0 <= u128_to_int x - u128_to_int y ==>      ?z. u128_sub x y = Return z /\ u128_to_int z = u128_to_int x - u128_to_int y @@ -718,7 +719,7 @@ Proof    prove_arith_op_eq  QED -Theorem USIZE_SUB_EQ: +Theorem usize_sub_eq:    !x y.      0 <= usize_to_int x - usize_to_int y ==>      ?z. usize_sub x y = Return z /\ usize_to_int z = usize_to_int x - usize_to_int y @@ -726,7 +727,7 @@ Proof    prove_arith_op_eq  QED -Theorem I8_SUB_EQ: +Theorem i8_sub_eq:    !x y.      i8_min <= i8_to_int x - i8_to_int y ==>      i8_to_int x - i8_to_int y <= i8_max ==> @@ -735,7 +736,7 @@ Proof    prove_arith_op_eq  QED -Theorem I16_SUB_EQ: +Theorem i16_sub_eq:    !x y.      i16_min <= i16_to_int x - i16_to_int y ==>      i16_to_int x - i16_to_int y <= i16_max ==> @@ -744,7 +745,7 @@ Proof    prove_arith_op_eq  QED -Theorem I32_SUB_EQ: +Theorem i32_sub_eq:    !x y.      i32_min <= i32_to_int x - i32_to_int y ==>      i32_to_int x - i32_to_int y <= i32_max ==> @@ -753,7 +754,7 @@ Proof    prove_arith_op_eq  QED -Theorem I64_SUB_EQ: +Theorem i64_sub_eq:    !x y.      i64_min <= i64_to_int x - i64_to_int y ==>      i64_to_int x - i64_to_int y <= i64_max ==> @@ -762,7 +763,7 @@ Proof    prove_arith_op_eq  QED -Theorem I128_SUB_EQ: +Theorem i128_sub_eq:    !x y.      i128_min <= i128_to_int x - i128_to_int y ==>      i128_to_int x - i128_to_int y <= i128_max ==> @@ -771,7 +772,7 @@ Proof    prove_arith_op_eq  QED -Theorem ISIZE_SUB_EQ: +Theorem isize_sub_eq:    !x y.      (i16_min <= isize_to_int x - isize_to_int y \/ isize_min <= isize_to_int x - isize_to_int y) ==>      (isize_to_int x - isize_to_int y <= i16_max \/ isize_to_int x - isize_to_int y <= isize_max) ==> @@ -781,21 +782,21 @@ Proof  QED  val all_sub_eqs = [ -  ISIZE_SUB_EQ, -  I8_SUB_EQ, -  I16_SUB_EQ, -  I32_SUB_EQ, -  I64_SUB_EQ, -  I128_SUB_EQ, -  USIZE_SUB_EQ, -  U8_SUB_EQ, -  U16_SUB_EQ, -  U32_SUB_EQ, -  U64_SUB_EQ, -  U128_SUB_EQ +  isize_sub_eq, +  i8_sub_eq, +  i16_sub_eq, +  i32_sub_eq, +  i64_sub_eq, +  i128_sub_eq, +  usize_sub_eq, +  u8_sub_eq, +  u16_sub_eq, +  u32_sub_eq, +  u64_sub_eq, +  u128_sub_eq  ] -Theorem U8_MUL_EQ: +Theorem u8_mul_eq:    !x y.      u8_to_int x * u8_to_int y <= u8_max ==>      ?z. u8_mul x y = Return z /\ u8_to_int z = u8_to_int x * u8_to_int y @@ -803,7 +804,7 @@ Proof    prove_arith_op_eq  QED -Theorem U16_MUL_EQ: +Theorem u16_mul_eq:    !x y.      u16_to_int x * u16_to_int y <= u16_max ==>      ?z. u16_mul x y = Return z /\ u16_to_int z = u16_to_int x * u16_to_int y @@ -811,7 +812,7 @@ Proof    prove_arith_op_eq  QED -Theorem U32_MUL_EQ: +Theorem u32_mul_eq:    !x y.      u32_to_int x * u32_to_int y <= u32_max ==>      ?z. u32_mul x y = Return z /\ u32_to_int z = u32_to_int x * u32_to_int y @@ -819,7 +820,7 @@ Proof    prove_arith_op_eq  QED -Theorem U64_MUL_EQ: +Theorem u64_mul_eq:    !x y.      u64_to_int x * u64_to_int y <= u64_max ==>      ?z. u64_mul x y = Return z /\ u64_to_int z = u64_to_int x * u64_to_int y @@ -827,7 +828,7 @@ Proof    prove_arith_op_eq  QED -Theorem U128_MUL_EQ: +Theorem u128_mul_eq:    !x y.      u128_to_int x * u128_to_int y <= u128_max ==>      ?z. u128_mul x y = Return z /\ u128_to_int z = u128_to_int x * u128_to_int y @@ -835,7 +836,7 @@ Proof    prove_arith_op_eq  QED -Theorem USIZE_MUL_EQ: +Theorem usize_mul_eq:    !x y.      (usize_to_int x * usize_to_int y <= u16_max) \/ (usize_to_int x * usize_to_int y <= usize_max) ==>      ?z. usize_mul x y = Return z /\ usize_to_int z = usize_to_int x * usize_to_int y @@ -843,7 +844,7 @@ Proof    prove_arith_op_eq  QED -Theorem I8_MUL_EQ: +Theorem i8_mul_eq:    !x y.      i8_min <= i8_to_int x * i8_to_int y ==>      i8_to_int x * i8_to_int y <= i8_max ==> @@ -852,7 +853,7 @@ Proof    prove_arith_op_eq  QED -Theorem I16_MUL_EQ: +Theorem i16_mul_eq:    !x y.      i16_min <= i16_to_int x * i16_to_int y ==>      i16_to_int x * i16_to_int y <= i16_max ==> @@ -861,7 +862,7 @@ Proof    prove_arith_op_eq  QED -Theorem I32_MUL_EQ: +Theorem i32_mul_eq:    !x y.      i32_min <= i32_to_int x * i32_to_int y ==>      i32_to_int x * i32_to_int y <= i32_max ==> @@ -870,7 +871,7 @@ Proof    prove_arith_op_eq  QED -Theorem I64_MUL_EQ: +Theorem i64_mul_eq:    !x y.      i64_min <= i64_to_int x * i64_to_int y ==>      i64_to_int x * i64_to_int y <= i64_max ==> @@ -879,7 +880,7 @@ Proof    prove_arith_op_eq  QED -Theorem I128_MUL_EQ: +Theorem i128_mul_eq:    !x y.      i128_min <= i128_to_int x * i128_to_int y ==>      i128_to_int x * i128_to_int y <= i128_max ==> @@ -888,7 +889,7 @@ Proof    prove_arith_op_eq  QED -Theorem ISIZE_MUL_EQ: +Theorem isize_mul_eq:    !x y.      (i16_min <= isize_to_int x * isize_to_int y \/ isize_min <= isize_to_int x * isize_to_int y) ==>      (isize_to_int x * isize_to_int y <= i16_max \/ isize_to_int x * isize_to_int y <= isize_max) ==> @@ -898,21 +899,21 @@ Proof  QED  val all_mul_eqs = [ -  ISIZE_MUL_EQ, -  I8_MUL_EQ, -  I16_MUL_EQ, -  I32_MUL_EQ, -  I64_MUL_EQ, -  I128_MUL_EQ, -  USIZE_MUL_EQ, -  U8_MUL_EQ, -  U16_MUL_EQ, -  U32_MUL_EQ, -  U64_MUL_EQ, -  U128_MUL_EQ +  isize_mul_eq, +  i8_mul_eq, +  i16_mul_eq, +  i32_mul_eq, +  i64_mul_eq, +  i128_mul_eq, +  usize_mul_eq, +  u8_mul_eq, +  u16_mul_eq, +  u32_mul_eq, +  u64_mul_eq, +  u128_mul_eq  ] -Theorem U8_DIV_EQ: +Theorem u8_div_eq:    !x y.      u8_to_int y <> 0 ==>      ?z. u8_div x y = Return z /\ u8_to_int z = u8_to_int x / u8_to_int y @@ -920,7 +921,7 @@ Proof    prove_arith_op_eq  QED -Theorem U16_DIV_EQ: +Theorem u16_div_eq:    !x y.      u16_to_int y <> 0 ==>      ?z. u16_div x y = Return z /\ u16_to_int z = u16_to_int x / u16_to_int y @@ -928,7 +929,7 @@ Proof    prove_arith_op_eq  QED -Theorem U32_DIV_EQ: +Theorem u32_div_eq:    !x y.      u32_to_int y <> 0 ==>      ?z. u32_div x y = Return z /\ u32_to_int z = u32_to_int x / u32_to_int y @@ -936,7 +937,7 @@ Proof    prove_arith_op_eq  QED -Theorem U64_DIV_EQ: +Theorem u64_div_eq:    !x y.      u64_to_int y <> 0 ==>      ?z. u64_div x y = Return z /\ u64_to_int z = u64_to_int x / u64_to_int y @@ -944,7 +945,7 @@ Proof    prove_arith_op_eq  QED -Theorem U128_DIV_EQ: +Theorem u128_div_eq:    !x y.      u128_to_int y <> 0 ==>      ?z. u128_div x y = Return z /\ u128_to_int z = u128_to_int x / u128_to_int y @@ -952,7 +953,7 @@ Proof    prove_arith_op_eq  QED -Theorem USIZE_DIV_EQ: +Theorem usize_div_eq:    !x y.      usize_to_int y <> 0 ==>      ?z. usize_div x y = Return z /\ usize_to_int z = usize_to_int x / usize_to_int y @@ -960,7 +961,7 @@ Proof    prove_arith_op_eq  QED -Theorem I8_DIV_EQ: +Theorem i8_div_eq:    !x y.      i8_to_int y <> 0 ==>      i8_min <= i8_to_int x / i8_to_int y ==> @@ -970,7 +971,7 @@ Proof    prove_arith_op_eq  QED -Theorem I16_DIV_EQ: +Theorem i16_div_eq:    !x y.      i16_to_int y <> 0 ==>      i16_min <= i16_to_int x / i16_to_int y ==> @@ -980,7 +981,7 @@ Proof    prove_arith_op_eq  QED -Theorem I32_DIV_EQ: +Theorem i32_div_eq:    !x y.      i32_to_int y <> 0 ==>      i32_min <= i32_to_int x / i32_to_int y ==> @@ -990,7 +991,7 @@ Proof    prove_arith_op_eq  QED -Theorem I64_DIV_EQ: +Theorem i64_div_eq:    !x y.      i64_to_int y <> 0 ==>      i64_min <= i64_to_int x / i64_to_int y ==> @@ -1000,7 +1001,7 @@ Proof    prove_arith_op_eq  QED -Theorem I128_DIV_EQ: +Theorem i128_div_eq:    !x y.      i128_to_int y <> 0 ==>      i128_min <= i128_to_int x / i128_to_int y ==> @@ -1010,7 +1011,7 @@ Proof    prove_arith_op_eq  QED -Theorem ISIZE_DIV_EQ: +Theorem isize_div_eq:    !x y.      isize_to_int y <> 0 ==>      (i16_min <= isize_to_int x / isize_to_int y \/ isize_min <= isize_to_int x / isize_to_int y) ==> @@ -1021,21 +1022,21 @@ Proof  QED  val all_div_eqs = [ -  ISIZE_DIV_EQ, -  I8_DIV_EQ, -  I16_DIV_EQ, -  I32_DIV_EQ, -  I64_DIV_EQ, -  I128_DIV_EQ, -  USIZE_DIV_EQ, -  U8_DIV_EQ, -  U16_DIV_EQ, -  U32_DIV_EQ, -  U64_DIV_EQ, -  U128_DIV_EQ +  isize_div_eq, +  i8_div_eq, +  i16_div_eq, +  i32_div_eq, +  i64_div_eq, +  i128_div_eq, +  usize_div_eq, +  u8_div_eq, +  u16_div_eq, +  u32_div_eq, +  u64_div_eq, +  u128_div_eq  ] -Theorem U8_REM_EQ: +Theorem u8_rem_eq:    !x y.      u8_to_int y <> 0 ==>      ?z. u8_rem x y = Return z /\ u8_to_int z = int_rem (u8_to_int x) (u8_to_int y) @@ -1043,7 +1044,7 @@ Proof    prove_arith_op_eq  QED -Theorem U16_REM_EQ: +Theorem u16_rem_eq:    !x y.      u16_to_int y <> 0 ==>      ?z. u16_rem x y = Return z /\ u16_to_int z = int_rem (u16_to_int x) (u16_to_int y) @@ -1051,7 +1052,7 @@ Proof    prove_arith_op_eq  QED -Theorem U32_REM_EQ: +Theorem u32_rem_eq:    !x y.      u32_to_int y <> 0 ==>      ?z. u32_rem x y = Return z /\ u32_to_int z = int_rem (u32_to_int x) (u32_to_int y) @@ -1059,7 +1060,7 @@ Proof    prove_arith_op_eq  QED -Theorem U64_REM_EQ: +Theorem u64_rem_eq:    !x y.      u64_to_int y <> 0 ==>      ?z. u64_rem x y = Return z /\ u64_to_int z = int_rem (u64_to_int x) (u64_to_int y) @@ -1067,7 +1068,7 @@ Proof    prove_arith_op_eq  QED -Theorem U128_REM_EQ: +Theorem u128_rem_eq:    !x y.      u128_to_int y <> 0 ==>      ?z. u128_rem x y = Return z /\ u128_to_int z = int_rem (u128_to_int x) (u128_to_int y) @@ -1075,7 +1076,7 @@ Proof    prove_arith_op_eq  QED -Theorem USIZE_REM_EQ: +Theorem usize_rem_eq:    !x y.      usize_to_int y <> 0 ==>      ?z. usize_rem x y = Return z /\ usize_to_int z = int_rem (usize_to_int x) (usize_to_int y) @@ -1083,7 +1084,7 @@ Proof    prove_arith_op_eq  QED -Theorem I8_REM_EQ: +Theorem i8_rem_eq:    !x y.      i8_to_int y <> 0 ==>      i8_min <= int_rem (i8_to_int x) (i8_to_int y) ==> @@ -1093,7 +1094,7 @@ Proof    prove_arith_op_eq  QED -Theorem I16_REM_EQ: +Theorem i16_rem_eq:    !x y.      i16_to_int y <> 0 ==>      i16_min <= int_rem (i16_to_int x) (i16_to_int y) ==> @@ -1103,7 +1104,7 @@ Proof    prove_arith_op_eq  QED -Theorem I32_REM_EQ: +Theorem i32_rem_eq:    !x y.      i32_to_int y <> 0 ==>      i32_min <= int_rem (i32_to_int x) (i32_to_int y) ==> @@ -1113,7 +1114,7 @@ Proof    prove_arith_op_eq  QED -Theorem I64_REM_EQ: +Theorem i64_rem_eq:    !x y.      i64_to_int y <> 0 ==>      i64_min <= int_rem (i64_to_int x) (i64_to_int y) ==> @@ -1123,141 +1124,44 @@ Proof    prove_arith_op_eq  QED -Theorem I8_REM_EQ: -  !x y. -    i8_to_int y <> 0 ==> -    i8_min <= int_rem (i8_to_int x) (i8_to_int y) ==> -    int_rem (i8_to_int x) (i8_to_int y) <= i8_max ==> -    ?z. i8_rem x y = Return z /\ i8_to_int z = int_rem (i8_to_int x) (i8_to_int y) -Proof -  prove_arith_op_eq -QED - -Theorem I8_REM_EQ: -  !x y. -    i8_to_int y <> 0 ==> -    i8_min <= int_rem (i8_to_int x) (i8_to_int y) ==> -    int_rem (i8_to_int x) (i8_to_int y) <= i8_max ==> -    ?z. i8_rem x y = Return z /\ i8_to_int z = int_rem (i8_to_int x) (i8_to_int y) -Proof -  prove_arith_op_eq -QED - -Theorem U16_DIV_EQ: -  !x y. -    u16_to_int y <> 0 ==> -    ?z. u16_div x y = Return z /\ u16_to_int z = u16_to_int x / u16_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem U32_DIV_EQ: -  !x y. -    u32_to_int y <> 0 ==> -    ?z. u32_div x y = Return z /\ u32_to_int z = u32_to_int x / u32_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem U64_DIV_EQ: -  !x y. -    u64_to_int y <> 0 ==> -    ?z. u64_div x y = Return z /\ u64_to_int z = u64_to_int x / u64_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem U128_DIV_EQ: -  !x y. -    u128_to_int y <> 0 ==> -    ?z. u128_div x y = Return z /\ u128_to_int z = u128_to_int x / u128_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem USIZE_DIV_EQ: -  !x y. -    usize_to_int y <> 0 ==> -    ?z. usize_div x y = Return z /\ usize_to_int z = usize_to_int x / usize_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem I8_DIV_EQ: -  !x y. -    i8_to_int y <> 0 ==> -    i8_min <= i8_to_int x / i8_to_int y ==> -    i8_to_int x / i8_to_int y <= i8_max ==> -    ?z. i8_div x y = Return z /\ i8_to_int z = i8_to_int x / i8_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem I16_DIV_EQ: -  !x y. -    i16_to_int y <> 0 ==> -    i16_min <= i16_to_int x / i16_to_int y ==> -    i16_to_int x / i16_to_int y <= i16_max ==> -    ?z. i16_div x y = Return z /\ i16_to_int z = i16_to_int x / i16_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem I32_DIV_EQ: -  !x y. -    i32_to_int y <> 0 ==> -    i32_min <= i32_to_int x / i32_to_int y ==> -    i32_to_int x / i32_to_int y <= i32_max ==> -    ?z. i32_div x y = Return z /\ i32_to_int z = i32_to_int x / i32_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem I64_DIV_EQ: -  !x y. -    i64_to_int y <> 0 ==> -    i64_min <= i64_to_int x / i64_to_int y ==> -    i64_to_int x / i64_to_int y <= i64_max ==> -    ?z. i64_div x y = Return z /\ i64_to_int z = i64_to_int x / i64_to_int y -Proof -  prove_arith_op_eq -QED - -Theorem I128_DIV_EQ: +Theorem i128_rem_eq:    !x y.      i128_to_int y <> 0 ==> -    i128_min <= i128_to_int x / i128_to_int y ==> -    i128_to_int x / i128_to_int y <= i128_max ==> -    ?z. i128_div x y = Return z /\ i128_to_int z = i128_to_int x / i128_to_int y +    i128_min <= int_rem (i128_to_int x) (i128_to_int y) ==> +    int_rem (i128_to_int x) (i128_to_int y) <= i128_max ==> +    ?z. i128_rem x y = Return z /\ i128_to_int z = int_rem (i128_to_int x) (i128_to_int y)  Proof    prove_arith_op_eq  QED -Theorem ISIZE_DIV_EQ: +Theorem isize_rem_eq:    !x y.      isize_to_int y <> 0 ==> -    (i16_min <= isize_to_int x / isize_to_int y \/ isize_min <= isize_to_int x / isize_to_int y) ==> -    (isize_to_int x / isize_to_int y <= i16_max \/ isize_to_int x / isize_to_int y <= isize_max) ==> -    ?z. isize_div x y = Return z /\ isize_to_int z = isize_to_int x / isize_to_int y -Proof -  prove_arith_op_eq -QED - -val all_div_eqs = [ -  ISIZE_DIV_EQ, -  I8_DIV_EQ, -  I16_DIV_EQ, -  I32_DIV_EQ, -  I64_DIV_EQ, -  I128_DIV_EQ, -  USIZE_DIV_EQ, -  U8_DIV_EQ, -  U16_DIV_EQ, -  U32_DIV_EQ, -  U64_DIV_EQ, -  U128_DIV_EQ +    (i16_min <= int_rem (isize_to_int x) (isize_to_int y) \/ +     isize_min <= int_rem (isize_to_int x) (isize_to_int y)) ==> +    (int_rem (isize_to_int x) (isize_to_int y) <= i16_max \/ +     int_rem (isize_to_int x) (isize_to_int y) <= isize_max) ==> +    ?z. isize_rem x y = Return z /\ isize_to_int z = int_rem (isize_to_int x) (isize_to_int y) +Proof +  prove_arith_op_eq +QED + +val all_rem_eqs = [ +  isize_rem_eq, +  i8_rem_eq, +  i16_rem_eq, +  i32_rem_eq, +  i64_rem_eq, +  i128_rem_eq, +  usize_rem_eq, +  u8_rem_eq, +  u16_rem_eq, +  u32_rem_eq, +  u64_rem_eq, +  u128_rem_eq  ] +  (***   * Vectors   *) @@ -1268,98 +1172,102 @@ val _ = new_constant ("vec_to_list", “:'a vec -> 'a list”)  val _ = new_constant ("mk_vec", “:'a list -> 'a vec result”) -val VEC_TO_LIST_NUM_BOUNDS = -  new_axiom ("VEC_TO_LIST_BOUNDS", +val vec_to_list_num_bounds = +  new_axiom ("vec_to_list_num_bounds",      “!v. let l = LENGTH (vec_to_list v) in       (0:num) <= l /\ l <= Num usize_max”) -Theorem VEC_TO_LIST_INT_BOUNDS: +Theorem vec_to_list_int_bounds:    !v. 0 <= int_of_num (LENGTH (vec_to_list v)) /\ int_of_num (LENGTH (vec_to_list v)) <= usize_max  Proof    gen_tac >> -  assume_tac VEC_TO_LIST_NUM_BOUNDS >> -  pop_assum (qspec_then ‘v’ ASSUME_TAC) >> -  pop_assum MP_TAC >> -  PURE_ONCE_REWRITE_TAC [GSYM INT_LE] >> -  sg ‘0 ≤ usize_max’ >- (ASSUME_TAC usize_bounds >> fs [u16_max_def] >> COOPER_TAC) >> +  assume_tac vec_to_list_num_bounds >> +  pop_assum (qspec_assume ‘v’) >> +  pop_assum mp_tac >> +  pure_once_rewrite_tac [GSYM INT_LE] >> +  sg ‘0 ≤ usize_max’ >- (assume_tac usize_bounds >> fs [u16_max_def] >> cooper_tac) >>    metis_tac [INT_OF_NUM]  QED -val VEC_LEN_DEF = Define ‘vec_len v = int_to_usize (int_of_num (LENGTH (vec_to_list v)))’ -Theorem VEC_LEN_SPEC: +val vec_len_def = Define ‘vec_len v = int_to_usize (int_of_num (LENGTH (vec_to_list v)))’ +Theorem vec_len_spec:    ∀v.      vec_len v = int_to_usize (&(LENGTH (vec_to_list v))) ∧      0 ≤ &(LENGTH (vec_to_list v)) ∧ &(LENGTH (vec_to_list v)) ≤ usize_max  Proof -  gen_tac >> rw [VEC_LEN_DEF] >> -  qspec_then ‘v’ ASSUME_TAC VEC_TO_LIST_INT_BOUNDS >> +  gen_tac >> rw [vec_len_def] >> +  qspec_assume ‘v’ vec_to_list_int_bounds >>    fs []  QED -val MK_VEC_SPEC = new_axiom ("MK_VEC_SPEC", “∀l. &(LENGTH l) ≤ usize_max ⇒ ∃v. mk_vec l = Return v ∧ vec_to_list v = l”) +val mk_vec_spec = new_axiom ("mk_vec_spec", +  “∀l. &(LENGTH l) ≤ usize_max ⇒ ∃v. mk_vec l = Return v ∧ vec_to_list v = l”) -val VEC_NEW_DEF = Define ‘vec_new = case mk_vec [] of Return v => v’ -Theorem VEC_NEW_SPEC: +val vec_new_def = Define ‘vec_new = case mk_vec [] of Return v => v’ +Theorem vec_new_spec:    vec_to_list vec_new = []  Proof -  rw [VEC_NEW_DEF] >> +  rw [vec_new_def] >>    qabbrev_tac ‘l = []’ >> -  qspec_then ‘l’ ASSUME_TAC MK_VEC_SPEC >> +  qspec_assume ‘l’ mk_vec_spec >>    Cases_on ‘mk_vec l’ >> -  rfs [markerTheory.Abbrev_def, NOT_LE_EQ_GT] >> fs [] >> -  ASSUME_TAC usize_bounds >> fs[u16_max_def] >> TRY (ex_falso >> COOPER_TAC) >> -  sg ‘0 ≤ usize_max’ >- COOPER_TAC >> +  rfs [markerTheory.Abbrev_def, not_le_eq_gt] >> fs [] >> +  assume_tac usize_bounds >> fs[u16_max_def] >> try_tac (exfalso >> cooper_tac) >> +  sg ‘0 ≤ usize_max’ >- cooper_tac >>    fs []  QED -val VEC_PUSH_DEF = Define ‘vec_push_back v x = mk_vec (vec_to_list v ++ [x])’ -Theorem VEC_PUSH_SPEC: +val vec_push_def = Define ‘vec_push_back v x = mk_vec (vec_to_list v ++ [x])’ +Theorem vec_push_spec:    ∀v x. usize_to_int (vec_len v) < usize_max ⇒      ∃vx. vec_push_back v x = Return vx ∧      vec_to_list vx = vec_to_list v ++ [x]  Proof -  rpt strip_tac >> fs [VEC_PUSH_DEF] >> -  qspec_then ‘v’ ASSUME_TAC VEC_LEN_SPEC >> rw [] >> -  qspec_then ‘vec_to_list v ++ [x]’ ASSUME_TAC MK_VEC_SPEC >> -  fs [VEC_LEN_DEF] >> rw [] >> +  rpt strip_tac >> fs [vec_push_def] >> +  qspec_assume ‘v’ vec_len_spec >> rw [] >> +  qspec_assume ‘vec_to_list v ++ [x]’ mk_vec_spec >> +  fs [vec_len_def] >> rw [] >>    pop_assum irule >> -  pop_last_assum MP_TAC >> +  pop_last_assum mp_tac >>    dep_rewrite.DEP_PURE_ONCE_REWRITE_TAC all_conversion_id_lemmas >> fs [] >> -  COOPER_TAC +  cooper_tac  QED -val UPDATE_DEF = Define ‘ +val update_def = Define ‘    update ([] : 'a list) (i : num) (y : 'a) : 'a list = [] ∧    update (_ :: ls) (0: num) y = y :: ls ∧    update (x :: ls) (SUC i) y = x :: update ls i y  ’ -Theorem UPDATE_LENGTH: +Theorem update_length:    ∀ls i y. LENGTH (update ls i y) = LENGTH ls  Proof -  Induct_on ‘ls’ >> Cases_on ‘i’ >> rw [UPDATE_DEF] +  Induct_on ‘ls’ >> Cases_on ‘i’ >> rw [update_def]  QED -Theorem UPDATE_SPEC: +Theorem update_spec:    ∀ls i y. i < LENGTH ls ==>      LENGTH (update ls i y) = LENGTH ls ∧      EL i (update ls i y) = y ∧      ∀j. j < LENGTH ls ⇒ j ≠ i ⇒ EL j (update ls i y) = EL j ls  Proof -  Induct_on ‘ls’ >> Cases_on ‘i’ >> rw [UPDATE_DEF] >> +  Induct_on ‘ls’ >> Cases_on ‘i’ >> rw [update_def] >>    Cases_on ‘j’ >> fs []  QED  (* TODO: this is the base definition for index. Shall we remove the ‘return’ type? *) -val VEC_INDEX_DEF = Define ‘ -  vec_index i v = if usize_to_int i ≤ usize_to_int (vec_len v) then Return (EL (Num (usize_to_int i)) (vec_to_list v)) else Fail Failure’ +val vec_index_def = Define ‘ +  vec_index i v = +    if usize_to_int i ≤ usize_to_int (vec_len v) +    then Return (EL (Num (usize_to_int i)) (vec_to_list v)) +    else Fail Failure’  (* TODO: shortcut for qspec_then ... ASSUME_TAC *)  (* TODO: use cooper_tac everywhere *)  (* TODO: use pure_once_rewrite_tac everywhere *)  (* TODO: injectivity lemmas for ..._to_int *) -Theorem USIZE_TO_INT_INJ: +Theorem usize_to_int_inj:    ∀i j. usize_to_int i = usize_to_int j ⇔ i = j  Proof    rpt strip_tac >> @@ -1368,23 +1276,16 @@ Proof    metis_tac []  QED -Theorem USIZE_TO_INT_NEQ_INJ: +Theorem usize_to_int_neq_inj:    ∀i j. i <> j ==> usize_to_int i <> usize_to_int j  Proof -  metis_tac [USIZE_TO_INT_INJ] -QED - -(* TODO: move *) -Theorem INT_OF_NUM: -  ∀i. 0 ≤ i ⇒ &Num i = i -Proof -  metis_tac[integerTheory.INT_OF_NUM] +  metis_tac [usize_to_int_inj]  QED -Theorem INT_OF_NUM_NEQ_INJ: +Theorem int_of_num_neq_inj:    ∀n m. &n ≠ &m ⇒ n ≠ m  Proof -  metis_tac [INT_OF_NUM_INJ] +  metis_tac [int_of_num_inj]  QED  (* TODO: automate: take assumption, intro first premise as subgoal *) @@ -1403,10 +1304,10 @@ QED    &n < &m  *) -val VEC_INSERT_BACK_DEF = Define ‘ +val vec_insert_back_def = Define ‘    vec_insert_back (v : 'a vec) (i : usize) (x : 'a) = mk_vec (update (vec_to_list v) (Num (usize_to_int i)) x)’ -Theorem VEC_INSERT_BACK_SPEC: +Theorem vec_insert_back_spec:    ∀v i x.      usize_to_int i < usize_to_int (vec_len v) ⇒      ∃nv. vec_insert_back v i x = Return nv ∧ @@ -1415,20 +1316,21 @@ Theorem VEC_INSERT_BACK_SPEC:      (* TODO: usize_to_int j ≠ usize_to_int i ? *)      (∀j. usize_to_int j < usize_to_int (vec_len nv) ⇒ j ≠ i ⇒ vec_index j nv = vec_index j v)  Proof -  rpt strip_tac >> fs [VEC_INSERT_BACK_DEF] >> -  qspec_assume ‘update (vec_to_list v) (Num (usize_to_int i)) x’ MK_VEC_SPEC >> -  qspecl_assume [‘vec_to_list v’, ‘Num (usize_to_int i)’, ‘x’] UPDATE_LENGTH >> +  rpt strip_tac >> fs [vec_insert_back_def] >> +  qspec_assume ‘update (vec_to_list v) (Num (usize_to_int i)) x’ mk_vec_spec >> +  qspecl_assume [‘vec_to_list v’, ‘Num (usize_to_int i)’, ‘x’] update_length >>    fs [] >> -  qspec_assume ‘v’ VEC_LEN_SPEC >> +  qspec_assume ‘v’ vec_len_spec >>    rw [] >> gvs [] >> -  fs [VEC_LEN_DEF, VEC_INDEX_DEF] >> -  sg ‘usize_to_int (int_to_usize (&LENGTH (vec_to_list v))) = &LENGTH (vec_to_list v)’ >-(irule int_to_usize_id >> COOPER_TAC) >> +  fs [vec_len_def, vec_index_def] >> +  sg ‘usize_to_int (int_to_usize (&LENGTH (vec_to_list v))) = &LENGTH (vec_to_list v)’ +  >-(irule int_to_usize_id >> cooper_tac) >>    fs [] >> -  qspecl_assume [‘vec_to_list v’, ‘Num (usize_to_int i)’, ‘x’] UPDATE_SPEC >> rfs [] >> +  qspecl_assume [‘vec_to_list v’, ‘Num (usize_to_int i)’, ‘x’] update_spec >> rfs [] >>    sg ‘Num (usize_to_int i) < LENGTH (vec_to_list v)’ >-(      (* TODO: automate *) -    pure_once_rewrite_tac [GSYM INT_LT] >> -    dep_pure_once_rewrite_tac [INT_OF_NUM] >> +    pure_once_rewrite_tac [gsym INT_LT] >> +    dep_pure_once_rewrite_tac [primitivesArithTheory.int_of_num] >>      qspec_assume ‘i’ usize_to_int_bounds >> fs []    ) >>    fs [] >> @@ -1437,35 +1339,19 @@ Proof    first_x_assum irule >>    rw [] >-(      (* TODO: automate *) -    irule INT_OF_NUM_NEQ_INJ >> -    dep_pure_rewrite_tac [INT_OF_NUM] >> +    irule int_of_num_neq_inj >> +    dep_pure_rewrite_tac [primitivesArithTheory.int_of_num] >>      rw [usize_to_int_bounds] >> -    metis_tac [USIZE_TO_INT_NEQ_INJ] +    metis_tac [usize_to_int_neq_inj]    ) >>    (* TODO: automate *) -  pure_once_rewrite_tac [GSYM INT_LT] >> -  dep_pure_once_rewrite_tac [INT_OF_NUM] >> +  pure_once_rewrite_tac [gsym INT_LT] >> +  dep_pure_once_rewrite_tac [primitivesArithTheory.int_of_num] >>    qspec_assume ‘j’ usize_to_int_bounds >> fs []  QED  (* TODO: use lowercase everywhere for the theorem names *) -(* We generate and save an induction theorem for positive integers *) -Theorem int_induction: -  !(P : int -> bool). P 0 /\ (!i. 0 <= i /\ P i ==> P (i+1)) ==> !i. 0 <= i ==> P i -Proof -  ntac 4 strip_tac >> -  Induct_on ‘Num i’ >> rpt strip_tac -  >-(sg ‘i = 0’ >- cooper_tac >> fs []) >> -  last_assum (qspec_assume ‘i-1’) >> -  fs [] >> pop_assum irule >> -  rw [] >> try_tac cooper_tac >> -  first_assum (qspec_assume ‘i - 1’) >> -  pop_assum irule >> -  rw [] >> try_tac cooper_tac -QED - -val _ = TypeBase.update_induction int_induction  (* Small experiment: trying to redefine common functions with integers instead of nums *)  val index_def = Define ‘ @@ -1479,7 +1365,9 @@ val len_def = Define ‘  val update_def = Define ‘    update ([] : 'a list) (i : int) (y : 'a) : 'a list = [] ∧ -  update (x :: ls) (i : int) y = if i = 0 then y :: ls else (if 0 < i then x :: update ls (i - 1) y else x :: ls) + +  update (x :: ls) (i : int) y = +    if i = 0 then y :: ls else (if 0 < i then x :: update ls (i - 1) y else x :: ls)  ’  Theorem update_len: @@ -1496,7 +1384,8 @@ Theorem update_spec:      index i (update ls i y) = y ∧      ∀j. j < len ls ⇒ j ≠ i ⇒ index j (update ls i y) = index j ls  Proof -  Induct_on ‘ls’ >> Cases_on ‘i = 0’ >> rw [update_def, len_def, index_def] >> try_tac (ex_falso >> cooper_tac) >> +  Induct_on ‘ls’ >> Cases_on ‘i = 0’ >> rw [update_def, len_def, index_def] >> +  try_tac (exfalso >> cooper_tac) >>    try_tac (      pop_last_assum (qspecl_assume [‘i' - 1’, ‘y’]) >>      pop_assum sg_premise_tac >- cooper_tac >> @@ -1550,10 +1439,14 @@ Proof  QED  val vec_index_def = Define ‘ -  vec_index i v = if usize_to_int i ≤ usize_to_int (vec_len v) then Return (index (usize_to_int i) (vec_to_list v)) else Fail Failure’ +  vec_index i v = +    if usize_to_int i ≤ usize_to_int (vec_len v) +    then Return (index (usize_to_int i) (vec_to_list v)) +    else Fail Failure’  (* TODO: *) -val mk_vec_spec = new_axiom ("mk_vec_spec", “∀l. len l ≤ usize_max ⇒ ∃v. mk_vec l = Return v ∧ vec_to_list v = l”) +val mk_vec_spec = new_axiom ("mk_vec_spec", +  “∀l. len l ≤ usize_max ⇒ ∃v. mk_vec l = Return v ∧ vec_to_list v = l”)  (* Redefining ‘vec_insert_back’ *)  val vec_insert_back_def = Define ‘  | 
