Theory HRBSlice

section ‹Horwitz-Reps-Binkley Slice›

theory HRBSlice imports SDG begin

context SDG begin

subsection ‹Set describing phase 1 of the two-phase slicer›

inductive_set sum_SDG_slice1 :: "'node SDG_node ⇒ 'node SDG_node set"
  for n::"'node SDG_node"
  where refl_slice1:"valid_SDG_node n ⟹ n ∈ sum_SDG_slice1 n"
  | cdep_slice1:
  "⟦n'' s⟶cd n'; n' ∈ sum_SDG_slice1 n⟧ ⟹ n'' ∈ sum_SDG_slice1 n"
  | ddep_slice1: 
  "⟦n'' s-V→dd n'; n' ∈ sum_SDG_slice1 n⟧ ⟹ n'' ∈ sum_SDG_slice1 n"
  | call_slice1:
  "⟦n'' s-p→call n'; n' ∈ sum_SDG_slice1 n⟧ ⟹ n'' ∈ sum_SDG_slice1 n"
  | param_in_slice1: 
  "⟦n'' s-p:V→in n'; n' ∈ sum_SDG_slice1 n⟧ ⟹ n'' ∈ sum_SDG_slice1 n"
  | sum_slice1:
  "⟦n'' s-p→sum n'; n' ∈ sum_SDG_slice1 n⟧ ⟹ n'' ∈ sum_SDG_slice1 n"


lemma slice1_cdep_slice1:
  "⟦nx ∈ sum_SDG_slice1 n; n s⟶cd n'⟧ ⟹ nx ∈ sum_SDG_slice1 n'"
by(induct rule:sum_SDG_slice1.induct,
   auto intro:sum_SDG_slice1.intros sum_SDG_edge_valid_SDG_node)

lemma slice1_ddep_slice1:
  "⟦nx ∈ sum_SDG_slice1 n; n s-V→dd n'⟧ ⟹ nx ∈ sum_SDG_slice1 n'"
by(induct rule:sum_SDG_slice1.induct,
   auto intro:sum_SDG_slice1.intros sum_SDG_edge_valid_SDG_node)

lemma slice1_sum_slice1:
  "⟦nx ∈ sum_SDG_slice1 n; n s-p→sum n'⟧ ⟹ nx ∈ sum_SDG_slice1 n'"
by(induct rule:sum_SDG_slice1.induct,
   auto intro:sum_SDG_slice1.intros sum_SDG_edge_valid_SDG_node)

lemma slice1_call_slice1:
  "⟦nx ∈ sum_SDG_slice1 n; n s-p→call n'⟧ ⟹ nx ∈ sum_SDG_slice1 n'"
by(induct rule:sum_SDG_slice1.induct,
   auto intro:sum_SDG_slice1.intros sum_SDG_edge_valid_SDG_node)

lemma slice1_param_in_slice1:
  "⟦nx ∈ sum_SDG_slice1 n; n s-p:V→in n'⟧ ⟹ nx ∈ sum_SDG_slice1 n'"
by(induct rule:sum_SDG_slice1.induct,
   auto intro:sum_SDG_slice1.intros sum_SDG_edge_valid_SDG_node)


lemma is_SDG_path_slice1:
  "⟦n is-ns→d* n'; n' ∈ sum_SDG_slice1 n''⟧ ⟹ n ∈ sum_SDG_slice1 n''"
proof(induct rule:intra_sum_SDG_path.induct)
  case isSp_Nil thus ?case by simp
