simps: fixes d :: "nat"   and i :: "nat"   and s :: "s"   and vs :: "v list"   and ves :: "v list"   and e :: "e" shows "run_one_step d i (s, vs, ves, e) = (case e of $Unreachable \<Rightarrow> (s, vs, RSNormal (vs_to_es ves @ [Trap])) | $Nop \<Rightarrow> (s, vs, RSNormal (vs_to_es ves)) | $Drop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es ves')) | $Select \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstInt32 c] \<Rightarrow> (s, vs, crash_error) | [ConstInt32 c, v2] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # v2 # v1 # ves' \<Rightarrow> if int_eq c 0 then (s, vs, RSNormal (vs_to_es (v2 # ves'))) else (s, vs, RSNormal (vs_to_es (v1 # ves'))) | _ # list \<Rightarrow> (s, vs, crash_error) | $Block (t1s _> t2s) es \<Rightarrow> if length t1s \<le> length ves then let (ves', ves'') = split_n ves (length t1s) in (s, vs, RSNormal (vs_to_es ves'' @ [Label (length t2s) [] (vs_to_es ves' @ ($* es))])) else (s, vs, crash_error) | $Loop (t1s _> t2s) es \<Rightarrow> if length t1s \<le> length ves then let (ves', ves'') = split_n ves (length t1s) in (s, vs, RSNormal (vs_to_es ves'' @ [Label (length t1s) [$Loop (t1s _> t2s) es] (vs_to_es ves' @ ($* es))])) else (s, vs, crash_error) | $b_e.If tf es1 es2 \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> if int_eq c 0 then (s, vs, RSNormal (vs_to_es ves' @ [$Block tf es2])) else (s, vs, RSNormal (vs_to_es ves' @ [$Block tf es1])) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Br j \<Rightarrow> (s, vs, RSBreak j ves) | $Br_if j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> if int_eq c 0 then (s, vs, RSNormal (vs_to_es ves')) else (s, vs, RSNormal (vs_to_es ves' @ [$Br j])) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Br_table js j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> let k = nat_of_int c in if k < length js then (s, vs, RSNormal (vs_to_es ves' @ [$Br (js ! k)])) else (s, vs, RSNormal (vs_to_es ves' @ [$Br j])) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Return \<Rightarrow> (s, vs, RSReturn ves) | $Call j \<Rightarrow> (s, vs, RSNormal (vs_to_es ves @ [Callcl (sfunc s i j)])) | $Call_indirect j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> expect (stab s i (nat_of_int c)) (\<lambda>cl. if stypes s i j = cl_type cl then (s, vs, RSNormal (vs_to_es ves' @ [Callcl cl])) else (s, vs, RSNormal (vs_to_es ves' @ [Trap]))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Get_local j \<Rightarrow> if j < length vs then (s, vs, RSNormal (vs_to_es (vs ! j # ves))) else (s, vs, crash_error) | $Set_local j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> if j < length vs then (s, vs[j := v], RSNormal (vs_to_es ves')) else (s, vs, crash_error) | $Tee_local j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (v # ves) @ [$Set_local j])) | $Get_global j \<Rightarrow> (s, vs, RSNormal (vs_to_es (sglob_val s i j # ves))) | $Set_global j \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> (supdate_glob s i j v, vs, RSNormal (vs_to_es ves')) | $Load t aa a off \<Rightarrow> expect aa (\<lambda>(tp, sx). case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 k # ves' \<Rightarrow> expect (smem_ind s i) (\<lambda>a'. expect (load_packed sx (s.mem s ! a') (nat_of_int k) off (tp_length tp) (t_length t)) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (wasm_deserialise a' t # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap]))) (s, vs, crash_error) | _ # ves' \<Rightarrow> (s, vs, crash_error)) (case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 k # ves' \<Rightarrow> expect (smem_ind s i) (\<lambda>a'. expect (load (s.mem s ! a') (nat_of_int k) off (t_length t)) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (wasm_deserialise a' t # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap]))) (s, vs, crash_error) | _ # ves' \<Rightarrow> (s, vs, crash_error)) | $Store t aa a off \<Rightarrow> expect aa (\<lambda>tp. case ves of [] \<Rightarrow> (s, vs, crash_error) | [v] \<Rightarrow> (s, vs, crash_error) | v # ConstInt32 k # ves' \<Rightarrow> if types_agree t v then expect (smem_ind s i) (\<lambda>a'. expect (store_packed (s.mem s ! a') (nat_of_int k) off (bits v) (tp_length tp)) (\<lambda>a'a. (s\<lparr>s.mem := (s.mem s)[a' := a'a]\<rparr>, vs, RSNormal (vs_to_es ves'))) (s, vs, RSNormal (vs_to_es ves' @ [Trap]))) (s, vs, crash_error) else (s, vs, crash_error) | v # _ # ves' \<Rightarrow> (s, vs, crash_error)) (case ves of [] \<Rightarrow> (s, vs, crash_error) | [v] \<Rightarrow> (s, vs, crash_error) | v # ConstInt32 k # ves' \<Rightarrow> if types_agree t v then expect (smem_ind s i) (\<lambda>a'. expect (store (s.mem s ! a') (nat_of_int k) off (bits v) (t_length t)) (\<lambda>a'a. (s\<lparr>s.mem := (s.mem s)[a' := a'a]\<rparr>, vs, RSNormal (vs_to_es ves'))) (s, vs, RSNormal (vs_to_es ves' @ [Trap]))) (s, vs, crash_error) else (s, vs, crash_error) | v # _ # ves' \<Rightarrow> (s, vs, crash_error)) | $Current_memory \<Rightarrow> expect (smem_ind s i) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (ConstInt32 (int_of_nat (mem_size (s.mem s ! a'))) # ves)))) (s, vs, crash_error) | $Grow_memory \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> expect (smem_ind s i) (\<lambda>a'. let l = mem_size (s.mem s ! a') in expect (mem_grow_impl (s.mem s ! a') (nat_of_int c)) (\<lambda>a'a. (s\<lparr>s.mem := (s.mem s)[a' := a'a]\<rparr>, vs, RSNormal (vs_to_es (ConstInt32 (int_of_nat l) # ves')))) (s, vs, RSNormal (vs_to_es (ConstInt32 int32_minus_one # ves')))) (s, vs, crash_error) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $C v \<Rightarrow> (s, vs, crash_error) | $Unop_i T_i32 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (app_unop_i iop c) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Unop_i T_i64 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt64 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt64 (app_unop_i iop c) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Unop_i _ iop \<Rightarrow> (s, vs, crash_error) | $Unop_f T_f32 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstFloat32 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstFloat32 (app_unop_f fop c) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Unop_f T_f64 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstFloat64 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstFloat64 (app_unop_f fop c) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Unop_f _ fop \<Rightarrow> (s, vs, crash_error) | $Binop_i T_i32 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstInt32 c2] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c2 # ConstInt32 c1 # ves' \<Rightarrow> expect (app_binop_i iop c1 c2) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (ConstInt32 a' # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) | ConstInt32 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Binop_i T_i64 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstInt64 c2] \<Rightarrow> (s, vs, crash_error) | ConstInt64 c2 # ConstInt64 c1 # ves' \<Rightarrow> expect (app_binop_i iop c1 c2) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (ConstInt64 a' # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) | ConstInt64 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Binop_i _ iop \<Rightarrow> (s, vs, crash_error) | $Binop_f T_f32 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstFloat32 c2] \<Rightarrow> (s, vs, crash_error) | ConstFloat32 c2 # ConstFloat32 c1 # ves' \<Rightarrow> expect (app_binop_f fop c1 c2) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (ConstFloat32 a' # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) | ConstFloat32 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Binop_f T_f64 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstFloat64 c2] \<Rightarrow> (s, vs, crash_error) | ConstFloat64 c2 # ConstFloat64 c1 # ves' \<Rightarrow> expect (app_binop_f fop c1 c2) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (ConstFloat64 a' # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) | ConstFloat64 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Binop_f _ fop \<Rightarrow> (s, vs, crash_error) | $Testop T_i32 testop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_testop_i testop c)) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Testop T_i64 testop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | ConstInt64 c # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_testop_i testop c)) # ves'))) | _ # ves' \<Rightarrow> (s, vs, crash_error) | $Testop _ testop \<Rightarrow> (s, vs, crash_error) | $Relop_i T_i32 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstInt32 c2] \<Rightarrow> (s, vs, crash_error) | ConstInt32 c2 # ConstInt32 c1 # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_relop_i iop c1 c2)) # ves'))) | ConstInt32 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Relop_i T_i64 iop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstInt64 c2] \<Rightarrow> (s, vs, crash_error) | ConstInt64 c2 # ConstInt64 c1 # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_relop_i iop c1 c2)) # ves'))) | ConstInt64 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Relop_i _ iop \<Rightarrow> (s, vs, crash_error) | $Relop_f T_f32 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstFloat32 c2] \<Rightarrow> (s, vs, crash_error) | ConstFloat32 c2 # ConstFloat32 c1 # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_relop_f fop c1 c2)) # ves'))) | ConstFloat32 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Relop_f T_f64 fop \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | [ConstFloat64 c2] \<Rightarrow> (s, vs, crash_error) | ConstFloat64 c2 # ConstFloat64 c1 # ves' \<Rightarrow> (s, vs, RSNormal (vs_to_es (ConstInt32 (wasm_bool (app_relop_f fop c1 c2)) # ves'))) | ConstFloat64 c2 # _ # ves' \<Rightarrow> (s, vs, crash_error) | _ # list \<Rightarrow> (s, vs, crash_error) | $Relop_f _ fop \<Rightarrow> (s, vs, crash_error) | $Cvtop t2 Convert t1 sx \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> if types_agree t1 v then expect (cvt t2 sx v) (\<lambda>a'. (s, vs, RSNormal (vs_to_es (a' # ves')))) (s, vs, RSNormal (vs_to_es ves' @ [Trap])) else (s, vs, crash_error) | $Cvtop t2 Reinterpret t1 sx \<Rightarrow> case ves of [] \<Rightarrow> (s, vs, crash_error) | v # ves' \<Rightarrow> if types_agree t1 v \<and> sx = None then (s, vs, RSNormal (vs_to_es (wasm_deserialise (bits v) t2 # ves'))) else (s, vs, crash_error) | Trap \<Rightarrow> (s, vs, crash_error) | Callcl (Func_native i' (t1s _> t2s) ts es) \<Rightarrow> let n = length t1s; m = length t2s in if n \<le> length ves then let (ves', ves'') = split_n ves n; zs = n_zeros ts in (s, vs, RSNormal (vs_to_es ves'' @ [Local m i' (rev ves' @ zs) [$Block ([] _> t2s) es]])) else (s, vs, crash_error) | Callcl (Func_host (t1s _> t2s) f) \<Rightarrow> let n = length t1s; m = length t2s in if n \<le> length ves then let (ves', ves'') = split_n ves n in expect (host_apply_impl s (t1s _> t2s) f (rev ves')) (\<lambda>(s', rves). if list_all2 types_agree t2s rves then (s', vs, RSNormal (vs_to_es ves'' @ ($$* rves))) else (s', vs, crash_error)) (s, vs, RSNormal (vs_to_es ves'' @ [Trap])) else (s, vs, crash_error) | Label ln les es \<Rightarrow> if es_is_trap es then (s, vs, RSNormal (vs_to_es ves @ [Trap])) else if const_list es then (s, vs, RSNormal (vs_to_es ves @ es)) else let (s', vs', y) = run_step d i (s, vs, es) in case_res_step (\<lambda>res_crash. (s', vs', crash_error)) (\<lambda>nat bvs. case nat of 0 \<Rightarrow> if ln \<le> length bvs then (s', vs', RSNormal (vs_to_es (take ln bvs @ ves) @ les)) else (s', vs', crash_error) | Suc n \<Rightarrow> (s', vs', RSBreak n bvs)) (\<lambda>rvs. (s', vs', RSReturn rvs)) (\<lambda>es'. (s', vs', RSNormal (vs_to_es ves @ [Label ln les es']))) y | Local ln j vls es \<Rightarrow> if es_is_trap es then (s, vs, RSNormal (vs_to_es ves @ [Trap])) else if const_list es then if length es = ln then (s, vs, RSNormal (vs_to_es ves @ es)) else (s, vs, crash_error) else case d of 0 \<Rightarrow> (s, vs, crash_error) | Suc d' \<Rightarrow> let (s', vls', y) = run_step d' j (s, vls, es) in case_res_step (\<lambda>res_crash. (s', vs, RSCrash CExhaustion)) (\<lambda>nat list. (s', vs, RSCrash CExhaustion)) (\<lambda>rvs. if ln \<le> length rvs then (s', vs, RSNormal (vs_to_es (take ln rvs @ ves))) else (s', vs, crash_error)) (\<lambda>es'. (s', vs, RSNormal (vs_to_es ves @ [Local ln j vls' es']))) y)"