# Theory Big_Step_Total

theory Big_Step_Total
imports Semantic_Extras
```section "Totality"

theory Big_Step_Total
imports Semantic_Extras
begin

context begin

private lemma evaluate_list_total0:
fixes s :: "'a state"
assumes "⋀e env s'::'a state. e ∈ set es ⟹ clock s' ≤ clock s ⟹ ∃s'' r. evaluate True env s' e (s'', r)"
shows "∃s' r. evaluate_list True env s es (s', r)"
using assms proof (induction es arbitrary: env s)
case Nil
show ?case by (metis evaluate_match_evaluate_list_evaluate.empty)
next
case (Cons e es)
then obtain s' r where e: "evaluate True env s e (s', r)"
by fastforce
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)

show ?case
proof (cases r)
case (Rval v)

have "∃s'' r. evaluate_list True env s' es (s'', r)"
using Cons clock by auto
then obtain s'' r where "evaluate_list True env s' es (s'', r)"
by auto

with e Rval show ?thesis
by (cases r)
(metis evaluate_match_evaluate_list_evaluate.cons1 evaluate_match_evaluate_list_evaluate.cons3)+
next
case Rerr
with e show ?thesis by (metis evaluate_match_evaluate_list_evaluate.cons2)
qed
qed

private lemma evaluate_match_total0:
fixes s :: "'a state"
assumes "⋀p e env s'::'a state. (p, e) ∈ set pes ⟹ clock s' ≤ clock s ⟹ ∃s'' r. evaluate True env s' e (s'', r)"
shows "∃s' r. evaluate_match True env s v pes v' (s', r)"
using assms proof (induction pes arbitrary: env s)
case Nil
show ?case by (metis mat_empty)
next
case (Cons pe pes)
then obtain p e where "pe = (p, e)" by force

show ?case
proof (cases "allDistinct (pat_bindings p [])")
case distinct: True
show ?thesis
proof (cases "pmatch (c env) (refs s) p v []")
case No_match

have "∃s' r. evaluate_match True env s v pes v' (s', r)"
apply (rule Cons)
apply (rule Cons)
by auto
then obtain s' r where "evaluate_match True env s v pes v' (s', r)"
by auto

show ?thesis
unfolding ‹pe = _›
apply (intro exI)
apply (rule mat_cons2)
apply safe
by fact+
next
case Match_type_error
then show ?thesis
unfolding ‹pe = _› by (metis mat_cons3)
next
case (Match env')

have "∃s' r. evaluate True (env ⦇ sem_env.v := (nsAppend (alist_to_ns env') (sem_env.v env)) ⦈) s e (s', r)"
apply (rule Cons)
unfolding ‹pe = _› by auto
then obtain s' r where "evaluate True (env ⦇ sem_env.v := (nsAppend (alist_to_ns env') (sem_env.v env)) ⦈) s e (s', r)"
by auto

show ?thesis
unfolding ‹pe = _›
apply (intro exI)
apply (rule mat_cons1)
apply safe
apply fact+
done
qed
next
case False
then show ?thesis
unfolding ‹pe = _› by (metis mat_cons4)
qed
qed

lemma evaluate_total: "∃s' r. evaluate True env s e (s', r)"
proof -
have "wf (less_than <*lex*> measure (size::exp ⇒ nat))"
by auto
then show ?thesis
proof (induction "(clock s, e)" arbitrary: env s e)
case less
show ?case
proof (cases e)
case (Raise e')
then have "∃s' r. evaluate True env s e' (s', r)"
using less by auto
then obtain s' r where "evaluate True env s e' (s', r)"
by auto
then show ?thesis
unfolding Raise by (cases r) (metis raise1 raise2)+
next
case (Con cn es)
show ?thesis
proof (cases "do_con_check (c env) cn (length es)")
case True
have "∃s' vs. evaluate_list True env s (rev es) (s', vs)"
apply (rule evaluate_list_total0)
apply (rule less)
unfolding Con
apply auto
using Con apply (auto simp: less_eq_Suc_le)
apply (rule size_list_estimation')
apply assumption
by simp
then obtain r s' where es: "evaluate_list True env s (rev es) (s', r)"
by auto

show ?thesis
proof (cases r)
case (Rval vs)
moreover obtain v where "build_conv (c env) cn (rev vs) = Some v"
using True
by (cases cn) (auto split: option.splits)
ultimately show ?thesis
using True es unfolding Con by (metis con1)
next
case Rerr
with True es show ?thesis unfolding Con by (metis con3)
qed
next
case False
with Con show ?thesis by (metis con2)
qed
next
case (Var n)
then show ?thesis
by (cases "nsLookup (sem_env.v env) n") (metis var1 var2)+
next
case (App op es)
have "∃s' vs. evaluate_list True env s (rev es) (s', vs)"
apply (rule evaluate_list_total0)
apply (rule less)
unfolding App apply (auto simp: less_eq_Suc_le)
apply (rule size_list_estimation')
apply assumption
by simp
then obtain r s2 where es: "evaluate_list True env s (rev es) (s2, r)"
by auto
then have clock: "clock s2 ≤ clock s"
by (metis evaluate_clock_mono)

show ?thesis
proof (cases r)
case (Rval vs)
show ?thesis
proof (cases "op = Opapp")
case opapp: True
show ?thesis
proof (cases "do_opapp (rev vs)")
case None
with App opapp Rval es show ?thesis by (metis app3)
next
case (Some r)
obtain env' e' where "r = (env', e')"
by (metis surj_pair)

show ?thesis
proof (cases "clock s2 = 0")
case True
show ?thesis
unfolding ‹op = _› App
apply (intro exI)
apply (rule app2)
apply (intro conjI)
using es unfolding Rval apply assumption
using Some unfolding ‹r = _› apply assumption
apply fact ..
next
case False

have "∃s' r. evaluate True env' (s2 ⦇ clock := clock s2 - Suc 0 ⦈) e' (s', r)"
apply (rule less)
using False clock by (auto simp: datatype_record_update split: state.splits)
then obtain s' r' where "evaluate True env' (s2 ⦇ clock := clock s2 - Suc 0 ⦈) e' (s', r')"
by auto

show ?thesis
unfolding ‹op = _› App
apply (intro exI)
apply (rule app1)
apply (intro conjI)
using es unfolding Rval apply assumption
using Some unfolding ‹r = _› apply assumption
using False apply metis
apply simp
apply fact
done
qed
qed
next
case False
show ?thesis
proof (cases "do_app ((refs   s2),(ffi   s2)) op (rev vs)")
case None
show ?thesis
unfolding App
apply (intro exI)
apply (rule app5)
apply (intro conjI)
using es unfolding Rval apply assumption
by fact+
next
case (Some r)
obtain refs' ffi' res where "r = ((refs', ffi'), res)"
by (metis surj_pair)

show ?thesis
unfolding App
apply (intro exI)
apply (rule app4)
apply (intro conjI)
using es unfolding Rval apply assumption
using Some unfolding ‹r = _› apply assumption
by fact
qed
qed
next
case Rerr
with es App show ?thesis by (metis app6)
qed
next
case (Log op e1 e2)
with less have "∃s' r. evaluate True env s e1 (s', r)" by simp
then obtain s' r where e1: "evaluate True env s e1 (s', r)"
by blast
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)

show ?thesis
proof (cases r)
case (Rval v)
with e1 Log show ?thesis
proof (cases op v e2 rule: do_log_cases)
case none
then show ?thesis
unfolding Log
using e1 Rval by (metis log3)
next
case val
then show ?thesis
unfolding Log
using e1 Rval by (metis log2)
next
case exp
have "∃s'' r. evaluate True env s' e2 (s'', r)"
apply (rule less)
using clock Log by auto
then obtain s'' r where "evaluate True env s' e2 (s'', r)"
by auto
show ?thesis
unfolding Log
apply (intro exI)
apply (rule log1)
apply (intro conjI)
using Rval e1 apply force
by fact+
qed
next
case Rerr
with e1 show ?thesis
unfolding Log by (metis log4)
qed
next
case (If e1 e2 e3)
with less have "∃s' r. evaluate True env s e1 (s', r)" by simp
then obtain s' r where e1: "evaluate True env s e1 (s', r)" by auto
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)

show ?thesis
proof (cases r)
case (Rval v1)
show ?thesis
proof (cases v1 e2 e3 rule: do_if_cases)
case none
show ?thesis
unfolding If
apply (intro exI)
apply (rule if2)
apply (intro conjI)
using Rval e1 apply force
by fact
next
case true
have "∃s'' r. evaluate True env s' e2 (s'', r)"
apply (rule less)
using clock If by auto
then obtain s'' r where "evaluate True env s' e2 (s'', r)"
by auto
show ?thesis
unfolding If
apply (intro exI)
apply (rule if1)
apply (intro conjI)
using Rval e1 apply force
by fact+
next
case false
have "∃s'' r. evaluate True env s' e3 (s'', r)"
apply (rule less)
using clock If by auto
then obtain s'' r where "evaluate True env s' e3 (s'', r)"
by auto
show ?thesis
unfolding If
apply (intro exI)
apply (rule if1)
apply (intro conjI)
using Rval e1 apply force
by fact+
qed
next
case Rerr
with e1 show ?thesis unfolding If by (metis if3)
qed
next
case (Handle e' pes)
with less have "∃s' r. evaluate True env s e' (s', r)" by simp
then obtain s' r where e': "evaluate True env s e' (s', r)" by auto
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)

show ?thesis
proof (cases r)
case Rval
with e' show ?thesis
unfolding Handle by (metis handle1)
next
case (Rerr err)
show ?thesis
proof (cases err)
case (Rraise exn)

have "∃s'' r. evaluate_match True env s' exn pes exn (s'', r)"
apply (rule evaluate_match_total0)
apply (rule less)
using Handle clock apply (auto simp: less_eq_Suc_le)
apply (rule size_list_estimation')
apply assumption
by auto
then obtain s'' r where "evaluate_match True env s' exn pes exn (s'', r)"
by auto

show ?thesis
unfolding Handle
apply (intro exI)
apply (rule handle2)
apply safe
using e' unfolding Rerr Rraise apply assumption
by fact
next
case (Rabort x2)
with e' Rerr show ?thesis
unfolding Handle
by (metis handle3)
qed
qed
next
case (Mat e' pes)
with less have "∃s' r. evaluate True env s e' (s', r)" by simp
then obtain s' r where e': "evaluate True env s e' (s', r)" by auto
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)

show ?thesis
proof (cases r)
case (Rval v)

have "∃s'' r. evaluate_match True env s' v pes (Conv (Some (''Bind'', TypeExn (Short ''Bind''))) []) (s'', r)"
apply (rule evaluate_match_total0)
apply (rule less)
unfolding Mat using clock apply (auto simp: less_eq_Suc_le)
apply (rule size_list_estimation')
apply assumption
by auto
then obtain s'' r where "evaluate_match True env s' v pes (Conv (Some (''Bind'', TypeExn (Short ''Bind''))) []) (s'', r)"
by auto

show ?thesis
unfolding Mat
apply (intro exI)
apply (rule mat1)
apply safe
using e' unfolding Rval
apply assumption
apply fact
done
next
case Rerr
with e' show ?thesis
unfolding Mat
by (metis mat2)
qed
next
case (Let n e1 e2)
then have "∃s' r. evaluate True env s e1 (s', r)"
using less by auto
then obtain s' r where e1: "evaluate True env s e1 (s', r)"
by auto
then have clock: "clock s' ≤ clock s"
by (metis evaluate_clock_mono)
show ?thesis
proof (cases r)
case (Rval v)
have "∃s'' r. evaluate True (env ⦇ sem_env.v := nsOptBind n v (sem_env.v env) ⦈) s' e2 (s'', r)"
apply (rule less)
using Let clock by auto
then show ?thesis
unfolding Let
using e1 Rval by (metis let1)
next
case Rerr
with e1 show ?thesis
unfolding Let
by (metis let2)
qed
next
case (Letrec funs e')
then have "∃s' r. evaluate True (env ⦇ sem_env.v := build_rec_env funs env (sem_env.v env) ⦈) s e' (s', r)"
using less by auto
then show ?thesis
unfolding Letrec
by (cases "allDistinct (map (λx. case x of (x, y, z) ⇒ x) funs)")
(metis letrec1 letrec2)+
next
case (Tannot e')
with less have "∃s' r. evaluate True env s e' (s', r)" by simp
then show ?thesis
unfolding ‹e = _›
by (fastforce intro: evaluate_match_evaluate_list_evaluate.intros)
next
case (Lannot e')
with less have "∃s' r. evaluate True env s e' (s', r)" by simp
then show ?thesis
unfolding ‹e = _›
by (fastforce intro: evaluate_match_evaluate_list_evaluate.intros)
qed (fastforce intro: evaluate_match_evaluate_list_evaluate.intros)+
qed
qed

end

text ‹
The following are pretty much the same proofs as above, but without additional assumptions;
instead using @{thm [source=true] evaluate_total} directly.
›

lemma evaluate_list_total: "∃s' r. evaluate_list True env s es (s', r)"
proof (induction es arbitrary: env s)
case Nil
show ?case by (metis evaluate_match_evaluate_list_evaluate.empty)
next
case (Cons e es)
obtain s' r where e: "evaluate True env s e (s', r)"
by (metis evaluate_total)
show ?case
proof (cases r)
case (Rval v)
have "∃s'' r. evaluate_list True env s' es (s'', r)"
using Cons by auto
then obtain s'' r where "evaluate_list True env s' es (s'', r)"
by auto

with e Rval show ?thesis
by (cases r)
(metis evaluate_match_evaluate_list_evaluate.cons1 evaluate_match_evaluate_list_evaluate.cons3)+
next
case Rerr
with e show ?thesis
by (metis evaluate_match_evaluate_list_evaluate.cons2)
qed
qed

lemma evaluate_match_total: "∃s' r. evaluate_match True env s v pes v' (s', r)"
proof (induction pes arbitrary: env s)
case Nil
show ?case by (metis mat_empty)
next
case (Cons pe pes)
then obtain p e where "pe = (p, e)" by force

show ?case
proof (cases "allDistinct (pat_bindings p [])")
case distinct: True
show ?thesis
proof (cases "pmatch (c env) (refs s) p v []")
case No_match

have "∃s' r. evaluate_match True env s v pes v' (s', r)"
by (rule Cons)
then obtain s' r where "evaluate_match True env s v pes v' (s', r)"
by auto

show ?thesis
unfolding ‹pe = _›
apply (intro exI)
apply (rule mat_cons2)
apply safe
by fact+
next
case Match_type_error
then show ?thesis
unfolding ‹pe = _› by (metis mat_cons3)
next
case (Match env')

have "∃s' r. evaluate True (env ⦇ sem_env.v := (nsAppend (alist_to_ns env') (sem_env.v env)) ⦈) s e (s', r)"
by (metis evaluate_total)
then obtain s' r where "evaluate True (env ⦇ sem_env.v := (nsAppend (alist_to_ns env') (sem_env.v env)) ⦈) s e (s', r)"
by auto

show ?thesis
unfolding ‹pe = _›
apply (intro exI)
apply (rule mat_cons1)
apply safe
apply fact+
done
qed
next
case False
then show ?thesis
unfolding ‹pe = _› by (metis mat_cons4)
qed
qed

end```