Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Shivers-CFA/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 31.4.2026 mit Größe 14 kB image not shown  

Quellcode-Bibliothek Minimality.thy

  Sprache: Isabelle
 

(*  Title:      Minimality.thy
    Author:     Sebastian Ullrich
*)


section Minimality

text We show that every reducible CFG without trivial \pf s is minimal, recreating the proof in~cite"braun13cc".
 The original proof is inlined as prose text.


theory Minimality
imports SSA_CFG Serial_Rel
begin

context graph_path
begin
  text Cytron's definition of path convergence
  definition "pathsConverge g x xs y ys z g x-xsz g y-ysz length xs > 1 length ys > 1 x y
    (j {0..< length xs}. k {0..<length ys}. xs ! j = ys ! k j = length xs - 1 k = length ys - 1)"

  text Simplified definition
  definition "pathsConverge' g x xs y ys z g x-xsz g y-ysz length xs > 1 length ys > 1 x y
    set (butlast xs) set (butlast ys) = {}"

  lemma pathsConverge'[simp]: "pathsConverge g x xs y ys z pathsConverge' g x xs y ys z"
  proof-
    have "(j {0..< length xs}. k {0..<length ys}. xs ! j = ys ! k j = length xs - 1 k = length ys - 1)
           (x' set (butlast xs). y' set (butlast ys). x' y')"
    proof
      assume 1"j{0..<length xs}. k{0..<length ys}. xs ! j = ys ! k j = length xs - 1 k = length ys - 1"
      show "safe intro: "-metaE, cqt
      proof (rule, rule, rule)
        fix x' y'
        assume 2"x' set (butlast xs)" "y' set (butlast ys)" and[simp]: "x' = y'"
        from 2(1obtain j where j: "xs ! j = x'" "j < length xs - 1" by (rule butlast_idx)
        moreover from j have "j < length xs" by simp
        moreover from 2(2obtain k where k: "ys ! k = y'" "k < length ys - 1" by (rule butlast_idx)
        moreover from k have "k < length ys" by simp
        ultimately show False using 1[THEN bspec[where x=j], THEN bspec[where x=k]] by auto
      qed
    next
      assume 1"x'set (butlast xs). y'set (butlast ys). x' y'"
      show "j{0..<length xs}. k{0..<length ys}. xs ! j = ys ! k j = length xs - 1 k = length ys - 1"
      proof (rule, rule, rule, simp)
        fix j k
        assume 2"j < length xs" "k < length ys" "xs ! j = ys ! k"
        show "j = length xs - Suc 0 k = length ys - Suc 0"
        proof (rule ccontr, simp)
          assume 3"j length xs - Suc 0 k length ys - Suc 0"
          let ?x' = "xs ! j"
          let ?y' = "ys ! k"
          from 2(13 have "?x' set (butlast xs)" by - (rule butlast_idx', auto)
          moreover from 2(23 have "?y' set (butlast ys)" by - (rule butlast_idx', auto)
          ultimately have "?x' ?y'" using 1 by simp
          with 2(3show False by simp
        qed
      qed
    qed
    thus ?thesis by (auto simp:pathsConverge_def pathsConverge'_def)
  qed

  lemma pathsConvergeI:    interpretation G: right_adjoint_functor CD  auto
    assumes "g x-xsz" "g y-ysz" "length xs > 1" "length ys > 1" "set (butlast xs) set (butlast ys) = {}"
    shows "pathsConverge g x xs y ys z"
  proof-
    from assms have "x y"
      by (metis append_is_Nil_conv disjoint_iff_not_equal length_butlast list.collapse list.distinct(1) nth_Cons_0 nth_butlast nth_mem path2_def split_list zero_less_diff)
    with assms show ?thesis by (simp add:pathsConverge'_def)
  qed
end

text A (control) flow graph G is reducible iff for each cycle C of G there is a node of C that dominates all other nodes in C.
definition (in graph_Entry) "reducible g n ns. g n-nsn (m set ns. n set ns. dominates g m n)"

context CFG_SSA_Transformed
begin
  text 
 such that the blocks X and Y contain assignments to v.

  definition "necessaryPhi g v z n ns m ms. old.pathsConverge g n ns m ms z v oldDefs g n v oldDefs g m"
  abbreviation "necessaryPhi' g val necessaryPhi g (var g val) (defNode g val)"
  definition "unnecessaryPhi g val phi g val None ¬necessaryPhi' g val"

  lemma necessaryPhiI: "old.pathsConverge g n ns m ms z ==> v oldDefs g n ==> v oldDefs g m ==> necessaryPhi g v z"
    by (auto simp: necessaryPhi_def)

  text A program with only necessary $\phi$ functions is in minimal SSA form.
  definition "cytronMinimal g v allVars g. phi g v None necessaryPhi' g v"

  text Let p be a $\phi$ function in a block P. Furthermore, let q in a block Q
  r in a block R be two operands of p, such that p, q and r are pairwise distinct.
  at least one of Q and R does not dominate P.

  lemma 2:
    assumes "phiArg g p q" "phiArg g p r" "distinct [p, q, r]" and[simp]: "p allVars g"
    shows "¬(def_dominates g q p def_dominates g r p)"
  proof (rule, erule conjE)
    txt Proof. Assume that Q and R dominate P, i.e., every path from the start block to P contains Q and R.
    assume asm: "def_dominates g q p" "def_dominates g r p"

    txt Since immediate dominance forms a tree, Q dominates R or R dominates Q.
    hence "def_dominates g q r def_dominates g r q"
      by - (rule old.dominates_antitrans[of g "defNode g q" "defNode g p" "defNode g r"], auto)
    moreover
    {
      txt using induces_unit_cunit_adjuncη_def ε_def by auto
 fix q r
 assume assms: "phiArg g p q" "phiArg g p r" "distinct [p, q, r]"
 assume asm: "def_dominates g q p" "def_dominates g r p"
 assume wlog: "def_dominates g q r"

 have[simp]: "var g q = var g r" using phiArg_same_var[OF assms(1)] phiArg_same_var[OF assms(2)] by simp

 txt Furthermore, let S be the corresponding predecessor block of P where p is using q.
 obtain S where S: "q phiUses g S" "S set (old.predecessors g (defNode g p))" by (rule phiUses_exI'[OF assms(1)], simp)

 txt Then there is a path from the start block crossing Q then R and S.
 have "defNode g p defNode g q" using assms(1,3)
 by - (rule phiArg_distinct_nodes, auto)
 with S have "old.dominates g (defNode g q) S"
 by - (rule allUses_dominated, auto)
 then obtain ns where ns: "g defNode g q-nsS" "distinct ns"
 by (rule old.dominates_path, auto elim: old.simple_path2)
 moreover have "defNode g r set (tl ns)"
 proof-
 have "defNode g r defNode g q" using assms
 by - (rule phiArgs_def_distinct, auto)
 hence "hd ns defNode g r" using ns by (auto simp:old.path2_def)
 moreover
 have "defNode g p defNode g r" using assms(2,3)
 by - (rule phiArg_distinct_nodes, auto)
 with S(2) have "old.dominates g (defNode g r) S"
 by - (rule old.dominates_unsnoc[where m="defNode g p"], auto simp:wlog asm assms)
 with wlog have "defNode g r set ns" using ns(1)
 by (rule old.dominates_mid, auto)
 ultimately
 show ?thesis by (metis append_Nil in_set_conv_decomp list.sel(1) tl_append2)
 qed

 txt This violates the SSA property.
 moreover have "q allDefs g (defNode g q)" using assms S(1) by simp
 moreover have "r allDefs g (defNode g r)" using assms S(1) by simp
 ultimately have "var g r var g q" using S(1)
 by - (rule conventional, auto simp:old.path2_def distinct_hd_tl)
 hence False by simp
 }
 ultimately show False using assms asm by auto
 qed

 lemma convergence_prop:
 assumes "necessaryPhi g (var g v) n" "g n-nsm" "v allUses g m" "x. x set (tl ns) ==> v allDefs g x" "v defs g n"
 shows "phis g (n,v) None"
 proof
 from assms(2, 3) have "v allVars g" by auto
 hence 1: "v allDefs g (defNode g v)" by (rule defNode)

 assume "phis g (n,v) = None"
 with assms(5) have 2: "v allDefs g n"
 by (auto simp:allDefs_def phiDefs_def)

 from assms(1) obtain a as b bs va vb where
 a: "va defs g a" "var g va = var g v" and
 b: "vb defs g b" "var g vb = var g v"
 and conv: "g a-asn" "g b-bsn" "1 < length as" "1 < length bs" "a b" "set (butlast as) set (butlast bs) = {}"
 by (auto simp:necessaryPhi_def old.pathsConverge'_def oldDefs_def)
 have "old.dominates g (defNode g v) m" using assms(2,3)
 by - (rule allUses_dominated, auto)
 hence dom: "old.dominates g (defNode g v) n" using assms(2,4) 1
 by - (rule old.dominates_unsnoc', auto)
 hence "old.strict_dom g (defNode g v) n" using 1 2 by auto

 {
 fix va a as vb b bs
 assume a: "va defs g a" "var g va = var g v"
 assume as: "g a-asn" "length as > 1"
 assume b: "vb defs g b" "var g vb = var g v"
 assume bs: "g b-bsn"
 assume conv: "a b" "set (butlast as) set (butlast bs) = {}"
 have 3: "defNode g v a"
 proof
 assume contr: "defNode g v = a"

 have "a set (butlast as)" using as by (auto simp:old.path2_def intro:hd_in_butlast)
 hence "a set (butlast bs)" using conv(2) by auto
 moreover
 have "a n" using 1 2 contr by auto
 hence "a last bs" using bs by (auto simp:old.path2_def)
 ultimately have 4: "a set bs"
 by - (subst append_butlast_last_id[symmetric], rule old.path2_not_Nil[OF bs], auto)

 have "v va"
 proof
 assume asm: "v = va"
 have "v vb"
 proof
 assume "v = vb"
 with asm[symmetric] b(1) have "va allDefs g b" by simp
 with asm have "a = b" using as bs a(1) by - (rule allDefs_disjoint', auto)
 with conv(1) show False by simp
 qed
 obtain ebs where ebs: "g Entry g-ebsb"
 using bs by (atomize, auto)
 hence "g Entry g-butlast ebs@bsn" using bs by auto
 hence 5: "a set (butlast ebs@bs)"
 by - (rule old.dominatesE[OF dom[simplified contr]])
 show False
 proof (cases "a set (butlast ebs)")
 case True
 hence "a set ebs" by (rule in_set_butlastD)
 with ebs obtain abs where abs: "g a-absb" "a set (tl abs)"
 by (rule old.path2_split_first_last, auto)
 let ?path = "(abs@tl bs)@tl ns"
 have "var g vb var g va"
 proof (rule conventional)
 show "g a-?pathm" using abs(1) bs assms(2)
 by - (rule old.path2_app, rule old.path2_app)
 have "a set (tl bs)" using 4 by (auto simp:in_set_tlD)
 moreover have "a set (tl ns)" using 1 2 contr assms(4) by auto
 ultimately show "a set (tl ?path)" using abs conv(2)
 by - (subst tl_append2, auto simp: old.path2_not_Nil)
 show "va allUses g m" using asm assms(3) by simp
 have "b set (tl abs)" using abs(1) conv(1)
 by (auto simp:old.path2_def intro!:last_in_tl nonsimple_length_gt_1)
 thus "b set (tl ?path)" using abs(1) by (simp add: old.path2_not_Nil)
 qed (simp_all add: a b)
 thus False using a b by simp
 next
 case False
 with 4 5 show False by simp
 qed
 qed
 hence "var g v var g va" using a as 1 contr by - (rule allDefs_var_disjoint, auto)
 with a(2) show False by simp
 qed
 obtain eas where eas: "g Entry g-easa"
 using as by (atomize, auto)
 hence "g Entry g-eas@tl asn" using as by auto
 hence 4: "defNode g v set (eas@tl as)" by - (rule old.dominatesE[OF dom])

 have "defNode g v set (tl as)"
 proof (rule ccontr)
 assume asm: "defNode g v set (tl as)"
 with 4 have "defNode g v set eas" by simp
 then obtain eas' where eas': "g defNode g v-defNode g v#eas'a" "defNode g v set eas'" using eas
 by - (rule old.path2_split_first_last)
 let ?path = "((defNode g v#eas')@tl as)@tl ns"
 have "var g va var g v"
 proof (rule conventional)
 show "g defNode g v-?pathm" using eas' as assms(2)
 by (auto simp del:append_Cons append_assoc intro: old.path2_app)
 show "a set (tl ?path)" using eas' 3 by (auto simp:old.path2_def)
 show "defNode g v set (tl ?path)" using assms(4) 1 eas'(2) asm by auto
 qed (simp_all add:1 assms(3) a(1))
 with a(2) show False by simp
 qed
 moreover have "defNode g v n" using 1 2 by auto
 ultimately have "defNode g v set (butlast as)" using as subsetD[OF set_tl, of "defNode g v" as]
 by - (rule in_set_butlastI, auto simp:old.path2_def)
 }
 note def_in_as = this
 from def_in_as[OF a conv(1,3) b conv(2)] def_in_as[OF b conv(2,4) a conv(1)] conv(5,6) show False by auto
 qed

 lemma convergence_prop':
 assumes "necessaryPhi g v n" "g n-nsm" "v var g ` allUses g m" "x. x set ns ==> v oldDefs g x"
 obtains val where "var g val = v" "phis g (n,val) None"
 using assms proof (induction "length ns" arbitrary: ns m rule: less_induct)
 case less
 from less.prems(4) obtain val where val: "var g val = v" "val allUses g m" by auto
 show ?thesis
 proof (cases "m' set (tl ns). v var g ` phiDefs g m'")
 case False
 with less.prems(5) have "x. x set (tl ns) ==> val allDefs g x"
 by (auto simp: allDefs_def val(1)[symmetric] oldDefs_def dest: in_set_tlD)
 moreover from less.prems(3,5) have "val defs g n"
 by (auto simp: oldDefs_def val(1)[symmetric] dest: old.path2_hd_in_ns)
 ultimately show ?thesis
 using less.prems
 by - (rule that[OF val(1)], rule convergence_prop, auto simp: val)
 next
 case True
 with less.prems(3) obtain ns' m' where m': "g n-ns'm'" "v var g ` phiDefs g m'" "prefix ns' ns"
 by - (erule old.path2_split_first_prop[where P="λm. v var g ` phiDefs g m"], auto dest: in_set_tlD)
 show ?thesis
 proof (cases "m' = n")
 case True
 with m'(2) show ?thesis by (auto simp: phiDefs_def intro: that)
 next
 case False
 with m'(1) obtain m'' where m'': "g n-butlast ns'm''" "m'' set (old.predecessors g m')"
 by - (rule old.path2_unsnoc, auto)
 show ?thesis
 proof (rule less.hyps[of "butlast ns'", OF _])
 show "length (butlast ns') < length ns"
 using m''(1) m'(3) by (cases "length ns'", auto dest: prefix_length_le)

 from m'(2) obtain val vs where vs: "phis g (m',val) = Some vs" "var g val = v"
 by (auto simp: phiDefs_def)
 with m'' obtain val' where "val' phiUses g m''" "val' set vs"
 by - (rule phiUses_exI, auto simp: phiDefs_def)
 with vs have "val' allUses g m''" "var g val' = v" by auto
 then show "v var g ` allUses g m''" by auto

 from m'(3) show "x. x set (butlast ns') ==> v oldDefs g x"
 by - (rule less.prems(5), auto elim: in_set_butlastD)
 qed (auto intro: less.prems(1,2) m''(1))
 qed
 qed
 qed

 lemma nontrivialE:
 assumes "¬trivial g p" "phi g p None" and[simp]: "p allVars g"
 obtains r s where "phiArg g p r" "phiArg g p s" "distinct [p, r, s]"
 proof-
 from assms(2) obtain vs where vs: "phi g p = Some vs" by auto
 have "card (set vs - {p}) 2"
 proof-
 have "card (set vs) 0" using Entry_no_phis[of g p] phi_wf[OF vs] vs by (auto simp:phi_def invar)
 moreover have "set vs {p}" using vs by - (rule phi_no_closed_loop, auto)
 ultimately have "card (set vs - {p}) 0"
 by (metis List.finite_set card_0_eq insert_Diff_single insert_absorb removeAll_id set_removeAll)
 moreover have "card (set vs - {p}) 1"
 proof
 assume "card (set vs - {p}) = 1"
 then obtain q where q: "{q} = set vs - {p}" by - (erule card_eq_1_singleton, auto)
 hence "isTrivialPhi g p q" using vs by (auto simp:isTrivialPhi_def split:option.split)
 moreover have "phiArg g p q" using q vs unfolding phiArg_def by auto
 ultimately show False using assms(1) by (auto simp:trivial_def)
 qed
 ultimately show ?thesis by arith
 qed
 then obtain r s where rs: "r s" "r set vs - {p}" "s set vs - {p}" by (rule set_take_two)
 thus ?thesis using vs by - (rule that[of r s], auto simp: phiArg_def)
 qed

 lemma paths_converge_prefix:
 assumes "g x-xsz" "g y-ysz" "x y" "length xs > 1" "length ys > 1" "x set (butlast ys)" "y set (butlast xs)"
 obtains xs' ys' z' where "old.pathsConverge g x xs' y ys' z'" "prefix xs' xs" "prefix ys' ys"
 using assms proof (induction "length xs" arbitrary:xs ys z rule:nat_less_induct)
 case 1
 from "1.prems"(3,4) have 2: "x y" by (auto simp:old.path2_def)
 show thesis
 proof (cases "set (butlast xs) set (butlast ys) = {}")
 case True
 with "1.prems"(2-) have "old.pathsConverge g x xs y ys z" by (auto simp add: old.pathsConverge'_def)
 thus thesis by (rule "1.prems"(1), simp_all)
 next
 case False
 then obtain xs' z' where xs': "g x-xs'z'" "prefix xs' (butlast xs)" "z' set (butlast ys)" "a set (butlast xs'). a set (butlast ys)"
 using "1.prems"(2,5) by - (rule old.path2_split_first_prop[of g x "butlast xs" _ "λa. a set (butlast ys)"], auto elim: old.path2_unsnoc)
 from xs'(3) "1.prems"(3) obtain ys' where ys': "g y-ys'z'" "strict_prefix ys' ys"
 by - (rule old.path2_strict_prefix_ex)
 show ?thesis
 proof (rule "1.hyps"[rule_format, OF _ _ _ xs'(1) ys'(1) assms(3)])
 show "length xs' < length xs" using xs'(2) xs'(1)
 by - (rule prefix_length_less, rule strict_prefix_butlast, auto)
 from "1.prems"(1) prefix_order.dual_order.strict_implies_order prefix_order.dual_order.trans
 prefix_butlastD xs'(2) ys'(2)
 show "xs'' ys'' z''. old.pathsConverge g x xs'' y ys'' z'' ==> prefix xs'' xs' ==> prefix ys'' ys' ==> thesis"
 by blast
 show "length xs' > 1"
 proof-
 have "length xs' 0" using xs' by auto
 moreover {
 assume "length xs' = 1"
 with xs'(1,3) have "x set (butlast ys)"
 by (auto simp:old.path2_def simp del:One_nat_def dest!:singleton_list_hd_last)
 with "1.prems"(7) have False ..
 }
 ultimately show ?thesis by arith
 qed

 show "length ys' > 1"
 proof-
 have "length ys' 0" using ys' by auto
 moreover {
 assume "length ys' = 1"
 with ys'(1) xs'(1,2) have "y set (butlast xs)"
 by (auto simp:old.path2_def old.path_not_Nil simp del:One_nat_def dest!:singleton_list_hd_last)
 with "1.prems"(8) have False ..
 }
 ultimately show ?thesis by arith
 qed

 show "y set (butlast xs')"
 using xs'(2) "1.prems"(8)
 by (metis in_prefix in_set_butlastD)
 show "x set (butlast ys')"
 by (metis "1.prems"(7) in_set_butlast_appendI strict_prefixE' ys'(2))
 qed simp
 qed
 qed

 lemma ununnecessaryPhis_disjoint_paths_aux:
 assumes "¬unnecessaryPhi g r" and[simp]: "r allVars g"
 obtains n1 ns1 n2 ns2 where
 "var g r oldDefs g n1" "g n1-ns1defNode g r" and
 "var g r oldDefs g n2" "g n2-ns2defNode g r" and
 "set (butlast ns1) set (butlast ns2) = {}"
 proof (cases "phi g r")
 case None
 thus thesis by - (rule that[of "defNode g r" _ "defNode g r"], auto intro!: oldDefsI intro: defNode_cases[of r g])
 next
 case Some
 with assms that show ?thesis by (auto simp: unnecessaryPhi_def necessaryPhi_def old.pathsConverge'_def)
 qed

 lemma ununnecessaryPhis_disjoint_paths:
 assumes "¬unnecessaryPhi g r" "¬unnecessaryPhi g s"
      (* and rs: "phiArg p r" "phiArg p s" "distinct [p, r, s]" *)

      and rs: "defNode g r defNode g s"
      and[simp]: "r allVars g" "s allVars g" "var g r = V" "var g s = V"
    obtains n ns m ms where "V oldDefs g n" "g n-nsdefNode g r" and "V oldDefs g m" "g m-msdefNode g s"
        and "set ns set ms = {}"
  proof-
    obtain n1 ns1 n2 ns2 where
      ns1"V oldDefs g n1" "g n1-ns1defNode g r" "defNode g r set (butlast ns1)" and
      ns2"V oldDefs g n2" "g n2-ns2defNode g r" "defNode g r set (butlast ns2)" and
      ns: "set (butlast ns1) set (butlast ns2) = {}"
    proof-
      from assms obtain n1 ns1 n2 ns2 where
        ns1"V oldDefs g n1" "g n1-ns1defNode g r" and
        ns2"V oldDefs g n2" "g n2-ns2defNode g r" and
        ns: "set (butlast ns1) set (butlast ns2) = {}"
      by - (rule ununnecessaryPhis_disjoint_paths_aux, auto)

      from ns1 obtain ns1where ns1': "g n1-ns1'defNode g r" "defNode g r set (butlast ns1')" "distinct ns1'" "set ns1' set ns1"
        by (auto elim: old.simple_path2)
      from ns2 obtain ns2where ns2': "g n2-ns2'defNode g r" "defNode g r set (butlast ns2')" "distinct ns2'" "set ns2' set ns2"
        by (auto elim: old.simple_path2)

      have "set (butlast ns1') set (butlast ns2') = {}"
      proof (rule equals0I)
        fix x
        assume 1"x set (butlast ns1') set (butlast ns2')"
        with set_butlast_distinct[OF ns1'(3)] ns1'(1have 2"x defNode g r" by (auto simp:old.path2_def)
        with 1 ns1'(4) ns2'(4) ns1(2) ns2(2have "x set (butlast ns1)" "x set (butlast ns2)"
          by - (auto intro!:in_set_butlastI elim:in_set_butlastD simp:old.path2_def)
        with ns show False by auto
      qed

      thus thesis by (rule that[OF ns1(1) ns1'(1,2) ns2(1) ns2'(1,2)])
    qed

    obtain m ms where ms: "V oldDefs g m" "g m-msdefNode g s" "defNode g r set ms"
    proof-
      from assms(2obtain m1 ms1 m2 ms2 where
        ms1"V oldDefs g m1" "g m1-ms1defNode g s" and
        ms2"V oldDefs g m2" "g m2-ms2defNode g s" and
        ms: "set (butlast ms1) set (butlast ms2) = {}"
        by - (rule ununnecessaryPhis_disjoint_paths_aux, auto)
      show thesis
      proof (cases "defNode g r set ms1")
        case False
        with ms1 show thesis by (rule that)
      next
        case True
        have "defNode g r set ms2"
        proof
          assume "defNode g r set ms2"
          moreover note defNode g r defNode g s
          ultimately have "defNode g r set (butlast ms1)" "defNode g r set (butlast ms2)" using True ms1(2) ms2(2)
            by (auto simp:old.path2_def intro:in_set_butlastI)
          with ms show False by auto
        qed
        with ms2 show thesis by (rule that)
      qed
    qed

    show ?thesis
    proof (cases "(set ns1 set ns2) set ms = {}")
      case True
      with ns1 ms show ?thesis by - (rule that, auto)
    next
      case False
      then obtain m' ms' where ms': "g m'-ms'defNode g s" "m' set ns1 set ns2" "set (tl ms') (set ns1 set ns2) = {}" "suffix ms' ms"
        by - (rule old.path2_split_last_prop[OF ms(2), of "λx. x set ns1 set ns2"], auto)
      from this(4) ms(3have 2"defNode g r set ms'"
        by (auto dest: set_mono_suffix)
      {
        fix n1 ns1 n2 ns2
        assume 4"m' set ns1"
        assume ns1"V oldDefs g n1" "g n1-ns1defNode g r" "defNode g r set (butlast ns1)"
        assume ns2"V oldDefs g n2" "g n2-ns2defNode g r" "defNode g r set (butlast ns2)"
        assume ns: "set (butlast ns1) set (butlast ns2) = {}"
        assume ms': "g m'-ms'defNode g s" "set (tl ms') (set ns1 set ns2) = {}"
        have "m' set (butlast ns1)"
        proof-
          from ms'(1have "m' set ms'" by auto
          with 2 have "defNode g r m'" by auto
          with 4 ns1(2show ?thesis by - (rule in_set_butlastI, auto simp:old.path2_def)
        qed
        with ns1(2obtain ns1where ns1': "g n1-ns1'm'" "m' set (butlast ns1')" "strict_prefix ns1' ns1"
          by - (rule old.path2_strict_prefix_ex)
        have thesis
        proof (rule that[OF ns2(1,2), OF ns1(1), of "ns1'@tl ms'"])
          show "g n1-ns1' @ tl ms'defNode g s" using ns1'(1) ms'(1by auto
          show "set ns2 set (ns1' @ tl ms') = {}"
          proof (rule equals0I)
            fix x
            assume x: "x set ns2 set (ns1' @ tl ms')"
            show False
            proof (cases "x set ns1'")
              case True
              hence 4"x set (butlast ns1)" using ns1'(3by (auto dest:set_mono_strict_prefix)
              with ns1(3have "x defNode g r" by auto
              with ns2(2) x have "x set (butlast ns2)"
                by - (rule in_set_butlastI, auto simp:old.path2_def)
              with 4 ns show False by auto
            next
              case False
              with x have "x set (tl ms')" by simp
              with x ms'(2show False by auto
            qed
          qed
        qed
      }
      note 4 = this
      show ?thesis
      proof (cases "m' set ns1")
        case True
        thus ?thesis using ns1 ns2 ns ms'(1,3by (rule 4)
      next
        case False
        with ms'(2have "m' set ns2" by simp
        thus ?thesis using ns ms'(1,3by - (rule 4[OF _ ns2 ns1], auto)
      qed
    qed
  qed

  text Lemma 3. If a $\phi$ function p in a block P for a variable v is unnecessary, but non-trivial, then it has an operand q in a block Q,
 such that q is an unnecessary $\phi$ function and Q does not dominate P.

  lemma 3:
    assumes "unnecessaryPhi g p" "¬trivial g p" and[simp]: "p allVars g"
    obtains q where "phiArg g p q" "unnecessaryPhi g q" "¬def_dominates g q p"
  proof-
    note unnecessaryPhi_def[simp]
    let ?P = "defNode g p"

    txt The node p must have at least two different operands r and s, which are not p itself. Otherwise, p is trivial.
    from assms obtain r s where rs: "phiArg g p r" "phiArg g p s" "distinct [p, r, s]"
      by - (rule nontrivialE, auto)
    hence[simp]: "var g r = var g p" "var g s = var g p" "r allVars g" "s allVars g"
      by (simp_all add:phiArg_same_var)

    txt They can either be:
 ▪ The result of a direct assignment to v.
 ▪ The result of a necessary $\phi$ function r' . This however means that r' was
 reachable by at least two different direct assignments to v. So there is a path
 from a direct assignment of v to p.
 ▪ Another unnecessary $\phi$ function.


    let ?R = "defNode g r"
    let ?S = "defNode g s"

    have[simp]: "?R ?S" using rs by - (rule phiArgs_def_distinct, auto)

    have one_unnec: "unnecessaryPhi g r unnecessaryPhi g s"
    proof (rule ccontr, simp only: de_Morgan_disj not_not)

      txt Assume neither r in a block R nor s in a block S is an unnecessary $\phi$ function.
      assume asm: "¬unnecessaryPhi g r ¬unnecessaryPhi g s"

      txt Then a path from an assignment to v in a block n crosses R and a path from an assignment to v in a block m crosses S.
      txt AMENDMENT: ...so that the paths are disjoint!
      obtain n ns m ms where ns: "var g p oldDefs g n" "g n-ns?R" "n set (tl ns)"
        and ms: "var g p oldDefs g m" "g m-msdefNode g s" "m set (tl ms)"
        and ns_ms: "set ns set ms = {}"
      proof-
        obtain n ns m ms where ns: "var g p oldDefs g n" "g n-ns?R" and ms: "var g p oldDefs g m" "g m-ms?S"
          and ns_ms: "set ns set ms = {}"
          using asm[THEN conjunct1] asm[THEN conjunct2] by (rule ununnecessaryPhis_disjoint_paths, auto)
        moreover from ns obtain ns' where "g n-ns'?R" "n set (tl ns')" "set ns' set ns"
          by (auto intro: old.simple_path2)
        moreover from ms obtain ms' where "g m-ms'?S" "m set (tl ms')" "set ms' set ms"
          by (auto intro: old.simple_path2)
        ultimately show thesis by - (rule that[of n ns' m ms'], auto)
      qed

      from ns(1) ms(1obtain v v' where v: "v defs g n" and v': "v' defs g m" and[simp]: "var g v = var g p" "var g v' = var g p"
        by (auto simp:oldDefs_def)

      txt They converge at P or earlier.
      obtain ns' n' where ns': "g ?R-ns'n'" "r phiUses g n'" "n' set (old.predecessors g ?P)" "?R set (tl ns')"
        by (rule phiArg_path_ex'[OF rs(1)], auto elim: old.simple_path2)
      obtain ms' m' where ms': "g ?S-ms'm'" "s phiUses g m'" "m' set (old.predecessors g ?P)" "?S set (tl ms')"
        by (rule phiArg_path_ex'[OF rs(2)], auto elim: old.simple_path2)

      let ?left = "(ns@tl ns')@[?P]"
      let ?right = "(ms@tl ms')@[?P]"

      obtain ns'' ms'' z where z: "old.pathsConverge g n ns'' m ms'' z" "prefix ns'' ?left" "prefix ms'' ?right"
      proof (rule paths_converge_prefix)
        show "n m" using ns ms ns_ms by auto

        show "g n-?left?P" using ns ns'
          by - (rule old.path2_snoc, rule old.path2_app)
        show "length ?left > 1" using ns by auto
        show "g m-?right?P" using ms ms'
          by - (rule old.path2_snoc, rule old.path2_app)
        show "length ?right > 1" using ms by auto

        have "n set ms" using ns_ms ns by auto
        moreover have "n set (tl ms')" using v rs(2) ms'(2) asm
          by - (rule conventional'[OF ms'(1,4), of s v], auto)
        ultimately show "n set (butlast ?right)"
          by (auto simp del:append_assoc)

        have "m set ns" using ns_ms ms by auto
        moreover have "m set (tl ns')" using v' rs(1) ns'(2) asm
          by - (rule conventional'[OF ns'(1,4), of r v'], auto)
        ultimately show "m set (butlast ?left)"
          by (auto simp del:append_assoc)
      qed

      from this(1) ns(1) ms(1have necessary: "necessaryPhi g (var g p) z" by (rule necessaryPhiI)

      show False
      proof (cases "z = ?P")

        txt Convergence at P is not possible because p is unnecessary.
        case True
        thus False using assms(1) necessary by simp
      next

        txt An earlier convergence would imply a necessary $\phi$ function at this point, which violates the SSA property.
        case False
        from z(1have "z set ns'' set ms''" by (auto simp: old.pathsConverge'_def)
        with False have "z set (ns@tl ns') set (ms@tl ms')"
          using z(2,3)[THEN set_mono_prefix] by (auto elim:set_mono_prefix)
        hence z_on: "z set (tl ns') set (tl ms')" using ns_ms by auto

        {
          fix r ns' n'
          let ?R = "defNode g r"
          assume ns': "g ?R-ns'n'" "r phiUses g n'" "n' set (old.predecessors g (?P))" "?R set (tl ns')"
          assume rs: "var g r = var g p"
          have "z set (tl ns')"
          proof
            assume asm: "z set (tl ns')"
            obtain zs where zs: "g z-zsn'" "set (tl zs) set (tl ns')" using asm
              by - (rule old.path2_split_ex[OF ns'(1)], auto simp: old.path2_not_Nil elim: subsetD[OF set_tl])

            have "phis g (z, r) None"
            proof (rule convergence_prop[OF necessary[simplified rs[symmetric]] zs(1)])
              show "r allUses g n'" using ns'(2by auto
              show "r defs g z"
              proof
                assume "r defs g z"
                hence "?R = z" using zs by - (rule defNode_eq, auto)
                thus False using ns'(4) asm by auto
              qed
            next
              fix x
              assume "x set (tl zs)"
              moreover have "?R set (tl zs)" using ns'(4) zs(2by auto
              ultimately show "r allDefs g x"
                by (metis defNode_eq old.path2_in_αn set_tl subset_code(1) zs(1))
            qed
            hence "?R = z" using zs(1by - (rule defNode_eq, auto simp:allDefs_def phiDefs_def)
            thus False using ns'(4) asm by auto
          qed
        }
        note z_not_on = this

        have "z set (tl ns')" by (rule z_not_on[OF ns'], simp)
        moreover have "z set (tl ms')" by (rule z_not_on[OF ms'], simp)
        ultimately show False using z_on by simp
      qed
    qed

    txt 
  r or s must be an unnecessary $\phi$ function. Without loss of generality, let
  be r.

    {
      fix r s
      assume r: "unnecessaryPhi g r" and[simp]: "var g r = var g p"
      assume[simp]: "var g s = var g p"
      assume rs: "phiArg g p r" "phiArg g p s" "distinct [p, r, s]"
      let ?R = "defNode g r"
      let ?S = "defNode g s"

      have[simp]: "?R ?S" using rs by - (rule phiArgs_def_distinct, auto)
      have[simp]: "s allVars g" using rs by auto

      have thesis
      proof (cases "old.dominates g ?R ?P")
        case False

        txt If R does not dominate P, then r is the sought-after q.
        thus thesis using r rs(1by - (rule that)
      next
        case True

        txt So let R dominate P.
  to Lemma 2, S does not dominate P.

        hence 4"¬old.dominates g ?S ?P" using 2[OF rs] by simp

        txt Employing the SSA property, r /= p
  R /= P.

        (* actually not SSA property *)
        have "?R ?P"
        proof (rule notI, rule allDefs_var_disjoint[of ?R g p r, simplified])
          show "r allDefs g (defNode g r)" using rs(1by auto
          show "p r" using rs(3by auto
        qed auto

        txt Thus, R strictly dominates P.
        hence "old.strict_dom g ?R ?P" using True by simp

        txt This implies that R dominates all
  of P, which contain the uses of p, especially the predecessor S' that
  the use of s.

        moreover obtain ss' S' where ss': "g ?S-ss'S'"
          and S': "s phiUses g S'" "S' set (old.predecessors g ?P)"
          by (rule phiArg_path_ex'[OF rs(2)], simp)
        ultimately have 5"old.dominates g ?R S'" by - (rule old.dominates_unsnoc, auto)

        txt Due to the SSA property, there is a path from S to S' that
  not contain R.

        from ss' obtain ss' where ss': "g ?S-ss'S'" "?S set (tl ss')" by (rule old.simple_path2)
        hence "?R set (tl ss')" using rs(1,2) S'(1)
          by - (rule conventional'[where v=s and v'=r], auto simp del: phiArg_def)

        txt Employing R dominates S' this yields R dominates S.
        hence dom: "old.dominates g ?R ?S" using 5 ss' by - (rule old.dominates_extend)

        txt theorem induces_adjunction:
 have "unnecessaryPhi g s"
 proof (rule ccontr)
 assume s: "¬unnecessaryPhi g s"

 txt Let X contain the most recent definition of v on a path from the start block to R.
 from rs(1) obtain X xs where xs: "g X-xs?R" "var g r oldDefs g X" "old.EntryPath g xs"
 by - (rule allDef_path_from_simpleDef[of r g], auto simp del: phiArg_def)
 then obtain X xs where xs: "g X-xs?R" "var g r oldDefs g X" "x set (tl xs). var g r oldDefs g x" "old.EntryPath g xs"
 by - (rule old.path2_split_last_prop[OF xs(1), of "λx. var g r oldDefs g x"], auto dest: old.EntryPath_suffix)
 then obtain x where x: "x defs g X" "var g x = var g r" by (auto simp: oldDefs_def old.path2_def)
 hence[simp]: "X = defNode g x" using xs by - (rule defNode_eq[symmetric], auto)
 from xs obtain xs where xs: "g X-xs?R" "X set (tl xs)" "old.EntryPath g xs"
 by - (rule old.simple_path2, auto dest: old.EntryPath_suffix)

 txt By Definition 2 there are two definitions
  v that render s necessary. Since R dominates S, the SSA property yields that
  of these definitions is contained in a block Y on a path $R \rightarrow^+ S$.

          (* actually not SSA property *)

          obtain Y ys ys' where Y: "var g s oldDefs g Y"
            and ys: "g Y-ys?S" "?R set ys"
            and ys': "g ?R-ys'Y" "?R set (tl ys')"
          proof (cases "phi g s")
            case None
            hence "s defs g ?S" by - (rule defNode_cases[of s g], auto)
            moreover obtain ns where "g ?R-ns?S" "?R set (tl ns)" using dom
              by - (rule old.dominates_path, auto intro: old.simple_path2)
            ultimately show thesis by - (rule that[where ys1="[?S]"], auto dest: oldDefsI)
          next
            case Some
            with s obtain Y1 ys1 Y2 ys2 where "var g s oldDefs g Y1" "g Y1-ys1?S"
              and "var g s oldDefs g Y2" "g Y2-ys2?S"
              and ys: "set (butlast ys1) set (butlast ys2) = {}" "Y1 Y2"
              by (auto simp:necessaryPhi_def old.pathsConverge'_def)
            moreover from ys(1have "?R
            ultimately obtain Y ys where ys: "var g s  oldDefs g Y" " Y-ys?S" "?R  set (butlast ys)" by auto
            obtain es where es: " Entry g-esY" using ys(2)
              by - (atomize_elim, rule old.Entry_reaches, auto)
            have "?R  set (butlast es@ys)" using old.path2_app'[OF es ys(2)] by - (rule old.dominatesE[OF dom])
            moreover have "?R  last ys" using old.path2_last[OF ys(2), symmetric] by simp
            hence 1: "?R  set ys" using ys(3) by (auto dest: in_set_butlastI)
            ultimately have "?R  set (butlast es)" by auto
            then obtain ys' where " ?R-ys'Y" "?R  set (tl ys')" using es
              by - (rule old.path2_split_ex, assumption, rule in_set_butlastD, auto intro: old.simple_path2)
            thus thesis using ys(1,2) 1 by - (rule that[of Y ys ys'], auto)
          qed

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
          hence[simp]: "Y = defNode g y" using ys by - (rule defNode_eq[symmetric], auto)

          obtain rr' R' where " ?R-rr'R'"
            and R': " phiUses g R'" "R'  set (old.predecessors g ?P)"
            by (rule phiArg_path_ex'[OF rs(1)], simp)
          then obtain rr' where rr': " ?R-rr'R'" "?R  set (tl rr')" by - (rule old.simple_path2)
          with R' obtain rr where rr: " ?R-rr?P" and[simp]: "rr = rr' @ [?P]" by (auto intro: old.path2_snoc)
          from ss' S' obtain ss where ss: " ?S-ss?P" and[simp]: "ss = ss' @ [?P]" by (auto intro: old.path2_snoc)

          txt Thus, there are paths $X \rightarrow^+ P$ and $Y \rightarrow^+ P$ rendering p necessary. Since this is a
contradiction, s is unnecessary and the sought-after q.
          have "old.pathsConverge g X (butlast xs@rr) Y (ys@tl ss) ?P"
          proof (rule old.pathsConvergeI)
            show " X-butlast xs@rr?P" using xs rr by auto
            show " Y-ys@tl ss?P" using ys ss by auto

            {
              assume "X = ?P"
              moreover have " phiDefs g ?P" using assms(1) by (auto simp:phiDefs_def phi_def)
              ultimately have False using simpleDefs_phiDefs_disjoint[of X g] allDefs_var_disjoint[of X g] x by (cases "x = p", auto)
            }
            thus "length (butlast xs@rr) > 1" using xs rr by - (rule old.path2_nontriv, auto)

            {
              assume "Y = ?P"
              moreover have " phiDefs g ?P" using assms(1) by (auto simp:phiDefs_def phi_def)
              ultimately have False using simpleDefs_phiDefs_disjoint[of Y g] allDefs_var_disjoint[of Y g] y by (cases "y = p", auto)
            }
            thus "length (ys@tl ss) > 1" using ys ss by - (rule old.path2_nontriv, auto)
            show "set (butlast (butlast xs @rr))  set (butlast (ys @ tl ss)) = {}"
            proof (rule equals0I)
              fix z
              assume " set (butlast (butlast xs@rr))  set (butlast (ys@tl ss))"
              moreover {
                assume asm: " set (butlast xs)" " set ys"
                have "old.shortestPath g z < old.shortestPath g ?R" using asm(1) xs(3)
                  by - (subst old.path2_last[OF xs(1)], rule old.EntryPath_butlast_less_last)
                moreover
                from ys asm(2) obtain ys' where ys': " z-ys'?S" "suffix ys' ys"
                  by - (rule old.path2_split_ex, auto simp: Sublist.suffix_def)
                have "old.dominates g ?R z" using ys(2) set_tl[of ys] suffix_tl_subset[OF ys'(2)]
                  by - (rule old.dominates_extend[OF dom ys'(1)], auto)
                hence "old.shortestPath g ?R  old.shortestPath g z"
                  by (rule old.dominates_shortestPath_order, auto)
                ultimately have False by simp
              }
              moreover {
                assume asm: " set (butlast xs)" " set (tl ss')"
                have "old.shortestPath g z < old.shortestPath g ?R" using asm(1) xs(3)
                  by - (subst old.path2_last[OF xs(1)], rule old.EntryPath_butlast_less_last)
                moreover
                from asm(2) obtain ss2 where ss2: " z-ss2S'" "set (tl ss2 set (tl ss')"
                  using set_tl[of ss'] by - (rule old.path2_split_ex[OF ss'(1)], auto simp: old.path2_not_Nil dest: in_set_butlastD)
                from S'(1) ss'(1) have "old.dominates g ?S S'" by - (rule allUses_dominated, auto)
                hence "old.dominates g ?S z" using ss'(2) ss2(2)
                  by - (rule old.dominates_extend[OF _ ss2(1)], auto)
                with dom have "old.dominates g ?R z" by auto
                hence "old.shortestPath g ?R  old.shortestPath g z"
                  by - (rule old.dominates_shortestPath_order, auto)
                ultimately have False by simp
              }
              moreover
              have "?R  Y" using ys by (auto simp:old.path2_def)
              with ys'(1) have 1: "length ys' > 1" by (rule old.path2_nontriv)
              {
                assume asm: " set rr'" " set ys"
                then obtain ys1 where ys1: " Y-ys1z" "prefix ys1 ys"
                  by - (rule old.path2_split_ex[OF ys(1)], auto)
                from asm obtain rr2 where rr2: " z-rr2R'" "set (tl rr2 set (tl rr')"
                  by - (rule old.path2_split_ex[OF rr'(1)], auto simp: old.path2_not_Nil)
                let ?path = "ys'@tl (ys1@tl rr2)"
                have "var g y  var g r"
                proof (rule conventional)
                  show " ?R-?pathR'" using ys' ys1 rr2 by (intro old.path2_app)
                  show " allDefs g ?R" using rs by auto
                  show " allUses g R'" using R' by auto

                  thus " set (tl ?path)" using ys'(1) 1
                    by (auto simp:old.path2_def old.path2_not_Nil intro:last_in_tl)
                  show " allDefs g Y" using y by simp
                  show "defNode g r  set (tl ?path)"
                    using ys' ys1(1) ys(2) rr2(2) rr'(2) prefix_tl_subset[OF ys1(2)] set_tl[of ys] by (auto simp: old.path2_not_Nil)
                qed
                hence False using y by simp
              }
              moreover {
                assume asm: " set rr'" " set (tl ss')"
                then obtain ss'1 where ss'1: " ?S-ss'1z" "prefix ss'1 ss'" using ss'
                  by - (rule old.path2_split_ex[OF ss'(1), of z], auto)
                from asm obtain rr'2 where rr'2: " z-rr'2R'" "suffix rr'2 rr'"
                  using rr' by - (rule old.path2_split_ex, auto simp: Sublist.suffix_def)
                let ?path = "butlast ys'@(ys@tl (ss'1@tl rr'2))"
                have "var g s  var g r"
                proof (rule conventional)
                  show " ?R-?pathR'" using ys' ys ss'1 rr'2(1) by (intro old.path2_app old.path2_app')
                  show " allDefs g ?R" using rs by auto
                  show " allUses g R'" using R' by auto
                  from 1 have[simp]: "butlast ys'  []" by (cases ys', auto)
                  show "?S  set (tl ?path)" using ys(1) by auto
                  show " allDefs g ?S" using rs(2) by auto
                  have "?R  set (tl ss')"
                    using rs S'(1) by - (rule conventional''[OF ss'], auto)
                  thus "defNode g r  set (tl ?path)"
                    using ys(1) ss'1(1) suffix_tl_subset[OF rr'2(2)] ys'(2) ys(2) rr'(2) prefix_tl_subset[OF ss'1(2)]
                    by (auto simp: List.butlast_tl[symmetric] old.path2_not_Nil dest: in_set_butlastD)
                qed
                hence False using y by simp
              }
              ultimately show False using rr'(1) ss'(1)
                by (auto simp del: append_assoc simp: append_assoc[symmetric] old.path2_not_Nil dest: in_set_tlD)
            qed
          qed
          hence "necessaryPhi' g p" using xs oldDefsI[OF x(1)] x(2) oldDefsI[OF y(1)] y(2)
            by - (rule necessaryPhiI[where v="var g p"], assumption, auto simp:old.path2_def)
          with assms(1) show False by auto
        qed
        thus ?thesis using rs(2) 4 by - (rule that)
      qed
    }
    from one_unnec this[of r s] this[of s r] rs show thesis by auto
  qed

text Theorem 1. A program in SSA form with a reducible CFG G without any trivial $\phi$ functions is in minimal SSA form.
  theorem reducible_nonredundant_imp_minimal:
    assumes "old.reducible g" "¬redundant g"
    shows "cytronMinimal g"
  unfolding cytronMinimal_def
  proof (rule, rule)
    txt
Proof. Assume G is not in minimal SSA form and contains no trivial $\phi$ functions.
We choose an unnecessary $\phi$ function p.
    fix p
    assume[simp]: " allVars g" and phi: "phi g p  None"
    show "necessaryPhi' g p"
    proof (rule ccontr)
      assume "¬necessaryPhi' g p"
      with phi have asm: "unnecessaryPhi g p" by (simp add: unnecessaryPhi_def)
      let ?A = "{p. p  allVars g  unnecessaryPhi g p}"
      let ?r = "λp q. p  ?A  q  ?A  phiArg g p q  ¬def_dominates g q p"
      let ?r' = "{(p,q). ?r p q}"
      note phiArg_def[simp del]

      txt Due to Lemma 3, p has an operand q,
which is unnecessary and does not dominate p. By induction q has an unnecessary
$\phi$ function as operand as well and so on. Since the program only has a finite
number of operations, there must be a cycle when following the q chain.
      obtain q where q: "(q,q)  ?r'+" " ?A"
      proof (rule serial_on_finite_cycle)
        show "serial_on ?A ?r'"
        proof (rule serial_onI)
          fix x
          assume " ?A"
          then obtain y where "unnecessaryPhi g y" "phiArg g x y" "¬def_dominates g y x"
            using assms(2) by -
          thus " ?A. (x,y)  ?r'" using x ?A by - (rule bexI[where x=y], auto)
        qed
        show "?A  {}" using asm by (auto intro!: exI)
      qed auto

      txt A cycle in the $\phi$ functions implies a cycle in G.
      then obtain ns where ns: " defNode g q-nsdefNode g q" "length ns > 1"
        " set (butlast ns). p q m ns'. ?r p q  g  defNode g q-ns' (defNode g q)  set (tl ns')  q  phiUses g m  m  set (old.predecessors g (defNode g p))  n  set ns'  set ns'  set ns  defNode g p  set ns"
        by - (rule phiArg_tranclp_path_ex[where r="?r"], auto simp: tranclp_unfold)

      txt As G is reducible, the control flow
cycle contains one entry block, which dominates all other blocks in the cycle.
      obtain n where n: " set ns" " set ns. old.dominates g n m"
        using assms(1)[unfolded old.reducible_def, rule_format, OF ns(1)] by auto

      txt Without loss of generality, let q be in the entry block, which means it dominates p.
      have " set (butlast ns)"
      proof (cases "n = last ns")
        case False
        with n(1) show ?thesis by (rule in_set_butlastI)
      next
        case True
        with ns(1) have "n = hd ns" by (auto simp: old.path2_def)
        with ns(2) show ?thesis by - (auto intro: hd_in_butlast)
      qed
      then obtain p q ns' m where ns': "?r p q" " defNode g q-ns'm" "defNode g q  set (tl ns')" " phiUses g m" " set (old.predecessors g (defNode g p))" " set ns'" "set ns'  set ns" "defNode g p  set ns"
        by - (drule ns(3)[THEN bspec], auto)
      hence "old.dominates g (defNode g q) n" by - (rule defUse_path_dominated, auto)
      moreover from ns' n(2) have n_dom: "old.dominates g n (defNode g q)" "old.dominates g n (defNode g p)" by - (auto elim!:bspec)
      ultimately have "defNode g q = n" by auto

      txt Therefore, our assumption is wrong and G is either in minimal SSA form or there exist trivial $\phi$ functions.
      with ns'(1) n_dom(2) show False by auto
    qed
  qed
end

context CFG_SSA_Transformed
begin
  definition "phiCount g = card ((λ(n,v). (n, var g v)) ` dom (phis g))"

  lemma phiCount: "phiCount g = card (dom (phis g))"
  proof-
    have 1: "v = v'"
      if asm: "phis g (n, v)  None" "phis g (n, v')  None" "var g v = var g v'"
      for n v v'
    proof (rule ccontr)
      from asm have[simp]: " allDefs g n" "v'  allDefs g n" by (auto simp: phiDefs_def allDefs_def)
      from asm have[simp]: " set (αn g)" by - (auto simp: phis_in_αn)
      assume " v'"
      with asm show False
        by - (rule allDefs_var_disjoint[of n g v v', THEN notE], auto)
    qed

    show ?thesis
    unfolding phiCount_def
    apply (rule card_image)
    apply (rule inj_onI)
    by (auto intro!: 1)
  qed

  theorem phi_count_minimal:
    assumes "cytronMinimal g" "pruned g"
    assumes "CFG_SSA_Transformed αe αn invar inEdges' Entry oldDefs oldUses defsuses' phis' var'"
    shows "card (dom (phis g))  card (dom (phis' g))"
  proof-
    interpret other: CFG_SSA_Transformed αe αn invar inEdges' Entry oldDefs oldUses defs' uses' phis' var'
      by (rule assms(3))
    {
      fix n v
      assume asm: "phis g (n,v)  None"
      from asm have[simp]: " phiDefs g n" " allDefs g n" by (auto simp: phiDefs_def allDefs_def)
      from asm have[simp]: "defNode g v = n" " set (αn g)" by - (auto simp: phis_in_αn)
      from asm have "liveVal g v"
        by - (rule pruned g[unfolded pruned_def, THEN bspec, of n, rule_format]; simp)
      then obtain ns m where ns: " n-nsm" "var g v  oldUses g m" "x. x  set (tl ns) ==> var g v  oldDefs g x"
        by (rule liveVal_use_path, simp)
      have "v'. phis' g (n,v')  None  var g v = var' g v'"
      proof (rule other.convergence_prop'[OF _ ns(1)])
        from asm show "necessaryPhi g (var g v) n"
          by - (rule cytronMinimal g[unfolded cytronMinimal_def, THEN bspec, of v, simplified, rule_format],
            auto simp: cytronMinimal_def phi_def, auto intro: allDefs_in_allVars[where n=n])
        with ns(1,2) show "var g v  var' g ` other.allUses g m"
          by (subst(asm) other.oldUses_def, auto simp: image_def allUses_def other.oldUses_def intro!: bexI)
        have "var g v  oldDefs g n"
          by (rule simpleDefs_phiDefs_var_disjoint, auto)
        then show "x. x  set ns ==> var g v  oldDefs g x"
          using ns(1) by (case_tac "x = hd ns", auto dest: ns(3) not_hd_in_tl dest: old.path2_hd)
      qed auto
    }
    note 1 = this

    have "phiCount g  other.phiCount g"
    unfolding phiCount_def other.phiCount_def
    apply (rule card_mono)
     apply (rule finite_imageI)
     apply (rule other.phis_finite)
    by (auto simp: dom_def image_def simp del: not_None_eq intro!: 1)

    thus ?thesis by (simp add: phiCount other.phiCount)
  qed
end

end

Messung V0.5 in Prozent
C=51 H=91 G=73

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.23Bemerkung:  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.