(* Title: HOL/Unix/Nested_Environment.thy Author: Markus Wenzel, TU Muenchen
*)
section‹Nested environments›
theory Nested_Environment imports Main begin
text‹
Consider a partial function @{term [source] "e :: 'a \ 'b option"}; this may
be understood as an 🚫‹environment› mapping indexes 🍋‹'a\ to optional
entry values 🍋‹'b\ (cf.\ the basic theory \Map\ of Isabelle/HOL). This
basic idea is easily generalized to that of a 🚫‹nested environment›, where
entries may be either basic values or again proper environments. Then each
entry is accessed by a 🚫‹path›, i.e.\ a list of indexes leading to its
position within the structure. ›
datatype (dead 'a, dead 'b, dead 'c) env =
Val 'a
| Env 'b "'c ==> ('a, 'b, 'c) env option"
text‹ 🚫 In the type 🍋‹('a, 'b, 'c) env\ the parameter \<^typ>\'a› refers to
basic values (occurring in terminal positions), type 🍋‹'b\ to values
associated with proper (inner) environments, and type 🍋‹'c\ with the
index type for branching. Note that there is no restriction on any of these types. In particular, arbitrary branching may yield rather large
(transfinite) tree structures. ›
subsection‹The lookup operation›
text‹
Lookup in nested environments works by following a given path of index
elements, leading to an optional result (a terminal value or nested
environment). A 🚫‹defined position› within a nested environment is one where 🍋‹lookup› at its path does not yield 🍋‹None›. ›
primrec lookup :: "('a, 'b, 'c) env \ 'c list \ ('a, 'b, 'c) env option" and lookup_option :: "('a, 'b, 'c) env option \ 'c list \ ('a, 'b, 'c) env option" where "lookup (Val a) xs = (if xs = [] then Some (Val a) else None)"
| "lookup (Env b es) xs =
(case xs of
[] ==> Some (Env b es)
| y # ys ==> lookup_option (es y) ys)"
| "lookup_option None xs = None"
| "lookup_option (Some e) xs = lookup e xs"
hide_const lookup_option
text‹ 🚫
The characteristic cases of 🍋‹lookup› are expressed by the following
equalities. ›
theorem lookup_nil: "lookup e [] = Some e" by (cases e) simp_all
theorem lookup_val_cons: "lookup (Val a) (x # xs) = None" by simp
theorem lookup_env_cons: "lookup (Env b es) (x # xs) =
(case es x of
None ==> None
| Some e ==> lookup e xs)" by (cases "es x") simp_all
theorem lookup_eq: "lookup env xs =
(case xs of
[] ==> Some env
| x # xs ==>
(case env of
Val a ==> None
| Env b es ==>
(case es x of
None ==> None
| Some e ==> lookup e xs)))" by (simp split: list.split env.split)
text‹ 🚫
Displaced 🍋‹lookup› operations, relative to a certain base path prefix,
may be reduced as follows. There are two cases, depending whether the
environment actually extends far enough to follow the base path. ›
theorem lookup_append_none: assumes"lookup env xs = None" shows"lookup env (xs @ ys) = None" using assms proof (induct xs arbitrary: env) case Nil thenhave False by simp thenshow ?case .. next case (Cons x xs) show ?case proof (cases env) case Val thenshow ?thesis by simp next case (Env b es) show ?thesis proof (cases "es x") case None with Env show ?thesis by simp next case (Some e) note es = ‹es x = Some e› show ?thesis proof (cases "lookup e xs") case None thenhave"lookup e (xs @ ys) = None"by (rule Cons.hyps) with Env Some show ?thesis by simp next case Some with Env es have False using Cons.prems by simp thenshow ?thesis .. qed qed qed qed
theorem lookup_append_some: assumes"lookup env xs = Some e" shows"lookup env (xs @ ys) = lookup e ys" using assms proof (induct xs arbitrary: env e) case Nil thenhave"env = e"by simp thenshow"lookup env ([] @ ys) = lookup e ys"by simp next case (Cons x xs) note asm = ‹lookup env (x # xs) = Some e› show"lookup env ((x # xs) @ ys) = lookup e ys" proof (cases env) case (Val a) with asm have False by simp thenshow ?thesis .. next case (Env b es) show ?thesis proof (cases "es x") case None with asm Env have False by simp thenshow ?thesis .. next case (Some e') note es = ‹es x = Some e'\ show ?thesis proof (cases "lookup e' xs") case None with asm Env es have False by simp thenshow ?thesis .. next case Some with asm Env es have"lookup e' xs = Some e" by simp thenhave"lookup e' (xs @ ys) = lookup e ys"by (rule Cons.hyps) with Env es show ?thesis by simp qed qed qed qed
text‹ 🚫
Successful 🍋‹lookup› deeper down an environment structure means we are
able to peek further up as well. Note that this is basically just the
contrapositive statement of @{thm [source] lookup_append_none} above. ›
theorem lookup_some_append: assumes"lookup env (xs @ ys) = Some e" shows"\e. lookup env xs = Some e" proof - from assms have"lookup env (xs @ ys) \ None"by simp thenhave"lookup env xs \ None" by (rule contrapos_nn) (simp only: lookup_append_none) thenshow ?thesis by (simp) qed
text‹
The subsequent statement describes in more detail how a successful 🍋‹lookup›with a non-empty path results in a certain situation at any upper
position. ›
theorem lookup_some_upper: assumes"lookup env (xs @ y # ys) = Some e" shows"\b' es' env'.
lookup env xs = Some (Env b' es') ∧
es' y = Some env'∧
lookup env' ys = Some e" using assms proof (induct xs arbitrary: env e) case Nil from Nil.prems have"lookup env (y # ys) = Some e" by simp thenobtain b' es' env' where
env: "env = Env b' es'"and
es': "es' y = Some env'" and
look': "lookup env' ys = Some e" by (auto simp add: lookup_eq split: option.splits env.splits) from env have"lookup env [] = Some (Env b' es')"by simp with es' look'show ?caseby blast next case (Cons x xs) from Cons.prems obtain b' es' env' where
env: "env = Env b' es'"and
es': "es' x = Some env'" and
look': "lookup env' (xs @ y # ys) = Some e" by (auto simp add: lookup_eq split: option.splits env.splits) from Cons.hyps [OF look'] obtain b'' es'' env'' where
upper': "lookup env' xs = Some (Env b'' es'')" and
es'': "es'' y = Some env''"and
look'': "lookup env'' ys = Some e" by blast from env es' upper'have"lookup env (x # xs) = Some (Env b'' es'')" by simp with es'' look''show ?caseby blast qed
subsection‹The update operation›
text‹
Update at a certain position in a nested environment may either delete an
existing entry, or overwrite an existing one. Note that update at undefined
positions is simple absorbed, i.e.\ the environment is left unchanged. ›
primrec update :: "'c list \ ('a, 'b, 'c) env option \
('a, 'b, 'c) env \ ('a, 'b, 'c) env" and update_option :: "'c list \ ('a, 'b, 'c) env option \
('a, 'b, 'c) env option \ ('a, 'b, 'c) env option" where "update xs opt (Val a) =
(if xs = [] then (case opt of None ==> Val a | Some e ==> e)
else Val a)"
| "update xs opt (Env b es) =
(case xs of
[] ==> (case opt of None ==> Env b es | Some e ==> e)
| y # ys ==> Env b (es (y := update_option ys opt (es y))))"
| "update_option xs opt None =
(if xs = [] then opt else None)"
| "update_option xs opt (Some e) =
(if xs = [] then opt else Some (update xs opt e))"
hide_const update_option
text‹ 🚫
The characteristic cases of 🍋‹update› are expressed by the following
equalities. ›
theorem update_cons_val: "update (x # xs) opt (Val a) = Val a" by simp
theorem update_cons_nil_env: "update [x] opt (Env b es) = Env b (es (x := opt))" by (cases "es x") simp_all
theorem update_cons_cons_env: "update (x # y # ys) opt (Env b es) =
Env b (es (x :=
(case es x of
None ==> None
| Some e ==> Some (update (y # ys) opt e))))" by (cases "es x") simp_all
lemma update_eq: "update xs opt env =
(case xs of
[] ==>
(case opt of
None ==> env
| Some e ==> e)
| x # xs ==>
(case env of
Val a ==> Val a
| Env b es ==>
(case xs of
[] ==> Env b (es (x := opt))
| y # ys ==>
Env b (es (x :=
(case es x of
None ==> None
| Some e ==> Some (update (y # ys) opt e)))))))" by (simp split: list.split env.split option.split)
text‹ 🚫
The most basic correspondence of 🍋‹lookup›and🍋‹update›states
that after 🍋‹update› at a defined position, subsequent 🍋‹lookup›
operations would yield the new value. ›
theorem lookup_update_some: assumes"lookup env xs = Some e" shows"lookup (update xs (Some env') env) xs = Some env'" using assms proof (induct xs arbitrary: env e) case Nil thenhave"env = e"by simp thenshow ?caseby simp next case (Cons x xs) note hyp = Cons.hyps and asm = ‹lookup env (x # xs) = Some e› show ?case proof (cases env) case (Val a) with asm have False by simp thenshow ?thesis .. next case (Env b es) show ?thesis proof (cases "es x") case None with asm Env have False by simp thenshow ?thesis .. next case (Some e') note es = ‹es x = Some e'\ show ?thesis proof (cases xs) case Nil with Env show ?thesis by simp next case (Cons x' xs') from asm Env es have"lookup e' xs = Some e"by simp thenhave"lookup (update xs (Some env') e') xs = Some env'"by (rule hyp) with Env es Cons show ?thesis by simp qed qed qed qed
text‹ 🚫
The properties of displaced 🍋‹update› operations are analogous to those
of 🍋‹lookup› above. There are two cases: below an undefined position 🍋‹update›is absorbed altogether, and below a defined positions 🍋‹update› affects subsequent 🍋‹lookup› operations in the obvious way. ›
theorem update_append_none: assumes"lookup env xs = None" shows"update (xs @ y # ys) opt env = env" using assms proof (induct xs arbitrary: env) case Nil thenhave False by simp thenshow ?case .. next case (Cons x xs) note hyp = Cons.hyps and asm = ‹lookup env (x # xs) = None› show"update ((x # xs) @ y # ys) opt env = env" proof (cases env) case (Val a) thenshow ?thesis by simp next case (Env b es) show ?thesis proof (cases "es x") case None note es = ‹es x = None› show ?thesis by (cases xs) (simp_all add: es Env fun_upd_idem_iff) next case (Some e) note es = ‹es x = Some e› show ?thesis proof (cases xs) case Nil with asm Env Some have False by simp thenshow ?thesis .. next case (Cons x' xs') from asm Env es have"lookup e xs = None"by simp thenhave"update (xs @ y # ys) opt e = e"by (rule hyp) with Env es Cons show"update ((x # xs) @ y # ys) opt env = env" by (simp add: fun_upd_idem_iff) qed qed qed qed
theorem update_append_some: assumes"lookup env xs = Some e" shows"lookup (update (xs @ y # ys) opt env) xs = Some (update (y # ys) opt e)" using assms proof (induct xs arbitrary: env e) case Nil thenhave"env = e"by simp thenshow ?caseby simp next case (Cons x xs) note hyp = Cons.hyps and asm = ‹lookup env (x # xs) = Some e› show"lookup (update ((x # xs) @ y # ys) opt env) (x # xs) =
Some (update (y # ys) opt e)" proof (cases env) case (Val a) with asm have False by simp thenshow ?thesis .. next case (Env b es) show ?thesis proof (cases "es x") case None with asm Env have False by simp thenshow ?thesis .. next case (Some e') note es = ‹es x = Some e'\ show ?thesis proof (cases xs) case Nil with asm Env es have"e = e'"by simp with Env es Nil show ?thesis by simp next case (Cons x' xs') from asm Env es have"lookup e' xs = Some e"by simp thenhave"lookup (update (xs @ y # ys) opt e') xs =
Some (update (y # ys) opt e)" by (rule hyp) with Env es Cons show ?thesis by simp qed qed qed qed
text‹ 🚫
Apparently, 🍋‹update› does not affect the result of subsequent 🍋‹lookup› operations at independent positions, i.e.\ incase that the paths for🍋‹update›and🍋‹lookup› fork at a certain point. ›
theorem lookup_update_other: assumes neq: "y \ (z::'c)" shows"lookup (update (xs @ z # zs) opt env) (xs @ y # ys) =
lookup env (xs @ y # ys)" proof (induct xs arbitrary: env) case Nil show ?case proof (cases env) case Val thenshow ?thesis by simp next case Env show ?thesis proof (cases zs) case Nil with neq Env show ?thesis by simp next case Cons with neq Env show ?thesis by simp qed qed next case (Cons x xs) note hyp = Cons.hyps show ?case proof (cases env) case Val thenshow ?thesis by simp next case (Env y es) show ?thesis proof (cases xs) case Nil show ?thesis proof (cases "es x") case None with Env Nil show ?thesis by simp next case Some with neq hyp and Env Nil show ?thesis by simp qed next case (Cons x' xs') show ?thesis proof (cases "es x") case None with Env Cons show ?thesis by simp next case Some with neq hyp and Env Cons show ?thesis by simp qed qed qed qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.