Theory NodeClass
section‹Node›
text‹In this theory, we introduce the types for the Node class.›
theory NodeClass
imports
ObjectClass
"../pointers/NodePointer"
begin
subsubsection‹Node›
record RNode = RObject
+ nothing :: unit
register_default_tvars "'Node RNode_ext"
type_synonym 'Node Node = "'Node RNode_scheme"
register_default_tvars "'Node Node"
type_synonym ('Object, 'Node) Object = "('Node RNode_ext + 'Object) Object"
register_default_tvars "('Object, 'Node) Object"
type_synonym ('object_ptr, 'node_ptr, 'Object, 'Node) heap
= "('node_ptr node_ptr + 'object_ptr, 'Node RNode_ext + 'Object) heap"
register_default_tvars
"('object_ptr, 'node_ptr, 'Object, 'Node) heap"
type_synonym heap⇩f⇩i⇩n⇩a⇩l = "(unit, unit, unit, unit) heap"
definition node_ptr_kinds :: "(_) heap ⇒ (_) node_ptr fset"
where
"node_ptr_kinds heap =
(the |`| (cast⇩o⇩b⇩j⇩e⇩c⇩t⇩_⇩p⇩t⇩r⇩2⇩n⇩o⇩d⇩e⇩_⇩p⇩t⇩r |`| (ffilter is_node_ptr_kind (object_ptr_kinds heap))))"
lemma node_ptr_kinds_simp [simp]:
"node_ptr_kinds (Heap (fmupd (cast node_ptr) node (the_heap h)))
= {|node_ptr|} |∪| node_ptr_kinds h"
by (auto simp add: node_ptr_kinds_def)
definition cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e :: "(_) Object ⇒ (_) Node option"
where
"cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e obj = (case RObject.more obj of Inl node
⇒ Some (RObject.extend (RObject.truncate obj) node) | _ ⇒ None)"
adhoc_overloading cast cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e
definition cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t:: "(_) Node ⇒ (_) Object"
where
"cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t node = (RObject.extend (RObject.truncate node) (Inl (RObject.more node)))"
adhoc_overloading cast cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t
definition is_node_kind :: "(_) Object ⇒ bool"
where
"is_node_kind ptr ⟷ cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e ptr ≠ None"
definition get⇩N⇩o⇩d⇩e :: "(_) node_ptr ⇒ (_) heap ⇒ (_) Node option"
where
"get⇩N⇩o⇩d⇩e node_ptr h = Option.bind (get (cast node_ptr) h) cast"
adhoc_overloading get get⇩N⇩o⇩d⇩e
locale l_type_wf_def⇩N⇩o⇩d⇩e
begin
definition a_type_wf :: "(_) heap ⇒ bool"
where
"a_type_wf h = (ObjectClass.type_wf h
∧ (∀node_ptr ∈ fset( node_ptr_kinds h). get⇩N⇩o⇩d⇩e node_ptr h ≠ None))"
end
global_interpretation l_type_wf_def⇩N⇩o⇩d⇩e defines type_wf = a_type_wf .
lemmas type_wf_defs = a_type_wf_def
locale l_type_wf⇩N⇩o⇩d⇩e = l_type_wf type_wf for type_wf :: "((_) heap ⇒ bool)" +
assumes type_wf⇩N⇩o⇩d⇩e: "type_wf h ⟹ NodeClass.type_wf h"
sublocale l_type_wf⇩N⇩o⇩d⇩e ⊆ l_type_wf⇩O⇩b⇩j⇩e⇩c⇩t
apply(unfold_locales)
using ObjectClass.a_type_wf_def by auto
locale l_get⇩N⇩o⇩d⇩e_lemmas = l_type_wf⇩N⇩o⇩d⇩e
begin
sublocale l_get⇩O⇩b⇩j⇩e⇩c⇩t_lemmas by unfold_locales
lemma get⇩N⇩o⇩d⇩e_type_wf:
assumes "type_wf h"
shows "node_ptr |∈| node_ptr_kinds h ⟷ get⇩N⇩o⇩d⇩e node_ptr h ≠ None"
using l_type_wf⇩N⇩o⇩d⇩e_axioms assms
apply(simp add: type_wf_defs get⇩N⇩o⇩d⇩e_def l_type_wf⇩N⇩o⇩d⇩e_def)
by (metis bind_eq_None_conv ffmember_filter fimage_eqI is_node_ptr_kind_cast
get⇩O⇩b⇩j⇩e⇩c⇩t_type_wf node_ptr_casts_commute2 node_ptr_kinds_def option.sel option.simps(3))
end
global_interpretation l_get⇩N⇩o⇩d⇩e_lemmas type_wf
by unfold_locales
definition put⇩N⇩o⇩d⇩e :: "(_) node_ptr ⇒ (_) Node ⇒ (_) heap ⇒ (_) heap"
where
"put⇩N⇩o⇩d⇩e node_ptr node = put (cast node_ptr) (cast node)"
adhoc_overloading put put⇩N⇩o⇩d⇩e
lemma put⇩N⇩o⇩d⇩e_ptr_in_heap:
assumes "put⇩N⇩o⇩d⇩e node_ptr node h = h'"
shows "node_ptr |∈| node_ptr_kinds h'"
using assms
unfolding put⇩N⇩o⇩d⇩e_def node_ptr_kinds_def
by (metis ffmember_filter fimage_eqI is_node_ptr_kind_cast node_ptr_casts_commute2
option.sel put⇩O⇩b⇩j⇩e⇩c⇩t_ptr_in_heap)
lemma put⇩N⇩o⇩d⇩e_put_ptrs:
assumes "put⇩N⇩o⇩d⇩e node_ptr node h = h'"
shows "object_ptr_kinds h' = object_ptr_kinds h |∪| {|cast node_ptr|}"
using assms
by (simp add: put⇩N⇩o⇩d⇩e_def put⇩O⇩b⇩j⇩e⇩c⇩t_put_ptrs)
lemma node_ptr_kinds_commutes [simp]:
"cast node_ptr |∈| object_ptr_kinds h ⟷ node_ptr |∈| node_ptr_kinds h"
proof (rule iffI)
show "cast node_ptr |∈| object_ptr_kinds h ⟹ node_ptr |∈| node_ptr_kinds h"
by (metis ffmember_filter fimage.rep_eq image_eqI is_node_ptr_kind_cast node_ptr_casts_commute2
node_ptr_kinds_def option.sel)
next
show "node_ptr |∈| node_ptr_kinds h ⟹ cast node_ptr |∈| object_ptr_kinds h"
by (auto simp: node_ptr_kinds_def)
qed
lemma node_empty [simp]:
"⦇RObject.nothing = (), RNode.nothing = (), … = RNode.more node⦈ = node"
by simp
lemma cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t_inject [simp]: "cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t x = cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t y ⟷ x = y"
apply(simp add: cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t_def RObject.extend_def)
by (metis (full_types) RObject.surjective old.unit.exhaust)
lemma cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e_none [simp]:
"cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e obj = None ⟷ ¬ (∃node. cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t node = obj)"
apply(auto simp add: cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e_def cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t_def RObject.extend_def split: sum.splits)[1]
by (metis (full_types) RObject.select_convs(2) RObject.surjective old.unit.exhaust)
lemma cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e_some [simp]: "cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e obj = Some node ⟷ cast node = obj"
by(auto simp add: cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e_def cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t_def RObject.extend_def split: sum.splits)
lemma cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e_inv [simp]: "cast⇩O⇩b⇩j⇩e⇩c⇩t⇩2⇩N⇩o⇩d⇩e (cast⇩N⇩o⇩d⇩e⇩2⇩O⇩b⇩j⇩e⇩c⇩t node) = Some node"
by simp
locale l_known_ptr⇩N⇩o⇩d⇩e
begin
definition a_known_ptr :: "(_) object_ptr ⇒ bool"
where
"a_known_ptr ptr = False"
end
global_interpretation l_known_ptr⇩N⇩o⇩d⇩e defines known_ptr = a_known_ptr .
lemmas known_ptr_defs = a_known_ptr_def
locale l_known_ptrs⇩N⇩o⇩d⇩e = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr ⇒ bool"
begin
definition a_known_ptrs :: "(_) heap ⇒ bool"
where
"a_known_ptrs h = (∀ptr ∈ fset (object_ptr_kinds h). known_ptr ptr)"
lemma known_ptrs_known_ptr: "a_known_ptrs h ⟹ ptr |∈| object_ptr_kinds h ⟹ known_ptr ptr"
by (simp add: a_known_ptrs_def)
lemma known_ptrs_preserved:
"object_ptr_kinds h = object_ptr_kinds h' ⟹ a_known_ptrs h = a_known_ptrs h'"
by(auto simp add: a_known_ptrs_def)
lemma known_ptrs_subset:
"object_ptr_kinds h' |⊆| object_ptr_kinds h ⟹ a_known_ptrs h ⟹ a_known_ptrs h'"
by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
lemma known_ptrs_new_ptr:
"object_ptr_kinds h' = object_ptr_kinds h |∪| {|new_ptr|} ⟹ known_ptr new_ptr ⟹
a_known_ptrs h ⟹ a_known_ptrs h'"
by(simp add: a_known_ptrs_def)
end
global_interpretation l_known_ptrs⇩N⇩o⇩d⇩e known_ptr defines known_ptrs = a_known_ptrs .
lemmas known_ptrs_defs = a_known_ptrs_def
lemma known_ptrs_is_l_known_ptrs: "l_known_ptrs known_ptr known_ptrs"
using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset
known_ptrs_new_ptr
by blast
lemma get_node_ptr_simp1 [simp]: "get⇩N⇩o⇩d⇩e node_ptr (put⇩N⇩o⇩d⇩e node_ptr node h) = Some node"
by(auto simp add: get⇩N⇩o⇩d⇩e_def put⇩N⇩o⇩d⇩e_def)
lemma get_node_ptr_simp2 [simp]:
"node_ptr ≠ node_ptr' ⟹ get⇩N⇩o⇩d⇩e node_ptr (put⇩N⇩o⇩d⇩e node_ptr' node h) = get⇩N⇩o⇩d⇩e node_ptr h"
by(auto simp add: get⇩N⇩o⇩d⇩e_def put⇩N⇩o⇩d⇩e_def)
end