|
|
|
|
Quelle Expressions.thy
Sprache: Isabelle
|
|
section ‹Expressions›
theory Expressions
imports Contracts StateMonad
begin
subsection ‹Semantics of Expressions›
definition lift ::
"(E → Environment → CalldataT → State → (Stackvalue * Type, Ex, Gas) state_monad)
→ (Types → Types → Valuetype → Valuetype → (Valuetype * Types) option)
→ E → E → Environment → CalldataT → State → (Stackvalue * Type, Ex, Gas) state_monad"
where
"lift expr f e1 e2 e cd st ≡
(do {
kv1 ← expr e1 e cd st;
(v1, t1) ← case kv1 of (KValue v1, Value t1) → return (v1, t1) | _ → (throw Err::(Valuetype * Types, Ex, Gas) state_monad);
kv2 ← expr e2 e cd st;
(v2, t2) ← case kv2 of (KValue v2, Value t2) → return (v2, t2) | _ → (throw Err::(Valuetype * Types, Ex, Gas) state_monad);
(v, t) ← (option Err (λ_::Gas. f t1 t2 v1 v2))::(Valuetype * Types, Ex, Gas) state_monad;
return (KValue v, Value t)::(Stackvalue * Type, Ex, Gas) state_monad
})"
declare lift_def[simp, solidity_symbex]
lemma lift_cong [fundef_cong]:
assumes "expr e1 e cd st g = expr' e1 e cd st g"
and "∧v g'. expr' e1 e cd st g = Normal (v,g') ==> expr e2 e cd st g' = expr' e2 e cd st g'"
shows "lift expr f e1 e2 e cd st g = lift expr' f e1 e2 e cd st g"
unfolding lift_def using assms by (auto split: prod.split_asm result.split option.split_asm option.split Stackvalue.split Type.split)
datatype LType = LStackloc Location
| LMemloc Location
| LStoreloc Location
locale expressions_with_gas =
fixes costse :: "E → Environment → CalldataT → State → Gas"
and ep::EnvironmentP
assumes call_not_zero[termination_simp]: "∧e cd st i ix. 0 < (costse (CALL i ix) e cd st)"
and ecall_not_zero[termination_simp]: "∧e cd st a i ix. 0 < (costse (ECALL a i ix) e cd st)"
begin
function (domintros) msel::"bool → MTypes → Location → E list → Environment → CalldataT → State → (Location * MTypes, Ex, Gas) state_monad"
and ssel::"STypes → Location → E list → Environment → CalldataT → State → (Location * STypes, Ex, Gas) state_monad"
and expr::"E → Environment → CalldataT → State → (Stackvalue * Type, Ex, Gas) state_monad"
and load :: "bool → (Identifier × Type) list → E list → Environment → CalldataT → Stack → MemoryT → Environment → CalldataT → State → (Environment × CalldataT × Stack × MemoryT, Ex, Gas) state_monad"
and rexp::"L → Environment → CalldataT → State → (Stackvalue * Type, Ex, Gas) state_monad"
where
"msel _ _ _ [] _ _ _ g = throw Err g"
| "msel _ (MTValue _) _ _ _ _ _ g = throw Err g"
| "msel _ (MTArray al t) loc [x] env cd st g =
(do {
kv ← expr x env cd st;
(v, t') ← case kv of (KValue v, Value t') → return (v, t') | _ → throw Err;
assert Err (λ_. less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool));
return (hash loc v, t)
}) g"
(*
Note that it is indeed possible to modify the state while evaluating the expression
to determine the index of the array to look up.
*)
| "msel mm (MTArray al t) loc (x # y # ys) env cd st g =
(do {
kv ← expr x env cd st;
(v, t') ← case kv of (KValue v, Value t') → return (v,t') | _ → throw Err;
assert Err (λ_. less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool));
l ← case accessStore (hash loc v) (if mm then memory st else cd) of Some (MPointer l) → return l | _ → throw Err;
msel mm t l (y#ys) env cd st
}) g"
| "ssel tp loc Nil _ _ _ g = return (loc, tp) g"
| "ssel (STValue _) _ (_ # _) _ _ _ g = throw Err g"
| "ssel (STArray al t) loc (x # xs) env cd st g =
(do {
kv ← expr x env cd st;
(v, t') ← case kv of (KValue v, Value t') → return (v, t') | _ → throw Err;
assert Err (λ_. less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool));
ssel t (hash loc v) xs env cd st
}) g"
| "ssel (STMap _ t) loc (x # xs) env cd st g =
(do {
kv ← expr x env cd st;
v ← case kv of (KValue v, _) → return v | _ → throw Err;
ssel t (hash loc v) xs env cd st
}) g"
| "expr (E.INT b x) e cd st g =
(do {
assert Gas (λg. g > costse (E.INT b x) e cd st);
modify (λg. g - costse (E.INT b x) e cd st);
assert Err (λ_. b ∈ vbits);
return (KValue (createSInt b x), Value (TSInt b))
}) g"
| "expr (UINT b x) e cd st g =
(do {
assert Gas (λg. g > costse (UINT b x) e cd st);
modify (λg. g - costse (UINT b x) e cd st);
assert Err (λ_. b ∈ vbits);
return (KValue (createUInt b x), Value (TUInt b))
}) g"
| "expr (ADDRESS ad) e cd st g =
(do {
assert Gas (λg. g > costse (ADDRESS ad) e cd st);
modify (λg. g - costse (ADDRESS ad) e cd st);
return (KValue ad, Value TAddr)
}) g"
| "expr (BALANCE ad) e cd st g =
(do {
assert Gas (λg. g > costse (BALANCE ad) e cd st);
modify (λg. g - costse (BALANCE ad) e cd st);
kv ← expr ad e cd st;
adv ← case kv of (KValue adv, Value TAddr) → return adv | _ → throw Err;
return (KValue (bal ((accounts st) adv)), Value (TUInt 256))
}) g"
| "expr THIS e cd st g =
(do {
assert Gas (λg. g > costse THIS e cd st);
modify (λg. g - costse THIS e cd st);
return (KValue (address e), Value TAddr)
}) g"
| "expr SENDER e cd st g =
(do {
assert Gas (λg. g > costse SENDER e cd st);
modify (λg. g - costse SENDER e cd st);
return (KValue (sender e), Value TAddr)
}) g"
| "expr VALUE e cd st g =
(do {
assert Gas (λg. g > costse VALUE e cd st);
modify (λg. g - costse VALUE e cd st);
return (KValue (svalue e), Value (TUInt 256))
}) g"
| "expr TRUE e cd st g =
(do {
assert Gas (λg. g > costse TRUE e cd st);
modify (λg. g - costse TRUE e cd st);
return (KValue (ShowLbool True), Value TBool)
}) g"
| "expr FALSE e cd st g =
(do {
assert Gas (λg. g > costse FALSE e cd st);
modify (λg. g - costse FALSE e cd st);
return (KValue (ShowLbool False), Value TBool)
}) g"
| "expr (NOT x) e cd st g =
(do {
assert Gas (λg. g > costse (NOT x) e cd st);
modify (λg. g - costse (NOT x) e cd st);
kv ← expr x e cd st;
v ← case kv of (KValue v, Value TBool) → return v | _ → throw Err;
(if v = ShowLbool True then expr FALSE e cd st
else if v = ShowLbool False then expr TRUE e cd st
else throw Err)
}) g"
| "expr (PLUS e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (PLUS e1 e2) e cd st);
modify (λg. g - costse (PLUS e1 e2) e cd st);
lift expr add e1 e2 e cd st
}) g"
| "expr (MINUS e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (MINUS e1 e2) e cd st);
modify (λg. g - costse (MINUS e1 e2) e cd st);
lift expr sub e1 e2 e cd st
}) g"
| "expr (LESS e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (LESS e1 e2) e cd st);
modify (λg. g - costse (LESS e1 e2) e cd st);
lift expr less e1 e2 e cd st
}) g"
| "expr (EQUAL e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (EQUAL e1 e2) e cd st);
modify (λg. g - costse (EQUAL e1 e2) e cd st);
lift expr equal e1 e2 e cd st
}) g"
| "expr (AND e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (AND e1 e2) e cd st);
modify (λg. g - costse (AND e1 e2) e cd st);
lift expr vtand e1 e2 e cd st
}) g"
| "expr (OR e1 e2) e cd st g =
(do {
assert Gas (λg. g > costse (OR e1 e2) e cd st);
modify (λg. g - costse (OR e1 e2) e cd st);
lift expr vtor e1 e2 e cd st
}) g"
| "expr (LVAL i) e cd st g =
(do {
assert Gas (λg. g > costse (LVAL i) e cd st);
modify (λg. g - costse (LVAL i) e cd st);
rexp i e cd st
}) g"
(* Notes about method calls:
- Internal method calls use a fresh environment and stack but keep the memory [1]
- External method calls use a fresh environment and stack and memory [2]
[1]: https://docs.soliditylang.org/en/v0.8.5/control-structures.html#internal-function-calls
[2]: https://docs.soliditylang.org/en/v0.8.5/control-structures.html#external-function-calls
*)
| "expr (CALL i xe) e cd st g =
(do {
assert Gas (λg. g > costse (CALL i xe) e cd st);
modify (λg. g - costse (CALL i xe) e cd st);
(ct, _) ← option Err (λ_. ep $$ (contract e));
(fp, x) ← case ct $$ i of Some (Function (fp, False, x)) → return (fp, x) | _ → throw Err;
let e' = ffold_init ct (emptyEnv (address e) (contract e) (sender e) (svalue e)) (fmdom ct);
(el, cdl, kl, ml) ← load False fp xe e' emptyStore emptyStore (memory st) e cd st;
expr x el cdl (st(stack:=kl, memory:=ml))
}) g"
(*It is not allowed to transfer money to external function calls*)
| "expr (ECALL ad i xe) e cd st g =
(do {
assert Gas (λg. g > costse (ECALL ad i xe) e cd st);
modify (λg. g - costse (ECALL ad i xe) e cd st);
kad ← expr ad e cd st;
adv ← case kad of (KValue adv, Value TAddr) → return adv | _ → throw Err;
assert Err (λ_. adv ≠ address e);
c ← case type (accounts st adv) of Some (Contract c) → return c | _ → throw Err;
(ct, _) ← option Err (λ_. ep $$ c);
(fp, x) ← case ct $$ i of Some (Function (fp, True, x)) → return (fp, x) | _ → throw Err;
let e' = ffold_init ct (emptyEnv adv c (address e) (ShowLnat 0)) (fmdom ct);
(el, cdl, kl, ml) ← load True fp xe e' emptyStore emptyStore emptyStore e cd st;
expr x el cdl (st(stack:=kl, memory:=ml))
}) g"
| "load cp ((ip, tp)#pl) (ex#el) ev' cd' sck' mem' ev cd st g =
(do {
(v, t) ← expr ex ev cd st;
(c, m, k, e) ← case decl ip tp (Some (v,t)) cp cd (memory st) (storage st) (cd', mem', sck', ev') of Some (c, m, k, e) → return (c, m, k, e) | None → throw Err;
load cp pl el e c k m ev cd st
}) g"
| "load _ [] (_#_) _ _ _ _ _ _ _ g = throw Err g"
| "load _ (_#_) [] _ _ _ _ _ _ _ g = throw Err g"
| "load _ [] [] ev' cd' sck' mem' ev cd st g = return (ev', cd', sck', mem') g"
| "rexp (Id i) e cd st g =
(case fmlookup (denvalue e) i of
Some (tp, Stackloc l) →
(case accessStore l (stack st) of
Some (KValue v) → return (KValue v, tp)
| Some (KCDptr p) → return (KCDptr p, tp)
| Some (KMemptr p) → return (KMemptr p, tp)
| Some (KStoptr p) → return (KStoptr p, tp)
| _ → throw Err)
| Some (Storage (STValue t), Storeloc l) → return (KValue (accessStorage t l (storage st (address e))), Value t)
| Some (Storage (STArray x t), Storeloc l) → return (KStoptr l, Storage (STArray x t))
| _ → throw Err) g"
| "rexp (Ref i r) e cd st g =
(case fmlookup (denvalue e) i of
Some (tp, (Stackloc l)) →
(case accessStore l (stack st) of
Some (KCDptr l') →
do {
t ← case tp of Calldata t → return t | _ → throw Err;
(l'', t') ← msel False t l' r e cd st;
(case t' of
MTValue t'' →
do {
v ← case accessStore l'' cd of Some (MValue v) → return v | _ → throw Err;
return (KValue v, Value t'')
}
| MTArray x t'' →
do {
p ← case accessStore l'' cd of Some (MPointer p) → return p | _ → throw Err;
return (KCDptr p, Calldata (MTArray x t''))
}
)
}
| Some (KMemptr l') →
do {
t ← case tp of Memory t → return t | _ → throw Err;
(l'', t') ← msel True t l' r e cd st;
(case t' of
MTValue t'' →
do {
v ← case accessStore l'' (memory st) of Some (MValue v) → return v | _ → throw Err;
return (KValue v, Value t'')
}
| MTArray x t'' →
do {
p ← case accessStore l'' (memory st) of Some (MPointer p) → return p | _ → throw Err;
return (KMemptr p, Memory (MTArray x t''))
}
)
}
| Some (KStoptr l') →
do {
t ← case tp of Storage t → return t | _ → throw Err;
(l'', t') ← ssel t l' r e cd st;
(case t' of
STValue t'' → return (KValue (accessStorage t'' l'' (storage st (address e))), Value t'')
| STArray _ _ → return (KStoptr l'', Storage t')
| STMap _ _ → return (KStoptr l'', Storage t'))
}
| _ → throw Err)
| Some (tp, (Storeloc l)) →
do {
t ← case tp of Storage t → return t | _ → throw Err;
(l', t') ← ssel t l r e cd st;
(case t' of
STValue t'' → return (KValue (accessStorage t'' l' (storage st (address e))), Value t'')
| STArray _ _ → return (KStoptr l', Storage t')
| STMap _ _ → return (KStoptr l', Storage t'))
}
| None → throw Err) g"
| "expr CONTRACTS e cd st g =
(do {
assert Gas (λg. g > costse CONTRACTS e cd st);
modify (λg. g - costse CONTRACTS e cd st);
prev ← case contracts (accounts st (address e)) of 0 → throw Err | Suc n → return n;
return (KValue (hash (address e) (ShowLnat prev)), Value TAddr)
}) g"
by pat_completeness auto
subsection ‹Termination›
text ‹To prove termination we first need to show that expressions do not increase gas›
lemma lift_gas:
assumes "lift expr f e1 e2 e cd st g = Normal (v, g')"
and "∧v g'. expr e1 e cd st g = Normal (v, g') ==> g' ≤ g"
and "∧v g' v' t' g''. expr e1 e cd st g = Normal (v, g')
==> expr e2 e cd st g' = Normal (v', g'')
==> g'' ≤ g'"
shows "g' ≤ g"
proof (cases "expr e1 e cd st g")
case (n a g0')
then show ?thesis
proof (cases a)
case (Pair b c)
then show ?thesis
proof (cases b)
case (KValue v1)
then show ?thesis
proof (cases c)
case (Value t1)
then show ?thesis
proof (cases "expr e2 e cd st g0'")
case r2: (n a' g0'')
then show ?thesis
proof (cases a')
case p2: (Pair b c)
then show ?thesis
proof (cases b)
case v2: (KValue v2)
then show ?thesis
proof (cases c)
case t2: (Value t2)
then show ?thesis
proof (cases "f t1 t2 v1 v2")
case None
with assms n Pair KValue Value r2 p2 v2 t2 show ?thesis by simp
next
case (Some a'')
then show ?thesis
proof (cases a'')
case p3: (Pair v t)
with assms n Pair KValue Value r2 p2 v2 t2 Some have "g0'≤ g" by simp
moreover from assms n Pair KValue Value r2 p2 v2 t2 Some have "g0''≤g0'" by simp
moreover from assms n Pair KValue Value r2 p2 v2 t2 Some have "g'=g0''" by (simp split:prod.split_asm)
ultimately show ?thesis by arith
qed
qed
next
case (Calldata x2)
with assms n Pair KValue Value r2 p2 v2 show ?thesis by simp
next
case (Memory x3)
with assms n Pair KValue Value r2 p2 v2 show ?thesis by simp
next
case (Storage x4)
with assms n Pair KValue Value r2 p2 v2 show ?thesis by simp
qed
next
case (KCDptr x2)
with assms n Pair KValue Value r2 p2 show ?thesis by simp
next
case (KMemptr x3)
with assms n Pair KValue Value r2 p2 show ?thesis by simp
next
case (KStoptr x4)
with assms n Pair KValue Value r2 p2 show ?thesis by simp
qed
qed
next
case (e x)
with assms n Pair KValue Value show ?thesis by simp
qed
next
case (Calldata x2)
with assms n Pair KValue show ?thesis by simp
next
case (Memory x3)
with assms n Pair KValue show ?thesis by simp
next
case (Storage x4)
with assms n Pair KValue show ?thesis by simp
qed
next
case (KCDptr x2)
with assms n Pair show ?thesis by simp
next
case (KMemptr x3)
with assms n Pair show ?thesis by simp
next
case (KStoptr x4)
with assms n Pair show ?thesis by simp
qed
qed
next
case (e x)
with assms show ?thesis by simp
qed
lemma msel_ssel_expr_load_rexp_dom_gas[rule_format]:
"msel_ssel_expr_load_rexp_dom (Inl (Inl (c1, t1, l1, xe1, ev1, cd1, st1, g1)))
==> (∀v1' g1'. msel c1 t1 l1 xe1 ev1 cd1 st1 g1 = Normal (v1', g1') ⟶ g1' ≤ g1)"
"msel_ssel_expr_load_rexp_dom (Inl (Inr (t2, l2, xe2, ev2, cd2, st2, g2)))
==> (∀v2' g2'. ssel t2 l2 xe2 ev2 cd2 st2 g2 = Normal (v2', g2') ⟶ g2' ≤ g2)"
"msel_ssel_expr_load_rexp_dom (Inr (Inl (e4, ev4, cd4, st4, g4)))
==> (∀v4' g4'. expr e4 ev4 cd4 st4 g4 = Normal (v4', g4') ⟶ g4' ≤ g4)"
"msel_ssel_expr_load_rexp_dom (Inr (Inr (Inl (lcp, lis, lxs, lev0, lcd0, lk, lm, lev, lcd, lst, lg))))
==> (∀ev cd k m g'. load lcp lis lxs lev0 lcd0 lk lm lev lcd lst lg = Normal ((ev, cd, k, m), g') ⟶ g' ≤ lg ∧ address ev = address lev0 ∧ sender ev = sender lev0 ∧ svalue ev = svalue lev0)"
"msel_ssel_expr_load_rexp_dom (Inr (Inr (Inr (l3, ev3, cd3, st3, g3))))
==> (∀v3' g3'. rexp l3 ev3 cd3 st3 g3 = Normal (v3', g3') ⟶ g3' ≤ g3)"
proof (induct rule: msel_ssel_expr_load_rexp.pinduct
[where ?P1.0="λc1 t1 l1 xe1 ev1 cd1 st1 g1. (∀l1' g1'. msel c1 t1 l1 xe1 ev1 cd1 st1 g1 = Normal (l1', g1') ⟶ g1' ≤ g1)"
and ?P2.0="λt2 l2 xe2 ev2 cd2 st2 g2. (∀v2' g2'. ssel t2 l2 xe2 ev2 cd2 st2 g2 = Normal (v2', g2') ⟶ g2' ≤ g2)"
and ?P3.0="λe4 ev4 cd4 st4 g4. (∀v4' g4'. expr e4 ev4 cd4 st4 g4 = Normal (v4', g4') ⟶ g4' ≤ g4)"
and ?P4.0="λlcp lis lxs lev0 lcd0 lk lm lev lcd lst lg. (∀ev cd k m g'. load lcp lis lxs lev0 lcd0 lk lm lev lcd lst lg = Normal ((ev, cd, k, m), g') ⟶ g' ≤ lg ∧ address ev = address lev0 ∧ sender ev = sender lev0 ∧ svalue ev = svalue lev0)"
and ?P5.0="λl3 ev3 cd3 st3 g3. (∀v3' g3'. rexp l3 ev3 cd3 st3 g3 = Normal (v3', g3') ⟶ g3' ≤ g3)"
])
case 1
then show ?case using msel.psimps(1) by auto
next
case 2
then show ?case using msel.psimps(2) by auto
next
case 3
then show ?case using msel.psimps(3) by (auto split: if_split_asm Type.split_asm Stackvalue.split_asm prod.split_asm StateMonad.result.split_asm)
next
case (4 mm al t loc x y ys env cd st g)
show ?case
proof (rule allI[THEN allI, OF impI])
fix v1' g1' assume a1: "msel mm (MTArray al t) loc (x # y # ys) env cd st g = Normal (v1', g1')"
show "g1' ≤ g"
proof (cases v1')
case (Pair l1' t1')
then show ?thesis
proof (cases "expr x env cd st g")
case (n a g')
then show ?thesis
proof (cases a)
case p2: (Pair b c)
then show ?thesis
proof (cases b)
case (KValue v)
then show ?thesis
proof (cases c)
case (Value t')
then show ?thesis
proof (cases)
assume l: "less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool)"
then show ?thesis
proof (cases "accessStore (hash loc v) (if mm then memory st else cd)")
case None
with 4 a1 n p2 KValue Value l show ?thesis using msel.psimps(4) by simp
next
case (Some a)
then show ?thesis
proof (cases a)
case (MValue _)
with 4 a1 n p2 KValue Value Some l show ?thesis using msel.psimps(4) by simp
next
case (MPointer l)
with n p2 KValue Value l Some
have "msel mm (MTArray al t) loc (x # y # ys) env cd st g = msel mm t l (y # ys) env cd st g'"
using msel.psimps(4) 4(1) by simp
moreover from n have "g' ≤ g" using 4(2) by simp
moreover from a1 MPointer n Pair p2 KValue Value l Some
have "g1' ≤ g'" using msel.psimps(4) 4(3) 4(1) by simp
ultimately show ?thesis by simp
qed
qed
next
assume "¬ less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool)"
with 4 a1 n p2 KValue Value show ?thesis using msel.psimps(4) by simp
qed
next
case (Calldata _)
with 4 a1 n p2 KValue show ?thesis using msel.psimps(4) by simp
next
case (Memory _)
with 4 a1 n p2 KValue show ?thesis using msel.psimps(4) by simp
next
case (Storage _)
with 4 a1 n p2 KValue show ?thesis using msel.psimps(4) by simp
qed
next
case (KCDptr _)
with 4 a1 n p2 show ?thesis using msel.psimps(4) by simp
next
case (KMemptr _)
with 4 a1 n p2 show ?thesis using msel.psimps(4) by simp
next
case (KStoptr _)
with 4 a1 n p2 show ?thesis using msel.psimps(4) by simp
qed
qed
next
case (e _)
with 4 a1 show ?thesis using msel.psimps(4) by simp
qed
qed
qed
next
case 5
then show ?case using ssel.psimps(1) by auto
next
case 6
then show ?case using ssel.psimps(2) by auto
next
case (7 al t loc x xs env cd st g)
show ?case
proof (rule allI[THEN allI, OF impI])
fix v2' g2' assume a1: "ssel (STArray al t) loc (x # xs) env cd st g = Normal (v2', g2')"
show "g2' ≤ g"
proof (cases v2')
case (Pair l2' t2')
then show ?thesis
proof (cases "expr x env cd st g")
case (n a g'')
then show ?thesis
proof (cases a)
case p2: (Pair b c)
then show ?thesis
proof (cases b)
case (KValue v)
then show ?thesis
proof (cases c)
case (Value t')
then show ?thesis
proof (cases)
assume l: "less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool)"
with n p2 KValue Value l
have "ssel (STArray al t) loc (x # xs) env cd st g = ssel t (hash loc v) xs env cd st g''"
using ssel.psimps(3) 7(1) by simp
moreover from n have "g'' ≤ g" using 7(2) by simp
moreover from a1 n Pair p2 KValue Value l
have "g2' ≤ g''" using ssel.psimps(3) 7(3) 7(1) by simp
ultimately show ?thesis by simp
next
assume "¬ less t' (TUInt 256) v (ShowLint al) = Some (ShowLbool True, TBool)"
with 7 a1 n p2 KValue Value show ?thesis using ssel.psimps(3) by simp
qed
next
case (Calldata _)
with 7 a1 n p2 KValue show ?thesis using ssel.psimps(3) by simp
next
case (Memory _)
with 7 a1 n p2 KValue show ?thesis using ssel.psimps(3) by simp
next
case (Storage _)
with 7 a1 n p2 KValue show ?thesis using ssel.psimps(3) by simp
qed
next
case (KCDptr _)
with 7 a1 n p2 show ?thesis using ssel.psimps(3) by simp
next
case (KMemptr _)
with 7 a1 n p2 show ?thesis using ssel.psimps(3) by simp
next
case (KStoptr x4)
with 7 a1 n p2 show ?thesis using ssel.psimps(3) by simp
qed
qed
next
case (e _)
with 7 a1 show ?thesis using ssel.psimps(3) by simp
qed
qed
qed
next
case (8 vv t loc x xs env cd st g)
show ?case
proof (rule allI[THEN allI, OF impI])
fix v2' g2' assume a1: "ssel (STMap vv t) loc (x # xs) env cd st g = Normal (v2', g2')"
show "g2' ≤ g"
proof (cases v2')
case (Pair l2' t2')
then show ?thesis
proof (cases "expr x env cd st g")
case (n a g')
then show ?thesis
proof (cases a)
case p2: (Pair b c)
then show ?thesis
proof (cases b)
case (KValue v)
with 8 n p2 have "ssel (STMap vv t) loc (x # xs) env cd st g = ssel t (hash loc v) xs env cd st g'" using ssel.psimps(4) by simp
moreover from n have "g' ≤ g" using 8(2) by simp
moreover from a1 n Pair p2 KValue
have "g2' ≤ g'" using ssel.psimps(4) 8(3) 8(1) by simp
ultimately show ?thesis by simp
next
case (KCDptr _)
with 8 a1 n p2 show ?thesis using ssel.psimps(4) by simp
next
case (KMemptr _)
with 8 a1 n p2 show ?thesis using ssel.psimps(4) by simp
next
case (KStoptr _)
with 8 a1 n p2 show ?thesis using ssel.psimps(4) by simp
qed
qed
next
case (e _)
with 8 a1 show ?thesis using ssel.psimps(4) by simp
qed
qed
qed
next
case 9
then show ?case using expr.psimps(1) by (simp split:if_split_asm)
next
case 10
then show ?case using expr.psimps(2) by (simp split:if_split_asm)
next
case 11
then show ?case using expr.psimps(3) by simp
next
case (12 ad e cd st g)
define gc where "gc = costse (BALANCE ad) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa
assume *: "expr (BALANCE ad) e cd st g = Normal (xa, g4)"
show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 12 gc_def * show ?thesis using expr.psimps(4) by simp
next
assume gcost: "¬ g ≤ gc"
then show ?thesis
proof (cases "expr ad e cd st (g - gc)")
case (n a s)
show ?thesis
proof (cases a)
case (Pair b c)
then show ?thesis
proof (cases b)
case (KValue x1)
then show ?thesis
proof (cases c)
case (Value x1)
then show ?thesis
proof (cases x1)
case (TSInt _)
with 12 gc_def * gcost n Pair KValue Value show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case (TUInt _)
with 12 gc_def * gcost n Pair KValue Value show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case TBool
with 12 gc_def * gcost n Pair KValue Value show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case TAddr
with 12(2)[where ?s'a="g-costse (BALANCE ad) e cd st"] gc_def * gcost n Pair KValue Value show "g4 ≤ g" using expr.psimps(4)[OF 12(1)] by simp
qed
next
case (Calldata _)
with 12 gc_def * gcost n Pair KValue show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case (Memory _)
with 12 gc_def * gcost n Pair KValue show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case (Storage _)
with 12 gc_def * gcost n Pair KValue show ?thesis using expr.psimps(4)[of ad e cd st] by simp
qed
next
case (KCDptr _)
with 12 gc_def * gcost n Pair show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case (KMemptr _)
with 12 gc_def * gcost n Pair show ?thesis using expr.psimps(4)[of ad e cd st] by simp
next
case (KStoptr _)
with 12 gc_def * gcost n Pair show ?thesis using expr.psimps(4)[of ad e cd st] by simp
qed
qed
next
case (e _)
with 12 gc_def * gcost show ?thesis using expr.psimps(4)[of ad e cd st] by simp
qed
qed
qed
next
case 13
then show ?case using expr.psimps(5) by simp
next
case 14
then show ?case using expr.psimps(6) by simp
next
case 15
then show ?case using expr.psimps(7) by simp
next
case 16
then show ?case using expr.psimps(8) by simp
next
case 17
then show ?case using expr.psimps(9) by simp
next
case (18 x e cd st g)
define gc where "gc = costse (NOT x) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix v4 g4' assume a1: "expr (NOT x) e cd st g = Normal (v4, g4')"
show "g4' ≤ g"
proof (cases v4)
case (Pair l4 t4)
show ?thesis
proof (cases)
assume "g ≤ gc"
with gc_def a1 show ?thesis using expr.psimps(10)[OF 18(1)] by simp
next
assume gcost: "¬ g ≤ gc"
then show ?thesis
proof (cases "expr x e cd st (g - gc)")
case (n a g')
then show ?thesis
proof (cases a)
case p2: (Pair b c)
then show ?thesis
proof (cases b)
case (KValue v)
then show ?thesis
proof (cases c)
case (Value t)
then show ?thesis
proof (cases t)
case (TSInt x1)
with a1 gc_def gcost n p2 KValue Value show ?thesis using expr.psimps(10)[OF 18(1)] by simp
next
case (TUInt x2)
with a1 gc_def gcost n p2 KValue Value show ?thesis using expr.psimps(10)[OF 18(1)] by simp
next
case TBool
then show ?thesis
proof (cases)
assume v_def: "v = ShowLbool True"
with 18(1) gc_def gcost n p2 KValue Value TBool have "expr (NOT x) e cd st g = expr FALSE e cd st g' " using expr.psimps(10)[OF 18(1)] by simp
moreover from 18(2) gc_def gcost n p2 have "g' ≤ g-gc" by simp
moreover from 18(3)[OF _ _ n] a1 gc_def gcost have "g4' ≤ g'" using expr.psimps(10)[OF 18(1)] n Pair p2 KValue Value TBool v_def by simp
ultimately show ?thesis by arith
next
assume v_def: "¬ v = ShowLbool True"
then show ?thesis
proof (cases)
assume v_def2: "v = ShowLbool False"
with 18(1) gc_def gcost n p2 KValue Value v_def TBool have "expr (NOT x) e cd st g = expr TRUE e cd st g'" using expr.psimps(10) by simp
moreover from 18(2)[where ?s'a="g-costse (NOT x) e cd st"] gc_def gcost n p2 have "g' ≤ g" by simp
moreover from 18(4)[OF _ _ n] a1 gc_def gcost have "g4' ≤ g'" using expr.psimps(10)[OF 18(1)] n Pair p2 KValue Value TBool v_def v_def2 by simp
ultimately show ?thesis by arith
next
assume "¬ v = ShowLbool False"
with 18(1) a1 gc_def gcost n p2 KValue Value v_def TBool show ?thesis using expr.psimps(10) by simp
qed
qed
next
case TAddr
with 18(1) a1 gc_def gcost n p2 KValue Value show ?thesis using expr.psimps(10) by simp
qed
next
case (Calldata _)
with 18(1) a1 gc_def gcost n p2 KValue show ?thesis using expr.psimps(10) by simp
next
case (Memory _)
with 18(1) a1 gc_def gcost n p2 KValue show ?thesis using expr.psimps(10) by simp
next
case (Storage _)
with 18(1) a1 gc_def gcost n p2 KValue show ?thesis using expr.psimps(10) by simp
qed
next
case (KCDptr _)
with 18(1) a1 gc_def gcost n p2 show ?thesis using expr.psimps(10) by simp
next
case (KMemptr _)
with 18(1) a1 gc_def gcost n p2 show ?thesis using expr.psimps(10) by simp
next
case (KStoptr _)
with 18(1) a1 gc_def gcost n p2 show ?thesis using expr.psimps(10) by simp
qed
qed
next
case (e _)
with 18(1) a1 gc_def gcost show ?thesis using expr.psimps(10) by simp
qed
qed
qed
qed
next
case (19 e1 e2 e cd st g)
define gc where "gc = costse (PLUS e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (PLUS e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 19(1) e_def show ?thesis using expr.psimps(11) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (PLUS e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 19(1) e_def gc_def have lift:"lift expr add e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(11)[OF 19(1)] by simp
moreover have **: "modify (λg. g - costse (PLUS e1 e2) e cd st) g = Normal ((), g - costse (PLUS e1 e2) e cd st)" by simp
with 19(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (PLUS e1 e2) e cd st) = Normal (v, g')" using expr.psimps(11)[OF 19(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 19(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (20 e1 e2 e cd st g)
define gc where "gc = costse (MINUS e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (MINUS e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 20(1) e_def show ?thesis using expr.psimps(12) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (MINUS e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 20(1) e_def gc_def have lift:"lift expr sub e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(12)[OF 20(1)] by simp
moreover have **: "modify (λg. g - costse (MINUS e1 e2) e cd st) g = Normal ((), g - costse (MINUS e1 e2) e cd st)" by simp
with 20(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (MINUS e1 e2) e cd st) = Normal (v, g')" using expr.psimps(12)[OF 20(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 20(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (21 e1 e2 e cd st g)
define gc where "gc = costse (LESS e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (LESS e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 21(1) e_def show ?thesis using expr.psimps(13) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (LESS e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 21(1) e_def gc_def have lift:"lift expr less e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(13)[OF 21(1)] by simp
moreover have **: "modify (λg. g - costse (LESS e1 e2) e cd st) g = Normal ((), g - costse (LESS e1 e2) e cd st)" by simp
with 21(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (LESS e1 e2) e cd st) = Normal (v, g')" using expr.psimps(13)[OF 21(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 21(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (22 e1 e2 e cd st g)
define gc where "gc = costse (EQUAL e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (EQUAL e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 22(1) e_def show ?thesis using expr.psimps(14) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (EQUAL e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 22(1) e_def gc_def have lift:"lift expr equal e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(14)[OF 22(1)] by simp
moreover have **: "modify (λg. g - costse (EQUAL e1 e2) e cd st) g = Normal ((), g - costse (EQUAL e1 e2) e cd st)" by simp
with 22(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (EQUAL e1 e2) e cd st) = Normal (v, g')" using expr.psimps(14)[OF 22(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 22(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (23 e1 e2 e cd st g)
define gc where "gc = costse (AND e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (AND e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 23(1) e_def show ?thesis using expr.psimps(15) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (AND e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 23(1) e_def gc_def have lift:"lift expr vtand e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(15)[OF 23(1)] by simp
moreover have **: "modify (λg. g - costse (AND e1 e2) e cd st) g = Normal ((), g - costse (AND e1 e2) e cd st)" by simp
with 23(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (AND e1 e2) e cd st) = Normal (v, g')" using expr.psimps(15)[OF 23(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 23(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (24 e1 e2 e cd st g)
define gc where "gc = costse (OR e1 e2) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa assume e_def: "expr (OR e1 e2) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 24(1) e_def show ?thesis using expr.psimps(16) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (OR e1 e2) e cd st)) g = Normal ((), g)" using gc_def by simp
with 24(1) e_def gc_def have lift:"lift expr vtor e1 e2 e cd st (g - gc) = Normal (xa, g4)" using expr.psimps(16)[OF 24(1)] by simp
moreover have **: "modify (λg. g - costse (OR e1 e2) e cd st) g = Normal ((), g - costse (OR e1 e2) e cd st)" by simp
with 24(2)[OF * **] have "∧g4' v4 t4. expr e1 e cd st (g-gc) = Normal ((v4, t4), g4') ==> g4' ≤ g - gc" unfolding gc_def by simp
moreover obtain v g' where ***: "expr e1 e cd st (g - costse (OR e1 e2) e cd st) = Normal (v, g')" using expr.psimps(16)[OF 24(1)] e_def by (simp split:if_split_asm result.split_asm prod.split_asm)
with 24(3)[OF * ** ***] have "∧v t g' v' t' g''. expr e1 e cd st (g-gc) = Normal ((KValue v, Value t), g') ==> expr e2 e cd st g' = Normal ((v', t'), g'') ==> g'' ≤ g'" unfolding gc_def by simp
ultimately show "g4 ≤ g" using lift_gas[OF lift] `¬ g ≤ gc` by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (25 i e cd st g)
define gc where "gc = costse (LVAL i) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4 xa xaa assume e_def: "expr (LVAL i) e cd st g = Normal (xa, g4)"
then show "g4 ≤ g"
proof (cases)
assume "g ≤ gc"
with 25(1) e_def show ?thesis using expr.psimps(17) gc_def by simp
next
assume "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (LVAL i) e cd st)) g = Normal ((), g)" using gc_def by simp
then have "expr (LVAL i) e cd st g = rexp i e cd st (g - gc)" using expr.psimps(17)[OF 25(1)] gc_def by simp
then have "rexp i e cd st (g - gc) = Normal (xa, g4)" using e_def by simp
moreover have **: "modify (λg. g - costse (LVAL i) e cd st) g = Normal ((), g - costse (LVAL i) e cd st)" by simp
ultimately show ?thesis using 25(2)[OF * **] unfolding gc_def by (simp split:result.split_asm Stackvalue.split_asm Type.split_asm prod.split_asm)
qed
qed
next
case (26 i xe e cd st g)
define gc where "gc = costse (CALL i xe) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4' v4 assume a1: "expr (CALL i xe) e cd st g = Normal (v4, g4')"
then have *: "assert Gas ((<) (costse (CALL i xe) e cd st)) g = Normal ((), g)" using gc_def using expr.psimps(18)[OF 26(1)] by (simp split:if_split_asm)
have **: "modify (λg. g - costse (CALL i xe) e cd st) g = Normal ((), g - gc)" unfolding gc_def by simp
show "g4' ≤ g"
proof (cases)
assume "g ≤ gc"
with 26(1) gc_def a1 show ?thesis using expr.psimps(18) by simp
next
assume gcost: "¬ g ≤ gc"
then show ?thesis
proof (cases v4)
case (Pair l4 t4)
then show ?thesis
proof (cases "ep $$ contract e")
case None
with 26(1) a1 gc_def gcost show ?thesis using expr.psimps(18) by simp
next
case (Some a)
then show ?thesis
proof (cases a)
case p2: (fields ct x0 x1)
then have 1: "option Err (λ_. ep $$ contract e) (g - gc) = Normal ((ct, x0, x1), (g - gc))" using Some by simp
then show ?thesis
proof (cases "fmlookup ct i")
case None
with 26(1) a1 gc_def gcost Some p2 show ?thesis using expr.psimps(18) by simp
next
case s1: (Some a)
then show ?thesis
proof (cases a)
case (Function x1)
then show ?thesis
proof (cases x1)
case p1: (fields fp ext x)
then show ?thesis
proof (cases ext)
case True
with 26(1) a1 gc_def gcost Some p2 s1 Function p1 show ?thesis using expr.psimps(18)[of i xe e cd st] by (auto split:unit.split_asm)
next
case False
then have 2: "(case ct $$ i of None → throw Err | Some (Function (fp, True, xa)) → throw Err | Some (Function (fp, False, xa)) → return (fp, xa) | Some _ → throw Err) (g - gc) = Normal ((fp, x), (g - gc))" using s1 Function p1 by simp
define e' where "e' = ffold (init ct) (emptyEnv (address e) (contract e) (sender e) (svalue e)) (fmdom ct)"
then show ?thesis
proof (cases "load False fp xe e' emptyStore emptyStore (memory st) e cd st (g - gc)")
case s4: (n a g')
then show ?thesis
proof (cases a)
case f2: (fields el cdl kl ml)
then show ?thesis
proof (cases "expr x el cdl (st(stack:=kl, memory:=ml)) g'")
case n2: (n a g'')
then show ?thesis
proof (cases a)
case p3: (Pair sv tp)
with 26(1) a1 gc_def gcost Some p2 s1 Function p1 e'_def s4 f2 n2 False
have "expr (CALL i xe) e cd st g = Normal ((sv, tp), g'')"
using expr.psimps(18)[OF 26(1)] by simp
with a1 have "g4' ≤ g''" by simp
also from 26(3)[OF * ** 1 _ 2 _ _ s4] e'_def f2 n2 p3 gcost gc_def
have "… ≤ g'" by auto
also from 26(2)[OF * ** 1 _ 2 _] False e'_def f2 s4
have "… ≤ g - gc" unfolding ffold_init_def gc_def by blast
finally show ?thesis by simp
qed
next
case (e _)
with 26(1) a1 gc_def gcost Some p2 s1 Function p1 e'_def s4 f2 False show ?thesis using expr.psimps(18)[of i xe e cd st] by (auto simp add:Let_def split:unit.split_asm)
qed
qed
next
case (e _)
with 26(1) a1 gc_def gcost Some p2 s1 Function p1 e'_def False show ?thesis using expr.psimps(18)[of i xe e cd st] by (auto split:unit.split_asm)
qed
qed
qed
next
case (Method _)
with 26(1) a1 gc_def gcost Some p2 s1 show ?thesis using expr.psimps(18) by simp
next
case (Var _)
with 26(1) a1 gc_def gcost Some p2 s1 show ?thesis using expr.psimps(18) by simp
qed
qed
qed
qed
qed
qed
qed
next
case (27 ad i xe e cd st g)
define gc where "gc = costse (ECALL ad i xe) e cd st"
show ?case
proof (rule allI[THEN allI, OF impI])
fix g4' v4 assume a1: "expr (ECALL ad i xe) e cd st g = Normal (v4, g4')"
show "g4' ≤ g"
proof (cases v4)
case (Pair l4 t4)
then show ?thesis
proof (cases)
assume "g ≤ gc"
with gc_def a1 show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
assume gcost: "¬ g ≤ gc"
then have *: "assert Gas ((<) (costse (ECALL ad i xe) e cd st)) g = Normal ((), g)" using gc_def using expr.psimps(19)[OF 27(1)] by (simp split:if_split_asm)
have **: "modify (λg. g - costse (ECALL ad i xe) e cd st) g = Normal ((), g - gc)" unfolding gc_def by simp
then show ?thesis
proof (cases "expr ad e cd st (g-gc)")
case (n a0 g')
then show ?thesis
proof (cases a0)
case p0: (Pair a b)
then show ?thesis
proof (cases a)
case (KValue adv)
then show ?thesis
proof (cases b)
case (Value x1)
then show ?thesis
proof (cases x1)
case (TSInt x1)
with a1 gc_def gcost n p0 KValue Value show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (TUInt x2)
with a1 gc_def gcost n p0 KValue Value show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case TBool
with a1 gc_def gcost n p0 KValue Value show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case TAddr
then have 1: "(case a0 of (KValue adv, Value TAddr) → return adv | (KValue adv, Value _) → throw Err | (KValue adv, _) → throw Err | (_, b) → throw Err) g' = Normal (adv, g')" using p0 KValue Value by simp
then show ?thesis
proof (cases "adv = address e")
case True
with a1 gc_def gcost n p0 KValue Value TAddr show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case False
then have 2: "assert Err (λ_. adv ≠ address e) g' = Normal ((), g')" by simp
then show ?thesis
proof (cases "type (accounts st adv)")
case None
with a1 gc_def gcost n p0 KValue Value TAddr False show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (Some x2)
then show ?thesis
proof (cases x2)
case EOA
with a1 gc_def gcost n p0 KValue Value TAddr False Some show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case c: (Contract c)
then have 3: "(case type (accounts st adv) of Some (Contract c) → return c | _ → throw Err) g' = Normal (c, g')" using Some by simp
then show ?thesis
proof (cases "ep $$ c")
case None
with a1 gc_def gcost n p0 KValue Value TAddr False Some c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case s0: (Some a)
then show ?thesis
proof (cases a)
case p1: (fields ct xa xb)
then have 4: "option Err (λ_. ep $$ c) g' = Normal ((ct, xa, xb), g')" using Some s0 by simp
then show ?thesis
proof (cases "ct $$ i")
case None
with a1 gc_def gcost n p0 KValue Value TAddr Some p1 False c s0 show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case s1: (Some a)
then show ?thesis
proof (cases a)
case (Function x1)
then show ?thesis
proof (cases x1)
case p2: (fields fp ext x)
then show ?thesis
proof (cases ext)
case True
then have 5: "(case ct $$ i of None → throw Err | Some (Function (fp, True, xa)) → return (fp, xa) | Some (Function (fp, False, xa)) → throw Err | Some _ → throw Err) g' = Normal ((fp, x), g')" using s1 Function p2 by simp
define e' where "e' = ffold (init ct) (emptyEnv adv c (address e) (ShowLnat 0)) (fmdom ct)"
then show ?thesis
proof (cases "load True fp xe e' emptyStore emptyStore emptyStore e cd st g'")
case n1: (n a g'')
then show ?thesis
proof (cases a)
case f2: (fields el cdl kl ml)
show ?thesis
proof (cases "expr x el cdl (st(stack:=kl, memory:=ml)) g''")
case n2: (n a g''')
then show ?thesis
proof (cases a)
case p3: (Pair sv tp)
with a1 gc_def gcost n p2 KValue Value TAddr Some p1 s1 Function p0 e'_def n1 f2 n2 True False s0 c
have "expr (ECALL ad i xe) e cd st g = Normal ((sv, tp), g''')"
using expr.psimps(19)[OF 27(1)] by auto
with a1 have "g4' ≤ g'''" by auto
also from 27(4)[OF * ** n 1 2 3 4 _ 5 _ _ n1] p3 f2 e'_def n2
have "… ≤ g''" by simp
also from 27(3)[OF * ** n 1 2 3 4 _ 5, of "(xa, xb)" fp x e'] e'_def n1 f2
have "… ≤ g'" by auto
also from 27(2)[OF * **] n
have "… ≤ g" by simp
finally show ?thesis by simp
qed
next
case (e _)
with a1 gc_def gcost n p0 KValue Value TAddr False Some p1 s1 Function p2 e'_def n1 f2 True s0 c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
qed
next
case (e _)
with a1 gc_def gcost n p0 KValue Value TAddr False Some p1 s1 Function p2 e'_def True s0 c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
next
case f: False
with a1 gc_def gcost n p0 KValue Value TAddr Some p1 s1 Function p2 False s0 c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
qed
next
case (Method _)
with a1 gc_def gcost n p0 KValue Value TAddr Some p1 s1 False s0 c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (Var _)
with a1 gc_def gcost n p0 KValue Value TAddr Some p1 s1 False s0 c show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
qed
qed
qed
qed
qed
qed
qed
next
case (Calldata _)
with a1 gc_def gcost n p0 KValue show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (Memory _)
with a1 gc_def gcost n p0 KValue show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (Storage _)
with a1 gc_def gcost n p0 KValue show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
next
case (KCDptr _)
with a1 gc_def gcost n p0 show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (KMemptr _)
with a1 gc_def gcost n p0 show ?thesis using expr.psimps(19)[OF 27(1)] by simp
next
case (KStoptr _)
with a1 gc_def gcost n p0 show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
qed
next
case (e _)
with a1 gc_def gcost show ?thesis using expr.psimps(19)[OF 27(1)] by simp
qed
qed
qed
qed
next
case (28 cp ip tp pl e el ev' cd' sck' mem' ev cd st g)
then show ?case
proof (cases "expr e ev cd st g")
case (n a g'')
then show ?thesis
proof (cases a)
case (Pair v t)
then show ?thesis
proof (cases "decl ip tp (Some (v,t)) cp cd (memory st) (storage st) (cd', mem', sck', ev')")
case None
with 28(1) n Pair show ?thesis using load.psimps(1) by simp
next
case (Some a)
show ?thesis
proof (cases a)
case (fields cd'' m'' k'' ev'')
then have 1: "(case decl ip tp (Some (v, t)) cp cd (memory st) (storage st) (cd', mem', sck', ev') of None → throw Err | Some (c, m, k, e) → return (c, m, k, e)) g'' = Normal ((cd'',m'',k'',ev''), g'')" using Some by simp
show ?thesis
proof ((rule allI)+,(rule impI))
fix ev cda k m g' assume load_def: "load cp ((ip, tp) # pl) (e # el) ev' cd' sck' mem' ev cd st g = Normal ((ev, cda, k, m), g')"
with n Pair Some fields have "load cp ((ip, tp) # pl) (e # el) ev' cd' sck' mem' ev cd st g = load cp pl el ev'' cd'' k'' m'' ev cd st g''" using load.psimps(1)[OF 28(1)] by simp
with load_def have "load cp pl el ev'' cd'' k'' m'' ev cd st g'' = Normal ((ev, cda, k, m), g')" by simp
with Pair fields have "g' ≤ g'' ∧ address ev = address ev'' ∧ sender ev = sender ev'' ∧ svalue ev = svalue ev''" using 28(3)[OF n Pair 1, of cd'' _ m''] by simp
moreover from n have "g'' ≤ g" using 28(2) by simp
moreover from Some fields have "address ev'' = address ev' ∧ sender ev'' = sender ev' ∧ svalue ev'' = svalue ev'" using decl_env by auto
ultimately show "g' ≤ g ∧ address ev = address ev' ∧ sender ev = sender ev' ∧ svalue ev = svalue ev'" by auto
qed
qed
qed
qed
next
case (e _)
with 28(1) show ?thesis using load.psimps(1) by simp
qed
next
case 29
then show ?case using load.psimps(2) by auto
next
case 30
then show ?case using load.psimps(3) by auto
next
case 31
then show ?case using load.psimps(4) by auto
next
case (32 i e cd st g)
show ?case
proof (rule allI[THEN allI, OF impI])
fix xa xaa assume "rexp (L.Id i) e cd st g = Normal (xa, xaa)"
then show "xaa ≤ g" using 32(1) rexp.psimps(1) by (simp split: option.split_asm Denvalue.split_asm Stackvalue.split_asm prod.split_asm Type.split_asm STypes.split_asm)
qed
next
case (33 i r e cd st g)
show ?case
proof (rule allI[THEN allI,OF impI])
fix xa xaa assume rexp_def: "rexp (Ref i r) e cd st g = Normal (xa, xaa)"
show "xaa ≤ g"
proof (cases "fmlookup (denvalue e) i")
case None
with 33(1) show ?thesis using rexp.psimps rexp_def by simp
next
case (Some a)
then show ?thesis
proof (cases a)
case (Pair tp b)
then show ?thesis
proof (cases b)
case (Stackloc l)
then show ?thesis
proof (cases "accessStore l (stack st)")
case None
with 33(1) Some Pair Stackloc show ?thesis using rexp.psimps(2) rexp_def by simp
next
case s1: (Some a)
then show ?thesis
proof (cases a)
case (KValue x1)
with 33(1) Some Pair Stackloc s1 show ?thesis using rexp.psimps(2) rexp_def by simp
next
case (KCDptr l')
with 33 Some Pair Stackloc s1 show ?thesis using rexp.psimps(2)[of i r e cd st] rexp_def by (simp split: option.split_asm Memoryvalue.split_asm MTypes.split_asm prod.split_asm Type.split_asm StateMonad.result.split_asm)
next
case (KMemptr x3)
with 33 Some Pair Stackloc s1 show ?thesis using rexp.psimps(2)[of i r e cd st] rexp_def by (simp split: option.split_asm Memoryvalue.split_asm MTypes.split_asm prod.split_asm Type.split_asm StateMonad.result.split_asm)
next
case (KStoptr x4)
with 33 Some Pair Stackloc s1 show ?thesis using rexp.psimps(2)[of i r e cd st] rexp_def by (simp split: option.split_asm STypes.split_asm prod.split_asm Type.split_asm StateMonad.result.split_asm)
qed
qed
next
case (Storeloc x2)
with 33 Some Pair show ?thesis using rexp.psimps rexp_def by (simp split: option.split_asm STypes.split_asm prod.split_asm Type.split_asm StateMonad.result.split_asm)
qed
qed
qed
qed
next
case (34 e cd st g)
then show ?case using expr.psimps(20) by (simp split:nat.split)
qed
text ‹Now we can define the termination function›
fun mgas
where "mgas (Inr (Inr (Inr l))) = snd (snd (snd (snd l)))" (*rexp*)
| "mgas (Inr (Inr (Inl l))) = snd (snd (snd (snd (snd (snd (snd (snd (snd (snd l)))))))))" (*load*)
| "mgas (Inr (Inl l)) = snd (snd (snd (snd l)))" (*expr*)
| "mgas (Inl (Inr l)) = snd (snd (snd (snd (snd (snd l)))))" (*ssel*)
| "mgas (Inl (Inl l)) = snd (snd (snd (snd (snd (snd (snd l))))))" (*msel*)
fun msize
where "msize (Inr (Inr (Inr l))) = size (fst l)"
| "msize (Inr (Inr (Inl l))) = size_list size (fst (snd (snd l)))"
| "msize (Inr (Inl l)) = size (fst l)"
| "msize (Inl (Inr l)) = size_list size (fst (snd (snd l)))"
| "msize (Inl (Inl l)) = size_list size (fst (snd (snd (snd l))))"
method msel_ssel_expr_load_rexp_dom =
match premises in e: "expr _ _ _ _ _ = Normal (_,_)" and d[thin]: "msel_ssel_expr_load_rexp_dom (Inr (Inl _))" → ‹insert msel_ssel_expr_load_rexp_dom_gas(3)[OF d e]› |
match premises in l: "load _ _ _ _ _ _ _ _ _ _ _ = Normal (_,_)" and d[thin]: "msel_ssel_expr_load_rexp_dom (Inr (Inr (Inl _)))" → ‹insert msel_ssel_expr_load_rexp_dom_gas(4)[OF d l, THEN conjunct1]›
method costs =
match premises in "costse (CALL i xe) e cd st < _" for i xe and e::Environment and cd::CalldataT and st::State → ‹insert call_not_zero[of (unchecked) i xe e cd st]› |
match premises in "costse (ECALL ad i xe) e cd st < _" for ad i xe and e::Environment and cd::CalldataT and st::State → ‹insert ecall_not_zero[of (unchecked) ad i xe e cd st]›
termination msel
apply (relation "measures [mgas, msize]")
apply (auto split:Member.split_asm prod.split_asm bool.split_asm if_split_asm Stackvalue.split_asm option.split_asm Type.split_asm Types.split_asm Memoryvalue.split_asm atype.split_asm)
apply (msel_ssel_expr_load_rexp_dom+, costs?, arith)+
done
subsection ‹Gas Reduction›
text ‹
The following corollary is a generalization of @{thm [source] msel_ssel_expr_load_rexp_dom_gas}.
We first prove that the function is defined for all input values and then obtain the final result as a corollary.
›
lemma msel_ssel_expr_load_rexp_dom:
"msel_ssel_expr_load_rexp_dom (Inl (Inl (c1, t1, l1, xe1, ev1, cd1, st1, g1)))"
"msel_ssel_expr_load_rexp_dom (Inl (Inr (t2, l2, xe2, ev2, cd2, st2, g2)))"
"msel_ssel_expr_load_rexp_dom (Inr (Inl (e4, ev4, cd4, st4, g4)))"
"msel_ssel_expr_load_rexp_dom (Inr (Inr (Inl (lcp, lis, lxs, lev0, lcd0, lk, lm, lev, lcd, lst, lg))))"
"msel_ssel_expr_load_rexp_dom (Inr (Inr (Inr (l3, ev3, cd3, st3, g3))))"
by (induct rule: msel_ssel_expr_load_rexp.induct
[where ?P1.0="λc1 t1 l1 xe1 ev1 cd1 st1 g1. msel_ssel_expr_load_rexp_dom (Inl (Inl (c1, t1, l1, xe1, ev1, cd1, st1, g1)))"
and ?P2.0="λt2 l2 xe2 ev2 cd2 st2 g2. msel_ssel_expr_load_rexp_dom (Inl (Inr (t2, l2, xe2, ev2, cd2, st2, g2)))"
and ?P3.0="λe4 ev4 cd4 st4 g4. msel_ssel_expr_load_rexp_dom (Inr (Inl (e4, ev4, cd4, st4, g4)))"
and ?P4.0="λlcp lis lxs lev0 lcd0 lk lm lev lcd lst lg. msel_ssel_expr_load_rexp_dom (Inr (Inr (Inl (lcp, lis, lxs, lev0, lcd0, lk, lm, lev, lcd, lst, lg))))"
and ?P5.0="λl3 ev3 cd3 st3 g3. msel_ssel_expr_load_rexp_dom (Inr (Inr (Inr (l3, ev3, cd3, st3, g3))))"
], simp_all add: msel_ssel_expr_load_rexp.domintros)
lemmas msel_ssel_expr_load_rexp_gas =
msel_ssel_expr_load_rexp_dom_gas(1)[OF msel_ssel_expr_load_rexp_dom(1)]
msel_ssel_expr_load_rexp_dom_gas(2)[OF msel_ssel_expr_load_rexp_dom(2)]
msel_ssel_expr_load_rexp_dom_gas(3)[OF msel_ssel_expr_load_rexp_dom(3)]
msel_ssel_expr_load_rexp_dom_gas(4)[OF msel_ssel_expr_load_rexp_dom(4)]
msel_ssel_expr_load_rexp_dom_gas(5)[OF msel_ssel_expr_load_rexp_dom(5)]
lemma expr_sender:
assumes "expr SENDER e cd st g = Normal ((KValue adv, Value TAddr), g')"
shows "adv = sender e" using assms by (simp split:if_split_asm)
declare expr.simps[simp del, solidity_symbex add]
declare load.simps[simp del, solidity_symbex add]
declare ssel.simps[simp del, solidity_symbex add]
declare msel.simps[simp del, solidity_symbex add]
declare rexp.simps[simp del, solidity_symbex add]
end
end
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|
2026-11-01
|
|
|
|
|
Neuigkeiten |
| Aktuelles |
| Motto des Tages |
|
Open Source Software |
|
|
|
Jenseits des Üblichen ....
|
|
Besucherstatistik |
|
|
| Statistik |
| #Sources=1104848 |
| #Domains=499278 |
|
|