(*********************************************************************************** * Copyright (c) 2016-2020 The University of Sheffield, UK * 2019-2020 University of Exeter, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * SPDX-License-Identifier: BSD-2-Clause ***********************************************************************************) section \Shadow Root Components\ theory Shadow_DOM_Components imports Shadow_DOM.Shadow_DOM Core_DOM_Components begin subsection \get\_component\ global_interpretation l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs to_tree_order defines get_component = a_get_component and is_strongly_dom_component_safe = a_is_strongly_dom_component_safe and is_weakly_dom_component_safe = a_is_weakly_dom_component_safe . interpretation i_get_component?: l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name by(auto simp add: l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_component_def is_strongly_dom_component_safe_def is_weakly_dom_component_safe_def instances) declare l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsection \attach\_shadow\_root\ lemma attach_shadow_root_not_strongly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'ShadowRoot::{equal,linorder}) heap" and h' and host and new_shadow_root_ptr where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ attach_shadow_root host m \\<^sub>r new_shadow_root_ptr \\<^sub>h h'" and "\ is_strongly_dom_component_safe {cast host} {cast new_shadow_root_ptr} h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'ShadowRoot::{equal,linorder}) heap" let ?P = "do { doc \ create_document; create_element doc ''div'' }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?e1 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and host="?e1"]) by code_simp+ qed locale l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_component_safe is_weakly_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name + l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr set_shadow_root set_shadow_root_locs set_mode set_mode_locs attach_shadow_root type_wf get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs + l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_mode set_mode_locs + l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_shadow_root set_shadow_root_locs for known_ptr :: "(_::linorder) object_ptr \ bool" and heap_is_wellformed :: "(_) heap \ bool" and parent_child_rel :: "(_) heap \ ((_) object_ptr \ (_) object_ptr) set" and type_wf :: "(_) heap \ bool" and known_ptrs :: "(_) heap \ bool" and to_tree_order :: "(_) object_ptr \ ((_) heap, exception, (_) object_ptr list) prog" and get_parent :: "(_) node_ptr \ ((_) heap, exception, (_) object_ptr option) prog" and get_parent_locs :: "((_) heap \ (_) heap \ bool) set" and get_child_nodes :: "(_) object_ptr \ ((_) heap, exception, (_) node_ptr list) prog" and get_child_nodes_locs :: "(_) object_ptr \ ((_) heap \ (_) heap \ bool) set" and get_dom_component :: "(_) object_ptr \ ((_) heap, exception, (_) object_ptr list) prog" and get_root_node :: "(_) object_ptr \ ((_) heap, exception, (_) object_ptr) prog" and get_root_node_locs :: "((_) heap \ (_) heap \ bool) set" and get_ancestors :: "(_) object_ptr \ ((_) heap, exception, (_) object_ptr list) prog" and get_ancestors_locs :: "((_) heap \ (_) heap \ bool) set" and get_element_by_id :: "(_) object_ptr \ char list \ ((_) heap, exception, (_) element_ptr option) prog" and get_elements_by_class_name :: "(_) object_ptr \ char list \ ((_) heap, exception, (_) element_ptr list) prog" and get_elements_by_tag_name :: "(_) object_ptr \ char list \ ((_) heap, exception, (_) element_ptr list) prog" and set_shadow_root :: "(_) element_ptr \ (_) shadow_root_ptr option \ ((_) heap, exception, unit) prog" and set_shadow_root_locs :: "(_) element_ptr \ ((_) heap, exception, unit) prog set" and set_mode :: "(_) shadow_root_ptr \ shadow_root_mode \ ((_) heap, exception, unit) prog" and set_mode_locs :: "(_) shadow_root_ptr \ ((_) heap, exception, unit) prog set" and attach_shadow_root :: "(_) element_ptr \ shadow_root_mode \ ((_) heap, exception, (_) shadow_root_ptr) prog" and get_disconnected_nodes :: "(_) document_ptr \ ((_) heap, exception, (_) node_ptr list) prog" and get_disconnected_nodes_locs :: "(_) document_ptr \ ((_) heap \ (_) heap \ bool) set" and is_strongly_component_safe :: "(_) object_ptr set \ (_) object_ptr set \ (_) heap \ (_) heap \ bool" and is_weakly_component_safe :: "(_) object_ptr set \ (_) object_ptr set \ (_) heap \ (_) heap \ bool" and get_tag_name :: "(_) element_ptr \ ((_) heap, exception, char list) prog" and get_tag_name_locs :: "(_) element_ptr \ ((_) heap \ (_) heap \ bool) set" and get_shadow_root :: "(_) element_ptr \ ((_) heap, exception, (_) shadow_root_ptr option) prog" and get_shadow_root_locs :: "(_) element_ptr \ ((_) heap \ (_) heap \ bool) set" begin lemma attach_shadow_root_is_weakly_dom_component_safe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ attach_shadow_root element_ptr shadow_root_mode \\<^sub>h h'" assumes "ptr \ cast |h \ attach_shadow_root element_ptr shadow_root_mode|\<^sub>r" assumes "ptr \ set |h \ get_dom_component (cast element_ptr)|\<^sub>r" shows "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'" proof - obtain h2 h3 new_shadow_root_ptr where h2: "h \ new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \\<^sub>h h2" and new_shadow_root_ptr: "h \ new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \\<^sub>r new_shadow_root_ptr" and h3: "h2 \ set_mode new_shadow_root_ptr shadow_root_mode \\<^sub>h h3" and h': "h3 \ set_shadow_root element_ptr (Some new_shadow_root_ptr) \\<^sub>h h'" using assms(4) by(auto simp add: attach_shadow_root_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated] bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits) have "h \ attach_shadow_root element_ptr shadow_root_mode \\<^sub>r new_shadow_root_ptr" using new_shadow_root_ptr h2 h3 h' using assms(4) by(auto simp add: attach_shadow_root_def intro!: bind_returns_result_I bind_pure_returns_result_I[OF get_tag_name_pure] bind_pure_returns_result_I[OF get_shadow_root_pure] elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated] bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits) have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h2" using h2 new_shadow_root_ptr by (metis (no_types, lifting) \h \ attach_shadow_root element_ptr shadow_root_mode \\<^sub>r new_shadow_root_ptr\ assms(5) new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t select_result_I2) have "ptr \ cast new_shadow_root_ptr" using \h \ attach_shadow_root element_ptr shadow_root_mode \\<^sub>r new_shadow_root_ptr\ assms(5) by auto have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h2 h3" using set_mode_writes h3 apply(rule reads_writes_preserved2) apply(auto simp add: set_mode_locs_def all_args_def)[1] using \ptr \ cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr\ by (metis get_M_Mshadow_root_preserved3) have "element_ptr |\| element_ptr_kinds h" using \h \ attach_shadow_root element_ptr shadow_root_mode \\<^sub>r new_shadow_root_ptr\ attach_shadow_root_element_ptr_in_heap by blast have "ptr \ cast element_ptr" by (metis (no_types, lifting) \element_ptr |\| element_ptr_kinds h\ assms(1) assms(2) assms(3) assms(6) element_ptr_kinds_commutes is_OK_returns_result_E get_component_ok local.get_dom_component_ptr node_ptr_kinds_commutes select_result_I2) have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h3 h'" using set_shadow_root_writes h' apply(rule reads_writes_preserved2) apply(auto simp add: set_shadow_root_locs_def all_args_def)[1] by (metis \ptr \ cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr\ get_M_Element_preserved8) show ?thesis using \preserved (get_M ptr getter) h h2\ \preserved (get_M ptr getter) h2 h3\ \preserved (get_M ptr getter) h3 h'\ by(auto simp add: preserved_def) qed end interpretation i_get_dom_component_attach_shadow_root?: l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr heap_is_wellformed parent_child_rel type_wf known_ptrs to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_component get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name set_shadow_root set_shadow_root_locs set_mode set_mode_locs attach_shadow_root get_disconnected_nodes get_disconnected_nodes_locs is_strongly_dom_component_safe is_weakly_dom_component_safe get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs by(auto simp add: l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsection \get\_shadow\_root\ lemma get_shadow_root_not_weakly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and element_ptr and shadow_root_ptr_opt and h' where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ get_shadow_root element_ptr \\<^sub>r shadow_root_ptr_opt \\<^sub>h h'" and "\ is_weakly_dom_component_safe {cast element_ptr} (cast ` set_option shadow_root_ptr_opt) h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" let ?P = "do { document_ptr \ create_document; html \ create_element document_ptr ''html''; append_child (cast document_ptr) (cast html); head \ create_element document_ptr ''head''; append_child (cast html) (cast head); body \ create_element document_ptr ''body''; append_child (cast html) (cast body); e1 \ create_element document_ptr ''div''; append_child (cast body) (cast e1); e2 \ create_element document_ptr ''div''; append_child (cast e1) (cast e2); s1 \ attach_shadow_root e1 Open; e3 \ create_element document_ptr ''slot''; append_child (cast s1) (cast e3); return e1 }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?e1 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and element_ptr="?e1"]) by code_simp+ qed locale l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_shadow_root + l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_remove_shadow_root_get_child_nodes begin lemma get_shadow_root_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" shows "set |h \ get_component (cast host)|\<^sub>r \ set |h \ get_component (cast shadow_root_ptr)|\<^sub>r = {}" proof - have "cast host |\| object_ptr_kinds h" using assms(4) get_shadow_root_ptr_in_heap by auto then obtain host_c where host_c: "h \ get_component (cast host) \\<^sub>r host_c" by (meson assms(1) assms(2) assms(3) get_component_ok is_OK_returns_result_E) obtain host_root where host_root: "h \ get_root_node (cast host) \\<^sub>r host_root" by (metis (no_types, lifting) bind_returns_heap_E get_component_def host_c is_OK_returns_result_I pure_def pure_eq_iff) have "cast shadow_root_ptr |\| object_ptr_kinds h" using get_shadow_root_shadow_root_ptr_in_heap assms shadow_root_ptr_kinds_commutes using document_ptr_kinds_commutes by blast then obtain shadow_root_ptr_c where shadow_root_ptr_c: "h \ get_component (cast shadow_root_ptr) \\<^sub>r shadow_root_ptr_c" by (meson assms(1) assms(2) assms(3) get_component_ok is_OK_returns_result_E) have "h \ get_root_node (cast shadow_root_ptr) \\<^sub>r cast shadow_root_ptr" using \cast shadow_root_ptr |\| object_ptr_kinds h\ by(auto simp add: get_root_node_def get_ancestors_def intro!: bind_pure_returns_result_I split: option.splits) have "host_root \ cast shadow_root_ptr" proof (rule ccontr, simp) assume "host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr" have "(cast shadow_root_ptr, host_root) \ (parent_child_rel h)\<^sup>*" using \host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\ by auto moreover have "(host_root, cast host) \ (parent_child_rel h)\<^sup>*" using get_root_node_parent_child_rel host_root assms by blast moreover have "(cast host, cast shadow_root_ptr) \ (a_host_shadow_root_rel h)" using assms(4) apply(auto simp add: a_host_shadow_root_rel_def)[1] by (metis (mono_tags, lifting) get_shadow_root_ptr_in_heap image_eqI is_OK_returns_result_I mem_Collect_eq prod.simps(2) select_result_I2) moreover have " acyclic (parent_child_rel h \ local.a_host_shadow_root_rel h)" using assms(1)[unfolded heap_is_wellformed_def] by auto ultimately show False using local.parent_child_rel_node_ptr by (metis (no_types, lifting) Un_iff \host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\ acyclic_def in_rtrancl_UnI rtrancl_into_trancl1) qed then have "host_c \ shadow_root_ptr_c" by (metis \h \ get_root_node (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \\<^sub>r cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\ assms(1) assms(2) assms(3) get_dom_component_ptr get_component_root_node_same host_c host_root local.get_root_node_parent_child_rel local.get_root_node_same_no_parent_parent_child_rel rtranclE shadow_root_ptr_c) then have "set host_c \ set shadow_root_ptr_c = {}" using assms get_dom_component_no_overlap Shadow_DOM.a_heap_is_wellformed_def host_c shadow_root_ptr_c by blast then show ?thesis using host_c shadow_root_ptr_c by auto qed end interpretation i_get_shadow_root_component?: l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_tag_name get_tag_name_locs known_ptr heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs known_ptrs to_tree_order get_parent get_parent_locs get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name remove_shadow_root remove_shadow_root_locs by(auto simp add: l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsection \get\_host\ lemma get_host_not_weakly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and shadow_root_ptr and host and h' where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ get_host shadow_root_ptr \\<^sub>r host \\<^sub>h h'" and "\ is_weakly_dom_component_safe {cast shadow_root_ptr} {cast host} h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" let ?P = "do { document_ptr \ create_document; html \ create_element document_ptr ''html''; append_child (cast document_ptr) (cast html); head \ create_element document_ptr ''head''; append_child (cast html) (cast head); body \ create_element document_ptr ''body''; append_child (cast html) (cast body); e1 \ create_element document_ptr ''div''; append_child (cast body) (cast e1); e2 \ create_element document_ptr ''div''; append_child (cast e1) (cast e2); s1 \ attach_shadow_root e1 Open; e3 \ create_element document_ptr ''slot''; append_child (cast s1) (cast e3); return s1 }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?s1 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and shadow_root_ptr="?s1"]) by code_simp+ qed locale l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_host + l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M begin lemma get_host_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ get_host shadow_root_ptr \\<^sub>r host" shows "set |h \ get_component (cast host)|\<^sub>r \ set |h \ get_component (cast shadow_root_ptr)|\<^sub>r = {}" proof - have "h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" using assms(1) assms(2) assms(4) local.shadow_root_host_dual by blast then show ?thesis using assms(1) assms(2) assms(3) local.get_shadow_root_is_component_unsafe by blast qed end interpretation i_get_host_component?: l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs known_ptrs to_tree_order get_parent get_parent_locs get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name remove_shadow_root remove_shadow_root_locs by(auto simp add: l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsection \get\_root\_node\_si\ locale l_get_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M begin lemma get_root_node_si_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ get_root_node_si ptr' \\<^sub>r root" shows "set |h \ get_component ptr'|\<^sub>r = set |h \ get_component root|\<^sub>r \ set |h \ get_component ptr'|\<^sub>r \ set |h \ get_component root|\<^sub>r = {}" proof - have "ptr' |\| object_ptr_kinds h" using get_ancestors_si_ptr_in_heap assms(4) by(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2) then obtain c where "h \ get_component ptr' \\<^sub>r c" by (meson assms(1) assms(2) assms(3) local.get_component_ok select_result_I) moreover have "root |\| object_ptr_kinds h" using get_ancestors_si_ptr assms(4) apply(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)[1] by (metis (no_types, lifting) assms(1) assms(2) assms(3) empty_iff empty_set get_ancestors_si_ptrs_in_heap last_in_set) then obtain c' where "h \ get_component root \\<^sub>r c'" by (meson assms(1) assms(2) assms(3) local.get_component_ok select_result_I) ultimately show ?thesis by (metis (no_types, lifting) assms(1) assms(2) assms(3) local.get_dom_component_no_overlap select_result_I2) qed end interpretation i_get_component_get_root_node_si?: l_get_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_host get_host_locs get_ancestors_si get_ancestors_si_locs get_root_node_si get_root_node_si_locs get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document get_disconnected_document_locs to_tree_order get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name by(auto simp add: l_get_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_get_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsection \get\_assigned\_nodes\ lemma assigned_nodes_not_weakly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and node_ptr and nodes and h' where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ assigned_nodes node_ptr \\<^sub>r nodes \\<^sub>h h'" and "\ is_weakly_dom_component_safe {cast node_ptr} (cast ` set nodes) h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" let ?P = "do { document_ptr \ create_document; html \ create_element document_ptr ''html''; append_child (cast document_ptr) (cast html); head \ create_element document_ptr ''head''; append_child (cast html) (cast head); body \ create_element document_ptr ''body''; append_child (cast html) (cast body); e1 \ create_element document_ptr ''div''; append_child (cast body) (cast e1); e2 \ create_element document_ptr ''div''; append_child (cast e1) (cast e2); s1 \ attach_shadow_root e1 Closed; e3 \ create_element document_ptr ''slot''; append_child (cast s1) (cast e3); return e3 }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?e3 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and node_ptr="?e3"]) by code_simp+ qed lemma get_composed_root_node_not_weakly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and ptr and root and h' where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ get_root_node_si ptr \\<^sub>r root \\<^sub>h h'" and "\ is_weakly_dom_component_safe {ptr} {root} h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" let ?P = "do { document_ptr \ create_document; html \ create_element document_ptr ''html''; append_child (cast document_ptr) (cast html); head \ create_element document_ptr ''head''; append_child (cast html) (cast head); body \ create_element document_ptr ''body''; append_child (cast html) (cast body); e1 \ create_element document_ptr ''div''; append_child (cast body) (cast e1); e2 \ create_element document_ptr ''div''; append_child (cast e1) (cast e2); s1 \ attach_shadow_root e1 Closed; e3 \ create_element document_ptr ''slot''; append_child (cast s1) (cast e3); return e3 }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?e3 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e3"]) by code_simp+ qed lemma assigned_slot_not_weakly_component_safe: obtains h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and node_ptr and slot_opt and h' where "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and "h \ assigned_slot node_ptr \\<^sub>r slot_opt \\<^sub>h h'" and "\ is_weakly_dom_component_safe {cast node_ptr} (cast ` set_option slot_opt) h h'" proof - let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" let ?P = "do { document_ptr \ create_document; html \ create_element document_ptr ''html''; append_child (cast document_ptr) (cast html); head \ create_element document_ptr ''head''; append_child (cast html) (cast head); body \ create_element document_ptr ''body''; append_child (cast html) (cast body); e1 \ create_element document_ptr ''div''; append_child (cast body) (cast e1); e2 \ create_element document_ptr ''div''; append_child (cast e1) (cast e2); s1 \ attach_shadow_root e1 Open; e3 \ create_element document_ptr ''slot''; append_child (cast s1) (cast e3); return e2 }" let ?h1 = "|?h0 \ ?P|\<^sub>h" let ?e2 = "|?h0 \ ?P|\<^sub>r" show thesis apply(rule that[where h="?h1" and node_ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e2"]) by code_simp+ qed locale l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_tag_name + l_get_child_nodes + l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_remove_child_wf2 + l_insert_before_wf + l_insert_before_wf2 + l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ get_ancestors_si get_ancestors_si_locs + l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_append_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ get_ancestors_si get_ancestors_si_locs + l_set_disconnected_nodes_get_tag_name + l_set_shadow_root_get_child_nodes + l_set_child_nodes_get_tag_name + l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_remove_shadow_root_get_tag_name + l_set_disconnected_nodes_get_shadow_root + l_set_child_nodes_get_shadow_root + l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M begin lemma find_slot_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ find_slot open_flag node_ptr \\<^sub>r Some slot" shows "set |h \ get_component (cast node_ptr)|\<^sub>r \ set |h \ get_component (cast slot)|\<^sub>r = {}" proof - obtain host shadow_root_ptr to where "h \ get_parent node_ptr \\<^sub>r Some (cast host)" and "h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" and "h \ to_tree_order (cast shadow_root_ptr) \\<^sub>r to" and "cast slot \ set to" using assms(4) apply(auto simp add: find_slot_def first_in_tree_order_def elim!: bind_returns_result_E2 map_filter_M_pure_E[where y=slot] split: option.splits if_splits list.splits intro!: map_filter_M_pure bind_pure_I)[1] by (metis element_ptr_casts_commute3)+ have "node_ptr |\| node_ptr_kinds h" using assms(4) find_slot_ptr_in_heap by blast then obtain node_ptr_c where node_ptr_c: "h \ get_component (cast node_ptr) \\<^sub>r node_ptr_c" using assms(1) assms(2) assms(3) get_component_ok is_OK_returns_result_E node_ptr_kinds_commutes[symmetric] by metis then have "cast host \ set node_ptr_c" using \h \ get_parent node_ptr \\<^sub>r Some (cast host)\ get_component_parent_inside assms(1) assms(2) assms(3) get_dom_component_ptr by blast then have "h \ get_component (cast host) \\<^sub>r node_ptr_c" using \h \ get_parent node_ptr \\<^sub>r Some (cast host)\ get_component_subset a_heap_is_wellformed_def assms(1) assms(2) assms(3) node_ptr_c by blast moreover have "slot |\| element_ptr_kinds h" using assms(4) find_slot_slot_in_heap by blast then obtain slot_c where slot_c: "h \ get_component (cast slot) \\<^sub>r slot_c" using a_heap_is_wellformed_def assms(1) assms(2) assms(3) get_component_ok is_OK_returns_result_E node_ptr_kinds_commutes[symmetric] element_ptr_kinds_commutes[symmetric] by metis then have "cast shadow_root_ptr \ set slot_c" using \h \ to_tree_order (cast shadow_root_ptr) \\<^sub>r to\ \cast slot \ set to\ get_component_to_tree_order assms(1) assms(2) assms(3) get_dom_component_ptr by blast then have "h \ get_component (cast shadow_root_ptr) \\<^sub>r slot_c" using \h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr\ get_component_subset assms(1) assms(2) assms(3) slot_c by blast ultimately show ?thesis using get_shadow_root_is_component_unsafe assms \h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr\ node_ptr_c slot_c by fastforce qed lemma assigned_slot_pure: "pure (assigned_slot node_ptr) h" apply(auto simp add: assigned_slot_def a_find_slot_def intro!: bind_pure_I split: option.splits)[1] by(auto simp add: first_in_tree_order_def intro!: bind_pure_I map_filter_M_pure split: list.splits) lemma assigned_slot_is_strongly_dom_component_safe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ assigned_slot node_ptr \\<^sub>r slot_opt \\<^sub>h h'" assumes "\shadow_root_ptr \ fset (shadow_root_ptr_kinds h). h \ get_mode shadow_root_ptr \\<^sub>r Closed" shows "is_strongly_dom_component_safe {cast node_ptr} (cast ` set_option slot_opt) h h'" proof - have "h = h'" using assms(5) assigned_slot_pure by (meson assms(4) pure_returns_heap_eq returns_result_heap_def) obtain parent_opt where parent_opt: "h \ get_parent node_ptr \\<^sub>r parent_opt" using assms(4) by (auto simp add: assigned_slot_def a_find_slot_def returns_result_heap_def elim!: bind_returns_result_E2 split: option.splits split: if_splits) then have "slot_opt = None" proof (induct parent_opt) case None then show ?case using assms(4) apply(auto simp add: assigned_slot_def a_find_slot_def returns_result_heap_def elim!: bind_returns_result_E2 split: option.splits split: if_splits)[1] by (meson option.distinct(1) returns_result_eq)+ next case (Some parent) then show ?case proof (cases "is_element_ptr_kind parent") case True then obtain host where host: "parent = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host" by (metis (no_types, lifting) case_optionE element_ptr_casts_commute3 node_ptr_casts_commute) moreover have "host |\| element_ptr_kinds h" using Some.prems element_ptr_kinds_commutes host local.get_parent_parent_in_heap node_ptr_kinds_commutes by blast ultimately obtain shadow_root_opt where shadow_root_opt: "h \ get_shadow_root host \\<^sub>r shadow_root_opt" using get_shadow_root_ok by (meson assms(2) is_OK_returns_result_E) then show ?thesis proof (induct shadow_root_opt) case None then show ?case using assms(4) apply(auto dest!: returns_result_eq[OF \h \ get_parent node_ptr \\<^sub>r Some parent\] simp add: assigned_slot_def a_find_slot_def returns_result_heap_def elim!: bind_returns_result_E2 split: option.splits split: if_splits)[1] using host select_result_I2 by fastforce+ next case (Some shadow_root_ptr) have "shadow_root_ptr |\| shadow_root_ptr_kinds h" using Some.prems assms(1) local.get_shadow_root_shadow_root_ptr_in_heap by blast then have "h \ get_mode shadow_root_ptr \\<^sub>r Closed" using assms by simp have "\h \ get_mode shadow_root_ptr \\<^sub>r Open" proof (rule ccontr, simp) assume "h \ get_mode shadow_root_ptr \\<^sub>r Open" then have "Open = Closed" using returns_result_eq \h \ get_mode shadow_root_ptr \\<^sub>r Closed\ by fastforce then show False by simp qed then show ?case using assms(4) Some parent_opt host by(auto dest!: returns_result_eq[OF \h \ get_parent node_ptr \\<^sub>r Some parent\] returns_result_eq[OF \h \ get_shadow_root host \\<^sub>r Some shadow_root_ptr\] simp add: assigned_slot_def a_find_slot_def returns_result_heap_def elim!: bind_returns_result_E2 split: option.splits split: if_splits) qed next case False then show ?thesis using assms(4) by(auto dest!: returns_result_eq[OF \h \ get_parent node_ptr \\<^sub>r Some parent\] simp add: assigned_slot_def a_find_slot_def returns_result_heap_def elim!: bind_returns_result_E2 split: option.splits split: if_splits) qed qed then show ?thesis using \h = h'\ by(auto simp add: is_strongly_dom_component_safe_def preserved_def) qed lemma assigned_nodes_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ assigned_nodes element_ptr \\<^sub>r nodes" assumes "node_ptr \ set nodes" shows "set |h \ get_component (cast element_ptr)|\<^sub>r \ set |h \ get_component (cast node_ptr)|\<^sub>r = {}" proof - have "h \ find_slot False node_ptr \\<^sub>r Some element_ptr" using assms(4) assms(5) by(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2 dest!: filter_M_holds_for_result[where x=node_ptr] intro!: bind_pure_I split: if_splits) then show ?thesis using assms find_slot_is_component_unsafe by blast qed lemma flatten_dom_assigned_nodes_become_children: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ flatten_dom \\<^sub>h h'" assumes "h \ assigned_nodes slot \\<^sub>r nodes" assumes "nodes \ []" shows "h' \ get_child_nodes (cast slot) \\<^sub>r nodes" proof - obtain tups h2 element_ptrs shadow_root_ptrs where "h \ element_ptr_kinds_M \\<^sub>r element_ptrs" and tups: "h \ map_filter_M2 (\element_ptr. do { tag \ get_tag_name element_ptr; assigned_nodes \ assigned_nodes element_ptr; (if tag = ''slot'' \ assigned_nodes \ [] then return (Some (element_ptr, assigned_nodes)) else return None)}) element_ptrs \\<^sub>r tups" (is "h \ map_filter_M2 ?f element_ptrs \\<^sub>r tups") and h2: "h \ forall_M (\(slot, assigned_nodes). do { get_child_nodes (cast slot) \ forall_M remove; forall_M (append_child (cast slot)) assigned_nodes }) tups \\<^sub>h h2" and "h2 \ shadow_root_ptr_kinds_M \\<^sub>r shadow_root_ptrs" and h': "h2 \ forall_M (\shadow_root_ptr. do { host \ get_host shadow_root_ptr; get_child_nodes (cast host) \ forall_M remove; get_child_nodes (cast shadow_root_ptr) \ forall_M (append_child (cast host)); remove_shadow_root host }) shadow_root_ptrs \\<^sub>h h'" using \h \ flatten_dom \\<^sub>h h'\ apply(auto simp add: flatten_dom_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF ElementMonad.ptr_kinds_M_pure, rotated] bind_returns_heap_E2[rotated, OF ShadowRootMonad.ptr_kinds_M_pure, rotated])[1] apply(drule pure_returns_heap_eq) by(auto intro!: map_filter_M2_pure bind_pure_I) have all_tups_slot: "\slot assigned_nodes. (slot, assigned_nodes) \ set tups \ h \ get_tag_name slot \\<^sub>r ''slot''" using tups apply(induct element_ptrs arbitrary: tups) by(auto elim!: bind_returns_result_E2 split: if_splits intro!: map_filter_M2_pure bind_pure_I) have "distinct element_ptrs" using \h \ element_ptr_kinds_M \\<^sub>r element_ptrs\ by auto then have "distinct tups" using tups apply(induct element_ptrs arbitrary: tups) by(auto elim!: bind_returns_result_E2 intro!: map_filter_M2_pure bind_pure_I split: option.splits if_splits intro: map_filter_pure_foo[rotated] ) have "slot \ set element_ptrs" using assms(5) assigned_nodes_ptr_in_heap \h \ element_ptr_kinds_M \\<^sub>r element_ptrs\ by auto then have "(slot, nodes) \ set tups" apply(rule map_filter_M2_in_result[OF tups]) apply(auto intro!: bind_pure_I)[1] apply(intro bind_pure_returns_result_I) using assms assigned_nodes_slot_is_slot by(auto intro!: bind_pure_returns_result_I) have "\slot nodes. (slot, nodes) \ set tups \ h \ assigned_nodes slot \\<^sub>r nodes" using tups apply(induct element_ptrs arbitrary: tups) by(auto elim!: bind_returns_result_E2 intro!: map_filter_M2_pure bind_pure_I split: if_splits) then have elementwise_eq: "\slot slot' nodes nodes'. (slot, nodes) \ set tups \ (slot', nodes') \ set tups \ slot = slot' \ nodes = nodes'" by (meson returns_result_eq) have "\slot nodes. (slot, nodes) \ set tups \ distinct nodes" using \\slot nodes. (slot, nodes) \ set tups \ h \ assigned_nodes slot \\<^sub>r nodes\ assigned_nodes_distinct using assms(1) by blast have "\slot slot' nodes nodes'. (slot, nodes) \ set tups \ (slot', nodes') \ set tups \ slot \ slot' \ set nodes \ set nodes' = {}" using \\slot nodes. (slot, nodes) \ set tups \ h \ assigned_nodes slot \\<^sub>r nodes\ assigned_nodes_different_ptr assms(1) assms(2) assms(3) by blast have "h \ get_tag_name slot \\<^sub>r ''slot''" using \(slot, nodes) \ set tups\ all_tups_slot by blast then have "h2 \ get_tag_name slot \\<^sub>r ''slot''" using h2 proof(induct tups arbitrary: h, simp) case (Cons x xs) obtain xc ha hb slot' nodes' where "x = (slot', nodes')" and "h \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \\<^sub>r xc" and ha: "h \ forall_M remove xc \\<^sub>h ha" and hb: "ha \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \\<^sub>h hb" and remainder: "hb \ forall_M (\(slot, assigned_nodes). Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) (\x. Heap_Error_Monad.bind (forall_M remove x) (\_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) xs \\<^sub>h h2" using Cons(3) by (auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated] bind_returns_result_E bind_returns_result_E2[rotated, OF get_child_nodes_pure, rotated] split: prod.splits) have "ha \ get_tag_name slot \\<^sub>r ''slot''" using \h \ get_tag_name slot \\<^sub>r ''slot''\ ha proof(induct xc arbitrary: h, simp) case (Cons a yc) obtain hb1 where hb1: "h \ remove a \\<^sub>h hb1" and hba: "hb1 \ forall_M remove yc \\<^sub>h ha" using Cons by (auto elim!: bind_returns_heap_E) have "hb1 \ get_tag_name slot \\<^sub>r ''slot''" using \h \ get_tag_name slot \\<^sub>r ''slot''\ hb1 by(auto simp add: remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads remove_writes]) then show ?case using hba Cons(1) by simp qed then have "hb \ get_tag_name slot \\<^sub>r ''slot''" using hb proof (induct nodes' arbitrary: ha, simp) case (Cons a nodes') obtain ha1 where ha1: "ha \ append_child (cast slot') a \\<^sub>h ha1" and hb: "ha1 \ forall_M (append_child (cast slot')) nodes' \\<^sub>h hb" using Cons by (auto elim!: bind_returns_heap_E) have "ha1 \ get_tag_name slot \\<^sub>r ''slot''" using \ha \ get_tag_name slot \\<^sub>r ''slot''\ ha1 by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads insert_before_writes] split: if_splits) then show ?case using ha1 hb Cons(1) by simp qed then show ?case using Cons(1) remainder by simp qed have "h2 \ get_child_nodes (cast slot) \\<^sub>r nodes \ heap_is_wellformed h2 \ type_wf h2 \ known_ptrs h2" using \(slot, nodes) \ set tups\ using h2 assms(1) assms(2) assms(3) \distinct tups\ all_tups_slot elementwise_eq using \\slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \ set tups \ (slot', nodes') \ set tups \ slot \ slot' \ set assigned_nodes \ set nodes' = {}\ using \\slot assigned_nodes. (slot, assigned_nodes) \ set tups \ distinct assigned_nodes\ proof(induct tups arbitrary: h, simp) case (Cons x xs) obtain xc ha hb slot' nodes' where "x = (slot', nodes')" and "h \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \\<^sub>r xc" and ha: "h \ forall_M remove xc \\<^sub>h ha" and hb: "ha \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \\<^sub>h hb" and remainder: "hb \ forall_M (\(slot, assigned_nodes). Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) (\x. Heap_Error_Monad.bind (forall_M remove x) (\_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) xs \\<^sub>h h2" using Cons(3) by (auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated] bind_returns_result_E bind_returns_result_E2[rotated, OF get_child_nodes_pure, rotated] split: prod.splits) have "\slot assigned_nodes. (slot, assigned_nodes) \ set xs \ h \ get_tag_name slot \\<^sub>r ''slot''" using Cons by auto have "heap_is_wellformed ha" and "type_wf ha" and "known_ptrs ha" using Cons(4) Cons(5) Cons(6) \h \ forall_M remove xc \\<^sub>h ha\ apply(induct xc arbitrary: h) apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] apply (meson local.remove_child_heap_is_wellformed_preserved local.remove_child_preserves_known_ptrs local.remove_child_preserves_type_wf) apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] apply (meson local.remove_child_heap_is_wellformed_preserved local.remove_child_preserves_known_ptrs local.remove_child_preserves_type_wf) apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] simp add: remove_def split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply metis done then have "heap_is_wellformed hb" and "type_wf hb" and "known_ptrs hb" using \ha \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \\<^sub>h hb\ apply(induct nodes' arbitrary: ha) apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply (metis insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs) apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply (metis insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs) apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1] apply (metis insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs) done { fix slot assigned_nodes assume "(slot, assigned_nodes) \ set xs" then have "h \ get_tag_name slot \\<^sub>r ''slot''" using \\slot assigned_nodes. (slot, assigned_nodes) \ set xs \ h \ get_tag_name slot \\<^sub>r ''slot''\ by auto then have "ha \ get_tag_name slot \\<^sub>r ''slot''" using \h \ forall_M remove xc \\<^sub>h ha\ apply(induct xc arbitrary: h) by(auto simp add: remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads remove_writes] elim!: bind_returns_heap_E) then have "hb \ get_tag_name slot \\<^sub>r ''slot''" using \ha \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \\<^sub>h hb\ apply(induct nodes' arbitrary: ha) by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads insert_before_writes] elim!: bind_returns_heap_E split: if_splits) } note tag_names_same = this show ?case proof(cases "slot' = slot") case True then have "nodes' = nodes" using Cons.prems(1) Cons.prems(8) \x = (slot', nodes')\ by (metis list.set_intros(1)) then have "(slot, nodes) \ set xs" using Cons.prems(6) True \x = (slot', nodes')\ by auto have "ha \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r []" using remove_for_all_empty_children Cons.prems(3) Cons.prems(4) Cons.prems(5) True \h \ forall_M remove xc \\<^sub>h ha\ using \h \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \\<^sub>r xc\ by blast then have "hb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" using append_child_for_all_on_no_children[OF \heap_is_wellformed hb\ \type_wf hb\ \known_ptrs hb\] True \nodes' = nodes\ using \ha \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \\<^sub>h hb\ using \(slot, nodes) \ set tups\ \\slot assigned_nodes. (slot, assigned_nodes) \ set tups \ distinct assigned_nodes\ \heap_is_wellformed ha\ \known_ptrs ha\ \type_wf ha\ local.append_child_for_all_on_no_children by blast with \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ show ?thesis using \(slot, nodes) \ set xs\ remainder using \\slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \ set (x#xs) \ (slot', nodes') \ set (x#xs) \ slot = slot' \ assigned_nodes = nodes'\ using \(slot, nodes) \ set (x # xs)\ using \\slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \ set (x#xs) \ (slot', nodes') \ set (x#xs) \ slot \ slot' \ set assigned_nodes \ set nodes' = {}\ proof(induct xs arbitrary: hb, simp) case (Cons y ys) obtain yc hba hbb slot'' nodes'' where "y = (slot'', nodes'')" and "hb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \\<^sub>r yc" and "hb \ forall_M remove yc \\<^sub>h hba" and "hba \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \\<^sub>h hbb" and remainder: "hbb \ forall_M (\(slot, assigned_nodes). Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) (\x. Heap_Error_Monad.bind (forall_M remove x) (\_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) ys \\<^sub>h h2" using Cons(7) by (auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated] split: prod.splits) have "slot \ slot''" by (metis Cons.prems(5) Cons.prems(7) Cons.prems(8) \y = (slot'', nodes'')\ list.set_intros(1) list.set_intros(2)) then have "set nodes \ set nodes'' = {}" by (metis Cons.prems(8) Cons.prems(9) \y = (slot'', nodes'')\ list.set_intros(1) list.set_intros(2)) have "hba \ get_child_nodes (cast slot) \\<^sub>r nodes \ heap_is_wellformed hba \ type_wf hba \ known_ptrs hba" using \hb \ get_child_nodes (cast slot) \\<^sub>r nodes\ using \hb \ forall_M remove yc \\<^sub>h hba\ using \hb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \\<^sub>r yc\ using \heap_is_wellformed hb\ \type_wf hb\ \known_ptrs hb\ proof(induct yc arbitrary: hb, simp) case (Cons a yc) obtain hb1 where hb1: "hb \ remove a \\<^sub>h hb1" and hba: "hb1 \ forall_M remove yc \\<^sub>h hba" using Cons by (auto elim!: bind_returns_heap_E) have "hb \ get_parent a \\<^sub>r Some (cast slot'')" using Cons.prems(3) Cons.prems(4) Cons.prems(5) Cons.prems(6) local.child_parent_dual by auto moreover have "heap_is_wellformed hb1" and "type_wf hb1" and "known_ptrs hb1" using \hb \ remove a \\<^sub>h hb1\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast using \hb \ remove a \\<^sub>h hb1\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast using \hb \ remove a \\<^sub>h hb1\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast using \heap_is_wellformed hb\ and \type_wf hb\ and \known_ptrs hb\ remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply blast done moreover have "hb1 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \\<^sub>r yc" using \hb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \\<^sub>r a # yc\ hb1 using remove_removes_child \heap_is_wellformed hb\ \type_wf hb\ \known_ptrs hb\ by simp moreover have "hb1 \ get_child_nodes (cast slot) \\<^sub>r nodes" using Cons(2) hb1 set_child_nodes_get_child_nodes_different_pointers \hb \ get_parent a \\<^sub>r Some (cast slot'')\ \slot \ slot''\ apply(auto simp add: remove_child_locs_def elim!: bind_returns_heap_E dest!: reads_writes_separate_forwards[OF get_child_nodes_reads remove_writes])[1] by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject) ultimately show ?thesis using \hb1 \ forall_M remove (yc) \\<^sub>h hba\ Cons by auto qed then have "hbb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes \ heap_is_wellformed hbb \ type_wf hbb \ known_ptrs hbb" using \hba \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \\<^sub>h hbb\ using \set nodes \ set nodes'' = {}\ proof(induct nodes'' arbitrary: hba, simp) case (Cons a nodes'') then have "hba \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" and "heap_is_wellformed hba" and "type_wf hba" and "known_ptrs hba" by auto obtain hba1 where hba1: "hba \ append_child (cast slot'') a \\<^sub>h hba1" and "hba1 \ forall_M (append_child (cast slot'')) nodes'' \\<^sub>h hbb" using Cons(3) by (auto elim!: bind_returns_heap_E) have "heap_is_wellformed hba1" and "type_wf hba1" and "known_ptrs hba1" using \hba \ append_child (cast slot'') a \\<^sub>h hba1\ apply(auto simp add: append_child_def)[1] using \heap_is_wellformed hba\ and \type_wf hba\ and \known_ptrs hba\ insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply blast using \hba \ append_child (cast slot'') a \\<^sub>h hba1\ apply(auto simp add: append_child_def)[1] using \heap_is_wellformed hba\ and \type_wf hba\ and \known_ptrs hba\ insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply blast using \hba \ append_child (cast slot'') a \\<^sub>h hba1\ apply(auto simp add: append_child_def)[1] using \heap_is_wellformed hba\ and \type_wf hba\ and \known_ptrs hba\ insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply blast done moreover have "a \ set nodes" using \set nodes \ set (a # nodes'') = {}\ by auto moreover obtain parent_opt where "hba \ get_parent a \\<^sub>r parent_opt" using insert_before_child_in_heap hba1 get_parent_ok unfolding append_child_def by (meson Cons.prems(1) is_OK_returns_heap_I is_OK_returns_result_E) then have "hba1 \ get_child_nodes (cast slot) \\<^sub>r nodes" proof (induct parent_opt) case None then show ?case using \hba \ append_child (cast slot'') a \\<^sub>h hba1\ using \hba \ get_child_nodes (cast slot) \\<^sub>r nodes\ using \slot \ slot''\ apply(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def elim!: reads_writes_separate_forwards[OF get_child_nodes_reads insert_before_writes])[1] by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject set_child_nodes_get_child_nodes_different_pointers) next case (Some parent) have "parent \ cast slot" apply(rule ccontr, simp) using Cons(2) apply - apply(rule get_parent_child_dual[OF \hba \ get_parent a \\<^sub>r Some parent\]) apply(auto)[1] using \a \ set nodes\ returns_result_eq by fastforce show ?case apply(rule reads_writes_separate_forwards) apply(fact get_child_nodes_reads) apply(fact insert_before_writes) apply(fact \hba \ append_child (cast slot'') a \\<^sub>h hba1\[unfolded append_child_def]) apply(fact \hba \ get_child_nodes (cast slot) \\<^sub>r nodes\) using \hba \ get_parent a \\<^sub>r Some parent\ \parent \ cast slot\ \slot \ slot''\ apply(auto simp add: insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def)[1] apply (simp_all add: set_child_nodes_get_child_nodes_different_pointers set_disconnected_nodes_get_child_nodes) by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject set_child_nodes_get_child_nodes_different_pointers) qed moreover have "set nodes \ set nodes'' = {}" using Cons.prems(3) by auto ultimately show ?case using Cons.hyps \hba1 \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \\<^sub>h hbb\ by blast qed show ?case apply(rule Cons(1)) using \hbb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes \ heap_is_wellformed hbb \ type_wf hbb \ known_ptrs hbb\ apply(auto)[1] using \hbb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes \ heap_is_wellformed hbb \ type_wf hbb \ known_ptrs hbb\ apply(auto)[1] using \hbb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes \ heap_is_wellformed hbb \ type_wf hbb \ known_ptrs hbb\ apply(auto)[1] using \hbb \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes \ heap_is_wellformed hbb \ type_wf hbb \ known_ptrs hbb\ apply(auto)[1] using Cons.prems(5) apply auto[1] apply (simp add: remainder) using Cons.prems(7) apply auto[1] apply (simp add: True \nodes' = nodes\ \x = (slot', nodes')\) by (metis Cons.prems(9) insert_iff list.simps(15)) qed next case False then have "nodes' \ nodes" using Cons.prems(1) Cons.prems(9) \x = (slot', nodes')\ by (metis assms(6) inf.idem list.set_intros(1) set_empty2) then have "(slot, nodes) \ set xs" using Cons.prems(1) \x = (slot', nodes')\ by auto then show ?thesis using Cons(1)[simplified, OF \(slot, nodes) \ set xs\ remainder \heap_is_wellformed hb\ \type_wf hb\ \known_ptrs hb\] using Cons.prems(6) tag_names_same Cons.prems(8) Cons.prems(9) by (smt Cons.prems(10) distinct.simps(2) list.set_intros(2)) qed qed then show ?thesis using h' \h2 \ get_tag_name slot \\<^sub>r ''slot''\ proof(induct shadow_root_ptrs arbitrary: h2, simp) case (Cons shadow_root_ptr shadow_root_ptrs) then have "h2 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" and "heap_is_wellformed h2" and "type_wf h2" and "known_ptrs h2" by auto obtain host h2a h2b h2c host_children shadow_root_children where "h2 \ get_host shadow_root_ptr \\<^sub>r host" and "h2 \ get_child_nodes (cast host) \\<^sub>r host_children" and h2a: "h2 \ forall_M remove host_children \\<^sub>h h2a" and "h2a \ get_child_nodes (cast shadow_root_ptr) \\<^sub>r shadow_root_children" and h2b: "h2a \ forall_M (append_child (cast host)) shadow_root_children \\<^sub>h h2b" and "h2b \ remove_shadow_root host \\<^sub>h h2c" and remainder: "h2c \ forall_M(\shadow_root_ptr. Heap_Error_Monad.bind (get_host shadow_root_ptr) (\host. Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) (\x. Heap_Error_Monad.bind (forall_M remove x) (\_. Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr)) (\x. Heap_Error_Monad.bind (forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) x) (\_. remove_shadow_root host)))))) shadow_root_ptrs \\<^sub>h h'" using Cons(3) by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_host_pure, rotated] bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]) have "h2 \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" using \h2 \ get_host shadow_root_ptr \\<^sub>r host\ shadow_root_host_dual using \heap_is_wellformed h2\ \type_wf h2\ by blast then have "h2a \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" using \h2 \ forall_M remove host_children \\<^sub>h h2a\ apply(induct host_children arbitrary: h2) by(auto simp add: set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root remove_child_locs_def elim!: bind_returns_heap_E dest!: reads_writes_separate_forwards[OF get_shadow_root_reads remove_writes]) then have "h2b \ get_shadow_root host \\<^sub>r Some shadow_root_ptr" using \h2a \ forall_M (append_child (cast host)) shadow_root_children \\<^sub>h h2b\ apply(induct shadow_root_children arbitrary: h2a) by(auto simp add: set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def elim!: bind_returns_heap_E dest!: reads_writes_separate_forwards[OF get_shadow_root_reads insert_before_writes] split: if_splits) have "host \ slot" proof (rule ccontr, simp) assume "host = slot" show False using get_host_valid_tag_name[OF \heap_is_wellformed h2\ \type_wf h2\ \h2 \ get_host shadow_root_ptr \\<^sub>r host\[unfolded \host = slot\] \h2 \ get_tag_name slot \\<^sub>r ''slot''\] by(simp) qed have "heap_is_wellformed h2a" and "type_wf h2a" and "known_ptrs h2a" using \heap_is_wellformed h2\ and \type_wf h2\ and \known_ptrs h2\ \h2 \ forall_M remove host_children \\<^sub>h h2a\ apply(induct host_children arbitrary: h2) apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply metis apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply metis apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply metis done then have "heap_is_wellformed h2b" and "type_wf h2b" and "known_ptrs h2b" using \h2a \ forall_M (append_child (cast host)) shadow_root_children \\<^sub>h h2b\ apply(induct shadow_root_children arbitrary: h2a) apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis done then have "heap_is_wellformed h2c" and "type_wf h2c" and "known_ptrs h2c" using remove_shadow_root_preserves \h2b \ remove_shadow_root host \\<^sub>h h2c\ by blast+ moreover have "h2a \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" using \h2 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes\ using \h2 \ forall_M remove host_children \\<^sub>h h2a\ using \h2 \ get_child_nodes (cast host) \\<^sub>r host_children\ using \heap_is_wellformed h2\ \type_wf h2\ \known_ptrs h2\ proof (induct host_children arbitrary: h2, simp) case (Cons a host_children) obtain h21 where "h2 \ remove a \\<^sub>h h21" and "h21 \ forall_M remove host_children \\<^sub>h h2a" using Cons(3) by(auto elim!: bind_returns_heap_E) have "heap_is_wellformed h21" and "type_wf h21" and "known_ptrs h21" using \heap_is_wellformed h2\ and \type_wf h2\ and \known_ptrs h2\ \h2 \ remove a \\<^sub>h h21\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply (metis) using \heap_is_wellformed h2\ and \type_wf h2\ and \known_ptrs h2\ \h2 \ remove a \\<^sub>h h21\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply (metis) using \heap_is_wellformed h2\ and \type_wf h2\ and \known_ptrs h2\ \h2 \ remove a \\<^sub>h h21\ apply(auto simp add: remove_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1] using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs apply (metis) done have "h2 \ get_parent a \\<^sub>r Some (cast host)" using \h2 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \\<^sub>r a # host_children\ using \heap_is_wellformed h2\ \type_wf h2\ \known_ptrs h2\ child_parent_dual using heap_is_wellformed_def by auto then have "h21 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" using \h2 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes\ \host \ slot\ using \h2 \ remove a \\<^sub>h h21\ apply(auto simp add: remove_child_locs_def set_disconnected_nodes_get_child_nodes dest!: reads_writes_preserved[OF get_child_nodes_reads remove_writes])[1] by (meson cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject set_child_nodes_get_child_nodes_different_pointers) moreover have "h21 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \\<^sub>r host_children" using \h2 \ remove a \\<^sub>h h21\ remove_removes_child[OF \heap_is_wellformed h2\ \type_wf h2\ \known_ptrs h2\ \h2 \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \\<^sub>r a # host_children\] by blast ultimately show ?case using \heap_is_wellformed h21\ and \type_wf h21\ and \known_ptrs h21\ \h21 \ forall_M remove host_children \\<^sub>h h2a\ Cons(1) using Cons.prems(3) Cons.prems(4) Cons.prems(5) Cons.prems(6) heap_is_wellformed_def \h2 \ remove a \\<^sub>h h21\ remove_removes_child by blast qed then have "h2b \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" using \h2a \ forall_M (append_child (cast host)) shadow_root_children \\<^sub>h h2b\ using \h2a \ get_child_nodes (cast shadow_root_ptr) \\<^sub>r shadow_root_children\ using \heap_is_wellformed h2a\ \type_wf h2a\ \known_ptrs h2a\ proof(induct shadow_root_children arbitrary: h2a, simp) case (Cons a shadow_root_children) obtain h2a1 where "h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1" and "h2a1 \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) (shadow_root_children) \\<^sub>h h2b" using Cons(3) by(auto elim!: bind_returns_heap_E) have "heap_is_wellformed h2a1" and "type_wf h2a1" and "known_ptrs h2a1" using \heap_is_wellformed h2a\ and \type_wf h2a\ and \known_ptrs h2a\ \h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1\ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis using \heap_is_wellformed h2a\ and \type_wf h2a\ and \known_ptrs h2a\ \h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1\ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis using \heap_is_wellformed h2a\ and \type_wf h2a\ and \known_ptrs h2a\ \h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1\ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1] using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs apply metis done moreover have "h2a1 \ get_child_nodes (cast shadow_root_ptr) \\<^sub>r shadow_root_children" using \h2a \ get_child_nodes (cast shadow_root_ptr) \\<^sub>r a # shadow_root_children\ using insert_before_removes_child \h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1\[unfolded append_child_def] using \heap_is_wellformed h2a\ \type_wf h2a\ \known_ptrs h2a\ using cast_document_ptr_not_node_ptr(2) using cast_shadow_root_ptr_not_node_ptr(2) by blast moreover have "h2a \ get_parent a \\<^sub>r Some (cast shadow_root_ptr)" using \h2a \ get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \\<^sub>r a # shadow_root_children\ using \heap_is_wellformed h2a\ \type_wf h2a\ \known_ptrs h2a\ child_parent_dual using heap_is_wellformed_def by auto then have "h2a1 \ get_child_nodes (cast slot) \\<^sub>r nodes" using \h2a \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes\ using \h2a \ append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \\<^sub>h h2a1\ \host \ slot\ apply(auto simp add: set_disconnected_nodes_get_child_nodes append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def elim!: bind_returns_heap_E dest!: reads_writes_preserved[OF get_child_nodes_reads insert_before_writes])[1] using set_child_nodes_get_child_nodes_different_pointers cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast_document_ptr_not_node_ptr(2) by (metis cast_shadow_root_ptr_not_node_ptr(2))+ ultimately show ?case using Cons(1) \h2a1 \ forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) shadow_root_children \\<^sub>h h2b\ by blast qed then have "h2c \ get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \\<^sub>r nodes" using \h2b \ remove_shadow_root host \\<^sub>h h2c\ apply(auto simp add: remove_shadow_root_get_child_nodes_different_pointers dest!: reads_writes_separate_forwards[OF get_child_nodes_reads remove_shadow_root_writes])[1] by (meson cast_shadow_root_ptr_not_node_ptr(2) local.remove_shadow_root_get_child_nodes_different_pointers) moreover have "h2a \ get_tag_name slot \\<^sub>r ''slot''" using h2a \h2 \ get_tag_name slot \\<^sub>r ''slot''\ apply(induct host_children arbitrary: h2) by(auto simp add: remove_child_locs_def set_disconnected_nodes_get_tag_name set_child_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads remove_writes] elim!: bind_returns_heap_E) then have "h2b \ get_tag_name slot \\<^sub>r ''slot''" using h2b apply(induct shadow_root_children arbitrary: h2a) by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def adopt_node_locs_def remove_child_locs_def set_disconnected_nodes_get_tag_name set_child_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads insert_before_writes] elim!: bind_returns_heap_E split: if_splits) then have "h2c \ get_tag_name slot \\<^sub>r ''slot''" using \h2b \ remove_shadow_root host \\<^sub>h h2c\ by(auto simp add: remove_shadow_root_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads remove_shadow_root_writes]) ultimately show ?case using Cons(1) remainder by auto qed qed end interpretation i_assigned_nodes_component?: l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_tag_name get_tag_name_locs known_ptr get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs get_parent get_parent_locs get_mode get_mode_locs get_attribute get_attribute_locs first_in_tree_order find_slot assigned_slot known_ptrs to_tree_order assigned_nodes assigned_nodes_flatten flatten_dom get_root_node get_root_node_locs remove insert_before insert_before_locs append_child remove_shadow_root remove_shadow_root_locs set_shadow_root set_shadow_root_locs remove_child remove_child_locs get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name get_owner_document set_disconnected_nodes set_disconnected_nodes_locs adopt_node adopt_node_locs set_child_nodes set_child_nodes_locs by(auto simp add: l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] subsubsection \get\_owner\_document\ locale l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M begin lemma get_owner_document_is_component_unsafe: assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" assumes "h \ get_owner_document ptr \\<^sub>r owner_document" assumes "\is_document_ptr_kind |h \ get_root_node ptr|\<^sub>r" shows "set |h \ get_component ptr|\<^sub>r \ set |h \ get_component (cast owner_document)|\<^sub>r = {}" proof - have "owner_document |\| document_ptr_kinds h" using assms(1) assms(2) assms(3) assms(4) get_owner_document_owner_document_in_heap by blast have "ptr |\| object_ptr_kinds h" by (meson assms(4) is_OK_returns_result_I local.get_owner_document_ptr_in_heap) obtain root where root: "h \ get_root_node ptr \\<^sub>r root" by (meson assms(1) assms(2) assms(3) assms(4) is_OK_returns_result_I local.get_owner_document_ptr_in_heap local.get_root_node_ok returns_result_select_result) then obtain to where to: "h \ to_tree_order root \\<^sub>r to" by (meson assms(1) assms(2) assms(3) is_OK_returns_result_E local.get_root_node_root_in_heap local.to_tree_order_ok) then have "\p \ set to. \is_document_ptr_kind p" by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(5) document_ptr_casts_commute3 local.to_tree_order_node_ptrs node_ptr_no_document_ptr_cast root select_result_I2) then have "cast owner_document \ set |h \ get_component ptr|\<^sub>r" by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(5) document_ptr_document_ptr_cast is_OK_returns_result_I l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_component_ok local.get_component_root_node_same local.get_root_node_not_node_same local.get_root_node_ptr_in_heap local.l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_no_document_ptr_cast returns_result_select_result root select_result_I2) then have "|h \ get_component ptr|\<^sub>r \ |h \ get_component (cast owner_document)|\<^sub>r" by (metis (no_types, lifting) \owner_document |\| document_ptr_kinds h\ assms(1) assms(2) assms(3) document_ptr_kinds_commutes l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_component_ok local.get_dom_component_ptr local.l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms returns_result_select_result) then show ?thesis by (meson \owner_document |\| document_ptr_kinds h\ \ptr |\| object_ptr_kinds h\ assms(1) assms(2) assms(3) document_ptr_kinds_commutes l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_no_overlap l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_component_ok local.l_get_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms returns_result_select_result) qed end interpretation i_get_owner_document_component?: l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs known_ptr get_child_nodes get_child_nodes_locs DocumentClass.known_ptr get_parent get_parent_locs get_root_node_si get_root_node_si_locs CD.a_get_owner_document get_host get_host_locs get_owner_document get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document get_disconnected_document_locs known_ptrs get_ancestors_si get_ancestors_si_locs to_tree_order get_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name by(auto simp add: l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances) declare l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances] definition is_shadow_root_component :: "(_) object_ptr list \ bool" where "is_shadow_root_component c = is_shadow_root_ptr_kind (hd c)" end