Theory Ranking
section ‹Rankings›
theory Ranking
imports
"Alternate"
"Graph"
begin
subsection ‹Rankings›
type_synonym 'state ranking = "'state node ⇒ nat"
definition ranking :: "('label, 'state) nba ⇒ 'label stream ⇒ 'state ranking ⇒ bool" where
"ranking A w f ≡
(∀ v ∈ gunodes A w. f v ≤ 2 * card (nodes A)) ∧
(∀ v ∈ gunodes A w. ∀ u ∈ gusuccessors A w v. f u ≤ f v) ∧
(∀ v ∈ gunodes A w. gaccepting A v ⟶ even (f v)) ∧
(∀ v ∈ gunodes A w. ∀ r k. gurun A w r v ⟶ smap f (gtrace r v) = sconst k ⟶ odd k)"
subsection ‹Ranking Implies Word not in Language›
lemma ranking_stuck:
assumes "ranking A w f"
assumes "v ∈ gunodes A w" "gurun A w r v"
obtains n k
where "smap f (gtrace (sdrop n r) (gtarget (stake n r) v)) = sconst k"
proof -
have 0: "f u ≤ f v" if "v ∈ gunodes A w" "u ∈ gusuccessors A w v" for v u
using assms(1) that unfolding ranking_def by auto
have 1: "shd (v ## gtrace r v) ∈ gunodes A w" using assms(2) by auto
have 2: "sdescending (smap f (v ## gtrace r v))"
using 1 assms(3)
proof (coinduction arbitrary: r v rule: sdescending.coinduct)
case sdescending
obtain u s where 1: "r = u ## s" using stream.exhaust by blast
have 2: "v ∈ gunodes A w" using sdescending(1) by simp
have 3: "gurun A w (u ## s) v" using sdescending(2) 1 by auto
have 4: "u ∈ gusuccessors A w v" using 3 by auto
have 5: "u ∈ gureachable A w v" using graph.reachable_successors 4 by blast
show ?case
unfolding 1
proof (intro exI conjI disjI1)
show "f u ≤ f v" using 0 2 4 by this
show "shd (u ## gtrace s u) ∈ gunodes A w" using 2 5 by auto
show "gurun A w s u" using 3 by auto
qed auto
qed
obtain s k where 3: "smap f (v ## gtrace r v) = s @- sconst k"
using sdescending_stuck[OF 2] by metis
have "gtrace (sdrop (Suc (length s)) r) (gtarget (stake (Suc (length s)) r) v) = sdrop (Suc (length s)) (gtrace r v)"
using sscan_sdrop by rule
also have "smap f … = sdrop (length s) (smap f (v ## gtrace r v))"
by (metis "3" id_apply sdrop_simps(2) sdrop_smap sdrop_stl shift_eq siterate.simps(2) stream.sel(2))
also have "… = sconst k" unfolding 3 using shift_eq by metis
finally show ?thesis using that by blast
qed
lemma ranking_stuck_odd:
assumes "ranking A w f"
assumes "v ∈ gunodes A w" "gurun A w r v"
obtains n
where "Ball (sset (smap f (gtrace (sdrop n r) (gtarget (stake n r) v)))) odd"
proof -
obtain n k where 1: "smap f (gtrace (sdrop n r) (gtarget (stake n r) v)) = sconst k"
using ranking_stuck assms by this
have 2: "gtarget (stake n r) v ∈ gunodes A w"
using assms(2, 3) by (simp add: graph.nodes_target graph.run_stake)
have 3: "gurun A w (sdrop n r) (gtarget (stake n r) v)"
using assms(2, 3) by (simp add: graph.run_sdrop)
have 4: "odd k" using 1 2 3 assms(1) unfolding ranking_def by meson
have 5: "Ball (sset (smap f (gtrace (sdrop n r) (gtarget (stake n r) v)))) odd"
unfolding 1 using 4 by simp
show ?thesis using that 5 by this
qed
lemma ranking_language:
assumes "ranking A w f"
shows "w ∉ language A"
proof
assume 1: "w ∈ language A"
obtain r p where 2: "run A (w ||| r) p" "p ∈ initial A" "infs (accepting A) (p ## r)" using 1 by rule
let ?r = "fromN 1 ||| r"
let ?v = "(0, p)"
have 3: "?v ∈ gunodes A w" "gurun A w ?r ?v" using 2(1, 2) by (auto intro: run_grun)
obtain n where 4: "Ball (sset (smap f (gtrace (sdrop n ?r) (gtarget (stake n ?r) ?v)))) odd"
using ranking_stuck_odd assms 3 by this
let ?s = "stake n ?r"
let ?t = "sdrop n ?r"
let ?u = "gtarget ?s ?v"
have "sset (gtrace ?t ?u) ⊆ gureachable A w ?v"
proof (intro graph.reachable_trace graph.reachable_target graph.reachable.reflexive)
show "gupath A w ?s ?v" using graph.run_stake 3(2) by this
show "gurun A w ?t ?u" using graph.run_sdrop 3(2) by this
qed
also have "… ⊆ gunodes A w" using 3(1) by blast
finally have 7: "sset (gtrace ?t ?u) ⊆ gunodes A w" by this
have 8: "⋀ p. p ∈ gunodes A w ⟹ gaccepting A p ⟹ even (f p)"
using assms unfolding ranking_def by auto
have 9: "⋀ p. p ∈ sset (gtrace ?t ?u) ⟹ gaccepting A p ⟹ even (f p)" using 7 8 by auto
have 19: "infs (accepting A) (smap snd ?r)" using 2(3) by simp
have 18: "infs (gaccepting A) ?r" using 19 by simp
have 17: "infs (gaccepting A) (gtrace ?r ?v)" using 18 unfolding gtrace_alt_def by this
have 16: "infs (gaccepting A) (gtrace (?s @- ?t) ?v)" using 17 unfolding stake_sdrop by this
have 15: "infs (gaccepting A) (gtrace ?t ?u)" using 16 by simp
have 13: "infs (even ∘ f) (gtrace ?t ?u)" using infs_mono[OF _ 15] 9 by simp
have 12: "infs even (smap f (gtrace ?t ?u))" using 13 by (simp add: comp_def)
have 11: "Bex (sset (smap f (gtrace ?t ?u))) even" using 12 infs_any by metis
show False using 4 11 by auto
qed
subsection ‹Word not in Language Implies Ranking›
subsubsection ‹Removal of Endangered Nodes›
definition clean :: "('label, 'state) nba ⇒ 'label stream ⇒ 'state node set ⇒ 'state node set" where
"clean A w V ≡ {v ∈ V. infinite (greachable A w V v)}"
lemma clean_decreasing: "clean A w V ⊆ V" unfolding clean_def by auto
lemma clean_successors:
assumes "v ∈ V" "u ∈ gusuccessors A w v"
shows "u ∈ clean A w V ⟹ v ∈ clean A w V"
proof -
assume 1: "u ∈ clean A w V"
have 2: "u ∈ V" "infinite (greachable A w V u)" using 1 unfolding clean_def by auto
have 3: "u ∈ greachable A w V v" using graph.reachable.execute assms(2) 2(1) by blast
have 4: "greachable A w V u ⊆ greachable A w V v" using 3 by blast
have 5: "infinite (greachable A w V v)" using 2(2) 4 by (simp add: infinite_super)
show "v ∈ clean A w V" unfolding clean_def using assms(1) 5 by simp
qed
subsubsection ‹Removal of Safe Nodes›
definition prune :: "('label, 'state) nba ⇒ 'label stream ⇒ 'state node set ⇒ 'state node set" where
"prune A w V ≡ {v ∈ V. ∃ u ∈ greachable A w V v. gaccepting A u}"
lemma prune_decreasing: "prune A w V ⊆ V" unfolding prune_def by auto
lemma prune_successors:
assumes "v ∈ V" "u ∈ gusuccessors A w v"
shows "u ∈ prune A w V ⟹ v ∈ prune A w V"
proof -
assume 1: "u ∈ prune A w V"
have 2: "u ∈ V" "∃ x ∈ greachable A w V u. gaccepting A x" using 1 unfolding prune_def by auto
have 3: "u ∈ greachable A w V v" using graph.reachable.execute assms(2) 2(1) by blast
have 4: "greachable A w V u ⊆ greachable A w V v" using 3 by blast
show "v ∈ prune A w V" unfolding prune_def using assms(1) 2(2) 4 by auto
qed
subsubsection ‹Run Graph Interation›
definition graph :: "('label, 'state) nba ⇒ 'label stream ⇒ nat ⇒ 'state node set" where
"graph A w k ≡ alternate (clean A w) (prune A w) k (gunodes A w)"
abbreviation "level A w k l ≡ {v ∈ graph A w k. fst v = l}"
lemma graph_0[simp]: "graph A w 0 = gunodes A w" unfolding graph_def by simp
lemma graph_Suc[simp]: "graph A w (Suc k) = (if even k then clean A w else prune A w) (graph A w k)"
unfolding graph_def by simp
lemma graph_antimono: "antimono (graph A w)"
using alternate_antimono clean_decreasing prune_decreasing
unfolding monotone_def le_fun_def graph_def
by metis
lemma graph_nodes: "graph A w k ⊆ gunodes A w" using graph_0 graph_antimono le0 antimonoD by metis
lemma graph_successors:
assumes "v ∈ gunodes A w" "u ∈ gusuccessors A w v"
shows "u ∈ graph A w k ⟹ v ∈ graph A w k"
using assms
proof (induct k arbitrary: u v)
case 0
show ?case using 0(2) by simp
next
case (Suc k)
have 1: "v ∈ graph A w k" using Suc using antimono_iff_le_Suc graph_antimono rev_subsetD by blast
show ?case using Suc(2) clean_successors[OF 1 Suc(4)] prune_successors[OF 1 Suc(4)] by auto
qed
lemma graph_level_finite:
assumes "finite (nodes A)"
shows "finite (level A w k l)"
proof -
have "level A w k l ⊆ {v ∈ gunodes A w. fst v = l}" by (simp add: graph_nodes subset_CollectI)
also have "{v ∈ gunodes A w. fst v = l} ⊆ {l} × nodes A" using gnodes_nodes by force
also have "finite ({l} × nodes A)" using assms(1) by simp
finally show ?thesis by this
qed
lemma find_safe:
assumes "w ∉ language A"
assumes "V ≠ {}" "V ⊆ gunodes A w"
assumes "⋀ v. v ∈ V ⟹ gsuccessors A w V v ≠ {}"
obtains v
where "v ∈ V" "∀ u ∈ greachable A w V v. ¬ gaccepting A u"
proof (rule ccontr)
assume 1: "¬ thesis"
have 2: "⋀ v. v ∈ V ⟹ ∃ u ∈ greachable A w V v. gaccepting A u" using that 1 by auto
have 3: "⋀ r v. v ∈ initial A ⟹ run A (w ||| r) v ⟹ fins (accepting A) r" using assms(1) by auto
obtain v where 4: "v ∈ V" using assms(2) by force
obtain x where 5: "x ∈ greachable A w V v" "gaccepting A x" using 2 4 by blast
obtain y where 50: "gpath A w V y v" "x = gtarget y v" using 5(1) by rule
obtain r where 6: "grun A w V r x" "infs (λ x. x ∈ V ∧ gaccepting A x) r"
proof (rule graph.recurring_condition)
show "x ∈ V ∧ gaccepting A x" using greachable_subset 4 5 by blast
next
fix v
assume 1: "v ∈ V ∧ gaccepting A v"
obtain v' where 20: "v' ∈ gsuccessors A w V v" using assms(4) 1 by (meson IntE equals0I)
have 21: "v' ∈ V" using 20 by auto
have 22: "∃ u ∈ greachable A w V v'. u ∈ V ∧ gaccepting A u"
using greachable_subset 2 21 by blast
obtain r where 30: "gpath A w V r v'" "gtarget r v' ∈ V ∧ gaccepting A (gtarget r v')"
using 22 by blast
show "∃ r. r ≠ [] ∧ gpath A w V r v ∧ gtarget r v ∈ V ∧ gaccepting A (gtarget r v)"
proof (intro exI conjI)
show "v' # r ≠ []" by simp
show "gpath A w V (v' # r) v" using 20 30 by auto
show "gtarget (v' # r) v ∈ V" using 30 by simp
show "gaccepting A (gtarget (v' # r) v)" using 30 by simp
qed
qed auto
obtain u where 100: "u ∈ ginitial A" "v ∈ gureachable A w u" using 4 assms(3) by blast
have 101: "gupath A w y v" using gpath_subset 50(1) subset_UNIV by this
have 102: "gurun A w r x" using grun_subset 6(1) subset_UNIV by this
obtain t where 103: "gupath A w t u" "v = gtarget t u" using 100(2) by rule
have 104: "gurun A w (t @- y @- r) u" using 101 102 103 50(2) by auto
obtain s q where 7: "t @- y @- r = fromN (Suc 0) ||| s" "u = (0, q)"
using grun_elim[OF 104] 100(1) by blast
have 8: "run A (w ||| s) q" using grun_run[OF 104[unfolded 7]] by simp
have 9: "q ∈ initial A" using 100(1) 7(2) by auto
have 91: "sset (trace (w ||| s) q) ⊆ reachable A q"
using nba.reachable_trace nba.reachable.reflexive 8 by this
have 10: "fins (accepting A) s" using 3 9 8 by this
have 12: "infs (gaccepting A) r" using infs_mono[OF _ 6(2)] by simp
have "s = smap snd (t @- y @- r)" unfolding 7(1) by simp
also have "infs (accepting A) …" using 12 by (simp add: comp_def)
finally have 13: "infs (accepting A) s" by this
show False using 10 13 by simp
qed
lemma remove_run:
assumes "finite (nodes A)" "w ∉ language A"
assumes "V ⊆ gunodes A w" "clean A w V ≠ {}"
obtains v r
where
"grun A w V r v"
"sset (gtrace r v) ⊆ clean A w V"
"sset (gtrace r v) ⊆ - prune A w (clean A w V)"
proof -
obtain u where 1: "u ∈ clean A w V" "∀ x ∈ greachable A w (clean A w V) u. ¬ gaccepting A x"
proof (rule find_safe)
show "w ∉ language A" using assms(2) by this
show "clean A w V ≠ {}" using assms(4) by this
show "clean A w V ⊆ gunodes A w" using assms(3) by (meson clean_decreasing subset_iff)
next
fix v
assume 1: "v ∈ clean A w V"
have 2: "v ∈ V" using 1 clean_decreasing by blast
have 3: "infinite (greachable A w V v)" using 1 clean_def by auto
have "gsuccessors A w V v ⊆ gusuccessors A w v" by auto
also have "finite …" using 2 assms(1, 3) finite_nodes_gsuccessors by blast
finally have 4: "finite (gsuccessors A w V v)" by this
have 5: "infinite (insert v (⋃((greachable A w V) ` (gsuccessors A w V v))))"
using graph.reachable_step 3 by metis
obtain u where 6: "u ∈ gsuccessors A w V v" "infinite (greachable A w V u)" using 4 5 by auto
have 7: "u ∈ clean A w V" using 6 unfolding clean_def by auto
show "gsuccessors A w (clean A w V) v ≠ {}" using 6(1) 7 by auto
qed auto
have 2: "u ∈ V" using 1(1) unfolding clean_def by auto
have 3: "infinite (greachable A w V u)" using 1(1) unfolding clean_def by simp
have 4: "finite (gsuccessors A w V v)" if "v ∈ greachable A w V u" for v
proof -
have 1: "v ∈ V" using that greachable_subset 2 by blast
have "gsuccessors A w V v ⊆ gusuccessors A w v" by auto
also have "finite …" using 1 assms(1, 3) finite_nodes_gsuccessors by blast
finally show ?thesis by this
qed
obtain r where 5: "grun A w V r u" using graph.koenig[OF 3 4] by this
have 6: "greachable A w V u ⊆ V" using 2 greachable_subset by blast
have 7: "sset (gtrace r u) ⊆ V"
using graph.reachable_trace[OF graph.reachable.reflexive 5(1)] 6 by blast
have 8: "sset (gtrace r u) ⊆ clean A w V"
unfolding clean_def using 7 infinite_greachable_gtrace[OF 5(1)] by auto
have 9: "sset (gtrace r u) ⊆ greachable A w (clean A w V) u"
using 5 8 by (metis graph.reachable.reflexive graph.reachable_trace grun_subset)
show ?thesis
proof
show "grun A w V r u" using 5(1) by this
show "sset (gtrace r u) ⊆ clean A w V" using 8 by this
show "sset (gtrace r u) ⊆ - prune A w (clean A w V)"
proof (intro subsetI ComplI)
fix p
assume 10: "p ∈ sset (gtrace r u)" "p ∈ prune A w (clean A w V)"
have 20: "∃ x ∈ greachable A w (clean A w V) p. gaccepting A x"
using 10(2) unfolding prune_def by auto
have 30: "greachable A w (clean A w V) p ⊆ greachable A w (clean A w V) u"
using 10(1) 9 by blast
show "False" using 1(2) 20 30 by force
qed
qed
qed
lemma level_bounded:
assumes "finite (nodes A)" "w ∉ language A"
obtains n
where "⋀ l. l ≥ n ⟹ card (level A w (2 * k) l) ≤ card (nodes A) - k"
proof (induct k arbitrary: thesis)
case (0)
show ?case
proof (rule 0)
fix l :: nat
have "finite ({l} × nodes A)" using assms(1) by simp
also have "level A w 0 l ⊆ {l} × nodes A" using gnodes_nodes by force
also (card_mono) have "card … = card (nodes A)" using assms(1) by simp
finally show "card (level A w (2 * 0) l) ≤ card (nodes A) - 0" by simp
qed
next
case (Suc k)
show ?case
proof (cases "graph A w (Suc (2 * k)) = {}")
case True
have 3: "graph A w (2 * Suc k) = {}" using True prune_decreasing by simp blast
show ?thesis using Suc(2) 3 by simp
next
case False
obtain v r where 1:
"grun A w (graph A w (2 * k)) r v"
"sset (gtrace r v) ⊆ graph A w (Suc (2 * k))"
"sset (gtrace r v) ⊆ - graph A w (Suc (Suc (2 * k)))"
proof (rule remove_run)
show "finite (nodes A)" "w ∉ language A" using assms by this
show "clean A w (graph A w (2 * k)) ≠ {}" using False by simp
show "graph A w (2 * k) ⊆ gunodes A w" using graph_nodes by this
qed auto
obtain l q where 2: "v = (l, q)" by force
obtain n where 90: "⋀ l. n ≤ l ⟹ card (level A w (2 * k) l) ≤ card (nodes A) - k"
using Suc(1) by blast
show ?thesis
proof (rule Suc(2))
fix j
assume 100: "n + Suc l ≤ j"
have 6: "graph A w (Suc (Suc (2 * k))) ⊆ graph A w (Suc (2 * k))"
using graph_antimono antimono_iff_le_Suc by blast
have 101: "gtrace r v !! (j - Suc l) ∈ graph A w (Suc (2 * k))" using 1(2) snth_sset by auto
have 102: "gtrace r v !! (j - Suc l) ∉ graph A w (Suc (Suc (2 * k)))" using 1(3) snth_sset by blast
have 103: "gtrace r v !! (j - Suc l) ∈ level A w (Suc (2 * k)) j"
using 1(1) 100 101 2 by (auto elim: grun_elim)
have 104: "gtrace r v !! (j - Suc l) ∉ level A w (Suc (Suc (2 * k))) j" using 100 102 by simp
have "level A w (2 * Suc k) j = level A w (Suc (Suc (2 * k))) j" by simp
also have "… ⊂ level A w (Suc (2 * k)) j" using 103 104 6 by blast
also have "… ⊆ level A w (2 * k) j" by (simp add: Collect_mono clean_def)
finally have 105: "level A w (2 * Suc k) j ⊂ level A w (2 * k) j" by this
have "card (level A w (2 * Suc k) j) < card (level A w (2 * k) j)"
using assms(1) 105 by (simp add: graph_level_finite psubset_card_mono)
also have "… ≤ card (nodes A) - k" using 90 100 by simp
finally show "card (level A w (2 * Suc k) j) ≤ card (nodes A) - Suc k" by simp
qed
qed
qed
lemma graph_empty:
assumes "finite (nodes A)" "w ∉ language A"
shows "graph A w (Suc (2 * card (nodes A))) = {}"
proof -
obtain n where 1: "⋀ l. l ≥ n ⟹ card (level A w (2 * card (nodes A)) l) = 0"
using level_bounded[OF assms(1, 2), of "card (nodes A)"] by auto
have "graph A w (2 * card (nodes A)) =
(⋃ l ∈ {..< n}. level A w (2 * card (nodes A)) l) ∪
(⋃ l ∈ {n ..}. level A w (2 * card (nodes A)) l)"
by auto
also have "(⋃ l ∈ {n ..}. level A w (2 * card (nodes A)) l) = {}"
using graph_level_finite assms(1) 1 by fastforce
also have "finite ((⋃ l ∈ {..< n}. level A w (2 * card (nodes A)) l) ∪ {})"
using graph_level_finite assms(1) by auto
finally have 100: "finite (graph A w (2 * card (nodes A)))" by this
have 101: "finite (greachable A w (graph A w (2 * card (nodes A))) v)" for v
using 100 greachable_subset[of A w "graph A w (2 * card (nodes A))" v]
using finite_insert infinite_super by auto
show ?thesis using 101 by (simp add: clean_def)
qed
lemma graph_le:
assumes "finite (nodes A)" "w ∉ language A"
assumes "v ∈ graph A w k"
shows "k ≤ 2 * card (nodes A)"
using graph_empty graph_antimono assms
by (metis Suc_leI empty_iff monotone_def not_le_imp_less rev_subsetD)
subsection ‹Node Ranks›
definition rank :: "('label, 'state) nba ⇒ 'label stream ⇒ 'state node ⇒ nat" where
"rank A w v ≡ GREATEST k. v ∈ graph A w k"
lemma rank_member:
assumes "finite (nodes A)" "w ∉ language A" "v ∈ gunodes A w"
shows "v ∈ graph A w (rank A w v)"
unfolding rank_def
proof (rule GreatestI_nat)
show "v ∈ graph A w 0" using assms(3) by simp
show "k ≤ 2 * card (nodes A)" if "v ∈ graph A w k" for k
using graph_le assms(1, 2) that by blast
qed
lemma rank_removed:
assumes "finite (nodes A)" "w ∉ language A"
shows "v ∉ graph A w (Suc (rank A w v))"
proof
assume "v ∈ graph A w (Suc (rank A w v))"
then have 2: "Suc (rank A w v) ≤ rank A w v"
unfolding rank_def using Greatest_le_nat graph_le assms by metis
then show "False" by auto
qed
lemma rank_le:
assumes "finite (nodes A)" "w ∉ language A"
assumes "v ∈ gunodes A w" "u ∈ gusuccessors A w v"
shows "rank A w u ≤ rank A w v"
unfolding rank_def
proof (rule Greatest_le_nat)
have 1: "u ∈ gureachable A w v" using graph.reachable_successors assms(4) by blast
have 2: "u ∈ gunodes A w" using assms(3) 1 by auto
show "v ∈ graph A w (GREATEST k. u ∈ graph A w k)"
unfolding rank_def[symmetric]
proof (rule graph_successors)
show "v ∈ gunodes A w" using assms(3) by this
show "u ∈ gusuccessors A w v" using assms(4) by this
show "u ∈ graph A w (rank A w u)" using rank_member assms(1, 2) 2 by this
qed
show "k ≤ 2 * card (nodes A)" if "v ∈ graph A w k" for k
using graph_le assms(1, 2) that by blast
qed
lemma language_ranking:
assumes "finite (nodes A)" "w ∉ language A"
shows "ranking A w (rank A w)"
unfolding ranking_def
proof (intro conjI ballI allI impI)
fix v
assume 1: "v ∈ gunodes A w"
have 2: "v ∈ graph A w (rank A w v)" using rank_member assms 1 by this
show "rank A w v ≤ 2 * card (nodes A)" using graph_le assms 2 by this
next
fix v u
assume 1: "v ∈ gunodes A w" "u ∈ gusuccessors A w v"
show "rank A w u ≤ rank A w v" using rank_le assms 1 by this
next
fix v
assume 1: "v ∈ gunodes A w" "gaccepting A v"
have 2: "v ∈ graph A w (rank A w v)" using rank_member assms 1(1) by this
have 3: "v ∉ graph A w (Suc (rank A w v))" using rank_removed assms by this
have 4: "v ∈ prune A w (graph A w (rank A w v))" using 2 1(2) unfolding prune_def by auto
have 5: "graph A w (Suc (rank A w v)) ≠ prune A w (graph A w (rank A w v))" using 3 4 by blast
show "even (rank A w v)" using 5 by auto
next
fix v r k
assume 1: "v ∈ gunodes A w" "gurun A w r v" "smap (rank A w) (gtrace r v) = sconst k"
have "sset (gtrace r v) ⊆ gureachable A w v"
using 1(2) by (metis graph.reachable.reflexive graph.reachable_trace)
then have 6: "sset (gtrace r v) ⊆ gunodes A w" using 1(1) by blast
have 60: "rank A w ` sset (gtrace r v) ⊆ {k}"
using 1(3) by (metis equalityD1 sset_sconst stream.set_map)
have 50: "sset (gtrace r v) ⊆ graph A w k"
using rank_member[OF assms] subsetD[OF 6] 60 unfolding image_subset_iff by auto
have 70: "grun A w (graph A w k) r v" using grun_subset 1(2) 50 by this
have 7: "sset (gtrace r v) ⊆ clean A w (graph A w k)"
unfolding clean_def using 50 infinite_greachable_gtrace[OF 70] by auto
have 8: "sset (gtrace r v) ∩ graph A w (Suc k) = {}" using rank_removed[OF assms] 60 by blast
have 9: "sset (gtrace r v) ≠ {}" using stream.set_sel(1) by auto
have 10: "graph A w (Suc k) ≠ clean A w (graph A w k)" using 7 8 9 by blast
show "odd k" using 10 unfolding graph_Suc by auto
qed
subsection ‹Correctness Theorem›
theorem language_ranking_iff:
assumes "finite (nodes A)"
shows "w ∉ language A ⟷ (∃ f. ranking A w f)"
using ranking_language language_ranking assms by blast
end