Package machine-code-straightline: Hoare logic triple support for straightline code
Information
name | machine-code-straightline |
version | 1.0 |
description | Hoare logic triple support for straightline code |
author | HOL OpenTheory Packager <opentheory-packager@hol-theorem-prover.org> |
license | MIT |
checksum | 4f9f4e876569966d0c36c5decfc29b2bd3bc21ad |
requires | base hol-base hol-string hol-sort hol-words hol-integer machine-code-hoare-logic machine-code-hoare-triple arm-model arm-step arm-prog arm-decomp m0-model m0-prog m0-decomp |
show | Data.Bool Data.List Data.Option Data.Pair Function HOL4 Number.Natural Relation |
Files
- Package tarball machine-code-straightline-1.0.tgz
- Theory source file machine-code-straightline.thy (included in the package tarball)
Defined Type Operators
- HOL4
- GraphLang
- GraphLang.code
- GraphLang.func
- GraphLang.graph_function
- GraphLang.inst
- GraphLang.jump
- GraphLang.next
- GraphLang.next_node
- GraphLang.node
- GraphLang.variable
- GraphLang
Defined Constants
- HOL4
- straightline
- straightline.arm_assert
- straightline.DO_NOTHING
- GraphLang
- GraphLang.all_names
- GraphLang.all_names_ignore
- GraphLang.all_names_with_input
- GraphLang.apply_update
- GraphLang.arm_STACK_MEMORY
- GraphLang.arm_STATE
- GraphLang.arm_STATE_CPSR
- GraphLang.arm_STATE_REGS
- GraphLang.arm_assert_for
- GraphLang.carry_out
- GraphLang.check_jump
- GraphLang.check_ret
- GraphLang.code_CASE
- GraphLang.code_size
- GraphLang.count_leading_zero_bits
- GraphLang.default_state
- GraphLang.exec_graph
- GraphLang.exec_graph_n
- GraphLang.exec_graph_step
- GraphLang.exec_next
- GraphLang.exec_node
- GraphLang.exec_node_return
- GraphLang.find_func
- GraphLang.find_func_tupled
- GraphLang.find_inst
- GraphLang.find_inst_tupled
- GraphLang.fold
- GraphLang.fs_locs
- GraphLang.func_CASE
- GraphLang.func_body_trans
- GraphLang.func_name
- GraphLang.func_ok
- GraphLang.func_size
- GraphLang.func_trans
- GraphLang.funcs_ok
- GraphLang.get_assert
- GraphLang.get_jump
- GraphLang.good_stack
- GraphLang.good_stack_tail
- GraphLang.good_stack_tail_tupled
- GraphLang.graph
- GraphLang.graph_function_CASE
- GraphLang.graph_function_size
- GraphLang.init_vars
- GraphLang.inst_CASE
- GraphLang.inst_loc
- GraphLang.inst_size
- GraphLang.inst_trans
- GraphLang.jump_CASE
- GraphLang.jump_ok
- GraphLang.jump_size
- GraphLang.list_func_trans
- GraphLang.list_inst_trans
- GraphLang.m0_STACK_MEMORY
- GraphLang.m0_STATE
- GraphLang.m0_STATE_PSR
- GraphLang.m0_STATE_REGS
- GraphLang.m0_assert_for
- GraphLang.next_CASE
- GraphLang.next_node_CASE
- GraphLang.next_node_size
- GraphLang.next_ok
- GraphLang.next_size
- GraphLang.next_trans
- GraphLang.next_trans_tupled
- GraphLang.next_trans_tupled_aux
- GraphLang.node_CASE
- GraphLang.node_size
- GraphLang.odd_nums
- GraphLang.ret_and_all_names
- GraphLang.return_vars
- GraphLang.save_vals
- GraphLang.unspecified_pre
- GraphLang.upd_ok
- GraphLang.upd_stack
- GraphLang.upd_vars
- GraphLang.var_acc
- GraphLang.var_bool
- GraphLang.var_dom
- GraphLang.var_mem
- GraphLang.var_nat
- GraphLang.var_upd
- GraphLang.var_word32
- GraphLang.var_word8
- GraphLang.variable_CASE
- GraphLang.variable_size
- GraphLang.word32
- GraphLang.word_add_with_carry
- GraphLang.ARM
- GraphLang.ASM
- GraphLang.Basic
- GraphLang.CALL
- GraphLang.CALL_TAG
- GraphLang.Call
- GraphLang.Cond
- GraphLang.Err
- GraphLang.Func
- GraphLang.GraphFunction
- GraphLang.IF
- GraphLang.IMPL_INST
- GraphLang.Inst
- GraphLang.Jump
- GraphLang.LIST_IMPL_INST
- GraphLang.LIST_IMPL_INST_tupled
- GraphLang.LIST_SUBSET
- GraphLang.M0
- GraphLang.MemAcc32
- GraphLang.MemAcc8
- GraphLang.MemUpdate32
- GraphLang.MemUpdate8
- GraphLang.NextNode
- GraphLang.READ32
- GraphLang.READ8
- GraphLang.Ret
- GraphLang.Return
- GraphLang.SKIP_TAG
- GraphLang.ShiftLeft
- GraphLang.ShiftRight
- GraphLang.SignedShiftRight
- GraphLang.Skip
- GraphLang.VarBool
- GraphLang.VarDom
- GraphLang.VarMem
- GraphLang.VarNat
- GraphLang.VarNone
- GraphLang.VarWord32
- GraphLang.VarWord8
- GraphLang.WRITE32
- GraphLang.WRITE8
- straightline
Theorems
⊦ GraphLang.unspecified_pre ⇔ ⊥
⊦ GraphLang.arm_STACK_MEMORY = arm_prog.arm_MEMORY
⊦ GraphLang.m0_STACK_MEMORY = m0_prog.m0_MEMORY
⊦ GraphLang.default_state = λx. GraphLang.VarNone
⊦ (λv1. v1) = id
⊦ GraphLang.apply_update [] s = s
⊦ (x ⇔ ⊤) ⇒ x
⊦ (⊤ ⇒ b) ⇒ b
⊦ ∀x. straightline.DO_NOTHING x = x
⊦ ∀s. GraphLang.SKIP_TAG s ⇔ GraphLang.unspecified_pre
⊦ ∀a. ¬(GraphLang.Jump a = GraphLang.Return)
⊦ ∀f. GraphLang.func_body_trans f = snd (GraphLang.func_trans f)
⊦ ∀w.
GraphLang.count_leading_zero_bits w =
words.n2w (arm.CountLeadingZeroBits w)
⊦ ∀Gamma.
GraphLang.exec_graph Gamma =
relation.RTC (GraphLang.exec_graph_step Gamma)
⊦ ∀s is_tail_call. GraphLang.CALL_TAG s is_tail_call ⇔ ⊤
⊦ ∀fs.
GraphLang.list_func_trans fs =
GraphLang.graph (map GraphLang.func_trans fs)
⊦ ∀nn. GraphLang.Skip nn = GraphLang.Cond nn nn (λx. ⊤)
⊦ ∀nm f. GraphLang.var_acc nm f = f nm
⊦ ∀a mem. GraphLang.READ8 a mem = mem a
⊦ ∀a' a. ¬(GraphLang.ARM a = GraphLang.M0 a')
⊦ ¬(x = y) ⇔ ¬(y = x)
⊦ ∀m a. GraphLang.MemAcc8 m a = GraphLang.READ8 a m
⊦ ∀m a. GraphLang.MemAcc32 m a = GraphLang.READ32 a m
⊦ ∀jj. (∃c. jj = GraphLang.Jump c) ∨ jj = GraphLang.Return
⊦ ∀x x1. GraphLang.find_func x x1 = GraphLang.find_func_tupled (x, x1)
⊦ ∀x x1.
GraphLang.good_stack_tail x x1 ⇔
GraphLang.good_stack_tail_tupled (x, x1)
⊦ ∀w y. GraphLang.ShiftLeft w y = words.word_lsl w (words.w2n y)
⊦ ∀w y. GraphLang.ShiftRight w y = words.word_lsr w (words.w2n y)
⊦ ∀w y. GraphLang.SignedShiftRight w y = words.word_asr w (words.w2n y)
⊦ ∀Gamma n.
GraphLang.exec_graph_n Gamma n =
arithmetic.NRC (GraphLang.exec_graph_step Gamma) n
⊦ ∀x x1. GraphLang.find_inst x x1 = GraphLang.find_inst_tupled (x, x1)
⊦ arm.Aligned (w, n) ⇒ arm.Align (w, n) = w
⊦ set_sep.STAR set_sep.emp p = p ∧ set_sep.STAR p set_sep.emp = p
⊦ ∀name entry l. GraphLang.func_name (GraphLang.Func name entry l) = name
⊦ GraphLang.list_func_trans fs =
GraphLang.graph
(map (λf. (GraphLang.func_name f, GraphLang.func_body_trans f)) fs)
⊦ ∀ff. ∃s c l. ff = GraphLang.Func s c l
⊦ ∀ii. ∃c f n. ii = GraphLang.Inst c f n
⊦ ∀a a'. GraphLang.NextNode a = GraphLang.NextNode a' ⇔ a = a'
⊦ ∀a a'. GraphLang.Jump a = GraphLang.Jump a' ⇔ a = a'
⊦ const x = (λy. x) ∧ suc = λn. n + 1
⊦ GraphLang.get_assert none = (λx. ⊤) ∧
∀a. GraphLang.get_assert (some a) = a
⊦ ∀loc v0 v1. GraphLang.inst_loc (GraphLang.Inst loc v0 v1) = words.w2n loc
⊦ (∀a. GraphLang.jump_size (GraphLang.Jump a) = 1) ∧
GraphLang.jump_size GraphLang.Return = 0
⊦ ∀code fs.
GraphLang.funcs_ok code fs ⇔
all (GraphLang.func_ok code (GraphLang.fs_locs fs)) fs
⊦ address.ALIGNED w ⇒ ¬fcp.fcp_index w 0 ∧ ¬fcp.fcp_index w 1
⊦ words.n2w (arm.CountLeadingZeroBits w) =
GraphLang.count_leading_zero_bits w ∧
words.n2w (m0.CountLeadingZeroBits w) =
GraphLang.count_leading_zero_bits w
⊦ ∀nm v f. GraphLang.var_upd nm v f = combin.UPDATE nm v f
⊦ ∀cc. (∃f. cc = GraphLang.ARM f) ∨ ∃f. cc = GraphLang.M0 f
⊦ ∀xs ys.
GraphLang.LIST_SUBSET xs ys ⇔
all (λx. bool.IN x (list.LIST_TO_SET ys)) xs
⊦ ∀P. (∀c. P (GraphLang.Jump c)) ∧ P GraphLang.Return ⇒ ∀jj. P jj
⊦ ∀a w mem. GraphLang.WRITE8 a w mem = combin.UPDATE a w mem
⊦ ∀m a w. GraphLang.MemUpdate8 m a w = GraphLang.WRITE8 a w m
⊦ ∀m a w. GraphLang.MemUpdate32 m a w = GraphLang.WRITE32 a w m
⊦ all (λn. s1 n = s2 n) GraphLang.all_names ⇒
GraphLang.arm_STATE s1 = GraphLang.arm_STATE s2
⊦ all (λn. s1 n = s2 n) GraphLang.all_names ⇒
GraphLang.m0_STATE s1 = GraphLang.m0_STATE s2
⊦ (∀p. GraphLang.jump_ok (GraphLang.Jump p) ⇔ even (words.w2n p)) ∧
(GraphLang.jump_ok GraphLang.Return ⇔ ⊤)
⊦ (∀j.
GraphLang.get_jump (GraphLang.Jump j) =
GraphLang.NextNode (words.w2n j)) ∧
GraphLang.get_jump GraphLang.Return = GraphLang.Ret
⊦ ∀gg. ∃l l0 f n. gg = GraphLang.GraphFunction l l0 f n
⊦ ∀u.
GraphLang.upd_ok u ⇔
list.ALL_DISTINCT (map fst u) ∧
GraphLang.LIST_SUBSET (map fst u) GraphLang.all_names
⊦ ∀nn.
(∃n. nn = GraphLang.NextNode n) ∨ nn = GraphLang.Ret ∨
nn = GraphLang.Err
⊦ set_sep.STAR (if b then x else y) q =
if b then set_sep.STAR x q else set_sep.STAR y q
⊦ t1 = t2 ∧ u1 = u2 ⇒ (t1, u1) = (t2, u2)
⊦ ∀x x1 x2.
GraphLang.LIST_IMPL_INST x x1 x2 ⇔
GraphLang.LIST_IMPL_INST_tupled (x, x1, x2)
⊦ ∀x x1 x2.
GraphLang.next_trans x x1 x2 = GraphLang.next_trans_tupled (x, x1, x2)
⊦ ∀P. (∀s c l. P (GraphLang.Func s c l)) ⇒ ∀ff. P ff
⊦ ∀P. (∀c f n. P (GraphLang.Inst c f n)) ⇒ ∀ii. P ii
⊦ ∀a0 a1 a2.
GraphLang.inst_size (GraphLang.Inst a0 a1 a2) =
1 + GraphLang.next_size a2
⊦ ∀P. (∀f. P (GraphLang.ARM f)) ∧ (∀f. P (GraphLang.M0 f)) ⇒ ∀cc. P cc
⊦ (∀a. GraphLang.code_size (GraphLang.ARM a) = 1) ∧
∀a. GraphLang.code_size (GraphLang.M0 a) = 1
⊦ ∀xs n ys. list.DROP (length xs + n) (xs @ ys) = list.DROP n ys
⊦ ∀P.
(∀n. P (GraphLang.NextNode n)) ∧ P GraphLang.Ret ∧ P GraphLang.Err ⇒
∀nn. P nn
⊦ ∀w1 w2 c.
GraphLang.word_add_with_carry w1 w2 c =
fst (words.add_with_carry (w1, w2, c))
⊦ ∀vars accs st.
GraphLang.init_vars vars accs st =
GraphLang.save_vals vars (map (λi. i st) accs) GraphLang.default_state
⊦ ∀a0 a1 a2 f. GraphLang.func_CASE (GraphLang.Func a0 a1 a2) f = f a0 a1 a2
⊦ ∀inner outer inner_st.
GraphLang.return_vars inner outer inner_st =
GraphLang.save_vals outer
(map (λv. GraphLang.var_acc v inner_st) inner)
⊦ ∀a0 a1 a2 f. GraphLang.inst_CASE (GraphLang.Inst a0 a1 a2) f = f a0 a1 a2
⊦ ∀f0 f1.
∃fn. (∀a. fn (GraphLang.Jump a) = f0 a) ∧ fn GraphLang.Return = f1
⊦ ∀asm.
prog.SPEC arm_prog.ARM_MODEL
(set_sep.STAR (arm_prog.arm_PC p)
(set_sep.cond (GraphLang.SKIP_TAG asm))) pred_set.EMPTY
(arm_prog.arm_PC (words.word_add p (words.n2w (arithmetic.BIT2 1))))
⊦ ∀w1 w2 c.
GraphLang.carry_out w1 w2 c ⇔
fst (snd (words.add_with_carry (w1, w2, c)))
⊦ ∀f. ∃fn. ∀a0 a1 a2. fn (GraphLang.Func a0 a1 a2) = f a0 a1 a2
⊦ ∀f. ∃fn. ∀a0 a1 a2. fn (GraphLang.Inst a0 a1 a2) = f a0 a1 a2
⊦ GraphLang.IMPL_INST c locs (GraphLang.Inst n (const ⊤) next) ⇒
∀a. GraphLang.IMPL_INST c locs (GraphLang.Inst n a next)
⊦ ∀t l v0 next.
GraphLang.inst_trans t (GraphLang.Inst l v0 next) =
GraphLang.next_trans (words.w2n l) t next
⊦ ∀P. (∀l l0 f n. P (GraphLang.GraphFunction l l0 f n)) ⇒ ∀gg. P gg
⊦ ∀upds st.
GraphLang.upd_vars upds st =
GraphLang.save_vals (map fst upds)
(map (pair.UNCURRY (λnm vf. vf st)) upds) st
⊦ ¬fcp.fcp_index w 0 ∧ ¬fcp.fcp_index w 1 ⇒
(b ⇒ address.ALIGNED w ⇔ address.ALIGNED w)
⊦ GraphLang.func_ok code locs f ∧ all (GraphLang.func_ok code locs) fs ⇒
all (GraphLang.func_ok code locs) (f :: fs)
⊦ ∀b1 b2 b3 b4.
GraphLang.word32 b1 b2 b3 b4 =
words.word_concat b1 (words.word_concat b2 (words.word_concat b3 b4))
⊦ (∀a. ¬(GraphLang.NextNode a = GraphLang.Ret)) ∧
(∀a. ¬(GraphLang.NextNode a = GraphLang.Err)) ∧
¬(GraphLang.Ret = GraphLang.Err)
⊦ ∀fs stack.
GraphLang.good_stack fs stack ⇔
GraphLang.good_stack_tail fs stack ∧
GraphLang.next_node_CASE (fst (head stack)) (λn. even n) ⊤ ⊥
⊦ (∀a. GraphLang.next_node_size (GraphLang.NextNode a) = 1 + a) ∧
GraphLang.next_node_size GraphLang.Ret = 0 ∧
GraphLang.next_node_size GraphLang.Err = 0
⊦ ∀vars vals st.
GraphLang.save_vals vars vals st =
GraphLang.fold (pair.UNCURRY (λvar val. GraphLang.var_upd var val))
(list.ZIP (vars, vals)) st
⊦ ∀a0 a1 a2.
GraphLang.func_size (GraphLang.Func a0 a1 a2) =
1 +
(list.list_size string.char_size a0 +
list.list_size GraphLang.inst_size a2)
⊦ ∀a0 a1 a2 a3 f.
GraphLang.graph_function_CASE (GraphLang.GraphFunction a0 a1 a2 a3) f =
f a0 a1 a2 a3
⊦ ∀f0 f1.
∃fn. (∀a. fn (GraphLang.ARM a) = f0 a) ∧ ∀a. fn (GraphLang.M0 a) = f1 a
⊦ ∀xs n. n ≤ length xs ⇒ ∃ys zs. xs = ys @ zs ∧ length ys = n
⊦ ∀nm st.
GraphLang.var_bool nm st ⇔
GraphLang.variable_CASE (GraphLang.var_acc nm st) ⊥ (λv6. ⊥) (λv7. ⊥)
(λv8. ⊥) (λv9. ⊥) (λv10. ⊥) (λq. q)
⊦ ∀nm st.
GraphLang.var_nat nm st =
GraphLang.variable_CASE (GraphLang.var_acc nm st) 0 (λn. n) (λv7. 0)
(λv8. 0) (λv9. 0) (λv10. 0) (λv11. 0)
⊦ ∀nm st.
GraphLang.var_dom nm st =
GraphLang.variable_CASE (GraphLang.var_acc nm st) pred_set.EMPTY
(λv6. pred_set.EMPTY) (λv7. pred_set.EMPTY) (λv8. pred_set.EMPTY)
(λv9. pred_set.EMPTY) (λd. d) (λv11. pred_set.EMPTY)
⊦ ∀f.
∃fn.
∀a0 a1 a2 a3.
fn (GraphLang.GraphFunction a0 a1 a2 a3) = f a0 a1 a2 a3
⊦ words.word_msb (words.n2w n) ⇔
n div arithmetic.BIT2 0 ↑ 31 mod arithmetic.BIT2 0 = 1
⊦ ∀name entry l.
GraphLang.func_trans (GraphLang.Func name entry l) =
(name,
GraphLang.GraphFunction GraphLang.ret_and_all_names
GraphLang.all_names_with_input
(GraphLang.graph (GraphLang.list_inst_trans 1 l)) (words.w2n entry))
⊦ ∀insts.
GraphLang.LIST_IMPL_INST code names insts ⇒
list.ALL_DISTINCT (map GraphLang.inst_loc insts) ∧
even (words.w2n entry) ⇒
GraphLang.func_ok code names (GraphLang.Func name entry insts)
⊦ ∀P. P [] ∧ (∀x y xs. P xs ⇒ P ((x, y) :: xs)) ⇒ ∀v. P v
⊦ prog.SPEC m (set_sep.STAR p (r x)) c q ⇒
∀pc. pc = x ⇒ prog.SPEC m (set_sep.STAR p (r pc)) c q
⊦ prog.SPEC m (set_sep.STAR pre (res w)) code q ⇒
∀p. p = w ⇒ prog.SPEC m (set_sep.STAR pre (res p)) code q
⊦ (∀a f v. GraphLang.jump_CASE (GraphLang.Jump a) f v = f a) ∧
∀f v. GraphLang.jump_CASE GraphLang.Return f v = v
⊦ ∀P.
P [] ∧ (∀loc state name rest. P ((loc, state, name) :: rest)) ⇒ ∀z. P z
⊦ (c_post ⇒ prog.SPEC model (assert p) code (assert post)) ⇒
triple.TRIPLE (assert, model) (pre, p) code (pre ∧ c_post, post)
⊦ t1 = t2 ∧ (y1 = y2 ⇒ u1 = u2) ⇒ y1 = y2 ⇒ (t1, u1) = (t2, u2)
⊦ (x1 = x2 ⇒ t1 = t2) ∧ u1 = u2 ⇒ x1 = x2 ⇒ (t1, u1) = (t2, u2)
⊦ ∀f0 f1 f2.
∃fn.
(∀a. fn (GraphLang.NextNode a) = f0 a) ∧ fn GraphLang.Ret = f1 ∧
fn GraphLang.Err = f2
⊦ GraphLang.graph [] = const none ∧
∀y xs x.
GraphLang.graph ((x, y) :: xs) =
combin.UPDATE x (some y) (GraphLang.graph xs)
⊦ (∀k. GraphLang.odd_nums k 0 = []) ∧
∀k n.
GraphLang.odd_nums k (suc n) =
k :: GraphLang.odd_nums (k + arithmetic.BIT2 0) n
⊦ const = (λx y. x) ∧
(address.ALIGNED x ⇔ words.word_and x (words.n2w 3) = words.n2w 0) ∧
list.REV xs [] = reverse xs
⊦ GraphLang.IMPL_INST code names (GraphLang.Inst i (const ⊤) next) ∧
GraphLang.LIST_IMPL_INST code names xs ⇒
GraphLang.LIST_IMPL_INST code names
(GraphLang.Inst i (const ⊤) next :: xs)
⊦ ∀P.
P [] ∧
(∀name entry l xs. P xs ⇒ P (GraphLang.Func name entry l :: xs)) ⇒
∀fs. P fs
⊦ (∀a a'. GraphLang.ARM a = GraphLang.ARM a' ⇔ a = a') ∧
∀a a'. GraphLang.M0 a = GraphLang.M0 a' ⇔ a = a'
⊦ prog.SPEC arm_prog.ARM_MODEL
(set_sep.STAR (set_sep.STAR (aPC p) (aR (words.n2w 0) r0))
(set_sep.cond GraphLang.unspecified_pre)) pred_set.EMPTY
(set_sep.STAR (aR (words.n2w 0) bool.ARB)
(aPC (words.word_add p (words.n2w (arithmetic.BIT2 1)))))
⊦ list.EL (length xs + n) (reverse xs @ ys) = list.EL n ys ∧
list.EL (length xs) (reverse xs @ ys) = list.EL 0 ys
⊦ GraphLang.fs_locs [] = const none ∧
∀xs name l entry.
GraphLang.fs_locs (GraphLang.Func name entry l :: xs) =
combin.UPDATE name (some entry) (GraphLang.fs_locs xs)
⊦ (∀a f f1. GraphLang.code_CASE (GraphLang.ARM a) f f1 = f a) ∧
∀a f f1. GraphLang.code_CASE (GraphLang.M0 a) f f1 = f1 a
⊦ ∀nm st.
GraphLang.var_word8 nm st =
GraphLang.variable_CASE (GraphLang.var_acc nm st) (words.n2w 0)
(λv6. words.n2w 0) (λw. w) (λv8. words.n2w 0) (λv9. words.n2w 0)
(λv10. words.n2w 0) (λv11. words.n2w 0)
⊦ ∀nm st.
GraphLang.var_word32 nm st =
GraphLang.variable_CASE (GraphLang.var_acc nm st) (words.n2w 0)
(λv6. words.n2w 0) (λv7. words.n2w 0) (λw. w) (λv9. words.n2w 0)
(λv10. words.n2w 0) (λv11. words.n2w 0)
⊦ ∀a0 a1 a2 a3.
GraphLang.graph_function_size (GraphLang.GraphFunction a0 a1 a2 a3) =
1 +
(list.list_size (list.list_size string.char_size) a0 +
(list.list_size (list.list_size string.char_size) a1 + a3))
⊦ ∀n xs ys.
list.EL (length xs) (xs @ ys) = list.EL 0 ys ∧
list.EL (length xs + n) (xs @ ys) = list.EL n ys
⊦ ∀a x p c q.
(a ⇒ prog.SPEC x p c q) ⇒
∀d. pred_set.SUBSET c d ⇒ a ⇒ prog.SPEC x p d q
⊦ GraphLang.IMPL_INST c locs
(GraphLang.Inst n (const ⊤) (GraphLang.IF g next1 next2)) ⇒
∀a.
(∀s. a s ⇒ g s) ⇒ GraphLang.IMPL_INST c locs (GraphLang.Inst n a next1)
⊦ (∀s. GraphLang.apply_update [] s = s) ∧
∀y xs x s.
GraphLang.apply_update ((x, y) :: xs) s =
combin.UPDATE x (y s) (GraphLang.apply_update xs s)
⊦ prog.SPEC m (set_sep.STAR p (f x)) c (set_sep.STAR q (f x)) ⇔
∀v. v = x ⇒ prog.SPEC m (set_sep.STAR p (f v)) c (set_sep.STAR q (f v))
⊦ ∀a mem.
GraphLang.READ32 a mem =
GraphLang.word32 (mem (words.word_add a (words.n2w 3)))
(mem (words.word_add a (words.n2w (arithmetic.BIT2 0))))
(mem (words.word_add a (words.n2w 1))) (mem a)
⊦ (∀t. GraphLang.list_inst_trans t [] = []) ∧
∀t x xs.
GraphLang.list_inst_trans t (x :: xs) =
bool.LET (pair.UNCURRY (λt1 ys. ys @ GraphLang.list_inst_trans t1 xs))
(GraphLang.inst_trans t x)
⊦ snd (snd (words.add_with_carry (x, y, c))) ⇔
(words.word_msb x ⇔ words.word_msb y) ∧
¬(words.word_msb x ⇔
words.word_msb
(if c then words.word_sub x (words.word_1comp y)
else words.word_add x y))
⊦ (∀f s. GraphLang.fold f [] s = s) ∧
∀f x xs s. GraphLang.fold f (x :: xs) s = GraphLang.fold f xs (f x s)
⊦ ∀nm st.
GraphLang.var_mem nm st =
GraphLang.variable_CASE (GraphLang.var_acc nm st) (λv8. words.n2w 0)
(λv6 v8. words.n2w 0) (λv7 v8. words.n2w 0) (λv8 v8. words.n2w 0)
(λm. m) (λv10 v8. words.n2w 0) (λv11 v8. words.n2w 0)
⊦ ∀a0 a1 a2 a0' a1' a2'.
GraphLang.Func a0 a1 a2 = GraphLang.Func a0' a1' a2' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2'
⊦ ∀a0 a1 a2 a0' a1' a2'.
GraphLang.Inst a0 a1 a2 = GraphLang.Inst a0' a1' a2' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2'
⊦ GraphLang.IMPL_INST c locs
(GraphLang.Inst n (const ⊤) (GraphLang.IF g next1 next2)) ⇒
∀a.
(∀s. a s ⇒ ((¬) ∘ g) s) ⇒
GraphLang.IMPL_INST c locs (GraphLang.Inst n a next2)
⊦ ∀P.
(∀s. P [] s) ∧ (∀x y xs s. P xs s ⇒ P ((x, y) :: xs) s) ⇒ ∀v v1. P v v1
⊦ (b1 ⇒ prog.SPEC m p c1 q1) ∧ (b2 ⇒ prog.SPEC m p c2 q2) ⇒ (¬b1 ⇒ b2) ⇒
prog.SPEC m p (pred_set.UNION c1 c2) (if b1 then q1 else q2)
⊦ (x1 = x2 ⇒ t1 = t2) ∧ (y1 = y2 ⇒ u1 = u2) ⇒ (x1, y1) = (x2, y2) ⇒
(t1, u1) = (t2, u2)
⊦ GraphLang.funcs_ok (GraphLang.ARM code) fs ⇒
∀n s1 s2.
GraphLang.good_stack fs s1 ∧ GraphLang.good_stack fs s2 ∧
GraphLang.exec_graph_n (GraphLang.list_func_trans fs) n s1 s2 ⇒
prog.SPEC arm_prog.ARM_MODEL (GraphLang.arm_assert_for s1) code
(GraphLang.arm_assert_for s2)
⊦ GraphLang.funcs_ok (GraphLang.M0 code) fs ⇒
∀n s1 s2.
GraphLang.good_stack fs s1 ∧ GraphLang.good_stack fs s2 ∧
GraphLang.exec_graph_n (GraphLang.list_func_trans fs) n s1 s2 ⇒
prog.SPEC m0_prog.M0_MODEL (GraphLang.m0_assert_for s1) code
(GraphLang.m0_assert_for s2)
⊦ GraphLang.func_ok code locs f ⇒
∀c.
pair.pair_CASE (code, c)
(λv2 v3.
GraphLang.code_CASE v2
(λc1.
GraphLang.code_CASE v3 (λc2. pred_set.SUBSET c1 c2)
(λv11. ⊥))
(λc1'.
GraphLang.code_CASE v3 (λv14. ⊥)
(λc2'. pred_set.SUBSET c1' c2'))) ⇒
GraphLang.func_ok c locs f
⊦ GraphLang.IMPL_INST code locs (GraphLang.Inst pc1 assert1 next1) ∧
GraphLang.IMPL_INST code locs (GraphLang.Inst pc1 assert2 next2) ⇒
∀guard.
GraphLang.IMPL_INST code locs
(GraphLang.Inst pc1 (λs. if guard s then assert1 s else assert2 s)
(GraphLang.IF guard next1 next2))
⊦ ∀nn.
(∃n l. nn = GraphLang.Basic n l) ∨
(∃n n0 f. nn = GraphLang.Cond n n0 f) ∨
∃n s l l0. nn = GraphLang.Call n s l l0
⊦ GraphLang.IMPL_INST code locs (GraphLang.Inst pc1 assert1 next1) ∧
GraphLang.IMPL_INST code locs (GraphLang.Inst pc1 assert2 next2) ⇒
(∀s. assert1 s ⇒ assert2 s) ⇒
∀guard.
GraphLang.IMPL_INST code locs
(GraphLang.Inst pc1 assert1 (GraphLang.IF guard next1 next2))
⊦ (∀nn stf x xs.
GraphLang.upd_stack nn stf (x :: xs) =
(nn, stf (fst (snd x)), snd (snd x)) :: xs) ∧
∀nn stf. GraphLang.upd_stack nn stf [] = []
⊦ GraphLang.graph =
relation.WFREC
(select R'. wellFounded R' ∧ ∀y x xs. R' xs ((x, y) :: xs))
(λgraph a.
list.list_CASE a (id (const none))
(λv xs.
pair.pair_CASE v
(λx y. id (combin.UPDATE x (some y) (graph xs)))))
⊦ (∀n. GraphLang.find_func n [] = none) ∧
∀xs name n insts entry.
GraphLang.find_func n (GraphLang.Func name entry insts :: xs) =
if n = name then some (GraphLang.Func name entry insts)
else GraphLang.find_func n xs
⊦ (∀n. GraphLang.find_inst n [] = none) ∧
∀xs next n l asrt.
GraphLang.find_inst n (GraphLang.Inst l asrt next :: xs) =
if l = n then some (GraphLang.Inst l asrt next)
else GraphLang.find_inst n xs
⊦ ∀P.
(∀n l. P (GraphLang.Basic n l)) ∧
(∀n n0 f. P (GraphLang.Cond n n0 f)) ∧
(∀n s l l0. P (GraphLang.Call n s l l0)) ⇒ ∀nn. P nn
⊦ ∀M M' f.
M = M' ∧
(∀a0 a1 a2. M' = GraphLang.Func a0 a1 a2 ⇒ f a0 a1 a2 = f' a0 a1 a2) ⇒
GraphLang.func_CASE M f = GraphLang.func_CASE M' f'
⊦ ∀M M' f.
M = M' ∧
(∀a0 a1 a2. M' = GraphLang.Inst a0 a1 a2 ⇒ f a0 a1 a2 = f' a0 a1 a2) ⇒
GraphLang.inst_CASE M f = GraphLang.inst_CASE M' f'
⊦ ∀xs x n ys.
list.LUPDATE x (length xs) (xs @ ys) = xs @ list.LUPDATE x 0 ys ∧
list.LUPDATE x (length xs + n) (xs @ ys) = xs @ list.LUPDATE x n ys
⊦ ∀nn.
(∃f n n0. nn = GraphLang.IF f n n0) ∨
(∃o' l j. nn = GraphLang.ASM o' l j) ∨
∃o' l s j. nn = GraphLang.CALL o' l s j
⊦ ∀w.
address.ALIGNED w ⇒
arm.Align (w, arithmetic.BIT2 0) = w ∧
arm.Align (w, arithmetic.BIT2 1) = w ∧
m0.Align (w, arithmetic.BIT2 0) = w ∧
m0.Align (w, arithmetic.BIT2 1) = w
⊦ GraphLang.var_word32 n (GraphLang.apply_update ((x, y) :: xs) s) =
if n = x then
GraphLang.variable_CASE (y s) (words.n2w 0) (λv6. words.n2w 0)
(λv7. words.n2w 0) (λw. w) (λv9. words.n2w 0) (λv10. words.n2w 0)
(λv11. words.n2w 0)
else GraphLang.var_word32 n (GraphLang.apply_update xs s)
⊦ ∀P.
(∀n. P n []) ∧
(∀n name entry insts xs.
(¬(n = name) ⇒ P n xs) ⇒
P n (GraphLang.Func name entry insts :: xs)) ⇒ ∀v v1. P v v1
⊦ ∀P.
(∀n. P n []) ∧
(∀n l asrt next xs.
(¬(l = n) ⇒ P n xs) ⇒ P n (GraphLang.Inst l asrt next :: xs)) ⇒
∀v v1. P v v1
⊦ ∀a0 a1 a2 a3 a0' a1' a2' a3'.
GraphLang.GraphFunction a0 a1 a2 a3 =
GraphLang.GraphFunction a0' a1' a2' a3' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2' ∧ a3 = a3'
⊦ GraphLang.fs_locs =
relation.WFREC
(select R'.
wellFounded R' ∧
∀l entry name xs. R' xs (GraphLang.Func name entry l :: xs))
(λfs_locs a.
list.list_CASE a (id (const none))
(λv xs.
GraphLang.func_CASE v
(λname entry l.
id (combin.UPDATE name (some entry) (fs_locs xs)))))
⊦ bitstring.v2w
(bitstring.field_insert 31 (arithmetic.BIT2 7)
(bitstring.field 15 0 (bitstring.w2v w)) (bitstring.w2v v)) =
words.bit_field_insert 31 (arithmetic.BIT2 7) w v
⊦ ∀M M' f v.
M = M' ∧ (∀a. M' = GraphLang.Jump a ⇒ f a = f' a) ∧
(M' = GraphLang.Return ⇒ v = v') ⇒
GraphLang.jump_CASE M f v = GraphLang.jump_CASE M' f' v'
⊦ (∀a f v v1.
GraphLang.next_node_CASE (GraphLang.NextNode a) f v v1 = f a) ∧
(∀f v v1. GraphLang.next_node_CASE GraphLang.Ret f v v1 = v) ∧
∀f v v1. GraphLang.next_node_CASE GraphLang.Err f v v1 = v1
⊦ ∀P.
P GraphLang.VarNone ∧ (∀a. P (GraphLang.VarNat a)) ∧
(∀a. P (GraphLang.VarWord8 a)) ∧ (∀a. P (GraphLang.VarWord32 a)) ∧
(∀a. P (GraphLang.VarMem a)) ∧ (∀a. P (GraphLang.VarDom a)) ∧
(∀a. P (GraphLang.VarBool a)) ⇒ ∀x. P x
⊦ ∀M M' f.
M = M' ∧
(∀a0 a1 a2 a3.
M' = GraphLang.GraphFunction a0 a1 a2 a3 ⇒
f a0 a1 a2 a3 = f' a0 a1 a2 a3) ⇒
GraphLang.graph_function_CASE M f = GraphLang.graph_function_CASE M' f'
⊦ ∀P.
(∀code names. P code names []) ∧
(∀code names i assert next xs.
P code names xs ⇒
P code names (GraphLang.Inst i assert next :: xs)) ⇒
∀v v1 v2. P v v1 v2
⊦ (words.word_sub a
(words.word_mul (words.n2w (l + n)) (words.n2w (arithmetic.BIT2 1))) =
words.word_sub r13
(words.word_mul (words.n2w (arithmetic.BIT2 1)) (words.n2w l)) ⇒ b) ⇒
address.ALIGNED a ∧ address.ALIGNED r13 ∧
n = words.w2n (words.word_sub a r13) div arithmetic.BIT2 1 ⇒ b
⊦ ∀x.
x = GraphLang.VarNone ∨ (∃n. x = GraphLang.VarNat n) ∨
(∃c. x = GraphLang.VarWord8 c) ∨ (∃c. x = GraphLang.VarWord32 c) ∨
(∃f. x = GraphLang.VarMem f) ∨ (∃f. x = GraphLang.VarDom f) ∨
∃b. x = GraphLang.VarBool b
⊦ ∀M M' f f1.
M = M' ∧ (∀a. M' = GraphLang.ARM a ⇒ f a = f' a) ∧
(∀a. M' = GraphLang.M0 a ⇒ f1 a = f1' a) ⇒
GraphLang.code_CASE M f f1 = GraphLang.code_CASE M' f' f1'
⊦ GraphLang.IMPL_INST c locs
(GraphLang.Inst n b
(GraphLang.IF g (GraphLang.ASM x u (GraphLang.Jump j)) next)) ⇔
GraphLang.IMPL_INST c locs
(GraphLang.Inst n (λs. b s ∧ g s)
(GraphLang.ASM x u (GraphLang.Jump j))) ∧
GraphLang.IMPL_INST c locs (GraphLang.Inst n (λs. b s ∧ ¬g s) next)
⊦ ∀P.
(∀n n0. P n ∧ P n0 ⇒ ∀f. P (GraphLang.IF f n n0)) ∧
(∀o' l j. P (GraphLang.ASM o' l j)) ∧
(∀o' l s j. P (GraphLang.CALL o' l s j)) ⇒ ∀n. P n
⊦ (address.ALIGNED (arm.Align (w, arithmetic.BIT2 0)) ⇔
¬fcp.fcp_index w 1) ∧
(address.ALIGNED (arm.Align (w, arithmetic.BIT2 1)) ⇔ ⊤) ∧
(address.ALIGNED (m0.Align (w, arithmetic.BIT2 0)) ⇔
¬fcp.fcp_index w 1) ∧
(address.ALIGNED (m0.Align (w, arithmetic.BIT2 1)) ⇔ ⊤)
⊦ (∀k. GraphLang.odd_nums k 0 = []) ∧
(∀k n.
GraphLang.odd_nums k (bit1 n) =
k ::
GraphLang.odd_nums (k + arithmetic.BIT2 0)
(arithmetic.- (bit1 n) 1)) ∧
∀k n.
GraphLang.odd_nums k (arithmetic.BIT2 n) =
k :: GraphLang.odd_nums (k + arithmetic.BIT2 0) (bit1 n)
⊦ (∀names code. GraphLang.LIST_IMPL_INST code names [] ⇔ ⊤) ∧
∀xs next names i code assert.
GraphLang.LIST_IMPL_INST code names
(GraphLang.Inst i assert next :: xs) ⇔
GraphLang.IMPL_INST code names (GraphLang.Inst i assert next) ∧
assert = const ⊤ ∧ GraphLang.LIST_IMPL_INST code names xs
⊦ GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard (GraphLang.ASM (some s1) up1 j1)
(GraphLang.ASM (some s2) up2 j2))) ⇔
GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard
(GraphLang.ASM (some (λs. guard s ⇒ s1 s)) up1 j1)
(GraphLang.ASM (some (λs. ¬guard s ⇒ s2 s)) up2 j2)))
⊦ ∀code names name entry l.
GraphLang.func_ok code names (GraphLang.Func name entry l) ⇔
list.ALL_DISTINCT (map GraphLang.inst_loc l) ∧ even (words.w2n entry) ∧
∀i assert next.
bool.IN (GraphLang.Inst i assert next) (list.LIST_TO_SET l) ⇒
GraphLang.IMPL_INST code names (GraphLang.Inst i assert next) ∧
assert = const ⊤
⊦ GraphLang.IMPL_INST c locs
(GraphLang.Inst n b
(GraphLang.IF g (GraphLang.ASM pre u1 (GraphLang.Jump w)) next)) ∧
GraphLang.IMPL_INST c locs
(GraphLang.Inst w g (GraphLang.ASM none [] (GraphLang.Jump j))) ⇒
(∀s. g s ⇒ g (GraphLang.apply_update u1 s)) ⇒
GraphLang.IMPL_INST c locs
(GraphLang.Inst n b
(GraphLang.IF g (GraphLang.ASM pre u1 (GraphLang.Jump j)) next))
⊦ ∀M M' f v v1.
M = M' ∧ (∀a. M' = GraphLang.NextNode a ⇒ f a = f' a) ∧
(M' = GraphLang.Ret ⇒ v = v') ∧ (M' = GraphLang.Err ⇒ v1 = v1') ⇒
GraphLang.next_node_CASE M f v v1 =
GraphLang.next_node_CASE M' f' v' v1'
⊦ ∀f0 f1 f2.
∃fn.
(∀a0 a1. fn (GraphLang.Basic a0 a1) = f0 a0 a1) ∧
(∀a0 a1 a2. fn (GraphLang.Cond a0 a1 a2) = f1 a0 a1 a2) ∧
∀a0 a1 a2 a3. fn (GraphLang.Call a0 a1 a2 a3) = f2 a0 a1 a2 a3
⊦ GraphLang.IMPL_INST c locs
(GraphLang.Inst n b
(GraphLang.IF g next (GraphLang.ASM pre u1 (GraphLang.Jump w)))) ∧
GraphLang.IMPL_INST c locs
(GraphLang.Inst w ((¬) ∘ g)
(GraphLang.ASM none [] (GraphLang.Jump j))) ⇒
(∀s. g (GraphLang.apply_update u1 s) ⇔ g s) ⇒
GraphLang.IMPL_INST c locs
(GraphLang.Inst n b
(GraphLang.IF g next (GraphLang.ASM pre u1 (GraphLang.Jump j))))
⊦ (∀p s w. GraphLang.check_jump (GraphLang.Jump p) s w ⇔ w = p) ∧
∀s w.
GraphLang.check_jump GraphLang.Return s w ⇔
GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2 (bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) :: [])
s = w
⊦ ∀a w mem.
GraphLang.WRITE32 a w mem =
combin.UPDATE a (words.w2w w)
(combin.UPDATE (words.word_add a (words.n2w 1))
(words.w2w (words.word_lsr w (arithmetic.BIT2 3)))
(combin.UPDATE (words.word_add a (words.n2w (arithmetic.BIT2 0)))
(words.w2w (words.word_lsr w (arithmetic.BIT2 7)))
(combin.UPDATE (words.word_add a (words.n2w 3))
(words.w2w
(words.word_lsr w
(arithmetic.BIT2 (bit1 (bit1 (arithmetic.BIT2 0))))))
mem)))
⊦ (GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard (GraphLang.ASM (some (λx. ⊤)) up1 j1) next)) ⇔
GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard (GraphLang.ASM none up1 j1) next))) ∧
(GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard next (GraphLang.ASM (some (λx. ⊤)) up1 j1))) ⇔
GraphLang.IMPL_INST code locs
(GraphLang.Inst pc assert
(GraphLang.IF guard next (GraphLang.ASM none up1 j1))))
⊦ GraphLang.find_func_tupled =
relation.WFREC
(select R'.
wellFounded R' ∧
∀insts entry xs name n.
¬(n = name) ⇒
R' (n, xs) (n, GraphLang.Func name entry insts :: xs))
(λfind_func_tupled a.
pair.pair_CASE a
(λn v1.
list.list_CASE v1 (id none)
(λv2 xs.
GraphLang.func_CASE v2
(λname entry insts.
id
(if n = name then
some (GraphLang.Func name entry insts)
else find_func_tupled (n, xs))))))
⊦ GraphLang.find_inst_tupled =
relation.WFREC
(select R'.
wellFounded R' ∧
∀next asrt xs n l.
¬(l = n) ⇒ R' (n, xs) (n, GraphLang.Inst l asrt next :: xs))
(λfind_inst_tupled a.
pair.pair_CASE a
(λn v1.
list.list_CASE v1 (id none)
(λv2 xs.
GraphLang.inst_CASE v2
(λl asrt next.
id
(if l = n then some (GraphLang.Inst l asrt next)
else find_inst_tupled (n, xs))))))
⊦ ∀f0 f1 f2.
∃fn.
(∀a0 a1 a2.
fn (GraphLang.IF a0 a1 a2) = f0 a0 a1 a2 (fn a1) (fn a2)) ∧
(∀a0 a1 a2. fn (GraphLang.ASM a0 a1 a2) = f1 a0 a1 a2) ∧
∀a0 a1 a2 a3. fn (GraphLang.CALL a0 a1 a2 a3) = f2 a0 a1 a2 a3
⊦ (∀a2 a1' a1 a0' a0.
¬(GraphLang.Basic a0 a1 = GraphLang.Cond a0' a1' a2)) ∧
(∀a3 a2 a1' a1 a0' a0.
¬(GraphLang.Basic a0 a1 = GraphLang.Call a0' a1' a2 a3)) ∧
∀a3 a2' a2 a1' a1 a0' a0.
¬(GraphLang.Cond a0 a1 a2 = GraphLang.Call a0' a1' a2' a3)
⊦ ∀s.
GraphLang.arm_STATE_CPSR s =
set_sep.STAR
(set_sep.STAR
(set_sep.STAR
(arm_prog.arm_CPSR_N
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 0)))))) :: []) s))
(arm_prog.arm_CPSR_Z
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2 0)))))) :: []) s)))
(arm_prog.arm_CPSR_C
(GraphLang.var_bool
(string.CHR
(bit1
(bit1
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) :: []) s)))
(arm_prog.arm_CPSR_V
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) s))
⊦ ∀s.
GraphLang.m0_STATE_PSR s =
set_sep.STAR
(set_sep.STAR
(set_sep.STAR
(m0_prog.m0_PSR_N
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 0)))))) :: []) s))
(m0_prog.m0_PSR_Z
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2 0)))))) :: []) s)))
(m0_prog.m0_PSR_C
(GraphLang.var_bool
(string.CHR
(bit1
(bit1
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) :: []) s)))
(m0_prog.m0_PSR_V
(GraphLang.var_bool
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) s))
⊦ ∀P.
(∀fs. P fs []) ∧ (∀fs x. P fs (x :: [])) ∧
(∀fs l1 s1 n1 l2 s2 n2 xs.
P fs ((l2, s2, n2) :: xs) ⇒
P fs ((l1, s1, n1) :: (l2, s2, n2) :: xs)) ⇒ ∀v v1. P v v1
⊦ GraphLang.variable_size GraphLang.VarNone = 0 ∧
(∀a. GraphLang.variable_size (GraphLang.VarNat a) = 1 + a) ∧
(∀a. GraphLang.variable_size (GraphLang.VarWord8 a) = 1) ∧
(∀a. GraphLang.variable_size (GraphLang.VarWord32 a) = 1) ∧
(∀a. GraphLang.variable_size (GraphLang.VarMem a) = 1) ∧
(∀a. GraphLang.variable_size (GraphLang.VarDom a) = 1) ∧
∀a.
GraphLang.variable_size (GraphLang.VarBool a) =
1 + basicSize.bool_size a
⊦ (∀s u l.
GraphLang.next_ok (GraphLang.ASM s u l) ⇔
GraphLang.upd_ok u ∧ GraphLang.jump_ok l) ∧
(∀b n1 n2.
GraphLang.next_ok (GraphLang.IF b n1 n2) ⇔
GraphLang.next_ok n1 ∧ GraphLang.next_ok n2) ∧
∀a u n j.
GraphLang.next_ok (GraphLang.CALL a u n j) ⇔
map fst u = GraphLang.ret_and_all_names ∧ GraphLang.jump_ok j ∧
∀st. GraphLang.check_ret j st (GraphLang.apply_update u st)
⊦ (∀a2' a2 a1' a1 a0' a0.
¬(GraphLang.IF a0 a1 a2 = GraphLang.ASM a0' a1' a2')) ∧
(∀a3 a2' a2 a1' a1 a0' a0.
¬(GraphLang.IF a0 a1 a2 = GraphLang.CALL a0' a1' a2' a3)) ∧
∀a3 a2' a2 a1' a1 a0' a0.
¬(GraphLang.ASM a0 a1 a2 = GraphLang.CALL a0' a1' a2' a3)
⊦ s
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2 (bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) :: []) =
GraphLang.VarWord32 w ⇒
w =
GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2 (bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) :: []) s
⊦ ∀f0 f1 f2 f3 f4 f5 f6.
∃fn.
fn GraphLang.VarNone = f0 ∧ (∀a. fn (GraphLang.VarNat a) = f1 a) ∧
(∀a. fn (GraphLang.VarWord8 a) = f2 a) ∧
(∀a. fn (GraphLang.VarWord32 a) = f3 a) ∧
(∀a. fn (GraphLang.VarMem a) = f4 a) ∧
(∀a. fn (GraphLang.VarDom a) = f5 a) ∧
∀a. fn (GraphLang.VarBool a) = f6 a
⊦ GraphLang.LIST_IMPL_INST_tupled =
relation.WFREC
(select R'.
wellFounded R' ∧
∀next assert i xs names code.
R' (code, names, xs)
(code, names, GraphLang.Inst i assert next :: xs))
(λLIST_IMPL_INST_tupled a.
pair.pair_CASE a
(λcode v1.
pair.pair_CASE v1
(λnames v3.
list.list_CASE v3 (id ⊤)
(λv4 xs.
GraphLang.inst_CASE v4
(λi assert next.
id
(GraphLang.IMPL_INST code names
(GraphLang.Inst i assert next) ∧
assert = const ⊤ ∧
LIST_IMPL_INST_tupled (code, names, xs)))))))
⊦ (∀a0 a1 f f1 f2.
GraphLang.node_CASE (GraphLang.Basic a0 a1) f f1 f2 = f a0 a1) ∧
(∀a0 a1 a2 f f1 f2.
GraphLang.node_CASE (GraphLang.Cond a0 a1 a2) f f1 f2 = f1 a0 a1 a2) ∧
∀a0 a1 a2 a3 f f1 f2.
GraphLang.node_CASE (GraphLang.Call a0 a1 a2 a3) f f1 f2 =
f2 a0 a1 a2 a3
⊦ ∀code locs n assert next.
GraphLang.IMPL_INST code locs (GraphLang.Inst n assert next) ⇔
GraphLang.next_ok next ∧ even (words.w2n n) ∧
∀s t call w.
assert s ∧ GraphLang.exec_next locs next s t w call ⇒
GraphLang.code_CASE code
(λarm_c.
prog.SPEC arm_prog.ARM_MODEL
(set_sep.STAR (GraphLang.arm_STATE s) (arm_prog.arm_PC n))
arm_c
(set_sep.STAR (GraphLang.arm_STATE t) (arm_prog.arm_PC w)))
(λm0_c.
prog.SPEC m0_prog.M0_MODEL
(set_sep.STAR (GraphLang.m0_STATE s) (m0_prog.m0_PC n)) m0_c
(set_sep.STAR (GraphLang.m0_STATE t) (m0_prog.m0_PC w)))
⊦ (∀a0 a1 a2 f f1 f2.
GraphLang.next_CASE (GraphLang.IF a0 a1 a2) f f1 f2 = f a0 a1 a2) ∧
(∀a0 a1 a2 f f1 f2.
GraphLang.next_CASE (GraphLang.ASM a0 a1 a2) f f1 f2 = f1 a0 a1 a2) ∧
∀a0 a1 a2 a3 f f1 f2.
GraphLang.next_CASE (GraphLang.CALL a0 a1 a2 a3) f f1 f2 =
f2 a0 a1 a2 a3
⊦ (∀a0 a1.
GraphLang.node_size (GraphLang.Basic a0 a1) =
1 +
(GraphLang.next_node_size a0 +
list.list_size
(basicSize.pair_size (list.list_size string.char_size) (λv. 0))
a1)) ∧
(∀a0 a1 a2.
GraphLang.node_size (GraphLang.Cond a0 a1 a2) =
1 + (GraphLang.next_node_size a0 + GraphLang.next_node_size a1)) ∧
∀a0 a1 a2 a3.
GraphLang.node_size (GraphLang.Call a0 a1 a2 a3) =
1 +
(GraphLang.next_node_size a0 +
(list.list_size string.char_size a1 +
(list.list_size (λv. 0) a2 +
list.list_size (list.list_size string.char_size) a3)))
⊦ (∀v0 v1 v2 v3 stack.
GraphLang.exec_node_return v0 v1 (GraphLang.Basic v2 v3) stack =
pred_set.EMPTY) ∧
(∀v4 v5 v6 v7 v8 stack.
GraphLang.exec_node_return v4 v5 (GraphLang.Cond v6 v7 v8) stack =
pred_set.EMPTY) ∧
∀Gamma st cont fname inputs outputs stack.
GraphLang.exec_node_return Gamma st
(GraphLang.Call cont fname inputs outputs) stack =
option.option_CASE (Gamma fname) pred_set.EMPTY
(λv.
GraphLang.graph_function_CASE v
(λinps outps graph ep.
pred_set.INSERT
(GraphLang.upd_stack cont
(GraphLang.return_vars outps outputs st) stack)
pred_set.EMPTY))
⊦ (∀a a'. GraphLang.VarNat a = GraphLang.VarNat a' ⇔ a = a') ∧
(∀a a'. GraphLang.VarWord8 a = GraphLang.VarWord8 a' ⇔ a = a') ∧
(∀a a'. GraphLang.VarWord32 a = GraphLang.VarWord32 a' ⇔ a = a') ∧
(∀a a'. GraphLang.VarMem a = GraphLang.VarMem a' ⇔ a = a') ∧
(∀a a'. GraphLang.VarDom a = GraphLang.VarDom a' ⇔ a = a') ∧
∀a a'. GraphLang.VarBool a = GraphLang.VarBool a' ⇔ a ⇔ a'
⊦ GraphLang.next_trans_tupled =
GraphLang.next_trans_tupled_aux
(select R'.
wellFounded R' ∧
(∀guard n n2 n1 t t1 xs.
(t1, xs) =
GraphLang.next_trans_tupled_aux R'
(t, t + arithmetic.BIT2 1, n1) ⇒
R' (t + arithmetic.BIT2 0, t1, n2)
(n, t, GraphLang.IF guard n1 n2)) ∧
∀n2 guard n n1 t.
R' (t, t + arithmetic.BIT2 1, n1)
(n, t, GraphLang.IF guard n1 n2))
⊦ GraphLang.all_names_with_input =
GraphLang.all_names @
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR (arithmetic.BIT2 (bit1 (bit1 (bit1 (arithmetic.BIT2 0))))) ::
string.CHR (bit1 (bit1 (bit1 (bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2
(arithmetic.BIT2 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1 (bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) :: []) :: []
⊦ (∀a0 a1 a2.
GraphLang.next_size (GraphLang.IF a0 a1 a2) =
1 + (GraphLang.next_size a1 + GraphLang.next_size a2)) ∧
(∀a0 a1 a2.
GraphLang.next_size (GraphLang.ASM a0 a1 a2) =
1 +
(basicSize.option_size (λv. 0) a0 +
(list.list_size
(basicSize.pair_size (list.list_size string.char_size) (λv. 0))
a1 + GraphLang.jump_size a2))) ∧
∀a0 a1 a2 a3.
GraphLang.next_size (GraphLang.CALL a0 a1 a2 a3) =
1 +
(basicSize.option_size (λv. 0) a0 +
(list.list_size
(basicSize.pair_size (list.list_size string.char_size) (λv. 0))
a1 +
(list.list_size string.char_size a2 + GraphLang.jump_size a3)))
⊦ GraphLang.arm_assert_for [] = set_sep.SEP_F ∧
GraphLang.arm_assert_for ((loc, state, name) :: rest) =
set_sep.STAR (GraphLang.arm_STATE state)
(arm_prog.arm_PC
(GraphLang.next_node_CASE loc (λn. words.n2w n)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) state)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) state)))
⊦ GraphLang.m0_assert_for [] = set_sep.SEP_F ∧
GraphLang.m0_assert_for ((loc, state, name) :: rest) =
set_sep.STAR (GraphLang.m0_STATE state)
(m0_prog.m0_PC
(GraphLang.next_node_CASE loc (λn. words.n2w n)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) state)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
[]) state)))
⊦ ∀M M' f f1 f2.
M = M' ∧ (∀a0 a1. M' = GraphLang.Basic a0 a1 ⇒ f a0 a1 = f' a0 a1) ∧
(∀a0 a1 a2.
M' = GraphLang.Cond a0 a1 a2 ⇒ f1 a0 a1 a2 = f1' a0 a1 a2) ∧
(∀a0 a1 a2 a3.
M' = GraphLang.Call a0 a1 a2 a3 ⇒
f2 a0 a1 a2 a3 = f2' a0 a1 a2 a3) ⇒
GraphLang.node_CASE M f f1 f2 = GraphLang.node_CASE M' f' f1' f2'
⊦ GraphLang.arm_assert_for =
relation.WFREC (select R'. wellFounded R')
(λarm_assert_for a.
list.list_CASE a (id set_sep.SEP_F)
(λv rest.
pair.pair_CASE v
(λloc v3.
pair.pair_CASE v3
(λstate name.
id
(set_sep.STAR (GraphLang.arm_STATE state)
(arm_prog.arm_PC
(GraphLang.next_node_CASE loc
(λn. words.n2w n)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) :: [])
state)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) :: [])
state))))))))
⊦ GraphLang.m0_assert_for =
relation.WFREC (select R'. wellFounded R')
(λm0_assert_for a.
list.list_CASE a (id set_sep.SEP_F)
(λv rest.
pair.pair_CASE v
(λloc v3.
pair.pair_CASE v3
(λstate name.
id
(set_sep.STAR (GraphLang.m0_STATE state)
(m0_prog.m0_PC
(GraphLang.next_node_CASE loc
(λn. words.n2w n)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) :: [])
state)
(GraphLang.var_word32
(string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
(bit1
(bit1
(arithmetic.BIT2
0)))))) ::
string.CHR
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(bit1
(arithmetic.BIT2
(arithmetic.BIT2
0)))))) :: [])
state))))))))
⊦ ∀M M' f f1 f2.
M = M' ∧
(∀a0 a1 a2. M' = GraphLang.IF a0 a1 a2 ⇒ f a0 a1 a2 = f' a0 a1 a2) ∧
(∀a0 a1 a2. M' = GraphLang.ASM a0 a1 a2 ⇒ f1 a0 a1 a2 = f1' a0 a1 a2) ∧
(∀a0 a1 a2 a3.
M' = GraphLang.CALL a0 a1 a2 a3 ⇒
f2 a0 a1 a2 a3 = f2' a0 a1 a2 a3) ⇒
GraphLang.next_CASE M f f1 f2 = GraphLang.next_CASE M' f' f1' f2'
⊦ (∀a0 a1 a0' a1'.
GraphLang.Basic a0 a1 = GraphLang.Basic a0' a1' ⇔
a0 = a0' ∧ a1 = a1') ∧
(∀a0 a1 a2 a0' a1' a2'.
GraphLang.Cond a0 a1 a2 = GraphLang.Cond a0' a1' a2' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2') ∧
∀a0 a1 a2 a3 a0' a1' a2' a3'.
GraphLang.Call a0 a1 a2 a3 = GraphLang.Call a0' a1' a2' a3' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2' ∧ a3 = a3'
⊦ (∀a0 a1 a2 a0' a1' a2'.
GraphLang.IF a0 a1 a2 = GraphLang.IF a0' a1' a2' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2') ∧
(∀a0 a1 a2 a0' a1' a2'.
GraphLang.ASM a0 a1 a2 = GraphLang.ASM a0' a1' a2' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2') ∧
∀a0 a1 a2 a3 a0' a1' a2' a3'.
GraphLang.CALL a0 a1 a2 a3 = GraphLang.CALL a0' a1' a2' a3' ⇔
a0 = a0' ∧ a1 = a1' ∧ a2 = a2' ∧ a3 = a3'
⊦ (∀Gamma st cont upds stack.
GraphLang.exec_node Gamma st (GraphLang.Basic cont upds) stack =
pred_set.INSERT
(GraphLang.upd_stack cont (const (GraphLang.upd_vars upds st))
stack) pred_set.EMPTY) ∧
(∀Gamma st left right cond stack.
GraphLang.exec_node Gamma st (GraphLang.Cond left right cond) stack =
pred_set.INSERT
(GraphLang.upd_stack (if cond st then left else right) id stack)
pred_set.EMPTY) ∧
∀Gamma st cont fname inputs outputs stack.
GraphLang.exec_node Gamma st (GraphLang.Call cont fname inputs outputs)
stack =
option.option_CASE (Gamma fname)
(pred_set.INSERT (GraphLang.upd_stack GraphLang.Err id stack)
pred_set.EMPTY)
(λv.
GraphLang.graph_function_CASE v
(λinps outps graph1 ep.
pred_set.INSERT
((GraphLang.NextNode ep,
GraphLang.init_vars inps inputs st, fname) :: stack)
pred_set.EMPTY))
⊦ ∀P.
(∀n t upd jump. P n t (GraphLang.ASM none upd jump)) ∧
(∀n t a upd jump. P n t (GraphLang.ASM (some a) upd jump)) ∧
(∀n t guard n1 n2.
(∀t1 xs.
(t1, xs) = GraphLang.next_trans t (t + arithmetic.BIT2 1) n1 ⇒
P (t + arithmetic.BIT2 0) t1 n2) ∧
P t (t + arithmetic.BIT2 1) n1 ⇒ P n t (GraphLang.IF guard n1 n2)) ∧
(∀n t a upd name r. P n t (GraphLang.CALL a upd name r)) ⇒
∀v v1 v2. P v v1 v2
⊦ GraphLang.ret_and_all_names =
((string.CHR
(arithmetic.BIT2
(arithmetic.BIT2
(bit1 (bit1 (arithmetic.BIT2 (arithmetic.BIT2 0)))))) ::
string.CHR
(bit1
(arithmetic.BIT2
(arithmetic.BIT2 (