next
  case (isSp_Append_cdep n ns nx n')
  note IH = ‹nx ∈ sum_SDG_slice1 n'' ⟹ n ∈ sum_SDG_slice1 n''›
  from ‹nx s⟶cd n'› ‹n' ∈ sum_SDG_slice1 n''›
  have "nx ∈ sum_SDG_slice1 n''" by(rule cdep_slice1)
  from IH[OF this] show ?case .
next
  case (isSp_Append_ddep n ns nx V n')
  note IH = ‹nx ∈ sum_SDG_slice1 n'' ⟹ n ∈ sum_SDG_slice1 n''›
  from ‹nx s-V→dd n'› ‹n' ∈ sum_SDG_slice1 n''›
  have "nx ∈ sum_SDG_slice1 n''" by(rule ddep_slice1)
  from IH[OF this] show ?case .
next
  case (isSp_Append_sum n ns nx p n')
  note IH = ‹nx ∈ sum_SDG_slice1 n'' ⟹ n ∈ sum_SDG_slice1 n''›
  from ‹nx s-p→sum n'› ‹n' ∈ sum_SDG_slice1 n''›
  have "nx ∈ sum_SDG_slice1 n''" by(rule sum_slice1)
  from IH[OF this] show ?case .
qed


subsection ‹Set describing phase 2 of the two-phase slicer›

inductive_set sum_SDG_slice2 :: "'node SDG_node ⇒ 'node SDG_node set"
  for n::"'node SDG_node"
  where refl_slice2:"valid_SDG_node n ⟹ n ∈ sum_SDG_slice2 n"
  | cdep_slice2:
  "⟦n'' s⟶cd n'; n' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n"
  | ddep_slice2: 
  "⟦n'' s-V→dd n'; n' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n"
  | return_slice2:
  "⟦n'' s-p→ret n'; n' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n"
  | param_out_slice2: 
  "⟦n'' s-p:V→out n'; n' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n"
  | sum_slice2:
  "⟦n'' s-p→sum n'; n' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n"


lemma slice2_cdep_slice2:
  "⟦nx ∈ sum_SDG_slice2 n; n s⟶cd n'⟧ ⟹ nx ∈ sum_SDG_slice2 n'"
by(induct rule:sum_SDG_slice2.induct,
   auto intro:sum_SDG_slice2.intros sum_SDG_edge_valid_SDG_node)

lemma slice2_ddep_slice2:
  "⟦nx ∈ sum_SDG_slice2 n; n s-V→dd n'⟧ ⟹ nx ∈ sum_SDG_slice2 n'"
by(induct rule:sum_SDG_slice2.induct,
   auto intro:sum_SDG_slice2.intros sum_SDG_edge_valid_SDG_node)

lemma slice2_sum_slice2:
  "⟦nx ∈ sum_SDG_slice2 n; n s-p→sum n'⟧ ⟹ nx ∈ sum_SDG_slice2 n'"
by(induct rule:sum_SDG_slice2.induct,
   auto intro:sum_SDG_slice2.intros sum_SDG_edge_valid_SDG_node)

lemma slice2_ret_slice2:
  "⟦nx ∈ sum_SDG_slice2 n; n s-p→ret n'⟧ ⟹ nx ∈ sum_SDG_slice2 n'"
by(induct rule:sum_SDG_slice2.induct,
   auto intro:sum_SDG_slice2.intros sum_SDG_edge_valid_SDG_node)

lemma slice2_param_out_slice2:
  "⟦nx ∈ sum_SDG_slice2 n; n s-p:V→out n'⟧ ⟹ nx ∈ sum_SDG_slice2 n'"
by(induct rule:sum_SDG_slice2.induct,
   auto intro:sum_SDG_slice2.intros sum_SDG_edge_valid_SDG_node)


lemma is_SDG_path_slice2:
  "⟦n is-ns→d* n'; n' ∈ sum_SDG_slice2 n''⟧ ⟹ n ∈ sum_SDG_slice2 n''"
proof(induct rule:intra_sum_SDG_path.induct)
  case isSp_Nil thus ?case by simp
next
  case (isSp_Append_cdep n ns nx n')
  note IH = ‹nx ∈ sum_SDG_slice2 n'' ⟹ n ∈ sum_SDG_slice2 n''›
  from ‹nx s⟶cd n'› ‹n' ∈ sum_SDG_slice2 n''›
  have "nx ∈ sum_SDG_slice2 n''" by(rule cdep_slice2)
  from IH[OF this] show ?case .
next
  case (isSp_Append_ddep n ns nx V n')
  note IH = ‹nx ∈ sum_SDG_slice2 n'' ⟹ n ∈ sum_SDG_slice2 n''›
  from ‹nx s-V→dd n'› ‹n' ∈ sum_SDG_slice2 n''›
  have "nx ∈ sum_SDG_slice2 n''" by(rule ddep_slice2)
  from IH[OF this] show ?case .
next
  case (isSp_Append_sum n ns nx p n')
  note IH = ‹nx ∈ sum_SDG_slice2 n'' ⟹ n ∈ sum_SDG_slice2 n''›
  from ‹nx s-p→sum n'› ‹n' ∈ sum_SDG_slice2 n''›
  have "nx ∈ sum_SDG_slice2 n''" by(rule sum_slice2)
  from IH[OF this] show ?case .
qed



lemma slice2_is_SDG_path_slice2: 
  "⟦n is-ns→d* n'; n'' ∈ sum_SDG_slice2 n⟧ ⟹ n'' ∈ sum_SDG_slice2 n'"
proof(induct rule:intra_sum_SDG_path.induct)
  case isSp_Nil thus ?case by simp
next
  case (isSp_Append_cdep n ns nx n')
  from ‹n'' ∈ sum_SDG_slice2 n ⟹ n'' ∈ sum_SDG_slice2 nx› ‹n'' ∈ sum_SDG_slice2 n›
  have "n'' ∈ sum_SDG_slice2 nx" .
  with ‹nx s⟶cd n'› show ?case by -(rule slice2_cdep_slice2)
next
  case (isSp_Append_ddep n ns nx V n')
  from ‹n'' ∈ sum_SDG_slice2 n ⟹ n'' ∈ sum_SDG_slice2 nx› ‹n'' ∈ sum_SDG_slice2 n›
  have "n'' ∈ sum_SDG_slice2 nx" .
  with ‹nx s-V→dd n'› show ?case by -(rule slice2_ddep_slice2)
next
  case (isSp_Append_sum n ns nx p n')
  from ‹n'' ∈ sum_SDG_slice2 n ⟹ n'' ∈ sum_SDG_slice2 nx› ‹n'' ∈ sum_SDG_slice2 n›
  have "n'' ∈ sum_SDG_slice2 nx" .
  with ‹nx s-p→sum n'› show ?case by -(rule slice2_sum_slice2)
qed


subsection ‹The backward slice using the Horwitz-Reps-Binkley slicer›

text ‹Note: our slicing criterion is a set of nodes, not a unique node.›

inductive_set combine_SDG_slices :: "'node SDG_node set ⇒ 'node SDG_node set"
  for S::"'node SDG_node set"
  where combSlice_refl:"n ∈ S ⟹ n ∈ combine_SDG_slices S" 
  | combSlice_Return_parent_node:
  "⟦n' ∈ S; n'' s-p→ret CFG_node (parent_node n'); n ∈ sum_SDG_slice2 n'⟧ 
  ⟹ n ∈ combine_SDG_slices S"


definition HRB_slice :: "'node SDG_node set ⇒ 'node SDG_node set"
  where "HRB_slice S ≡ {n'. ∃n ∈ S. n' ∈ combine_SDG_slices (sum_SDG_slice1 n)}"


lemma HRB_slice_cases[consumes 1,case_names phase1 phase2]:
  "⟦x ∈ HRB_slice S; ⋀n nx. ⟦n ∈ sum_SDG_slice1 nx; nx ∈ S⟧ ⟹ P n;
   ⋀nx n' n'' p n. ⟦n' ∈ sum_SDG_slice1 nx; n'' s-p→ret CFG_node (parent_node n'); 
                    n ∈ sum_SDG_slice2 n'; nx ∈ S⟧ ⟹ P n⟧
  ⟹ P x"
  by(fastforce elim:combine_SDG_slices.cases simp:HRB_slice_def)



lemma HRB_slice_refl:
  assumes "valid_node m" and "CFG_node m ∈ S" shows "CFG_node m ∈ HRB_slice S"
proof -
  from ‹valid_node m› have "CFG_node m ∈ sum_SDG_slice1 (CFG_node m)"
    by(fastforce intro:refl_slice1)
  with ‹CFG_node m ∈ S› show ?thesis
    by(simp add:HRB_slice_def)(blast intro:combSlice_refl)
qed


lemma HRB_slice_valid_node: "n ∈ HRB_slice S ⟹ valid_SDG_node n"
proof(induct rule:HRB_slice_cases)
  case (phase1 n nx) thus ?case
    by(induct rule:sum_SDG_slice1.induct,auto intro:sum_SDG_edge_valid_SDG_node)
next
  case (phase2 nx n' n'' p n)
  from ‹n ∈ sum_SDG_slice2 n'›
  show ?case
    by(induct rule:sum_SDG_slice2.induct,auto intro:sum_SDG_edge_valid_SDG_node)
qed


lemma valid_SDG_node_in_slice_parent_node_in_slice:
  assumes "n ∈ HRB_slice S" shows "CFG_node (parent_node n) ∈ HRB_slice S"
proof -
  from ‹n ∈ HRB_slice S› have "valid_SDG_node n" by(rule HRB_slice_valid_node)
  hence "n = CFG_node (parent_node n) ∨ CFG_node (parent_node n) ⟶cd n"
    by(rule valid_SDG_node_cases)
  thus ?thesis
  proof
    assume "n = CFG_node (parent_node n)"
    with ‹n ∈ HRB_slice S› show ?thesis by simp
  next
    assume "CFG_node (parent_node n) ⟶cd n"
    hence "CFG_node (parent_node n) s⟶cd n" by(rule SDG_edge_sum_SDG_edge)
    with ‹n ∈ HRB_slice S› show ?thesis
      by(fastforce elim:combine_SDG_slices.cases 
                 intro:combine_SDG_slices.intros cdep_slice1 cdep_slice2 
                  simp:HRB_slice_def)
  qed
qed


lemma HRB_slice_is_SDG_path_HRB_slice: 
  "⟦n is-ns→d* n'; n'' ∈ HRB_slice {n}; n' ∈ S⟧ ⟹ n'' ∈ HRB_slice S"
proof(induct arbitrary:S rule:intra_sum_SDG_path.induct)
  case (isSp_Nil n) thus ?case by(fastforce simp:HRB_slice_def)
next
  case (isSp_Append_cdep n ns nx n')
  note IH = ‹⋀S. ⟦n'' ∈ HRB_slice {n}; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from IH[OF ‹n'' ∈ HRB_slice {n}›] have "n'' ∈ HRB_slice {nx}" by simp
  thus ?case
  proof(induct rule:HRB_slice_cases)
    case (phase1 n nx') 
    from ‹nx' ∈ {nx}› have "nx' = nx" by simp
    with ‹n ∈ sum_SDG_slice1 nx'› ‹nx s⟶cd n'› have "n ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_cdep_slice1)
    with ‹n' ∈ S› show ?case
      by(fastforce intro:combine_SDG_slices.combSlice_refl simp:HRB_slice_def)
  next
    case (phase2 nx'' nx' n'' p n)
    from ‹nx'' ∈ {nx}› have "nx'' = nx" by simp
    with ‹nx' ∈ sum_SDG_slice1 nx''› ‹nx s⟶cd n'› have "nx' ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_cdep_slice1)
    with ‹n'' s-p→ret CFG_node (parent_node nx')› ‹n ∈ sum_SDG_slice2 nx'› ‹n' ∈ S›
    show ?case by(fastforce intro:combine_SDG_slices.combSlice_Return_parent_node 
                            simp:HRB_slice_def)
  qed
next
  case (isSp_Append_ddep n ns nx V n')
  note IH = ‹⋀S. ⟦n'' ∈ HRB_slice {n}; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from IH[OF ‹n'' ∈ HRB_slice {n}›] have "n'' ∈ HRB_slice {nx}" by simp
  thus ?case
  proof(induct rule:HRB_slice_cases)
    case (phase1 n nx') 
    from ‹nx' ∈ {nx}› have "nx' = nx" by simp
    with ‹n ∈ sum_SDG_slice1 nx'› ‹nx s-V→dd n'› have "n ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_ddep_slice1)
    with ‹n' ∈ S› show ?case
      by(fastforce intro:combine_SDG_slices.combSlice_refl simp:HRB_slice_def)
  next
    case (phase2 nx'' nx' n'' p n)
    from ‹nx'' ∈ {nx}› have "nx'' = nx" by simp
    with ‹nx' ∈ sum_SDG_slice1 nx''› ‹nx s-V→dd n'› have "nx' ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_ddep_slice1)
    with ‹n'' s-p→ret CFG_node (parent_node nx')› ‹n ∈ sum_SDG_slice2 nx'› ‹n' ∈ S›
    show ?case by(fastforce intro:combine_SDG_slices.combSlice_Return_parent_node 
                            simp:HRB_slice_def)
  qed
next
  case (isSp_Append_sum n ns nx p n')
  note IH = ‹⋀S. ⟦n'' ∈ HRB_slice {n}; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from IH[OF ‹n'' ∈ HRB_slice {n}›] have "n'' ∈ HRB_slice {nx}" by simp
  thus ?case
  proof(induct rule:HRB_slice_cases)
    case (phase1 n nx') 
    from ‹nx' ∈ {nx}› have "nx' = nx" by simp
    with ‹n ∈ sum_SDG_slice1 nx'› ‹nx s-p→sum n'› have "n ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_sum_slice1)
    with ‹n' ∈ S› show ?case
      by(fastforce intro:combine_SDG_slices.combSlice_refl simp:HRB_slice_def)
  next
    case (phase2 nx'' nx' n'' p' n)
    from ‹nx'' ∈ {nx}› have "nx'' = nx" by simp
    with ‹nx' ∈ sum_SDG_slice1 nx''› ‹nx s-p→sum n'› have "nx' ∈ sum_SDG_slice1 n'"
      by(fastforce intro:slice1_sum_slice1)
    with ‹n'' s-p'→ret CFG_node (parent_node nx')› ‹n ∈ sum_SDG_slice2 nx'› ‹n' ∈ S›
    show ?case by(fastforce intro:combine_SDG_slices.combSlice_Return_parent_node 
                            simp:HRB_slice_def)
  qed
qed


lemma call_return_nodes_in_slice:
  assumes "valid_edge a" and "kind a = Q↩⇘p⇙f"
  and "valid_edge a'" and "kind a' = Q':r'↪⇘p⇙fs'" and "a ∈ get_return_edges a'"
  and "CFG_node (targetnode a) ∈ HRB_slice S"
  shows "CFG_node (sourcenode a) ∈ HRB_slice S"
  and "CFG_node (sourcenode a') ∈ HRB_slice S" 
  and "CFG_node (targetnode a') ∈ HRB_slice S"
proof -
  from ‹valid_edge a'› ‹kind a' = Q':r'↪⇘p⇙fs'› ‹a ∈ get_return_edges a'›
  have "CFG_node (sourcenode a') s-p→sum CFG_node (targetnode a)"
    by(fastforce intro:sum_SDG_call_summary_edge)
  with ‹CFG_node (targetnode a) ∈ HRB_slice S›
  show "CFG_node (sourcenode a') ∈ HRB_slice S"
    by(fastforce elim!:combine_SDG_slices.cases 
                intro:combine_SDG_slices.intros sum_slice1 sum_slice2 
                 simp:HRB_slice_def)
  from ‹CFG_node (targetnode a) ∈ HRB_slice S›
  obtain nc where "CFG_node (targetnode a) ∈ combine_SDG_slices (sum_SDG_slice1 nc)"
    and "nc ∈ S"
    by(simp add:HRB_slice_def) blast
  thus "CFG_node (sourcenode a) ∈ HRB_slice S"
  proof(induct "CFG_node (targetnode a)" rule:combine_SDG_slices.induct)
    case combSlice_refl
    from ‹valid_edge a› ‹kind a = Q↩⇘p⇙f›
    have "CFG_node (sourcenode a) s-p→ret CFG_node (targetnode a)"
      by(fastforce intro:sum_SDG_return_edge)
    with ‹valid_edge a› 
    have "CFG_node (sourcenode a) ∈ sum_SDG_slice2 (CFG_node (targetnode a))"
      by(fastforce intro:sum_SDG_slice2.intros)
    with ‹CFG_node (targetnode a) ∈ sum_SDG_slice1 nc› ‹nc ∈ S›
      ‹CFG_node (sourcenode a) s-p→ret CFG_node (targetnode a)›
    show ?case by(fastforce intro:combSlice_Return_parent_node simp:HRB_slice_def)
  next
    case (combSlice_Return_parent_node n' n'' p')
    from ‹valid_edge a› ‹kind a = Q↩⇘p⇙f›
    have "CFG_node (sourcenode a) s-p→ret CFG_node (targetnode a)"
      by(fastforce intro:sum_SDG_return_edge)
    with ‹CFG_node (targetnode a) ∈ sum_SDG_slice2 n'›
    have "CFG_node (sourcenode a) ∈ sum_SDG_slice2 n'"
      by(fastforce intro:sum_SDG_slice2.intros)
    with ‹n' ∈ sum_SDG_slice1 nc› ‹n'' s-p'→ret CFG_node (parent_node n')› ‹nc ∈ S›
    show ?case by(fastforce intro:combine_SDG_slices.combSlice_Return_parent_node 
                            simp:HRB_slice_def)
  qed
  from ‹valid_edge a'› ‹kind a' = Q':r'↪⇘p⇙fs'› ‹a ∈ get_return_edges a'›
  have "CFG_node (targetnode a') s⟶cd CFG_node (sourcenode a)"
    by(fastforce intro:sum_SDG_proc_entry_exit_cdep)
  with ‹CFG_node (sourcenode a) ∈ HRB_slice S› ‹nc ∈ S›
  show "CFG_node (targetnode a') ∈ HRB_slice S"
    by(fastforce elim!:combine_SDG_slices.cases 
                intro:combine_SDG_slices.intros cdep_slice1 cdep_slice2 
                 simp:HRB_slice_def)
qed



subsection ‹Proof of Precision›


lemma in_intra_SDG_path_in_slice2:
  "⟦n i-ns→d* n'; n'' ∈ set ns⟧ ⟹ n'' ∈ sum_SDG_slice2 n'"
proof(induct rule:intra_SDG_path.induct)
  case iSp_Nil thus ?case by simp
next
  case (iSp_Append_cdep n ns nx n')
  note IH = ‹n'' ∈ set ns ⟹ n'' ∈ sum_SDG_slice2 nx›
  from ‹n'' ∈ set (ns@[nx])› have "n'' ∈ set ns ∨ n'' = nx" by auto
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF this] have "n'' ∈ sum_SDG_slice2 nx" by simp
    with ‹nx ⟶cd n'› show ?thesis
      by(fastforce intro:slice2_cdep_slice2 SDG_edge_sum_SDG_edge)
  next
    assume "n'' = nx"
    from ‹nx ⟶cd n'› have "valid_SDG_node n'" by(rule SDG_edge_valid_SDG_node)
    hence "n' ∈ sum_SDG_slice2 n'" by(rule refl_slice2)
    with ‹nx ⟶cd n'› have "nx ∈ sum_SDG_slice2 n'"
      by(fastforce intro:cdep_slice2 SDG_edge_sum_SDG_edge)
    with ‹n'' = nx› show ?thesis by simp
  qed
next
  case (iSp_Append_ddep n ns nx V n')
  note IH = ‹n'' ∈ set ns ⟹ n'' ∈ sum_SDG_slice2 nx›
  from ‹n'' ∈ set (ns@[nx])› have "n'' ∈ set ns ∨ n'' = nx" by auto
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF this] have "n'' ∈ sum_SDG_slice2 nx" by simp
    with ‹nx -V→dd n'› show ?thesis
      by(fastforce intro:slice2_ddep_slice2 SDG_edge_sum_SDG_edge)
  next
    assume "n'' = nx"
    from ‹nx -V→dd n'› have "valid_SDG_node n'" by(rule SDG_edge_valid_SDG_node)
    hence "n' ∈ sum_SDG_slice2 n'" by(rule refl_slice2)
    with ‹nx -V→dd n'› have "nx ∈ sum_SDG_slice2 n'"
      by(fastforce intro:ddep_slice2 SDG_edge_sum_SDG_edge)
    with ‹n'' = nx› show ?thesis by simp
  qed
qed


lemma in_intra_SDG_path_in_HRB_slice:
  "⟦n i-ns→d* n'; n'' ∈ set ns; n' ∈ S⟧ ⟹ n'' ∈ HRB_slice S"
proof(induct arbitrary:S rule:intra_SDG_path.induct)
  case iSp_Nil thus ?case by simp
next
  case (iSp_Append_cdep n ns nx n')
  note IH = ‹⋀S. ⟦n'' ∈ set ns; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n'' ∈ set (ns@[nx])› have "n'' ∈ set ns ∨ n'' = nx" by auto
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF ‹n'' ∈ set ns›] have "n'' ∈ HRB_slice {nx}" by simp
    from this ‹nx ⟶cd n'› ‹n' ∈ S› show ?case
      by(fastforce elim:HRB_slice_cases slice1_cdep_slice1
        intro:bexI[where x="n'"] combine_SDG_slices.intros SDG_edge_sum_SDG_edge 
        simp:HRB_slice_def)
  next
    assume "n'' = nx"
    from ‹nx ⟶cd n'› have "valid_SDG_node n'" by(rule SDG_edge_valid_SDG_node)
    hence "n' ∈ sum_SDG_slice1 n'" by(rule refl_slice1)
    with ‹nx ⟶cd n'› have "nx ∈ sum_SDG_slice1 n'" 
      by(fastforce intro:cdep_slice1 SDG_edge_sum_SDG_edge)
    with ‹n'' = nx› ‹n' ∈ S› show ?case
      by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  qed
next
  case (iSp_Append_ddep n ns nx V n')
  note IH = ‹⋀S. ⟦n'' ∈ set ns; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n'' ∈ set (ns@[nx])› have "n'' ∈ set ns ∨ n'' = nx" by auto
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF ‹n'' ∈ set ns›] have "n'' ∈ HRB_slice {nx}" by simp
    from this ‹nx -V→dd n'› ‹n' ∈ S› show ?case
      by(fastforce elim:HRB_slice_cases slice1_ddep_slice1
        intro:bexI[where x="n'"] combine_SDG_slices.intros SDG_edge_sum_SDG_edge 
        simp:HRB_slice_def)
  next
    assume "n'' = nx"
    from ‹nx -V→dd n'› have "valid_SDG_node n'" by(rule SDG_edge_valid_SDG_node)
    hence "n' ∈ sum_SDG_slice1 n'" by(rule refl_slice1)
    with ‹nx -V→dd n'› have "nx ∈ sum_SDG_slice1 n'" 
      by(fastforce intro:ddep_slice1 SDG_edge_sum_SDG_edge)
    with ‹n'' = nx› ‹n' ∈ S› show ?case 
      by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  qed
qed


lemma in_matched_in_slice2:
  "⟦matched n ns n'; n'' ∈ set ns⟧ ⟹ n'' ∈ sum_SDG_slice2 n'"
proof(induct rule:matched.induct)
  case matched_Nil thus ?case by simp
next
  case (matched_Append_intra_SDG_path n ns nx ns' n')
  note IH = ‹n'' ∈ set ns ⟹ n'' ∈ sum_SDG_slice2 nx›
  from ‹n'' ∈ set (ns@ns')› have "n'' ∈ set ns ∨ n'' ∈ set ns'" by simp
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF this] have "n'' ∈ sum_SDG_slice2 nx" .
    with ‹nx i-ns'→d* n'› show ?thesis
      by(fastforce intro:slice2_is_SDG_path_slice2 
                        intra_SDG_path_is_SDG_path)
  next
    assume "n'' ∈ set ns'"
    with ‹nx i-ns'→d* n'› show ?case by(rule in_intra_SDG_path_in_slice2)
  qed
next
  case (matched_bracket_call n0 ns n1 p n2 ns' n3 n4 V a a')
  note IH1 = ‹n'' ∈ set ns ⟹ n'' ∈ sum_SDG_slice2 n1›
  note IH2 = ‹n'' ∈ set ns' ⟹ n'' ∈ sum_SDG_slice2 n3›
  from ‹n1 -p→call n2› ‹matched n2 ns' n3› ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› 
    ‹a' ∈ get_return_edges a› ‹valid_edge a›
    ‹sourcenode a = parent_node n1› ‹targetnode a = parent_node n2›
    ‹sourcenode a' = parent_node n3› ‹targetnode a' = parent_node n4›
  have "matched n1 ([]@n1#ns'@[n3]) n4"
    by(fastforce intro:matched.matched_bracket_call matched_Nil 
                 elim:SDG_edge_valid_SDG_node)
  then obtain nsx where "n1 is-nsx→d* n4" by(erule matched_is_SDG_path)
  from ‹n'' ∈ set (ns@n1#ns'@[n3])› 
  have "((n'' ∈ set ns ∨ n'' = n1) ∨ n'' ∈ set ns') ∨ n'' = n3" by auto
  thus ?case apply -
  proof(erule disjE)+
    assume "n'' ∈ set ns"
    from IH1[OF this] have "n'' ∈ sum_SDG_slice2 n1" .
    with ‹n1 is-nsx→d* n4› show ?thesis 
      by -(rule slice2_is_SDG_path_slice2)
  next
    assume "n'' = n1"
    from ‹n1 is-nsx→d* n4› have "n1 ∈ sum_SDG_slice2 n4" 
      by(fastforce intro:is_SDG_path_slice2 refl_slice2 is_SDG_path_valid_SDG_node)
    with ‹n'' = n1› show ?thesis by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  next
    assume "n'' ∈ set ns'"
    from IH2[OF this] have "n'' ∈ sum_SDG_slice2 n3" .
    with ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› show ?thesis 
      by(fastforce intro:slice2_ret_slice2 slice2_param_out_slice2 
                        SDG_edge_sum_SDG_edge)
  next
    assume "n'' = n3"
    from ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› have "n3 s-p→ret n4 ∨ n3 s-p:V→out n4" 
      by(fastforce intro:SDG_edge_sum_SDG_edge)
    hence "n3 ∈ sum_SDG_slice2 n4"
      by(fastforce intro:return_slice2 param_out_slice2 refl_slice2 
                        sum_SDG_edge_valid_SDG_node)
    with ‹n'' = n3› show ?thesis by simp
  qed
next
  case (matched_bracket_param n0 ns n1 p V n2 ns' n3 V' n4 a a')
  note IH1 = ‹n'' ∈ set ns ⟹ n'' ∈ sum_SDG_slice2 n1›
  note IH2 = ‹n'' ∈ set ns' ⟹ n'' ∈ sum_SDG_slice2 n3›
  from ‹n1 -p:V→in n2› ‹matched n2 ns' n3› ‹n3 -p:V'→out n4› 
    ‹a' ∈ get_return_edges a› ‹valid_edge a›
    ‹sourcenode a = parent_node n1› ‹targetnode a = parent_node n2›
    ‹sourcenode a' = parent_node n3› ‹targetnode a' = parent_node n4›
  have "matched n1 ([]@n1#ns'@[n3]) n4"
    by(fastforce intro:matched.matched_bracket_param matched_Nil 
                 elim:SDG_edge_valid_SDG_node)
  then obtain nsx where "n1 is-nsx→d* n4" by(erule matched_is_SDG_path)
  from ‹n'' ∈ set (ns@n1#ns'@[n3])› 
  have "((n'' ∈ set ns ∨ n'' = n1) ∨ n'' ∈ set ns') ∨ n'' = n3" by auto
  thus ?case apply -
  proof(erule disjE)+
    assume "n'' ∈ set ns"
    from IH1[OF this] have "n'' ∈ sum_SDG_slice2 n1" .
    with ‹n1 is-nsx→d* n4› show ?thesis 
      by -(rule slice2_is_SDG_path_slice2)
  next
    assume "n'' = n1"
    from ‹n1 is-nsx→d* n4› have "n1 ∈ sum_SDG_slice2 n4" 
      by(fastforce intro:is_SDG_path_slice2 refl_slice2 is_SDG_path_valid_SDG_node)
    with ‹n'' = n1› show ?thesis by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  next
    assume "n'' ∈ set ns'"
    from IH2[OF this] have "n'' ∈ sum_SDG_slice2 n3" .
    with ‹n3 -p:V'→out n4› show ?thesis 
      by(fastforce intro:slice2_param_out_slice2 SDG_edge_sum_SDG_edge)
  next
    assume "n'' = n3"
    from ‹n3 -p:V'→out n4› have "n3 s-p:V'→out n4" by(rule SDG_edge_sum_SDG_edge)
    hence "n3 ∈ sum_SDG_slice2 n4"
      by(fastforce intro:param_out_slice2 refl_slice2 sum_SDG_edge_valid_SDG_node)
    with ‹n'' = n3› show ?thesis by simp
  qed
qed


lemma in_matched_in_HRB_slice:
  "⟦matched n ns n'; n'' ∈ set ns; n' ∈ S⟧ ⟹ n'' ∈ HRB_slice S"
proof(induct arbitrary:S rule:matched.induct)
   case matched_Nil thus ?case by simp
next
  case (matched_Append_intra_SDG_path n ns nx ns' n')
  note IH = ‹⋀S. ⟦n'' ∈ set ns; nx ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n'' ∈ set (ns@ns')› have "n'' ∈ set ns ∨ n'' ∈ set ns'" by simp
  thus ?case
  proof
    assume "n'' ∈ set ns"
    from IH[OF ‹n'' ∈ set ns›] have "n'' ∈ HRB_slice {nx}" by simp
    with ‹nx i-ns'→d* n'› ‹n' ∈ S› show ?thesis
      by(fastforce intro:HRB_slice_is_SDG_path_HRB_slice 
                        intra_SDG_path_is_SDG_path)
  next
    assume "n'' ∈ set ns'"
    with ‹nx i-ns'→d* n'› ‹n' ∈ S› show ?case 
      by(fastforce intro:in_intra_SDG_path_in_HRB_slice simp:HRB_slice_def)
  qed
next
  case (matched_bracket_call n0 ns n1 p n2 ns' n3 n4 V a a')
  note IH1 = ‹⋀S. ⟦n'' ∈ set ns; n1 ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  note IH2 = ‹⋀S. ⟦n'' ∈ set ns'; n3 ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n1 -p→call n2› ‹matched n2 ns' n3› ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› 
    ‹a' ∈ get_return_edges a› ‹valid_edge a›
    ‹sourcenode a = parent_node n1› ‹targetnode a = parent_node n2›
    ‹sourcenode a' = parent_node n3› ‹targetnode a' = parent_node n4›
  have "matched n1 ([]@n1#ns'@[n3]) n4"
    by(fastforce intro:matched.matched_bracket_call matched_Nil 
                 elim:SDG_edge_valid_SDG_node)
  then obtain nsx where "n1 is-nsx→d* n4" by(erule matched_is_SDG_path)
  from ‹n'' ∈ set (ns@n1#ns'@[n3])› 
  have "((n'' ∈ set ns ∨ n'' = n1) ∨ n'' ∈ set ns') ∨ n'' = n3" by auto
  thus ?case apply -
  proof(erule disjE)+
    assume "n'' ∈ set ns"
    from IH1[OF this] have "n'' ∈ HRB_slice {n1}" by simp
    with ‹n1 is-nsx→d* n4› ‹n4 ∈ S› show ?thesis 
      by -(rule HRB_slice_is_SDG_path_HRB_slice)
  next
    assume "n'' = n1"
    from ‹n1 is-nsx→d* n4› have "n1 ∈ sum_SDG_slice1 n4" 
      by(fastforce intro:is_SDG_path_slice1 refl_slice1 is_SDG_path_valid_SDG_node)
    with ‹n'' = n1› ‹n4 ∈ S› show ?thesis
      by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  next
    assume "n'' ∈ set ns'"
    with ‹matched n2 ns' n3› have "n'' ∈ sum_SDG_slice2 n3"
      by(rule in_matched_in_slice2)
    with ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› have "n'' ∈ sum_SDG_slice2 n4"
      by(fastforce intro:slice2_ret_slice2 slice2_param_out_slice2 
                        SDG_edge_sum_SDG_edge)
    from ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› have "valid_SDG_node n4"
      by(fastforce intro:SDG_edge_valid_SDG_node)
    hence "n4 ∈ sum_SDG_slice1 n4" by(rule refl_slice1)
    from ‹n3 -p→ret n4 ∨ n3 -p:V→out n4›
    have "CFG_node (parent_node n3) -p→ret CFG_node (parent_node n4)"
      by(fastforce elim:SDG_edge.cases intro:SDG_return_edge)
    with ‹n'' ∈ sum_SDG_slice2 n4› ‹n4 ∈ sum_SDG_slice1 n4› ‹n4 ∈ S›
    show ?case by(fastforce intro:combSlice_Return_parent_node SDG_edge_sum_SDG_edge 
                            simp:HRB_slice_def)
  next
    assume "n'' = n3"
    from ‹n3 -p→ret n4 ∨ n3 -p:V→out n4›
    have "CFG_node (parent_node n3) -p→ret CFG_node (parent_node n4)"
      by(fastforce elim:SDG_edge.cases intro:SDG_return_edge)
    from ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› have "valid_SDG_node n4"
      by(fastforce intro:SDG_edge_valid_SDG_node)
    hence "n4 ∈ sum_SDG_slice1 n4" by(rule refl_slice1)
    from ‹valid_SDG_node n4› have "n4 ∈ sum_SDG_slice2 n4" by(rule refl_slice2)
    with ‹n3 -p→ret n4 ∨ n3 -p:V→out n4› have "n3 ∈ sum_SDG_slice2 n4" 
      by(fastforce intro:return_slice2 param_out_slice2 SDG_edge_sum_SDG_edge)
    with ‹n4 ∈ sum_SDG_slice1 n4› 
      ‹CFG_node (parent_node n3) -p→ret CFG_node (parent_node n4)› ‹n'' = n3› ‹n4 ∈ S›
    show ?case by(fastforce intro:combSlice_Return_parent_node SDG_edge_sum_SDG_edge
                            simp:HRB_slice_def)
  qed
next
  case (matched_bracket_param n0 ns n1 p V n2 ns' n3 V' n4 a a')
  note IH1 = ‹⋀S. ⟦n'' ∈ set ns; n1 ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  note IH2 = ‹⋀S. ⟦n'' ∈ set ns'; n3 ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n1 -p:V→in n2› ‹matched n2 ns' n3› ‹n3 -p:V'→out n4› 
    ‹a' ∈ get_return_edges a› ‹valid_edge a›
    ‹sourcenode a = parent_node n1› ‹targetnode a = parent_node n2›
    ‹sourcenode a' = parent_node n3› ‹targetnode a' = parent_node n4›
  have "matched n1 ([]@n1#ns'@[n3]) n4"
    by(fastforce intro:matched.matched_bracket_param matched_Nil 
                 elim:SDG_edge_valid_SDG_node)
  then obtain nsx where "n1 is-nsx→d* n4" by(erule matched_is_SDG_path)
  from ‹n'' ∈ set (ns@n1#ns'@[n3])› 
  have "((n'' ∈ set ns ∨ n'' = n1) ∨ n'' ∈ set ns') ∨ n'' = n3" by auto
  thus ?case apply -
  proof(erule disjE)+
    assume "n'' ∈ set ns"
    from IH1[OF this] have "n'' ∈ HRB_slice {n1}" by simp
    with ‹n1 is-nsx→d* n4› ‹n4 ∈ S› show ?thesis 
      by -(rule HRB_slice_is_SDG_path_HRB_slice)
  next
    assume "n'' = n1"
    from ‹n1 is-nsx→d* n4› have "n1 ∈ sum_SDG_slice1 n4"
      by(fastforce intro:is_SDG_path_slice1 refl_slice1 is_SDG_path_valid_SDG_node)
    with ‹n'' = n1› ‹n4 ∈ S› show ?thesis
      by(fastforce intro:combSlice_refl simp:HRB_slice_def)
  next
    assume "n'' ∈ set ns'"
    with ‹matched n2 ns' n3› have "n'' ∈ sum_SDG_slice2 n3"
      by(rule in_matched_in_slice2)
    with ‹n3 -p:V'→out n4› have "n'' ∈ sum_SDG_slice2 n4"
      by(fastforce intro:slice2_param_out_slice2 SDG_edge_sum_SDG_edge)
    from ‹n3 -p:V'→out n4› have "valid_SDG_node n4" by(rule SDG_edge_valid_SDG_node)
    hence "n4 ∈ sum_SDG_slice1 n4" by(rule refl_slice1)
    from ‹n3 -p:V'→out n4› 
    have "CFG_node (parent_node n3) -p→ret CFG_node (parent_node n4)"
      by(fastforce elim:SDG_edge.cases intro:SDG_return_edge)
    with ‹n'' ∈ sum_SDG_slice2 n4› ‹n4 ∈ sum_SDG_slice1 n4› ‹n4 ∈ S›
    show ?case by(fastforce intro:combSlice_Return_parent_node SDG_edge_sum_SDG_edge 
                            simp:HRB_slice_def)
  next
    assume "n'' = n3"
    from ‹n3 -p:V'→out n4› have "n3 s-p:V'→out n4" by(rule SDG_edge_sum_SDG_edge)
    from ‹n3 -p:V'→out n4› have "valid_SDG_node n4" by(rule SDG_edge_valid_SDG_node)
    hence "n4 ∈ sum_SDG_slice1 n4" by(rule refl_slice1)
    from ‹valid_SDG_node n4› have "n4 ∈ sum_SDG_slice2 n4" by(rule refl_slice2)
    with ‹n3 s-p:V'→out n4› have "n3 ∈ sum_SDG_slice2 n4" by(rule param_out_slice2)
    from ‹n3 -p:V'→out n4› 
    have "CFG_node (parent_node n3) -p→ret CFG_node (parent_node n4)"
      by(fastforce elim:SDG_edge.cases intro:SDG_return_edge)
    with ‹n3 ∈ sum_SDG_slice2 n4› ‹n4 ∈ sum_SDG_slice1 n4› ‹n'' = n3› ‹n4 ∈ S›
    show ?case by(fastforce intro:combSlice_Return_parent_node SDG_edge_sum_SDG_edge
                            simp:HRB_slice_def)
  qed
qed


theorem in_realizable_in_HRB_slice:
  "⟦realizable n ns n'; n'' ∈ set ns; n' ∈ S⟧ ⟹ n'' ∈ HRB_slice S"
proof(induct arbitrary:S rule:realizable.induct)
  case (realizable_matched n ns n') thus ?case by(rule in_matched_in_HRB_slice)
next
  case (realizable_call n0 ns n1 p n2 V ns' n3)
  note IH = ‹⋀S. ⟦n'' ∈ set ns; n1 ∈ S⟧ ⟹ n'' ∈ HRB_slice S›
  from ‹n'' ∈ set (ns@n1#ns')› have "(n'' ∈ set ns ∨ n'' = n1) ∨ n'' ∈ set ns'"
    by auto
  thus ?case apply -
  proof(erule disjE)+
    assume "n'' ∈ set ns"
    from IH[OF this] have "n'' ∈ HRB_slice {n1}" by simp
    hence "n'' ∈ HRB_slice {n2}"
    proof(induct rule:HRB_slice_cases)
      case (phase1 n nx)
      from ‹nx ∈ {n1}› have "nx = n1" by simp
      with ‹n ∈ sum_SDG_slice1 nx› ‹n1 -p→call n2 ∨ n1 -p:V→in n2›
      have "n ∈ sum_SDG_slice1 n2" 
        by(fastforce intro:slice1_call_slice1 slice1_param_in_slice1 
                          SDG_edge_sum_SDG_edge)
      thus ?case
        by(fastforce intro:combine_SDG_slices.combSlice_refl simp:HRB_slice_def)
    next
      case (phase2 nx n' n'' p' n)
      from ‹nx ∈ {n1}› have "nx = n1" by simp
      with ‹n' ∈ sum_SDG_slice1 nx› ‹n1 -p→call n2 ∨ n1 -p:V→in n2›
      have "n' ∈ sum_SDG_slice1 n2" 
        by(fastforce intro:slice1_call_slice1 slice1_param_in_slice1 
                          SDG_edge_sum_SDG_edge)
      with ‹n'' s-p'→ret CFG_node (parent_node n')› ‹n ∈ sum_SDG_slice2 n'› show ?case
        by(fastforce intro:combine_SDG_slices.combSlice_Return_parent_node 
                     simp:HRB_slice_def)
    qed
    from ‹matched n2 ns' n3› obtain nsx where "n2 is-nsx→d* n3"
      by(erule matched_is_SDG_path)
    with ‹n'' ∈ HRB_slice {n2}› ‹n3 ∈ S› show ?thesis
      by(fastforce intro:HRB_slice_is_SDG_path_HRB_slice)
  next
    assume "n'' = n1"
    from ‹matched n2 ns' n3› obtain nsx where "n2 is-nsx→d* n3"
      by(erule matched_is_SDG_path)
    hence "n2 ∈ sum_SDG_slice1 n2" 
      by(fastforce intro:refl_slice1 is_SDG_path_valid_SDG_node)
    with ‹n1 -p→call n2 ∨ n1 -p:V→in n2›
    have "n1 ∈ sum_SDG_slice1 n2"
      by(fastforce intro:call_slice1 param_in_slice1 SDG_edge_sum_SDG_edge)
    hence "n1 ∈ HRB_slice {n2}" by(fastforce intro:combSlice_refl simp:HRB_slice_def)
    with ‹n2 is-nsx→d* n3› ‹n'' = n1› ‹n3 ∈ S› show ?thesis
      by(fastforce intro:HRB_slice_is_SDG_path_HRB_slice)
  next
    assume "n'' ∈ set ns'"
    from ‹matched n2 ns' n3› this ‹n3 ∈ S› show ?thesis
      by(rule in_matched_in_HRB_slice)
  qed
qed


lemma slice1_ics_SDG_path:
  assumes "n ∈ sum_SDG_slice1 n'" and "n ≠ n'"
  obtains ns where "CFG_node (_Entry_) ics-ns→d* n'" and "n ∈ set ns"
proof(atomize_elim)
  from ‹n ∈ sum_SDG_slice1 n'› 
  have "n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)"
  proof(induct rule:sum_SDG_slice1.induct)
    case refl_slice1 thus ?case by simp
  next
    case (cdep_slice1 n'' n)
    from ‹n'' s⟶cd n› have "valid_SDG_node n''" by(rule sum_SDG_edge_valid_SDG_node)
    hence "n'' ics-[]→d* n''" by(rule icsSp_Nil)
    from ‹valid_SDG_node n''› have "valid_node (parent_node n'')"
      by(rule valid_SDG_CFG_node)
    thus ?case
    proof(cases "parent_node n'' = (_Exit_)")
      case True
      with ‹valid_SDG_node n''› have "n'' = CFG_node (_Exit_)"
        by(rule valid_SDG_node_parent_Exit)
      with ‹n'' s⟶cd n› have False by(fastforce intro:Exit_no_sum_SDG_edge_source)
      thus ?thesis by simp
    next
      case False
      from ‹n'' s⟶cd n› have "valid_SDG_node n''"
        by(rule sum_SDG_edge_valid_SDG_node)
      from this False obtain ns 
        where "CFG_node (_Entry_) cc-ns→d* n''"
        by(erule Entry_cc_SDG_path_to_inner_node)
      with ‹n'' s⟶cd n› have "CFG_node (_Entry_) cc-ns@[n'']→d* n"
        by(fastforce intro:ccSp_Append_cdep sum_SDG_edge_SDG_edge)
      hence "CFG_node (_Entry_) ics-ns@[n'']→d* n"
        by(rule cc_SDG_path_ics_SDG_path)
      from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
      show ?thesis
      proof
        assume "n = n'"
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n› show ?thesis by fastforce
      next
        assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
        then obtain nsx where "CFG_node (_Entry_) ics-nsx→d* n'" and "n ∈ set nsx"
          by blast
        then obtain ns' ns'' where "nsx = ns'@ns''" and "n ics-ns''→d* n'"
          by -(erule ics_SDG_path_split)
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n›
        show ?thesis by(fastforce intro:ics_SDG_path_Append)
      qed
    qed
  next
    case (ddep_slice1 n'' V n)
    from ‹n'' s-V→dd n› have "valid_SDG_node n''" by(rule sum_SDG_edge_valid_SDG_node)
    hence "n'' ics-[]→d* n''" by(rule icsSp_Nil)
    from ‹valid_SDG_node n''› have "valid_node (parent_node n'')"
      by(rule valid_SDG_CFG_node)
    thus ?case
    proof(cases "parent_node n'' = (_Exit_)")
      case True
      with ‹valid_SDG_node n''› have "n'' = CFG_node (_Exit_)"
        by(rule valid_SDG_node_parent_Exit)
      with ‹n'' s-V→dd n› have False by(fastforce intro:Exit_no_sum_SDG_edge_source)
      thus ?thesis by simp
    next
      case False
      from ‹n'' s-V→dd n› have "valid_SDG_node n''"
        by(rule sum_SDG_edge_valid_SDG_node)
      from this False obtain ns 
        where "CFG_node (_Entry_) cc-ns→d* n''"
        by(erule Entry_cc_SDG_path_to_inner_node)
     hence "CFG_node (_Entry_) ics-ns→d* n''"
        by(rule cc_SDG_path_ics_SDG_path)
      show ?thesis
      proof(cases "n'' = n")
        case True
        from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
        show ?thesis
        proof
          assume "n = n'"
          with ‹n'' = n› show ?thesis by simp
        next
          assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
          with ‹n'' = n› show ?thesis by fastforce
        qed
      next
        case False
        with ‹n'' s-V→dd n› ‹CFG_node (_Entry_) ics-ns→d* n''›
        have "CFG_node (_Entry_) ics-ns@[n'']→d* n"
          by -(rule icsSp_Append_ddep)
        from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
        show ?thesis
        proof
          assume "n = n'"
          with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n› show ?thesis by fastforce
        next
          assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
          then obtain nsx where "CFG_node (_Entry_) ics-nsx→d* n'" and "n ∈ set nsx"
            by blast
          then obtain ns' ns'' where "nsx = ns'@ns''" and "n ics-ns''→d* n'"
            by -(erule ics_SDG_path_split)
          with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n›
          show ?thesis by(fastforce intro:ics_SDG_path_Append)
        qed
      qed
    qed
  next
    case (call_slice1 n'' p n)
    from ‹n'' s-p→call n› have "valid_SDG_node n''" 
      by(rule sum_SDG_edge_valid_SDG_node)
    hence "n'' ics-[]→d* n''" by(rule icsSp_Nil)
    from ‹valid_SDG_node n''› have "valid_node (parent_node n'')"
      by(rule valid_SDG_CFG_node)
    thus ?case
    proof(cases "parent_node n'' = (_Exit_)")
      case True
      with ‹valid_SDG_node n''› have "n'' = CFG_node (_Exit_)"
        by(rule valid_SDG_node_parent_Exit)
      with ‹n'' s-p→call n› have False by(fastforce intro:Exit_no_sum_SDG_edge_source)
      thus ?thesis by simp
    next
      case False
      from ‹n'' s-p→call n› have "valid_SDG_node n''"
        by(rule sum_SDG_edge_valid_SDG_node)
      from this False obtain ns 
        where "CFG_node (_Entry_) cc-ns→d* n''"
        by(erule Entry_cc_SDG_path_to_inner_node)
      with ‹n'' s-p→call n› have "CFG_node (_Entry_) cc-ns@[n'']→d* n"
        by(fastforce intro:ccSp_Append_call sum_SDG_edge_SDG_edge)
      hence "CFG_node (_Entry_) ics-ns@[n'']→d* n"
        by(rule cc_SDG_path_ics_SDG_path)
      from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
      show ?thesis
      proof
        assume "n = n'"
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n› show ?thesis by fastforce
      next
        assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
        then obtain nsx where "CFG_node (_Entry_) ics-nsx→d* n'" and "n ∈ set nsx"
          by blast
        then obtain ns' ns'' where "nsx = ns'@ns''" and "n ics-ns''→d* n'"
          by -(erule ics_SDG_path_split)
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n›
        show ?thesis by(fastforce intro:ics_SDG_path_Append)
      qed
    qed
  next
    case (param_in_slice1 n'' p V n)
    from ‹n'' s-p:V→in n› have "valid_SDG_node n''" 
      by(rule sum_SDG_edge_valid_SDG_node)
    hence "n'' ics-[]→d* n''" by(rule icsSp_Nil)
    from ‹valid_SDG_node n''› have "valid_node (parent_node n'')"
      by(rule valid_SDG_CFG_node)
    thus ?case
    proof(cases "parent_node n'' = (_Exit_)")
      case True
      with ‹valid_SDG_node n''› have "n'' = CFG_node (_Exit_)"
        by(rule valid_SDG_node_parent_Exit)
      with ‹n'' s-p:V→in n› have False by(fastforce intro:Exit_no_sum_SDG_edge_source)
      thus ?thesis by simp
    next
      case False
      from ‹n'' s-p:V→in n› have "valid_SDG_node n''"
        by(rule sum_SDG_edge_valid_SDG_node)
      from this False obtain ns 
        where "CFG_node (_Entry_) cc-ns→d* n''"
        by(erule Entry_cc_SDG_path_to_inner_node)
      hence "CFG_node (_Entry_) ics-ns→d* n''"
        by(rule cc_SDG_path_ics_SDG_path)
      with ‹n'' s-p:V→in n› have "CFG_node (_Entry_) ics-ns@[n'']→d* n"
        by -(rule icsSp_Append_param_in)
      from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
      show ?thesis
      proof
        assume "n = n'"
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n› show ?thesis by fastforce
      next
        assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
        then obtain nsx where "CFG_node (_Entry_) ics-nsx→d* n'" and "n ∈ set nsx"
          by blast
        then obtain ns' ns'' where "nsx = ns'@ns''" and "n ics-ns''→d* n'"
          by -(erule ics_SDG_path_split)
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n›
        show ?thesis by(fastforce intro:ics_SDG_path_Append)
      qed
    qed
  next
    case (sum_slice1 n'' p n)
    from ‹n'' s-p→sum n› have "valid_SDG_node n''" 
      by(rule sum_SDG_edge_valid_SDG_node)
    hence "n'' ics-[]→d* n''" by(rule icsSp_Nil)
    from ‹valid_SDG_node n''› have "valid_node (parent_node n'')"
      by(rule valid_SDG_CFG_node)
    thus ?case
    proof(cases "parent_node n'' = (_Exit_)")
      case True
      with ‹valid_SDG_node n''› have "n'' = CFG_node (_Exit_)"
        by(rule valid_SDG_node_parent_Exit)
      with ‹n'' s-p→sum n› have False by(fastforce intro:Exit_no_sum_SDG_edge_source)
      thus ?thesis by simp
    next
      case False
      from ‹n'' s-p→sum n› have "valid_SDG_node n''"
        by(rule sum_SDG_edge_valid_SDG_node)
      from this False obtain ns 
        where "CFG_node (_Entry_) cc-ns→d* n''"
        by(erule Entry_cc_SDG_path_to_inner_node)
      hence "CFG_node (_Entry_) ics-ns→d* n''"
        by(rule cc_SDG_path_ics_SDG_path)
      with ‹n'' s-p→sum n› have "CFG_node (_Entry_) ics-ns@[n'']→d* n"
        by -(rule icsSp_Append_sum)
      from ‹n = n' ∨ (∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns)›
      show ?thesis
      proof
        assume "n = n'"
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n› show ?thesis by fastforce
      next
        assume "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns"
        then obtain nsx where "CFG_node (_Entry_) ics-nsx→d* n'" and "n ∈ set nsx"
          by blast
        then obtain ns' ns'' where "nsx = ns'@ns''" and "n ics-ns''→d* n'"
          by -(erule ics_SDG_path_split)
        with ‹CFG_node (_Entry_) ics-ns@[n'']→d* n›
        show ?thesis by(fastforce intro:ics_SDG_path_Append)
      qed
    qed
  qed
  with ‹n ≠ n'› show "∃ns. CFG_node (_Entry_) ics-ns→d* n' ∧ n ∈ set ns" by simp
qed


lemma slice2_irs_SDG_path:
  assumes "n ∈ sum_SDG_slice2 n'" and "valid_SDG_node n'"
  obtains ns where "n irs-ns→d* n'"
using assms
by(induct rule:sum_SDG_slice2.induct,auto intro:intra_return_sum_SDG_path.intros)


theorem HRB_slice_realizable:
  assumes "n ∈ HRB_slice S" and "∀n' ∈ S. valid_SDG_node n'" and "n ∉ S"
  obtains n' ns where "n' ∈ S" and "realizable (CFG_node (_Entry_)) ns n'" 
  and "n ∈ set ns"
proof(atomize_elim)
  from ‹n ∈ HRB_slice S› ‹n ∉ S›
  show "∃n' ns. n' ∈ S ∧ realizable (CFG_node (_Entry_)) ns n' ∧ n ∈ set ns"
  proof(induct rule:HRB_slice_cases)
    case (phase1 n nx)
    with ‹n ∉ S› show ?case
      by(fastforce elim:slice1_ics_SDG_path ics_SDG_path_realizable)
  next
    case (phase2 n' nx n'' p n)
    from ‹∀n' ∈ S. valid_SDG_node n'› ‹n' ∈ S› have "valid_SDG_node n'" by simp
    with ‹nx ∈ sum_SDG_slice1 n'› have "valid_SDG_node nx"
      by(auto elim:slice1_ics_SDG_path ics_SDG_path_split 
              intro:ics_SDG_path_valid_SDG_node)
    with ‹n ∈ sum_SDG_slice2 nx›
    obtain nsx where "n irs-nsx→d* nx" by(erule slice2_irs_SDG_path)
    show ?case
    proof(cases "n = nx")
      case True
      show ?thesis
      proof(cases "nx = n'")
        case True
        with ‹n = nx› ‹n ∉ S› ‹n' ∈ S› have False by simp
        thus ?thesis by simp
      next
        case False
        with ‹nx ∈ sum_SDG_slice1 n'› obtain ns 
          where "realizable (CFG_node (_Entry_)) ns n'" and "nx ∈ set ns"
          by(fastforce elim:slice1_ics_SDG_path ics_SDG_path_realizable)
        with ‹n = nx› ‹n' ∈ S› show ?thesis by blast
      qed
    next
      case False
      with ‹n irs-nsx→d* nx› obtain ns
        where "realizable (CFG_node (_Entry_)) ns nx" and "n ∈ set ns"
        by(erule irs_SDG_path_realizable)
      show ?thesis
      proof(cases "nx = n'")
        case True
        with ‹realizable (CFG_node (_Entry_)) ns nx› ‹n ∈ set ns› ‹n' ∈ S›
        show ?thesis by blast
      next
        case False
        with ‹nx ∈ sum_SDG_slice1 n'› obtain nsx'
          where "CFG_node (_Entry_) ics-nsx'→d* n'" and "nx ∈ set nsx'"
          by(erule slice1_ics_SDG_path)
        then obtain ns' where "nx ics-ns'→d* n'" by -(erule ics_SDG_path_split)
        with ‹realizable (CFG_node (_Entry_)) ns nx›
        obtain ns'' where "realizable (CFG_node (_Entry_)) (ns@ns'') n'"
          by(erule realizable_Append_ics_SDG_path)
        with ‹n ∈ set ns› ‹n' ∈ S› show ?thesis by fastforce
      qed
    qed
  qed
qed


theorem HRB_slice_precise:
  "⟦∀n' ∈ S. valid_SDG_node n'; n ∉ S⟧ ⟹
    n ∈ HRB_slice S = 
    (∃n' ns. n' ∈ S ∧ realizable (CFG_node (_Entry_)) ns n' ∧ n ∈ set ns)"
  by(fastforce elim:HRB_slice_realizable intro:in_realizable_in_HRB_slice)

end

end