Theory Dom_Kildall_Property
section ‹Properties of the kildall's algorithm on the semilattice ›
theory Dom_Kildall_Property
imports Dom_Kildall "Jinja.Listn" "Jinja.Kildall_1"
begin
lemma sorted_list_len_lt: "x ⊂ y ⟹ finite y ⟹ length (sorted_list_of_set x) < length (sorted_list_of_set y)"
proof-
let ?x = "sorted_list_of_set x"
let ?y = "sorted_list_of_set y"
assume x_y: "x ⊂ y" and fin_y: "finite y"
then have card_x_y: "card x < card y" and fin_x: "finite x"
by (auto simp add:psubset_card_mono finite_subset)
with fin_y have "length ?x = card x" and "length ?y = card y" by auto
with card_x_y show ?thesis by auto
qed
lemma wf_sorted_list:
"wf ((λ(x,y). (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset)"
apply (unfold finite_psubset_def)
apply (rule wf_measure [THEN wf_subset])
apply (simp add: measure_def inv_image_def image_def)
by (auto intro: sorted_list_len_lt)
lemma sorted_list_psub:
"sorted w ⟶
w ≠ [] ⟶
(sorted_list_of_set (set (tl w)), w) ∈ (λ(x, y). (sorted_list_of_set x, sorted_list_of_set y)) ` {(A, B). A ⊂ B ∧ finite B}"
proof(intro strip, simp add:image_iff)
assume sorted_w: "sorted w" and w_n_nil: "w ≠ []"
let ?a = "set (tl w)"
let ?b = "set w"
from sorted_w have sorted_tl_w: "sorted (tl w)" and dist: "distinct w" by (induct w) (auto simp add: sorted_wrt_append )
with w_n_nil have a_psub_b: "?a ⊂ ?b" by (induct w)auto
from sorted_w sorted_tl_w have "w = sorted_list_of_set ?b" and "tl w = sorted_list_of_set (set (tl w))"
by (auto simp add: sorted_less_set_eq)
with a_psub_b show "∃a b. a ⊂ b ∧ finite b ∧ sorted_list_of_set (set (tl w)) = sorted_list_of_set a ∧ w = sorted_list_of_set b"
by auto
qed
locale dom_sl = cfg_doms +
fixes A and r and f and step and start and n
defines "A ≡ ((rev ∘ sorted_list_of_set) ` (Pow (set (nodes))))"
defines "r ≡ nodes_le"
defines "f ≡ nodes_sup"
defines "n ≡ (size nodes)"
defines "step ≡ exec"
defines "start ≡ ([] # (replicate (length (g_V G) - 1) ( (rev[0..<n]))))::state_dom list "
begin
lemma is_semi: "semilat(A,r,f)"
by(insert nodes_semi_is_semilat) (auto simp add:nodes_semi_def A_def r_def f_def)
lemma Cons_less_Conss [simp]:
"x#xs [⊏⇩r] y#ys = (x ⊏⇩r y ∧ xs [⊑⇘r⇙] ys ∨ x = y ∧ xs [⊏⇩r] ys)"
apply (unfold lesssub_def)
apply auto
apply (unfold lesssub_def lesub_def r_def)
apply (simp only: nodes_le_refl)
done
lemma acc_le_listI [intro!]:
"acc r ⟹ acc (Listn.le r) "
apply (unfold acc_def)
apply (subgoal_tac "Wellfounded.wf(UN n. {(ys,xs). size xs = n ∧ size ys = n ∧ xs <_(Listn.le r) ys})")
apply (erule wf_subset)
apply (blast intro: lesssub_lengthD)
apply (rule wf_UN)
prefer 2
apply (rename_tac m n)
apply (case_tac "m=n")
apply simp
apply (fast intro!: equals0I dest: not_sym)
apply (rename_tac n)
apply (induct_tac n)
apply (simp add: lesssub_def cong: conj_cong)
apply (rename_tac k)
apply (simp add: wf_eq_minimal)
apply (simp (no_asm) add: length_Suc_conv cong: conj_cong)
apply clarify
apply (rename_tac M m)
apply (case_tac "∃x xs. size xs = k ∧ x#xs ∈ M")
prefer 2
apply (erule thin_rl)
apply (erule thin_rl)
apply blast
apply (erule_tac x = "{a. ∃xs. size xs = k ∧ a#xs:M}" in allE)
apply (erule impE)
apply blast
apply (thin_tac "∃x xs. P x xs" for P)
apply clarify
apply (rename_tac maxA xs)
apply (erule_tac x = "{ys. size ys = size xs ∧ maxA#ys ∈ M}" in allE)
apply (erule impE)
apply blast
apply clarify
apply (thin_tac "m ∈ M")
apply (thin_tac "maxA#xs ∈ M")
apply (rule bexI)
prefer 2
apply assumption
apply clarify
apply simp
apply blast
done
lemma wf_listn: "wf {(y,x). x ⊏⇘Listn.le r⇙ y}"
by(insert acc_nodes_le acc_le_listI r_def) (simp add:acc_def)
lemma wf_listn': "wf {(y,x). x [⊏⇩r] y}"
by (rule wf_listn)
lemma wf_listn_termination_rel:
"wf ({(y,x). x ⊏⇘Listn.le r⇙ y} <*lex*> (λ(x, y). (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset)"
by (insert wf_listn wf_sorted_list) (fastforce dest:wf_lex_prod)
lemma inA_is_sorted: "xs ∈ A ⟹ sorted (rev xs)"
by (auto simp add:A_def sorted_less_sorted_list_of_set)
lemma list_nA_lt_refl: "xs ∈ nlists n A ⟶ xs [⊑⇘r⇙] xs"
proof
assume "xs ∈ nlists n A"
then have "set xs ⊆ A" by (rule nlistsE_set)
then have "∀i<length xs. xs!i ∈ A" by auto
then have "∀i<length xs. sorted (rev (xs!i))" by (simp add:inA_is_sorted)
then show "xs [⊑⇘r⇙] xs" by(unfold Listn.le_def lesub_def)
(auto simp add:list_all2_conv_all_nth Listn.le_def r_def nodes_le_def)
qed
lemma nil_inA: "[] ∈ A"
apply (unfold A_def)
apply (subgoal_tac "{} ∈ Pow (set nodes)")
apply (subgoal_tac "[] = (λx. rev (sorted_list_of_set x)) {}")
apply (fastforce intro:rev_image_eqI)
by auto
lemma upt_n_in_pow_nodes: "{0..<n} ∈ Pow (set nodes)"
by(auto simp add:n_def nodes_def verts_set)
lemma rev_all_inA: "rev [0..<n] ∈ A"
proof(unfold A_def,simp)
let ?f = "λx. rev (sorted_list_of_set x)"
have "rev [0..<n] =?f {0..<n}" by auto
with upt_n_in_pow_nodes show "rev [0..<n] ∈ ?f ` Pow (set nodes)"
by (fastforce intro: image_eqI)
qed
lemma len_start_is_n: "length start = n"
by (insert len_verts_gt0) (auto simp add:start_def n_def nodes_def dest:Suc_pred)
lemma len_start_is_len_verts: "length start = length (g_V G)"
using len_verts_gt0 by (simp add:start_def)
lemma start_len_gt_0: "length start > 0"
by (insert len_verts_gt0) (simp add:start_def)
lemma start_subset_A: "set start ⊆ A"
by(auto simp add:nil_inA rev_all_inA start_def)
lemma start_in_A : "start ∈ (nlists n A)"
by (insert start_subset_A len_start_is_n)(fastforce intro:nlistsI)
lemma sorted_start_nth: "i < n ⟹ sorted (rev (start!i))"
apply(subgoal_tac "start!i ∈ A")
apply (fastforce dest:inA_is_sorted)
by (auto simp add:start_subset_A len_start_is_n)
lemma start_nth0_empty: "start!0 = []"
by (simp add:start_def)
lemma start_nth_lt0_all: "∀p∈{1..< length start}. start!p = (rev [0..<n])"
by (auto simp add:start_def)
lemma in_nodes_lt_n: "x ∈ set (g_V G) ⟹ x < n"
by (simp add:n_def nodes_def verts_set)
lemma start_nth0_unstable_auxi: "¬ [0] ⊑⇘r⇙ (rev [0..<n])"
by (insert len_verts_gt1 verts_ge_Suc0)
(auto simp add:r_def lesssub_def lesub_def nodes_le_def n_def nodes_def)
lemma start_nth0_unstable: "¬ stable r step start 0"
proof(rule notI,auto simp add: start_nth0_empty stable_def step_def exec_def transf_def)
assume ass: "∀x∈set (sorted_list_of_set (succs 0)). [0] ⊑⇘r⇙ start ! x"
from succ_of_entry0 obtain s where "s ∈ succs 0" and "s ≠ 0 ∧ s ∈ set (g_V G)" using head_is_vert
by (auto simp add:succs_def)
then have "s ∈ set (sorted_list_of_set (succs 0))"
and "start!s = (rev [0..<n])" using fin_succs verts_set len_verts_gt0 by (auto simp add:start_def)
then show False using ass start_nth0_unstable_auxi by auto
qed
lemma start_nth_unstable:
assumes "p ∈ {1 ..< length (g_V G)} "
and "succs p ≠ {}"
shows "¬ stable r step start p"
proof (rule notI, unfold stable_def)
let ?step_p = "step p (start ! p)"
let ?rev_all = "rev[0..<length(g_V G)]"
assume sta: "∀(q, τ)∈set ?step_p. τ ⊑⇘r⇙ start ! q"
from assms(1) have n_sorted: "¬ sorted (rev (p # ?rev_all))"
and p:"p ∈ set (g_V G)" and "start!p = ?rev_all" using verts_set by (auto simp add:n_def nodes_def start_def sorted_wrt_append)
with sta have step_p: "∀(q, τ)∈set ?step_p. sorted (rev (p # ?rev_all)) ∨ (p # ?rev_all = start!q)"
by (auto simp add:step_def exec_def transf_def lesssub_def lesub_def r_def nodes_le_def)
from assms(2) fin_succs p obtain a b where a_b: "(a, b) ∈ set ?step_p" by (auto simp add:step_def exec_def transf_def)
with step_p have "sorted (rev (p # ?rev_all)) ∨ (p # ?rev_all = start!a)" by auto
with n_sorted have eq_p_cons: "(p # ?rev_all = start!a)" by auto
from p have "∀(q, τ)∈set ?step_p. q < n" using succ_in_G fin_succs verts_set n_def nodes_def by (auto simp add:step_def exec_def)
with a_b have "a < n" using len_start_is_n by auto
then have "sorted (rev (start!a))" using sorted_start_nth by auto
with eq_p_cons n_sorted show False by auto
qed
lemma start_unstable_cond:
assumes "succs p ≠ {} "
and "p < length (g_V G)"
shows "¬ stable r step start p"
using assms start_nth0_unstable start_nth_unstable
by(cases "p = 0") auto
lemma unstable_start: "unstables r step start = sorted_list_of_set ({p. succs p ≠ {} ∧ p < length start})"
using len_start_is_len_verts start_unstable_cond
by (subgoal_tac "{p. p < length start ∧ ¬ stable r step start p} = {p. succs p ≠ {} ∧ p < length start}")
(auto simp add: unstables_def stable_def step_def exec_def)
end
declare sorted_list_of_set_insert_remove[simp del]
context dom_sl
begin
lemma (in dom_sl) decomp_propa: "⋀ss w.
(∀(q,t)∈set qs. q < size ss ∧ t ∈ A ) ⟹
sorted w ⟹
set ss ⊆ A ⟹
propa f qs ss w = (merges f qs ss, (sorted_list_of_set ({q. ∃t.(q,t)∈set qs ∧ t ⊔⇘f⇙ (ss!q) ≠ ss!q} ∪ set w)))"
apply (induct qs)
apply (fastforce intro:sorted_less_set_eq)
apply (simp (no_asm))
apply clarify
apply (subst sorted_insort_remove1)
apply simp
apply (simp add: sorted_less_sorted_list_of_set Semilat.closed_f[OF Semilat.intro, OF is_semi])
apply (rule conjI)
apply (blast intro: arg_cong)
apply(simp add: nth_list_update)
by (auto intro: arg_cong)
lemma distinct_pair_filter_n: "distinct (map fst xs) ⟹ a ∉ set (map fst xs) ⟹ (map snd (filter (λ(x,y). x = a) xs)) = []"
by (induct xs) (auto simp add: distinct_map_filter image_def)
lemma map_fst: "map fst (map (λpc. (pc, x)) xs) = xs"
by (induct xs) auto
lemma distinct_p: "p < n ⟶ distinct (map fst (step p (ss!p)))"
proof-
let ?qs = "step p (ss!p)"
have "map fst ?qs = (rev (sorted_list_of_set(succs p)))"
using map_fst[of _ "(rev (sorted_list_of_set(succs p)))"] by (auto simp add:step_def exec_def)
then show ?thesis by auto
qed
lemma distinct_pair_filter: "distinct (map fst xs) ⟹ (a,b)∈ set xs ⟹ map snd (filter (λx. fst x = a) xs) = [b]"
apply (induct xs)
apply simp
apply (auto simp add: distinct_map_filter image_def)
proof-
{
fix xs
assume "∀x∈set xs. a ≠ fst x " and " distinct (map fst xs)"
then show "filter (λx. fst x = a) xs = []" by (induct xs) auto
}
qed
lemma split_comp_eq_pair: "(λx. fst x = a) = (λ(x,y). x = a)"
by (rule split_comp_eq)
lemma distinct_pair_filter': "distinct (map fst xs) ⟹ (a,b)∈ set xs ⟹ (map snd (filter (λ(x,y). x = a) xs)) = [b]"
using distinct_pair_filter by (simp only: split_comp_eq_pair)
lemma merges_property1:
fixes ss w qs
assumes step_bounded_pres: "∀(q, τ) ∈ set qs. q < size ss ∧ τ ∈ A"
and subset_ss_A: "set ss ⊆ A "
and len_ss_n: "length ss = n "
and dist: "distinct (map fst qs) "
shows "∀(q, τ) ∈ set qs. merges f qs ss!q = τ ⊔⇘f⇙ss!q"
proof
fix x
assume "x ∈ set qs"
from dist have τ: "∀(q, τ) ∈ set qs. (map snd (filter (λ(x,y). x = q) qs)) = [τ]" using distinct_pair_filter' by fastforce
from len_ss_n subset_ss_A have "ss ∈ nlists n A" by (rule nlistsI)
with step_bounded_pres have merge_nth: "∀(q, τ) ∈ set qs. (merges f qs ss)!q = map snd [(p',t') ← qs. p'=q] ⨆⇘f⇙ ss!q"
by (fastforce intro:Semilat.nth_merges[OF Semilat.intro, OF is_semi])
with τ have "∀(q, τ) ∈ set qs. (merges f qs ss)!q = [τ]⨆⇘f⇙ ss!q" by fastforce
then show "case x of (q, τ) ⇒ merges f qs ss ! q = τ ⊔⇘f⇙ ss ! q" using ‹x ∈ set qs› by auto
qed
lemma propa_property1:
fixes ss w qs
assumes step_bounded_pres: "∀(q, τ) ∈ set qs. q < size ss ∧ τ ∈ A "
and sorted_w: "sorted (w ::nat list)"
and subset_ss_A: "set ss ⊆ A "
and len_ss_n: "length ss = n "
and dist: "distinct (map fst qs) "
shows "∀(q, τ) ∈ set qs. (fst(propa f qs ss w))!q = τ ⊔⇘f⇙ss!q"
using assms
apply (subgoal_tac "fst (propa f qs ss w) = merges f qs ss")
apply(simp add: merges_property1)
by (auto dest:decomp_propa)
lemma merges_property2:
fixes ss w qs q
assumes step_bounded_pres: "∀(q, τ) ∈ set qs. q < size ss ∧ τ ∈ A"
and subset_ss_A: "set ss ⊆ A"
and len_ss_n: "length ss = n "
and dist: "distinct (map fst qs) "
and q_nin: "q ∉ set(map fst qs) "
and q_lt_len_ss: "q < length ss "
shows "(merges f qs ss)!q = ss!q"
proof-
from len_ss_n subset_ss_A have "ss ∈ nlists n A" by (rule nlistsI)
with step_bounded_pres q_lt_len_ss have merge_nth: "(merges f qs ss)!q = map snd [(p',t') ← qs. p'=q] ⨆⇘f⇙ ss!q"
by (fastforce intro:Semilat.nth_merges[OF Semilat.intro, OF is_semi])
from dist have "q ∉ set(map fst qs) ⟹ (map snd (filter (λ(x,y). x = q) qs)) = []" using distinct_pair_filter_n by fastforce
with merge_nth q_nin have "(merges f qs ss)!q = []⨆⇘f⇙ ss!q" by fastforce
then show "(merges f qs ss)!q = ss ! q" by auto
qed
lemma propa_property2:
fixes ss w qs q
assumes step_bounded_pres: "∀(q, τ) ∈ set qs. q < size ss ∧ τ ∈ A"
and sorted_w: "sorted (w ::nat list)"
and subset_ss_A: "set ss ⊆ A"
and len_ss_n: "length ss = n "
and dist: "distinct (map fst qs) "
and q_nin: "q ∉ set(map fst qs) "
and q_lt_len_ss: "q < length ss "
shows "(fst(propa f qs ss w))!q = ss!q"
using assms
apply (subgoal_tac "fst (propa f qs ss w) = merges f qs ss")
apply(simp add: merges_property2)
by (auto dest:decomp_propa)
lemma merges_incr_lemma_dom:
"∀xs. xs ∈ nlists n A ⟶ distinct (map fst ps) ⟶ (∀(p,x)∈set ps. p<size xs ∧ x ∈ A) ⟶ xs [⊑⇘r⇙] merges f ps xs"
proof(intro strip)
fix xs
assume xs_inA: "xs ∈ nlists n A "
and step_bounded_pres: "∀(p, x)∈set ps. p < length xs ∧ x ∈ A"
and dist: "distinct (map fst ps)"
then have len_xs_n: "length xs = n" and subset_xs_inA: "set xs ⊆ A" by (auto simp add:nlistsE_length)
with step_bounded_pres dist have merge1: "∀(q, τ) ∈ set ps. (merges f ps xs)!q = τ ⊔⇘f⇙xs!q"
using merges_property1 by auto
from step_bounded_pres dist len_xs_n subset_xs_inA
have merge2: "⋀q. q ∉ set(map fst ps) ⟶ q < length xs ⟶ (merges f ps xs)!q = xs!q" using merges_property2 by auto
have len_eq: "length xs = length (merges f ps xs)" by simp
have "∀i<length xs. xs!i ⊑⇘r⇙ (merges f ps xs)!i"
proof(intro strip)
fix i
assume i_lt_len_xs: "i < length xs"
with xs_inA have xs_i_inA: "xs!i ∈ A" by auto
show " xs ! i ⊑⇘r⇙ (merges f ps xs) ! i "
proof(cases "i ∈ set (map fst ps)")
case True
then obtain s' where s': "(i, s') ∈ set ps" by auto
with merge1 have merge1': "(merges f ps xs)!i = s' ⊔⇘f⇙ xs ! i" by auto
from s' step_bounded_pres have "s' ∈ A" by auto
with xs_i_inA merge1' show ?thesis by (auto intro: Semilat.ub2[OF Semilat.intro, OF is_semi])
next
case False note i_nin = this
with i_lt_len_xs merge2 have "(merges f ps xs)!i = xs!i" by auto
with xs_i_inA show ?thesis by (auto simp add:Semilat.refl_r[OF Semilat.intro, OF is_semi])
qed
qed
then have "∀i<length xs. xs!i ⊑⇘r⇙ (merges f ps xs)!i" by auto
then have "∀i<length xs. lesub (xs!i) r ((merges f ps xs)!i)" by (auto simp add:lesssub_def lesub_def)
then have "∀i<length xs. (λx y. lesub x r y) (xs!i)((merges f ps xs)!i)" by simp
then have nth_lt: "⋀i. i <length xs ⟹ (λx y. lesub x r y) (xs!i)((merges f ps xs)!i)" by simp
with len_eq show "xs [⊑⇘r⇙] merges f ps xs"
by (auto simp only:list_all2_conv_all_nth Listn.le_def lesssub_def lesub_def)
qed
lemma merges_incr_dom:
"⟦ xs ∈ nlists n A; distinct (map fst ps); ∀(p,x)∈set ps. p<size xs ∧ x ∈ A ⟧ ⟹ xs [⊑⇘r⇙] merges f ps xs"
by (simp add: merges_incr_lemma_dom)
lemma merges_same_conv_dom [rule_format]:
"(∀xs. xs ∈ nlists n A ⟶ distinct (map fst ps) ⟶
(∀(p,x)∈set ps. p<size xs ∧ x∈A) ⟶
(merges f ps xs = xs) = (∀(p,x)∈set ps. x ⊑⇘r⇙ xs!p))"
apply (induct_tac ps)
apply (simp)
apply clarsimp
apply (rename_tac p x ps xs)
apply (rule iffI)
apply (rule context_conjI)
apply (subgoal_tac "xs[p := x ⊔⇘f⇙ xs!p] [⊑⇘r⇙] xs")
apply (fastforce dest!: le_listD
simp add: nth_list_update Semilat.plus_le_conv[OF Semilat.intro,OF is_semi]
Semilat.ub1[OF Semilat.intro,OF is_semi]
Semilat.ub2[OF Semilat.intro,OF is_semi]
Semilat.lub[OF Semilat.intro,OF is_semi]
)
apply (erule subst, rule merges_incr_dom)
apply (blast intro!: nlistsE_set intro: closedD nlistsE_length [THEN nth_in]
Semilat.closed_f[OF Semilat.intro, OF is_semi])
apply clarify
apply(intro strip)
apply auto
apply (erule allE)
apply (erule impE)
apply assumption
apply (drule bspec)
apply assumption
apply (simp add: Semilat.le_iff_plus_unchanged [OF Semilat.intro, OF is_semi, THEN iffD1] list_update_same_conv [THEN iffD2])
apply blast
apply (simp add: Semilat.le_iff_plus_unchanged[OF Semilat.intro, OF is_semi, THEN iffD1] list_update_same_conv [THEN iffD2])
done
lemma (in Semilat)list_update_le_listI [rule_format]:
"set xs ⊆ A ⟶ set ys ⊆ A ⟶ xs [⊑⇩r] ys ⟶ p < size xs ⟶
x ⊑⇩r ys!p ⟶ x∈A ⟶
xs[p := x ⊔⇩f xs!p] [⊑⇩r] ys"
apply (insert semilat)
apply (simp only: Listn.le_def lesub_def semilat_def)
apply (simp add: list_all2_conv_all_nth nth_list_update)
done
lemma (in Semilat) merges_pres_le_ub:
assumes "set ts ⊆ A"
"set ss ⊆ A"
"∀(p,t)∈set ps. t ⊑⇘r⇙ ts!p ∧ t ∈ A ∧ p < size ts"
"ss [⊑⇘r⇙] ts"
shows "merges f ps ss [⊑⇘r⇙] ts"
proof -
{ fix t ts ps
have
"⋀qs. ⟦set ts ⊆ A; ∀(p,t)∈set ps. t ⊑⇘r⇙ ts!p ∧ t ∈ A ∧ p< size ts ⟧ ⟹
set qs ⊆ set ps ⟶ (∀ss. set ss ⊆ A ⟶ ss [⊑⇘r⇙] ts ⟶ merges f qs ss [⊑⇘r⇙] ts)"
apply (induct_tac qs)
apply simp
apply (simp (no_asm_simp))
apply clarify
apply simp
apply (erule allE, erule impE, erule_tac [2] mp)
apply (drule bspec, assumption)
apply (simp add: closedD Semilat.closed_f)
apply (drule bspec, assumption)
apply (simp )
apply(rule list_update_le_listI)
apply auto
done
} note this [dest]
from assms show ?thesis by blast
qed
lemma termination_lemma:
shows "⟦ss ∈ nlists n A; distinct (map fst qs); ∀(q,t)∈set qs. q<n ∧ t∈A; sorted w; w ≠ [] ⟧ ⟹
ss [⊏⇩r] merges f qs ss ∨
merges f qs ss = ss ∧
(sorted_list_of_set ({q. ∃t. (q,t)∈set qs ∧ t ⊔⇘f⇙ ss!q ≠ ss!q} ∪ set (tl w)),w) ∈
(λx. case x of (x, y) ⇒ (sorted_list_of_set x, sorted_list_of_set y)) ` {(A, B). A ⊂ B ∧ finite B}"
apply(insert is_semi)
apply (unfold lesssub_def)
apply (simp (no_asm_simp) add: merges_incr_dom)
apply (rule impI)
apply (rule merges_same_conv_dom [THEN iffD1, elim_format])
apply assumption+
defer
apply (rule sym, assumption)
defer apply simp
apply (subgoal_tac "∀q t. ¬((q, t) ∈ set qs ∧ t ⊔⇘f⇙ ss ! q ≠ ss ! q)")
defer
apply clarsimp
apply (drule bspec, assumption)
apply (drule bspec, assumption)
apply clarsimp
apply(subgoal_tac "{q. ∃t. (q, t) ∈ set qs ∧ t ⊔⇘f⇙ ss ! q ≠ ss ! q} ∪ set (tl w) = set (tl w)")
apply (auto simp add: sorted_list_psub)
done
lemma bounded_exec: "bounded step n"
apply (insert is_semi,unfold semilat_def bounded_def step_def exec_def transf_def )
by (auto simp add: n_def nodes_def verts_set fin_succs' succ_range)
lemma bounded_exec':
fixes ss w a b
assumes w_n_nil: " w ≠ [] "
and step_hdw: " (a, b) ∈ set (step (hd w) (ss ! hd w)) "
and w_lt_n:"∀p∈set w. p < n "
shows" a < n"
using assms
proof-
from w_lt_n have "hd w < n" using w_n_nil by auto
with bounded_exec have "( ∀τ. ∀(q,τ') ∈ set (step (hd w) τ). q<n)" by (auto simp add:bounded_def)
with step_hdw show "a < n" by auto
qed
definition "wf_dom ss w ≡
(∀τ∈set ss. τ ∈ A) ∧
(∀p < n. sorted (rev ( (ss!p))) ∧
(ss!p ≠ rev [0..< n] ⟶ (∀x∈set ( (ss!p)). x < p)) ∧
(ss!p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)) ∧
sorted w ∧ length ss = n ∧ (∀x∈set w. x < n) "
lemma wf_dom_w:
assumes "wf_dom ss w"
shows "sorted w"
using assms
by (auto simp add:wf_dom_def)
lemma wf_dom_w2:
assumes "wf_dom ss w"
shows "(∀x∈set w. x < n)"
using assms
by (auto simp add:wf_dom_def)
lemma wf_dom_len_eq:
assumes "wf_dom ss w"
shows "(length ss = n)"
using assms
by (auto simp add:wf_dom_def)
lemma wf_dom_inA:
assumes "wf_dom ss w"
shows "ss ∈ nlists n A"
using assms by (auto simp add:wf_dom_def intro: nlistsI)
lemma wf_dom_le:
assumes wf_ss_w: "wf_dom ss w"
shows "ss [⊑⇘r⇙] ss"
using assms
proof-
from wf_ss_w have "∀i<length ss. ss!i ∈ A" by (auto simp add:wf_dom_def)
then have "∀i<length ss. sorted (rev (ss!i))" by (auto simp add:A_def sorted_less_sorted_list_of_set)
then show ?thesis
by (auto simp add:Listn.le_def lesssub_def lesub_def r_def nodes_le_def intro:list_all2_all_nthI)
qed
lemma pres_transf:
"∀ss∈A. p < n ⟶ (∀x<length ss. p > ss!x) ⟶ transf p ss ∈ A"
proof(intro strip, unfold transf_def)
fix ss
assume p_lt_n: "p < n" and p_gt: "∀x<length ss. ss!x < p" and τ_in_A: "ss ∈ A"
then have "set ss ⊆ set nodes" by (unfold A_def) (rule inpow_subset_nodes)
with p_lt_n have p_τ_in: "set (p # ss) ⊆ set nodes" by (auto simp add:n_def nodes_def verts_set)
from τ_in_A have sorted_τ: "sorted (rev ss)" by (simp add:inA_is_sorted)
with p_gt have "sorted (rev (p # ss))" using Cons_sorted_less_nth by auto
with p_τ_in show "(p # ss) ∈ A" by (unfold A_def) (fastforce intro: subset_nodes_inpow)
qed
lemma pres_exec:
assumes "(q,τ) ∈ set (step p (ss!p))"
and "∀n ∈ set (ss!p). p > n"
and "ss!p ∈ A"
and "p < n"
shows "τ ∈ A "
using assms
by (auto simp add:step_def exec_def pres_transf)
lemma wf_hd_neq_all:
assumes wf_ss_w: "wf_dom ss w "
and w_n_nil: "w ≠ [] "
shows " ss!(hd w) ≠ rev [0..<n]"
proof(rule ccontr)
assume "¬ ss ! hd w ≠ (rev [0..<n])" note x = this
from wf_ss_w have "∀x∈ set w. x < n" and "sorted w" by (auto simp add:wf_dom_def)
then have "hd w < n" and y:"∀x ∈ set w. x ≥ hd w" using w_n_nil by (induct w) (auto simp add:sorted_wrt_append)
with wf_ss_w x have "(∃x∈ set w. (x,hd w)∈ g_E G ∧ x < hd w)" by (auto simp add:wf_dom_def)
with y show False by auto
qed
lemma pres_wf_exec:
fixes ss w a b
assumes wf_ss_w: "wf_dom ss w "
and w_n_nil: "w ≠ [] "
shows "∀(q,τ) ∈ set (step (hd w) (ss!(hd w))). τ ∈ A "
using assms
proof(intro strip, auto)
fix a b
assume a_b: "(a, b) ∈ set (step (hd w) (ss ! hd w))"
from wf_ss_w have sorted_w: "sorted w" and hd_w_lt_n: "hd w < n"
and ss_hdw_inA: "ss!hd w ∈ A" using w_n_nil by (auto simp add:wf_dom_def)
from assms have ss_hd_w_neq_all: "ss!hd w ≠ (rev [0..<n])" by (rule wf_hd_neq_all)
with wf_ss_w hd_w_lt_n have "∀x∈set (ss!hd w). hd w > x" by (auto simp add:wf_dom_def)
with ss_hdw_inA hd_w_lt_n a_b show "b ∈ A" using pres_exec by auto
qed
lemma propa_dom_invariant_auxi:
assumes wf_a_b: "wf_dom a b" and b_n_nil: "b ≠ [] "
shows "a!hd b ≠ rev [0..<n] ∧
sorted (rev (hd b # (a!hd b))) ∧
set (hd b # (a!hd b)) ⊆ set nodes ∧
hd b # (a!hd b) ∈ A ∧
(∀(q, τ)∈set (step (hd b) (a!hd b)). q < length a ∧ τ ∈ A)"
using assms
proof-
from assms have "a!hd b ∈ (rev ∘ sorted_list_of_set) ` (Pow (set nodes))"
and sorted_hdb: "sorted (rev (a!hd b))"
and hd_b_lt_n: "hd b < n"
and sorted_b: "sorted b"
and len_eq: "length a = n" by (auto simp add:A_def wf_dom_def)
then have as_subset_nodes: "set (a!hd b) ⊆ set nodes" by (auto simp add:inpow_subset_nodes)
with n_def verts_set assms nodes_def have hdb_cons_subset_nodes: "set (hd b # (a!hd b)) ⊆ set nodes" by (auto simp add:wf_dom_def)
then have hdb_subset_n: "set (hd b # (a!hd b)) ⊆ {0..<n}" using nodes_def verts_set n_def by auto
from wf_a_b b_n_nil have a_hd_b_neq_all: "a!hd b ≠ (rev [0..<n])" using wf_hd_neq_all by auto
with wf_a_b hd_b_lt_n sorted_hdb have sorted_hd_b_cons: "sorted (rev (hd b # (a!hd b)))"
by (fastforce simp add: wf_dom_def dest: Cons_sorted_less)
from hdb_cons_subset_nodes have "set ((hd b # (a!hd b))) ∈ Pow (set (g_V G))" by (auto simp add:nodes_def)
then have pow1: "set ((hd b # (a!hd b))) ⊆ set nodes" by (auto simp add:nodes_def)
from hdb_cons_subset_nodes sorted_hd_b_cons have "hd b # (a!hd b) ∈ (rev ∘ sorted_list_of_set) ` (Pow (set nodes))"
by (fastforce intro: subset_nodes_inpow)
then have hd_b_cons_in_A: "(hd b # (a!hd b)) ∈ A" by (unfold A_def ) (auto simp add:nodes_def)
have "(∀p<n. ∀τ. ∀(q,τ') ∈ set (step p τ). q<n)"
using bounded_exec by (auto simp add:bounded_def)
with hd_b_lt_n have bounded: "∀(q,τ') ∈ set (step (hd b) (a!hd b)). q<n" by auto
from wf_a_b b_n_nil have pres: "∀(q, τ)∈set(step (hd b) (a!hd b)). τ ∈ A" by (rule pres_wf_exec)
with bounded pres have step_pres_bounded: "∀(q, τ)∈set (step (hd b) (a!hd b)). q < length a ∧ τ ∈ A " using len_eq by auto
with a_hd_b_neq_all sorted_hd_b_cons hdb_cons_subset_nodes hd_b_cons_in_A show ?thesis by auto
qed
lemma propa_dom_invariant_aux:
fixes a b ss w
assumes propa: "propa f (step (hd b) (a ! hd b)) a (tl b) = (ss, w) "
and b_n_nil: "b ≠ [] "
and a_in_A: "∀τ∈set a. τ ∈ A"
and ass: "∀p<n.
sorted (rev ( (a ! p))) ∧
(a!p ≠ rev [0..<n] ⟶ (∀x∈set (a!p). x < p)) ∧
(a!p = rev [0..<n] ⟶ (∃x∈set b. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set b ⟶ stable r step a p)"
and sorted_b: "sorted b "
and len_eq: "length a = n "
and b_lt_n: "∀x∈set b. x < n "
shows "(∀τ∈set ss. τ ∈ A) ∧
(∀p<n.
sorted (rev ( (ss ! p))) ∧
(ss!p ≠ rev [0..<n] ⟶ (∀x∈set (ss!p). x < p)) ∧
(ss!p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)) ∧
sorted w ∧ length ss = n ∧ (∀x∈set w. x <n)"
using assms
proof-
let ?a_hdb = "a!hd b"
let ?ss_hdw = "ss!hd w"
let ?ss_hdb = "ss!hd b"
let ?a_hdw = "a!hd w"
let ?qs_a = "step (hd b) ?a_hdb"
let ?qs_ss = "step (hd w) ?ss_hdw"
let ?qs_ss_hdb = "step (hd b) ?ss_hdb"
let ?q_a_wl = "{q. ∃t.(q,t)∈set ?qs_a ∧ t ⊔⇘f⇙ (a!q) ≠ a!q}"
let ?q_ss_wl = "{q. ∃t.(q,t)∈set ?qs_ss ∧ t ⊔⇘f⇙ (ss!q) ≠ ss!q}"
from a_in_A len_eq have a_in_list_nA: "a ∈ nlists n A" by (auto intro: nlistsI)
from a_in_A have "∀p< length a. a!p ∈ A" by (auto simp add:A_def)
then have a_p_subset: "∀p< length a. set (a!p) ⊆ set nodes" by (auto simp add:inpow_subset_nodes A_def)
from a_in_A ass sorted_b len_eq b_lt_n b_n_nil have wf_a_b: "wf_dom a b" by (auto simp add:wf_dom_def)
with b_n_nil have a_hd_b_neq_all: "?a_hdb ≠ rev [0..<n]"
and sorted_hd_b_cons: "sorted (rev (hd b # ?a_hdb))"
and hd_b_cons_in_nodes: "set (hd b # ?a_hdb) ⊆ set nodes"
and hd_b_cons_in_A: "hd b # ?a_hdb ∈ A"
and step_pres_bounded: "(∀(q, τ)∈set (step (hd b) ?a_hdb). q < length a ∧ τ ∈ A)"
using propa_dom_invariant_auxi
by auto
then have hdb_subset_n: "set (hd b # ?a_hdb) ⊆ {0..<n}" using nodes_def verts_set n_def by auto
from b_lt_n b_n_nil have hd_b_lt_n: "hd b < n"
and tl_b_lt_n: "∀x∈ set (tl b). x < n"
by (induct b)(auto simp add:wf_dom_def)
then have dist: "distinct (map fst ?qs_a)" using distinct_p by auto
from b_lt_n len_eq sorted_b have sorted_tl_b: "sorted (tl b)" by (induct b) auto
from b_lt_n verts n_def nodes_def verts_set have b_in_verts: "∀x∈set b. x ∈ set (g_V G)" by auto
then have hd_b_in_verts: "hd b ∈ set (g_V G)" using b_n_nil by auto
then have fin_succ_hd_b: "finite (succs (hd b))" using fin_succs by auto
have fin_q1: "finite {q. ∃t.(q,t)∈set ?qs_a}"
and fin_q2: "finite ?q_a_wl" by (auto simp add:step_def exec_def image_def)
then have fin: "finite (?q_a_wl ∪ set (tl b))" by auto
from a_in_A have set_a: "set a ⊆ A" by auto
with step_pres_bounded sorted_tl_b len_eq dist
have "∀(q, τ) ∈ set ?qs_a. (fst(propa f ?qs_a a (tl b)))!q = τ ⊔⇘f⇙a!q" by (auto dest:propa_property1)
with propa have propa_ss1: "∀(q, τ) ∈ set ?qs_a. ss!q = τ ⊔⇘f⇙a!q" by simp
then have propa_ss1': "∀(q, τ) ∈ set ?qs_a. ss!q = (hd b # ?a_hdb) ⊔⇘f⇙a!q" by (auto simp add:step_def exec_def transf_def)
then have succ_self_eq: "∀(q, τ) ∈ set ?qs_a. q = hd b ⟶ ss!q = a!q"
by(auto simp add: f_def nodes_sup_def plussub_def inter_sorted_cons[OF sorted_hd_b_cons])
have step_hd_b: "∀(q,τ)∈set ?qs_a. τ = (hd b # ?a_hdb)"
by(auto simp add:step_def exec_def transf_def)
from step_pres_bounded sorted_tl_b set_a len_eq dist
have "⋀q. q ∉ set(map fst ?qs_a) ⟹ q < length a ⟹ (fst(propa f ?qs_a a (tl b)))!q = a!q"
by (auto intro:propa_property2)
with propa have exec2: "⋀q. q ∉ set(map fst ?qs_a) ⟹ q < length a ⟹ ss!q = a!q" by auto
then have ss_hd_b_eq_a: "ss!hd b = a!hd b" using hd_b_lt_n len_eq fin_succ_hd_b succ_self_eq
by (auto simp add:step_def exec_def)
then have hdb_nin_w: "hd b ∉ ?q_a_wl" using fin_succ_hd_b propa_ss1 by (auto simp add:step_def exec_def)
from step_pres_bounded sorted_tl_b set_a
have "snd (propa f ?qs_a a (tl b)) = (sorted_list_of_set (?q_a_wl ∪ set (tl b)))"
by (fastforce dest:decomp_propa)
with propa have ww: "w = sorted_list_of_set (?q_a_wl ∪ set (tl b))" by simp
then have sorted_w:"sorted w" by (simp add:sorted_less_sorted_list_of_set)
from ww have set_ww: "set w =?q_a_wl ∪ set (tl b)" using fin by auto
with step_pres_bounded tl_b_lt_n ww fin len_eq have w_lt_n: "(∀x∈set w. x < n)" using len_eq by auto
then have w_set': "∀x∈set w. x ∈ {0..<n}" using verts_set len_eq by auto
then have w_set: "set w ⊆ {0..<n}" by auto
from sorted_b have hd_b_nin_tl_b: "hd b ∉ set (tl b) " by (induct b) (auto simp add:sorted_wrt_append)
with hdb_nin_w ww have "hd b ∉ set w" using fin by auto
from step_pres_bounded sorted_tl_b set_a propa have ss_merge: "ss = merges f ?qs_a a" by (auto dest: decomp_propa)
from step_pres_bounded a_in_list_nA have "∀(q, τ)∈set (step (hd b) (a ! hd b)). q < n ∧ τ ∈ A" using len_eq by simp
with a_in_list_nA have "merges f ?qs_a a ∈ nlists n A"
by (rule Semilat.merges_preserves_type[OF Semilat.intro, OF is_semi])
with ss_merge have ss_in_A: "ss ∈ nlists n A" by simp
then have len_ss_n: "length ss = n" using len_eq by simp
with len_eq have len_ss_n: "length ss = n" by auto
from ss_in_A have set_ss: "set ss ⊆ A " by (rule nlistsE_set)
then have ss_inA: "∀τ∈set ss. τ ∈ A" by auto
then have ss_p_subset: "∀p< length ss. set (ss!p) ⊆ set nodes" by (auto simp add:inpow_subset_nodes A_def)
from w_lt_n len_ss_n have bounded_a: "⋀a b. w ≠ [] ⟹ (a, b) ∈ set ?qs_ss ⟹ a < length ss"
by (auto simp add:bounded_exec')
have sorted_a_hdw_n: "w ≠ [] ⟶ sorted (rev ?a_hdw)"
using wf_a_b len_eq w_set' by (auto simp add:wf_dom_def)
have sorted_ss_hdw_n: "w ≠ [] ⟶ sorted (rev ?ss_hdw)"
using ss_in_A inA_is_sorted w_lt_n by auto
have "w ≠ [] ⟶ (hd w # ?ss_hdw) ∈ A"
proof
assume w_n_nil: "w ≠ []"
with w_lt_n have hd_w_lt_n: "hd w < n" by auto
with a_in_A have a_hdw_inA: "?a_hdw ∈ A" using len_eq by auto
then have a_hdw_in_nodes: "set ?a_hdw ⊆ set nodes" by (unfold A_def )(rule inpow_subset_nodes)
from hd_w_lt_n have hdw_in_nodes: "hd w ∈ set nodes" using verts_set by (simp add:n_def nodes_def)
from sorted_a_hdw_n w_n_nil have sorted_a_hdw: "sorted (rev ?a_hdw)" by auto
show "(hd w # ?ss_hdw) ∈ A"
proof(cases "hd w ∈ succs (hd b)")
case True
then obtain s where s: "(hd w, s) ∈ set ?qs_a" using fin_succ_hd_b by (auto simp add:step_def exec_def)
with step_hd_b have "s = (hd b # ?a_hdb)" by auto
with s propa_ss1 have ss_hd_w: "?ss_hdw = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_hdw" by auto
with hd_b_cons_in_A a_hdw_inA have "?ss_hdw ∈ A" by (simp add: Semilat.closed_f[OF Semilat.intro, OF is_semi])
then have ss_hdw_in_nodes: "set ?ss_hdw ⊆ set nodes"
by (auto simp add:inpow_subset_nodes A_def)
with hdw_in_nodes have hdw_cons_ss_in_nodes: "set (hd w # ?ss_hdw) ⊆ set nodes" by auto
then have in_pow: "set (hd w # ?ss_hdw) ∈ Pow (set (g_V G))" by (auto simp add:nodes_def)
from sorted_a_hdw ss_hd_w sorted_hd_b_cons
have "sorted (rev ?ss_hdw)" and "set ?ss_hdw = set (hd b # ?a_hdb) ∩ set ?a_hdw"
by (auto simp add:f_def plussub_def nodes_sup_def inter_sorted_correct)
then have sorted_ss_hdw: "sorted (rev ?ss_hdw)"
and ss_hdw_subset_a_hdb_cons: "set ?ss_hdw ⊆ set (hd b # ?a_hdb)"
and ss_hdw_subset_a_hdw: "set ?ss_hdw ⊆ set ?a_hdw" by auto
from sorted_hd_b_cons have "∀x∈ set (hd b # ?a_hdb). x ≤ hd b" using b_n_nil
by (induct b) (auto simp add:sorted_wrt_append)
with ss_hdw_subset_a_hdb_cons
have ss_hdw_lt_hdb: "∀x∈set ?ss_hdw. x ≤ hd b" using sorted_hd_b_cons by auto
have sorted_rev_hdw: "sorted (rev (hd w # ?ss_hdw))"
proof(cases "?a_hdw = rev [0..<n]")
case True
with wf_a_b have "∃x∈ set b. (x,hd w)∈ g_E G ∧ x < hd w" using hd_w_lt_n by (auto simp add:wf_dom_def)
then obtain prev_hd_w where prev_hd_w_in_b: "prev_hd_w ∈ set b"
and prev_hd_w: "(prev_hd_w, hd w)∈ g_E G"
and prev_hd_w_lt: "prev_hd_w < hd w" by auto
show ?thesis
proof(cases "prev_hd_w = hd b")
case True
with prev_hd_w_lt have "hd b < hd w" by auto
with ss_hdw_lt_hdb have "∀x∈set ?ss_hdw. hd w > x" by auto
with sorted_ss_hdw show ?thesis by (auto simp add:sorted_wrt_append)
next
case False
with prev_hd_w_in_b have "prev_hd_w ∈ set (tl b)" by (induct b) auto
with ww have prev_hd_w_nin_w: "prev_hd_w ∈ set w" using fin by auto
from sorted_w have "∀x∈ set w. x ≥ hd w" by(induct w) (auto simp add:sorted_wrt_append sorted_less_sorted_list_of_set)
with prev_hd_w_lt have "prev_hd_w ∉ set w" by auto
with prev_hd_w_nin_w show ?thesis by auto
qed
next
case False
with wf_a_b have "(∀x∈set ?a_hdw. x < hd w)" using hd_w_lt_n by (auto simp add:wf_dom_def)
with ss_hdw_subset_a_hdw
have "(∀x∈set ?ss_hdw. x < hd w)" by auto
with sorted_ss_hdw show ?thesis by (auto simp add:sorted_wrt_append)
qed
with hdw_cons_ss_in_nodes show "hd w # ?ss_hdw ∈ A" using A_def by (fastforce dest:subset_nodes_inpow)
next
case False note hd_w_nin_succ_hdb = this
then have "hd w ∉ set (map fst ?qs_a)" using fin_succ_hd_b by (auto simp add:step_def exec_def)
with exec2 have ss_hd_w_eq_a: "?ss_hdw = ?a_hdw" using hd_w_lt_n len_ss_n len_eq by auto
with a_hdw_in_nodes sorted_a_hdw have ss_hdw_in_nodes: "set ?ss_hdw ⊆ set nodes"
and sorted_ss_hdw: "sorted (rev ?ss_hdw)" by auto
with hdw_in_nodes have hdw_cons_in_nodes: "set (hd w # ?ss_hdw) ⊆ set nodes" by (auto)
from hd_w_nin_succ_hdb ww have hd_w_non: "hd w ∉{q. ∃t. (q, t) ∈ set ?qs_a ∧ t ⊔⇘f⇙ a ! q ≠ a ! q}"
using fin_succ_hd_b by (auto simp add:step_def exec_def )
from set_ww hd_w_non have hd_w_in_tl_b: "hd w ∈ set (tl b)" using sorted_tl_b ‹w ≠ []› by auto
have sorted_rev_hdw: "sorted (rev (hd w # ?ss_hdw))"
proof(cases "?a_hdw = rev [0..<n]")
case True
with wf_a_b have "∃x∈ set b. (x,hd w)∈ g_E G ∧ x < hd w" using hd_w_lt_n by (auto simp add:wf_dom_def)
then obtain prev_hd_w where prev_hd_w_in_b: "prev_hd_w ∈ set b"
and prev_hd_w: "(prev_hd_w, hd w)∈ g_E G"
and prev_hd_w_lt: "prev_hd_w < hd w" by auto
from ww have "sorted w" by(simp add:sorted_less_sorted_list_of_set)
then have "∀x∈ set w. x ≥ hd w" using w_n_nil by (induct w) (auto simp add:sorted_wrt_append)
with prev_hd_w_lt have prev_hd_w_nin_w: "prev_hd_w ∉ set w" using w_n_nil by auto
with set_ww have "prev_hd_w ∉ set (tl b)" by auto
with prev_hd_w_in_b have "prev_hd_w = hd b" using sorted_b by (induct b) auto
with prev_hd_w have "(hd b, hd w) ∈ g_E G" by auto
with hd_w_nin_succ_hdb show ?thesis by (auto simp add:succs_def)
next
case False
with wf_a_b have a_hdw_lt: "(∀x∈set ?a_hdw. x < hd w)"
and "sorted (rev ?a_hdw)" using hd_w_lt_n by (auto simp add:wf_dom_def)
with ss_hd_w_eq_a have "sorted (rev ?ss_hdw)" by simp
from ss_hd_w_eq_a have "?a_hdw = ?ss_hdw" by auto
with a_hdw_lt have "∀x∈set ?ss_hdw. x < hd w" by auto
with sorted_ss_hdw show ?thesis by (auto simp add:sorted_wrt_append)
qed
with hdw_cons_in_nodes show " (hd w # ss ! hd w) ∈ A" by (unfold A_def) (rule subset_nodes_inpow)
qed
qed
then have pres_ss: "⋀q τ. w ≠ [] ⟹ (q, τ) ∈ set (step (hd w) ?ss_hdw) ⟹ τ ∈ A"
by (auto simp add:step_def exec_def transf_def)
have hd_b_ss_sta: "stable r step ss (hd b)"
proof(unfold stable_def, clarsimp)
fix q τ
assume "(q, τ) ∈ set ?qs_ss_hdb "
then have "q ∈ succs (hd b)" and "τ = transf (hd b) ?ss_hdb" using hd_b_lt_n fin_succ_hd_b
by (auto simp add:step_def exec_def)
then have τ:"τ = (hd b # ?a_hdb)" using ss_hd_b_eq_a by (auto simp add:transf_def)
from ‹q ∈ succs (hd b)› hd_b_lt_n have "q∈ set (g_V G)" using succ_in_G by auto
then have "q < n" using verts_set by (auto simp add:n_def nodes_def)
with wf_a_b have a_q_inA: "a!q ∈ A" by (auto simp add:wf_dom_def)
from wf_a_b a_hd_b_neq_all hd_b_lt_n have "∀x∈ set ( (a!hd b)). x < hd b" by (auto simp add:wf_dom_def)
with sorted_hd_b_cons have "sorted (rev (hd b # ?a_hdb))" by (auto simp add:sorted_wrt_append)
from propa_ss1 ‹(q, τ) ∈ set (step (hd b) (ss ! hd b))›
have "ss!q = τ ⊔⇘f⇙ a ! q" using ‹ss!hd b = a!hd b› by auto
with τ have "ss!q = (hd b # ?a_hdb) ⊔⇘f⇙ a ! q" by simp
with hd_b_cons_in_A a_q_inA have " (hd b # ?a_hdb)⊑⇘r⇙ ss!q "
by (auto simp add: Semilat.ub1[OF Semilat.intro, OF is_semi])
with τ show "τ ⊑⇘r⇙ ss ! q" by auto
qed
have wf_dom_2: "∀p<n.
sorted (rev (ss ! p)) ∧
(ss ! p ≠ rev [0..<n] ⟶ (∀x∈set ( (ss ! p)). x < p)) ∧
(ss ! p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)"
proof (intro strip)
fix p
let ?a_p = "a!p"
let ?ss_p = "ss!p"
assume p_lt_n: "p < n"
with wf_a_b have a_p_inA: "?a_p ∈ A"
and sorted_a_p: "sorted (rev ?a_p)"
and sta_a_p: "p ∉ set b ⟶ stable r step a p" by (auto simp add:wf_dom_def)
from p_lt_n have "p ∈ set (g_V G)" using verts_set n_def nodes_def by auto
then have fin_succ_p: "finite (succs p)" using fin_succs by auto
from set_a p_lt_n have a_p_inA: "?a_p ∈ A" using ‹length a = n› by (auto simp add:A_def)
then have "set ?a_p ⊆ set nodes" using inpow_subset_nodes by (auto simp add:A_def)
with p_lt_n have set_p_a_p: "set (p#?a_p) ⊆ set nodes" using n_def nodes_def verts_set by auto
from p_lt_n len_eq have p_lt_len_a: "p < length a" by auto
with ss_inA have ss_p_in_A: "ss!p ∈ A" using len_eq len_ss_n by auto
with p_lt_n have sorted_ss_p: "sorted (rev ?ss_p)" by (auto simp add:A_def sorted_less_sorted_list_of_set)
have len_ss_eq_a: "length ss = length a" using len_eq len_ss_n by auto
have p_nin_w_eq: "p ∉ set w ⟷ (p ∉ set b ∨ p = hd b) ∧ (∀s. (p, s) ∈ set ?qs_a ⟶ s ⊔⇘f⇙ ?a_p = ?a_p)"
proof
assume "p ∉ set w"
with set_ww have p_nin1: "p ∉ {q. ∃t. (q, t) ∈ set ?qs_a∧ t ⊔⇘f⇙ a ! q ≠ a ! q}"
and p_nin2: "p ∉ set (tl b)" by auto
from p_nin1 have p_nin: "(∀s. (p, s) ∈ set ?qs_a ⟶ s ⊔⇘f⇙ ?a_p = ?a_p)" by auto
from p_nin2 have "p ∉ set b ∨ p = hd b" by (induct b) auto
with p_nin show "(p ∉ set b ∨ p = hd b) ∧ (∀s. (p, s) ∈ set ?qs_a ⟶ s ⊔⇘f⇙ ?a_p = ?a_p)" by auto
next
assume "(p ∉ set b ∨ p = hd b) ∧ (∀s. (p, s) ∈ set ?qs_a ⟶ s ⊔⇘f⇙ ?a_p = ?a_p)"
then have p1: "p ∉ set b ∨ p = hd b"
and p2: "∀s. (p, s) ∈ set ?qs_a ⟶ s ⊔⇘f⇙ a ! p = ?a_p" by auto
from p1 have "p ∉ set (tl b)"
proof
assume "p ∉ set b"
then show ?thesis by(induct b) auto
next
assume "p = hd b"
with sorted_b show ?thesis by (induct b) (auto simp add:sorted_wrt_append)
qed
with p2 set_ww show "p ∉ set w" using set_ww by auto
qed
have stable_ss_p: "p ∉ set w ⟶ w ≠ Nil ⟶ stable r step ss p"
proof (clarsimp simp add: stable_def split_paired_all)
fix q τ
assume p_nin_w: "p ∉ set w" and w_n_nil: "w ≠ Nil" and step_ss_p: "(q, τ) ∈ set (step p ?ss_p) "
from p_nin_w have p_cond: "(p ∉ set b ∨ p = hd b) ∧
(∀s. (p, s) ∈ set ?qs_a ⟶ (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p = ?a_p)"
using p_nin_w_eq by (auto simp add:transf_def step_def exec_def)
then have p_cond1: "(p ∉ set b ∨ p = hd b)"
and p_cond2: "(∀s. (p, s) ∈ set ?qs_a ⟶ (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p = ?a_p)"by auto
from bounded_a pres_ss w_n_nil have " ∀(q, t)∈set ?qs_ss. q < length ss ∧ t ∈ A" by auto
then have "∀(q, t)∈set (step (hd w) (ss ! hd w)). q < length ss ∧ (transf (hd w) (ss!hd w)) ∈ A"
by (auto simp add:step_def exec_def)
have ss_a_p_eq: "?ss_p = ?a_p"
proof(cases "p ∈ succs (hd b)")
case True note p_in_succ_hd_b = this
from ‹p ∈ succs (hd b)› propa_ss1' have ss_p: "?ss_p = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p" using fin_succ_hd_b
by (auto simp add:step_def exec_def)
from p_in_succ_hd_b p_cond2 have " (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p= ?a_p" using fin_succ_hd_b
by (auto simp add:step_def exec_def)
with ss_p show ?thesis by auto
next
case False
then have "p ∉ {q. ∃t. (q, t) ∈ set ?qs_a}" using fin fin_succ_hd_b by (auto simp add:step_def exec_def)
then have "p ∉ set ( map fst ?qs_a)" by auto
with p_lt_n show ?thesis using exec2 len_eq by auto
qed
have "(∀(q, τ)∈set (step p ?ss_p). transf p ?ss_p ⊑⇘r⇙ ss ! q) "
proof(intro strip, clarsimp)
fix succ_p z
let ?a_succ_p = "a!succ_p"
let ?ss_succ_p = "ss!succ_p"
assume "(succ_p, z) ∈ set (step p ?ss_p)"
then have succ_p: "succ_p ∈ succs p" using p_lt_n fin_succ_p by (auto simp add:step_def exec_def)
with p_lt_n have succ_p_lt_n: "succ_p < n" using succ_in_verts n_def nodes_def verts_set by auto
with wf_a_b have a_succ_p_inA: "?a_succ_p ∈ A" by (auto simp add:wf_dom_def)
from succ_p_lt_n ss_in_A have ss_succ_p_inA: "?ss_succ_p ∈ A" by auto
have p_nin_b_ssp: "p ∉ set b ⟹ transf p ?ss_p ∈ A ∧ transf p ?ss_p ⊑⇩r ?a_succ_p"
proof-
assume "p ∉ set b"
with sta_a_p have "(∀(q,τ) ∈ set (step p ?a_p). τ ⊑⇩r a!q)" by (simp add:stable_def)
with succ_p have transf_p_succp':"transf p ?a_p ⊑⇩r ?a_succ_p" using fin_succ_p
by (auto simp add:stable_def step_def exec_def)
with ss_a_p_eq have transf_lt_p: "transf p ?ss_p ⊑⇩r ?a_succ_p" by auto
from transf_p_succp' have "(p# ?a_p) ⊑⇩r ?a_succ_p" by (auto simp add:transf_def)
then have "sorted (rev (p#?a_p)) ∨ (p#?a_p = ?a_succ_p)"
by (auto simp add:step_def exec_def transf_def r_def lesssub_def lesub_def nodes_le_def)
with set_p_a_p a_succ_p_inA
have "(p#?a_p) ∈ (rev ∘ sorted_list_of_set) ` (Pow (set nodes))" using subset_nodes_inpow by (auto simp add:A_def)
then have "transf p ?a_p ∈ A" using transf_def by (auto simp add:A_def transf_def)
then show ?thesis using ss_a_p_eq transf_lt_p by auto
qed
show "transf p ?ss_p ⊑⇘r⇙ ?ss_succ_p"
proof(cases "p ∈ succs (hd b)")
case True note p_in_succ_hd_b = this
with p_cond have " (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p =?a_p" using fin_succ_hd_b
by (auto simp add:step_def exec_def)
from p_in_succ_hd_b propa_ss1' have ss_p: "?ss_p = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p" using fin_succ_hd_b
by (auto simp add:step_def exec_def)
then have transf_p2: "transf p ?ss_p = (p # (inter_sorted_rev (hd b # ?a_hdb) ?a_p))"
by (auto simp add:f_def plussub_def nodes_sup_def transf_def )
then show ?thesis
proof(cases "succ_p ∈ succs (hd b)")
case True note succ_p_is_succ_hdb = this
with propa_ss1 have ss_succ_p: "?ss_succ_p = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_succ_p" using fin_succ_hd_b
by (auto simp add:step_def exec_def transf_def)
with a_succ_p_inA hd_b_cons_in_A have succ_p1: "(hd b # ?a_hdb) ⊑⇘r⇙?ss_succ_p"
and succ_p2: "?a_succ_p⊑⇘r⇙ ?ss_succ_p "
by (auto simp add:Semilat.ub1[OF Semilat.intro, OF is_semi]
Semilat.ub2[OF Semilat.intro, OF is_semi])
show ?thesis
proof(cases "p ∈ set b")
case True note p_in_set_b = this
then have p_eq_hdb: "p = hd b" using p_cond by auto
with succ_p have succ_p_is_succ_hdb: "succ_p ∈ succs (hd b)" by auto
from ss_a_p_eq p_eq_hdb have "(hd b # ?ss_hdb) = hd b # ?a_hdb" by auto
with succ_p1 have "hd b # ss ! hd b ⊑⇘r⇙ ss ! succ_p" by auto
with p_eq_hdb show ?thesis by (auto simp add:transf_def)
next
case False
then have "transf p ?ss_p ∈ A" and "transf p ?ss_p ⊑⇩r ?a_succ_p" using p_nin_b_ssp by auto
with succ_p2 a_succ_p_inA ss_succ_p_inA
show ?thesis by (auto intro: order_trans Semilat.orderI[OF Semilat.intro, OF is_semi])
qed
next
case False note succ_p_n_succ_hdb = this
with exec2 have ss_succ_p_eq_a: "?ss_succ_p = ?a_succ_p" using fin_succ_hd_b succ_p_lt_n len_eq
by (auto simp add:step_def exec_def)
show ?thesis
proof(cases "p ∈ set b")
case True
with p_cond have p_eq_hdb: "p = hd b" by auto
with succ_p have succ_p_is_succ_hdb: "succ_p ∈ succs (hd b)" by auto
with succ_p_n_succ_hdb show ?thesis by auto
next
case False
with sta_a_p have "∀(q,τ) ∈ set (step p ?a_p). τ ⊑⇩r a!q" by (simp add:stable_def)
with succ_p fin_succ_p have "transf p ?a_p ⊑⇩r ?a_succ_p"
by (auto simp add:step_def exec_def)
with ss_succ_p_eq_a ss_a_p_eq show ?thesis by auto
qed
qed
next
case False note p_nin_succ_hd_b = this
from p_nin_succ_hd_b p_cond have "p ∉ set b ∨ p = hd b" by auto
then show ?thesis
proof
assume "p ∉ set b"
then have transf_ss_p_inA: "transf p ?ss_p ∈ A" and transf_lt_p: "transf p ?ss_p ⊑⇩r ?a_succ_p" using p_nin_b_ssp by auto
show "transf p ?ss_p ⊑⇘r⇙ ?ss_succ_p"
proof(cases "succ_p ∈ succs (hd b)")
case True
with succ_p_lt_n propa_ss1' len_eq fin_succ_hd_b have "?ss_succ_p = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_succ_p"
by (auto simp add:step_def exec_def)
with a_succ_p_inA hd_b_cons_in_A have "?a_succ_p ⊑⇩r ?ss_succ_p"
by (auto simp add:Semilat.ub2[OF Semilat.intro, OF is_semi])
with transf_lt_p transf_ss_p_inA a_succ_p_inA ss_succ_p_inA
show ?thesis by (auto intro: order_trans Semilat.orderI[OF Semilat.intro, OF is_semi])
next
case False
with succ_p_lt_n exec2 len_eq fin_succ_hd_b have "?ss_succ_p = ?a_succ_p"
by (auto simp add:step_def exec_def)
with transf_lt_p show ?thesis by auto
qed
next
assume "p = hd b"
with hd_b_ss_sta have "(∀(q,τ) ∈ set (step p ?ss_p). τ ⊑⇩r ss!q)" by (simp add:stable_def)
with succ_p ‹p = hd b›
show "transf p ?ss_p ⊑⇘r⇙ ?ss_succ_p" using fin_succ_hd_b
by (auto simp add:stable_def step_def exec_def transf_def)
qed
qed
qed
with step_ss_p show "τ ⊑⇘r⇙ ss ! q" by (auto simp add:step_def exec_def)
qed
show "sorted (rev ?ss_p) ∧
(?ss_p ≠ rev [0..<n] ⟶ (∀x∈set?ss_p. x < p)) ∧
(?ss_p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)"
proof(cases "w ≠ []")
case True note w_n_nil = this
show ?thesis
proof (cases "p ∈ set( map fst (?qs_a))")
case True
with propa_ss1 have ss_p: "?ss_p = (hd b # ?a_hdb) ⊔⇘f⇙ ?a_p" by (simp add:step_def exec_def transf_def)
with sorted_hd_b_cons sorted_a_p
have ss_p_lt_hdb: "set ?ss_p ⊆ set (hd b # ?a_hdb)"
and ss_p_lt: "set ?ss_p ⊆ set ?a_p"
and ss_p_inter: "set ?ss_p = set (hd b # ?a_hdb) ∩ set ?a_p"
by (auto simp add:f_def plussub_def nodes_sup_def inter_sorted_correct)
from sorted_hd_b_cons sorted_a_p
have "inter_sorted_rev (hd b # ?a_hdb) ?a_p = rev (sorted_list_of_set (set (hd b # ?a_hdb) ∩ set ?a_p))"
by (rule inter_sorted_correct_col)
with ss_p have ss_p2: "?ss_p = (rev (sorted_list_of_set (set (hd b # ?a_hdb) ∩ set ?a_p)))"
by (auto simp add:f_def plussub_def nodes_sup_def)
show ?thesis
proof(cases "?a_p ≠ (rev [0..<n])")
case True note a_p_neq_all = this
then have seta_p_neq_all: "set ?a_p ≠ {0..<n}" using sorted_a_p by (auto intro: sorted_less_rev_set_unique)
from a_p_neq_all wf_a_b p_lt_n have a_lt_p: "(∀x∈set ?a_p. x < p)" using n_def len_eq by (auto simp add:wf_dom_def)
with ss_p_lt have "∀x∈set ?ss_p. x < p" by auto
then have ss_lt_p: "?ss_p ≠ rev [0..<n] ⟶ (∀x∈set ?ss_p. x < p)" by auto
have "set ?ss_p ≠ {0..<n}"
proof(rule ccontr)
assume "¬ set ?ss_p ≠ {0..<n}"
with ss_p_lt have cc: "{0..<n} ⊆ set ?a_p" by auto
from a_in_A p_lt_len_a have " ?a_p ∈ ((rev ∘ sorted_list_of_set) ` (Pow (set nodes)))" by (auto simp add: A_def)
then have ass_set_in_nodes: "set ?a_p ⊆ set nodes" by (rule inpow_subset_nodes)
then have "set ?a_p ⊆ {0..<n}" by (auto simp add:nodes_def n_def verts_set)
with cc have "set ?a_p = {0..<n}" by auto
with seta_p_neq_all show False by auto
qed
then have ss_p_not_all: "?ss_p ≠ rev [0..<n]" using sorted_ss_p by (auto intro: sorted_less_rev_set_unique)
then have "?ss_p = rev [0..<n] ⟶ (∃x∈set w. (x,p)∈ g_E G ∧ x < p)" by auto
with sorted_ss_p ss_lt_p stable_ss_p w_n_nil show ?thesis by fastforce
next
case False
then have a_p_all: "?a_p = (rev [0..<n])" by auto
with wf_a_b p_lt_n have ex_lt_p: " (∃x∈ set b. (x,p)∈ g_E G ∧ x < p)" by (auto simp add:wf_dom_def)
have "hd b ∈ set b" using b_n_nil by auto
from a_p_all have "set ?a_p = {0..<n}" by auto
with ss_p_inter have "set ?ss_p ⊆ {0..<n}" by auto
with ss_p2 hdb_subset_n ‹set ?a_p = {0..<n}› have "(set (hd b # ?a_hdb) ∩ set ?a_p) = set (hd b # ?a_hdb)" by auto
with ss_p2 have ss_p3: "?ss_p = (rev (sorted_list_of_set (set (hd b # ?a_hdb))))" by auto
from sorted_hd_b_cons have "sorted_list_of_set (set (hd b # ?a_hdb)) = rev (hd b # ?a_hdb)" by (fastforce dest: sorted_less_rev_set_eq)
with ss_p3 have ss_p_4: "?ss_p = (hd b # ?a_hdb)" by auto
have "(?ss_p ≠ rev [0..<n] ⟶ (∀x∈set ?ss_p. x < p)) ∧
(?ss_p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)"
proof(cases "?ss_p ≠ (rev [0..<n])")
case True note ss_p_n_all = this
with ss_p_4 show ?thesis
proof(cases "hd b < p")
case True
with ss_p_4 sorted_hd_b_cons have ss_p_lt_p: "∀x∈set ( (ss ! p)). x < p" by (auto simp add:sorted_wrt_append)
with ss_p_4 ss_p_n_all stable_ss_p ‹w ≠ []› show ?thesis by auto
next
case False note hd_b_ge_p = this
from ex_lt_p obtain x where "x∈ set b " and " (x,p)∈ g_E G " and "x < p"by auto
from ‹x ∈ set b› ‹x < p› hd_b_ge_p have "tl b ≠ []" by (induct b) auto
with hd_b_ge_p sorted_b have temp_t: "∀x∈ set (tl b). x ≥ p" by (induct b) auto
with ‹¬hd b < p› have "x ∈ set (tl b)" using ‹(x,p)∈ g_E G › ‹x ∈ set b› ‹x < p› by (induct b) auto
with ‹x < p› temp_t have False by auto
then show ?thesis by auto
qed
next
case False
then have "?ss_p = (rev [0..<n])" by auto
with ss_p_4 have hd_b_as1: "(hd b # ?a_hdb) = rev [0..<n]" by auto
then have "hd (hd b # ?a_hdb) = hd (rev [0..<n])" by auto
then have hd_b: "hd b = hd (rev [0..<n])" by auto
have "n > 0 "using n_def nodes_def len_verts_gt0 by auto
then have last_hd: "last [0..<n] = hd (rev [0..<n])" apply (induct n) by auto
have "last[0..<n] = n - 1" using ‹n> 0› by auto
then have "hd (rev [0..<n]) = n - 1" using last_hd by auto
with hd_b have hd_b_n_minus1: "hd b = n - 1" by auto
show ?thesis
proof(cases "hd b < p")
case True
with hd_b_n_minus1 p_lt_n show ?thesis by arith
next
case False
from ex_lt_p obtain x where x: "x∈set b ∧ (x, p) ∈ g_E G ∧ x < p" by auto
then have "x∈set b " and " (x, p) ∈ g_E G " and " x < p"by auto
from x ‹¬hd b <p› have x_n_hd_b: "x ≠ hd b" by auto
with ‹x∈set b › have "tl b ≠ []" by (induct b) auto
with ‹x∈set b › x_n_hd_b have "x ∈ set (tl b)" by (induct b) auto
with ww have "x ∈ set w" using fin by auto
then show ?thesis using ‹ss!p = (rev [0..<n])› ‹(x, p) ∈ g_E G› ‹x<p› stable_ss_p ‹w ≠ []› by auto
qed
qed
then show ?thesis using sorted_ss_p by auto
qed
next
case False note p_not_in_succ = this
with exec2 p_lt_n len_eq have ss_a_p_eq: "ss!p = a!p" by auto
with ass p_lt_n wf_a_b
have cond1: "(?ss_p ≠ rev [0..<n] ⟶ (∀x∈set ?ss_p. x < p))"
by (auto simp add:wf_dom_def)
show ?thesis
proof(cases "?a_p ≠ (rev [0..<n])")
case True
with wf_a_b have "(∀x∈set ?a_p. x < p)" using p_lt_n len_eq by (auto simp add:wf_dom_def)
with ss_a_p_eq have "(∀x∈set ?ss_p. x < p)" by auto
with cond1 sorted_ss_p show ?thesis using p_lt_n len_eq stable_ss_p w_n_nil by auto
next
case False
then have "?a_p = (rev [0..<n])" by auto
from ss_a_p_eq ass p_lt_n wf_a_b
have "?ss_p = rev [0..<n] ⟶ (∃x∈ set b. (x,p)∈ g_E G ∧ x < p)" by (auto simp add:wf_dom_def)
with ss_a_p_eq ‹a!p = (rev [0..<n])› have hd_b_lt_p: " (∃x∈ set b. (x,p)∈ g_E G ∧ x < p)" using len_eq by auto
then obtain x where "x∈ set b " and " (x,p) ∈ g_E G" and " x < p" by auto
from fin_succ_hd_b ‹(x,p) ∈ g_E G› p_not_in_succ have "x ≠ hd b " by (auto simp add:step_def exec_def succs_def)
with ‹x∈ set b› have "x ∈ set (tl b)" using b_n_nil by (induct b) auto
with ww have "x ∈ set w" using fin by auto
with ‹(x,p) ∈ g_E G› and ‹ x < p› have "(∃x∈ set w. (x,p)∈ g_E G ∧ x < p)" by auto
with cond1 sorted_ss_p show ?thesis using stable_ss_p w_n_nil by auto
qed
qed
next
case False
then have w_n_nil: "w =[]" by auto
with set_ww have "tl b = []" and succ_hd_b_eq: "∀(q, t) ∈ set ?qs_a. t ⊔⇘f⇙ a ! q = a ! q" by auto
from succ_hd_b_eq propa have "∀p<n. ss!p = a!p"
proof (intro strip)
fix p
assume ass_eq: " ∀(q, t)∈set ?qs_a. t ⊔⇘f⇙ a ! q = a ! q "
and " propa f ?qs_a a (tl b) = (ss, w) " and p_lt_n: " p < n "
show "ss ! p = a ! p"
proof(cases "p ∈ succs (hd b)")
case True
with fin_succ_hd_b propa_ss1 have ss_p_eq: "ss!p = transf (hd b) (a!hd b) ⊔⇘f⇙ a ! p"
by (auto simp add:step_def exec_def)
with ass_eq ‹p ∈ succs (hd b)› fin_succ_hd_b have "transf (hd b) (a!hd b) ⊔⇘f⇙ a ! p = a ! p"
by (auto simp add:step_def exec_def)
with ss_p_eq show ?thesis by auto
next
case False
with fin_succ_hd_b exec2 p_lt_n n_def len_eq nodes_def show ?thesis
by (auto simp add:step_def exec_def)
qed
qed
then have "∀p< length ss. ss!p = a!p" using ‹length ss = n› by auto
then have ss_eq_a: "ss = a" using n_def len_eq nodes_def ‹length ss = n› by (auto simp add:list_eq_iff_nth_eq)
with wf_a_b p_lt_n have
t3: "(?ss_p ≠ rev [0..<n] ⟶ (∀x∈set ?ss_p. x < p))" and
t4: "(?ss_p = rev [0..<n] ⟶ (∃x∈set b. (x, p) ∈ g_E G ∧ x < p))" and
sta_temp: "(p ∉ set b ⟶ stable r step ss p)" by (auto simp add:wf_dom_def)
from ‹tl b = []› ‹b ≠ []› have "p ∉ set b ⟷ p ≠ hd b " by (induct b) auto
with sta_temp have "p ≠ hd b ⟶ stable r step ss p" by auto
with hd_b_ss_sta have "stable r step ss p" by auto
then have sta_temp': "p ∉ set w ⟶ stable r step ss p" using w_n_nil by auto
have "?ss_p ≠ (rev [0..<n])"
proof(rule ccontr)
assume "¬?ss_p ≠ (rev [0..<n])"
then have ss_p_all: "?ss_p = (rev [0..<n])" by simp
with ‹ss = a› have "a!p = (rev [0..<n])" by auto
from ‹?ss_p = (rev [0..<n])›
have " ?ss_p = rev [0..<n]" by auto
with t4 have "(∃x∈set b. (x, p) ∈ g_E G ∧ x < p)" by auto
then obtain x where x: "x ∈ set b ∧ (x, p) ∈ g_E G ∧ x < p" by auto
with ‹tl b = []› ‹b ≠ []› have "x =hd b" by (induct b) auto
with x have " (hd b, p) ∈ g_E G" and hdb_lt_p: "hd b < p" by auto
then have "p ∈ succs (hd b)" by (simp add:succs_def)
with succ_hd_b_eq have transf_hd_b_ap: "transf (hd b) (a!hd b) ⊔⇘f⇙ a ! p = a ! p" using fin_succ_hd_b
by (auto simp add:step_def exec_def)
have a_p_neq_all: "?a_p ≠ (rev [0..<n])"
proof(rule ccontr)
assume "¬ ?a_p ≠ (rev [0..<n])"
then have a_p_all: "?a_p = (rev [0..<n])" by auto
then have "transf (hd b) ?a_hdb ⊔⇘f⇙ ?a_p = (hd b # ?a_hdb) ⊔⇘f⇙ (rev [0..<n])"
by (auto simp add:transf_def)
then have "transf (hd b) ?a_hdb ⊔⇘f⇙?a_p = ( (inter_sorted_rev (hd b # ?a_hdb) (rev [0..<n])))"
by (auto simp add:f_def plussub_def nodes_sup_def )
with transf_hd_b_ap a_p_all have "inter_sorted_rev (hd b # ?a_hdb) (rev [0..<n]) =
(rev [0..<n])"by auto
then have tx: "inter_sorted_rev (hd b # ?a_hdb) (rev [0..<n]) = (rev [0..<n])" by auto
from sorted_hd_b_cons have "set (inter_sorted_rev (hd b # ?a_hdb) (rev [0..<n])) ⊆
set (hd b # ?a_hdb)" by (auto simp add: inter_sorted_correct)
with tx have "set (rev [0..<n]) ⊆ set (hd b # ?a_hdb)" by auto
then have ty: "{0..<n} ⊆ set (hd b # ?a_hdb)" by auto
from hdb_subset_n ty have "{0..<n} = set (hd b # ?a_hdb)" by auto
with sorted_hd_b_cons have tz: "hd b # ?a_hdb = rev [0..<n]" by (auto simp add:sorted_less_rev_set_unique)
from n_def nodes_def len_verts_gt0 verts have "n > 0" by auto
with tz have tzz: "hd b = n - 1" by (induct n) auto
from p_lt_n tzz hdb_lt_p show False by auto
qed
with ss_p_all ss_eq_a show False by auto
qed
with sta_temp' sorted_ss_p t3 show ?thesis by auto
qed
qed
from ss_inA wf_dom_2 sorted_w len_ss_n w_lt_n show ?thesis by auto
qed
lemma propa_dom_invariant_aux':
fixes a b ss w
assumes propa: "propa f (step (hd b) (a ! hd b)) a (tl b) = (ss, w) "
and b_n_nil: "b ≠ [] "
and a_in_A: "∀τ∈set a. τ ∈ A "
and ass: "∀p<length ss0.
sorted (rev ( (a ! p))) ∧
(a ! p ≠ rev [0..<length ss0] ⟶ (∀x∈set ( (a ! p)). x < p)) ∧
(a ! p = rev [0..<length ss0] ⟶ (∃x∈ set b. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set b ⟶ stable r step a p)"
and sorted_b: "sorted b "
and n_len: "n = length ss0 "
and len_eq: "length a = length ss0 "
and b_lt_n: "∀x∈set b. x < length ss0 "
shows "(∀τ∈set ss. τ ∈ A) ∧
(∀p<length ss0.
sorted (rev ( (ss ! p))) ∧
(ss ! p ≠ rev [0..<length ss0] ⟶ (∀x∈set (ss ! p). x < p)) ∧
(ss ! p = rev [0..<length ss0] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)) ∧
sorted w ∧ length ss = length ss0 ∧ (∀x∈set w. x < length ss0) "
using assms
by (auto dest: propa_dom_invariant_aux)
lemma propa_dom_invariant:
assumes wf_ss_w: "wf_dom ss w "
and w_n_nil: "w ≠ []"
and propa: "propa f (step (hd w) (ss ! hd w)) ss (tl w) = (ss', w') "
shows "wf_dom ss' w'"
using assms
proof-
from wf_ss_w have ass:
"(∀p< n. sorted (rev (ss!p)) ∧
(ss!p ≠ rev [0..< n] ⟶ (∀x∈set (ss!p). x < p)) ∧
(ss!p = rev [0..< n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)) "
and sorted_b: "sorted w"
and a_in_A: "∀τ∈set ss. τ ∈ A"
and len_eq: "length ss = n"
and b_lt_n: "(∀x∈set w. x < n)" by (auto simp add:wf_dom_def)
from propa w_n_nil a_in_A ass sorted_b len_eq b_lt_n
show ?thesis by (unfold wf_dom_def) (rule propa_dom_invariant_aux)
qed
lemma step_dom_mono_aux:
fixes τ p τ' a b
assumes sorted: "sorted (rev (transf p τ)) "
and a_b_step: "(a, b) ∈ set (step p τ) "
and "τ ∈ A " and " p < n " and " τ ⊑⇘r⇙ τ'"
shows "∃τ''. (a, τ'') ∈ set (step p τ') ∧ b ⊑⇘r⇙ τ''"
proof-
have step1: "step p τ = map (λpc. (pc, (transf p τ))) (rev (sorted_list_of_set(succs p)))" by (simp add:step_def exec_def)
from a_b_step have "set (step p τ) ≠ {}" by auto
with step1 have succ_p_n_nil: "(rev (sorted_list_of_set(succs p))) ≠ []" by auto
from ‹p<n› have "p ∈ set (g_V G)" using n_def nodes_def verts_set len_verts_gt0 by auto
then have fin: "finite (succs p)" using fin_succs by auto
with step1 have "∀(x,y)∈ set (step p τ). x ∈ succs p"
and step2: "∀(x,y)∈ set (step p τ). y = transf p τ" by (auto simp add:step_def exec_def)
with a_b_step have "a ∈ succs p" by auto
then have "succs p ≠ {}" by auto
from step2 a_b_step have b: "b = transf p τ" by auto
have step2: "step p τ' = map (λpc. (pc, (transf p τ'))) (rev (sorted_list_of_set(succs p)))" by (simp add:step_def exec_def)
with fin have g1: "∀(x,y)∈ set (step p τ'). x ∈ succs p"
and g2: "∀(x,y)∈ set (step p τ'). y = transf p τ'" by (auto simp add:step_def exec_def)
with ‹a ∈ succs p› have "∃t. (a,t)∈ set (step p τ')" using fin by (auto simp add:step_def exec_def)
then obtain t where ex: "(a,t)∈ set (step p τ')" by auto
with g2 have t: "t = transf p τ'" by auto
from‹ τ ⊑⇘r⇙ τ'› have g: "sorted (rev τ) ∧ sorted (rev τ')∧ set τ' ⊆ set τ ∨ τ = τ'"
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def)
then have subset_p: "set (p#τ') ⊆ set (p# τ)" and "set τ' ⊆ set τ" by auto
from sorted have "∀x∈ set τ. x < p" and "sorted (rev τ')" using g by (auto simp add:sorted_wrt_append transf_def)
with ‹set τ' ⊆ set τ› have "∀x∈ set τ'. x < p" by auto
with ‹sorted (rev τ')› have "sorted (rev (p#τ'))" by (auto simp add:sorted_wrt_append)
with sorted b t subset_p
have "b ⊑⇘r⇙ t" by (auto simp add:r_def lesssub_def lesub_def nodes_le_def transf_def)
with ex show ?thesis by auto
qed
lemma step_dom_mono:
"(∀τ p τ'. τ ∈ A ∧ p<n ∧ τ ⊑⇩r τ' ⟶
sorted (rev (transf p τ)) ⟶
set (step p τ) {⊑⇘r⇙} set (step p τ'))"
apply(unfold mono_def lesubstep_type_def)
by(auto simp add:step_dom_mono_aux n_def nodes_def transf_def)
lemma propa_termination:
fixes a b
assumes wf_a_b: "wf_dom a b"
and b_n_nil: "b ≠ [] "
shows "(propa f (step (hd b) (a ! hd b)) a (tl b), a, b) ∈
{(ss', ss). ss [⊏⇘r⇙] ss'} <*lex*>
(λx. case x of (x, y) ⇒ (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset"
proof-
let ?qs = "(step (hd b) (a ! hd b))"
from wf_a_b have "∀x∈set b. x < n" and n_len: "length a = n" and sorted_b: "sorted b"
and set_a: "set a ⊆ A" by (auto simp add:wf_dom_def)
then have sorted_tl_b: "sorted (tl b)" and hd_b_lt_n: "hd b < n" using b_n_nil by (induct b) (auto simp add:sorted_wrt_append)
from set_a have a_inA: "a ∈ nlists n A" using n_len by (auto intro: nlistsI)
from hd_b_lt_n have dist: "distinct (map fst ?qs)" using distinct_p by auto
from wf_a_b b_n_nil have step_pres_bounded: "∀(q, τ)∈set ?qs. q < n ∧ τ ∈ A"
using propa_dom_invariant_auxi n_len by fastforce
with sorted_tl_b set_a n_len
have propa: "propa f ?qs a (tl b) = (merges f ?qs a, (sorted_list_of_set ({q. ∃t.(q,t)∈set ?qs ∧ t ⊔⇘f⇙ (a!q) ≠ a!q} ∪ set(tl b))))"
by (auto dest: decomp_propa)
from a_inA step_pres_bounded sorted_b b_n_nil dist
have "((merges f ?qs a, (sorted_list_of_set ({q. ∃t.(q,t)∈set ?qs ∧ t ⊔⇘f⇙ (a!q) ≠ a!q} ∪ set(tl b)))),(a,b)) ∈
{(ss', ss). ss [⊏⇘r⇙] ss'} <*lex*> (λx. case x of (x, y) ⇒ (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset"
by (auto simp add: finite_psubset_def dest: termination_lemma)
with propa show ?thesis by auto
qed
lemma iter_dom_invariant:
assumes "wf_dom ss0 w0"
shows "iter f step ss0 w0 = (ss',w') ⟶ wf_dom ss' w'"
using assms
apply (unfold iter_def)
apply(rule_tac
P = "(λ(ss, w). wf_dom ss w )" and
r = "{(ss',ss). ss [⊏⇩r] ss'} <*lex*> (λ(x,y). (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset"
in while_rule)
apply (clarsimp)
apply(simp add: wf_dom_def)
apply clarsimp
apply(rule propa_dom_invariant_aux')
apply assumption+
apply clarsimp
apply (simp add: wf_listn_termination_rel)
apply clarsimp
apply (fastforce intro:propa_termination)
done
lemma propa_dom_invariant_aux2:
fixes ss w ssa wa
assumes wf_dom_ss0_w0: "wf_dom ss0 w0"
and w_n_nil: "w ≠ [] "
and propa: "propa f (step (hd w) (ss ! hd w)) ss (tl w) = (ssa, wa) "
and wf_ss_w: "wf_dom ss w "
and ss0_lt_ss: "ss0 [⊑⇘r⇙] ss"
and sta: " ∀ts∈nlists n A. ss0 [⊑⇘r⇙] ts ∧ (∀p<n. stable r step ts p) ⟶ ss [⊑⇘r⇙] ts"
shows "ss0 [⊑⇘r⇙] ssa ∧
(∀ts∈nlists n A. ss0 [⊑⇘r⇙] ts ∧ (∀p<n. stable r step ts p) ⟶ ssa [⊑⇘r⇙] ts)"
using assms
proof-
let ?ss_hdw = "ss!hd w"
from wf_dom_ss0_w0 have len_ss0: "length ss0 = n" and "∀x∈ set ss0. x ∈ A" by (auto simp add:wf_dom_def)
then have ss0_inA: "ss0 ∈ nlists n A" and set_ss0: "set ss0 ⊆ A"by (auto intro:nlistsI)
then have ss0_nth_inA: "∀i<length ss0. ss0!i ∈ A" by auto
then have ss0_p_subset: "∀p< length ss0. set (ss0!p) ⊆ set nodes" by (auto simp add:inpow_subset_nodes A_def)
from len_ss0 n_def nodes_def len_verts_gt0 have "0 < length ss0" by auto
from ss0_lt_ss have "list_all2 (λx y. x ⊑⇩r y) ss0 ss"
by (auto simp add:lesssub_def lesub_def list_all2_def Listn.le_def)
then have lt1: "∀p<length ss0. ss0 !p ⊑⇘r⇙ ss!p" by (auto simp add: list_all2_conv_all_nth)
from wf_ss_w have "∀τ∈set ss. τ ∈ A"
and ass1: "∀p<n. sorted (rev ( (ss ! p))) ∧
(ss!p ≠ rev [0..<n] ⟶ (∀x∈set (ss ! p). x < p)) ∧
(ss!p = rev [0..<n] ⟶ (∃x∈ set w. (x,p)∈ g_E G ∧ x < p)) ∧
(p ∉ set w ⟶ stable r step ss p)"
and sorted_w: "sorted w"
and len_ss: "length ss = n"
and w_lt_n: "∀x∈set w. x < n "by (auto simp add:wf_dom_def)
then have ss_inA: "ss ∈ nlists n A" and set_ss: "set ss ⊆ A" by (auto intro:nlistsI)
then have ss_nth_inA: "∀i<length ss. ss!i ∈ A" by auto
then have ss_p_subset: "∀p< length ss. set (ss!p) ⊆ set nodes" by (auto simp add:inpow_subset_nodes A_def)
then have ss_hdw_nodes: "set ?ss_hdw ⊆ set nodes" using w_lt_n w_n_nil len_ss by auto
let ?qs = "step (hd w) ?ss_hdw"
from w_lt_n have hd_w_lt_n: "hd w < n" using w_n_nil by auto
then have dist: "distinct (map fst ?qs)" using distinct_p by auto
from ss_nth_inA have ss_hdw_inA: "?ss_hdw ∈ A" using w_lt_n w_n_nil len_ss by auto
from ass1 have sorted_ss_hdw: "sorted (rev ?ss_hdw)" using w_lt_n w_n_nil by auto
then have "∀q∈succs (hd w). q ∈ set (g_V G)" by (auto simp add:succ_in_G)
then have hd_w_suc_lt_n: "∀q∈succs (hd w). q < n" using n_def verts_set nodes_def by auto
have hdw_in_nodes:"hd w ∈ set (g_V G)" using verts_set n_def nodes_def w_lt_n w_n_nil by auto
then have fin_succ_hd_w: "finite (succs (hd w))" using fin_succs by auto
from sorted_w have sorted_tl_w': "sorted (tl w)" using w_n_nil by (induct w) auto
from wf_ss_w w_n_nil have ss_hd_w_neq_all: "?ss_hdw ≠ (rev [0..<n])"
and sorted_hd_w_ss: "sorted (rev (hd w # ?ss_hdw))"
and hdb_subset_nodes: "set (hd w # ?ss_hdw) ⊆ set nodes"
and hd_w_ss_in_A: " (hd w # ?ss_hdw) ∈ A"
and step_pres_bounded: " ∀(q, τ)∈set (step (hd w) ?ss_hdw). q < length ss ∧ τ ∈ A"
using propa_dom_invariant_auxi by auto
from ss_hd_w_neq_all have ss_lt_hd_w: "∀x∈set ?ss_hdw. x < hd w" using hd_w_lt_n wf_ss_w by (auto simp add:wf_dom_def)
from wf_ss_w w_n_nil propa have wf_ssa_wa: "wf_dom ssa wa" using propa_dom_invariant by auto
then have sorted_ssa_p: "∀p<n. sorted (rev (ssa!p))"
and len_ssa: "length ssa = n"
and "∀x∈ set ssa. x ∈ A"
and sorted_wa: "sorted wa"
and len_ssa: "length ssa = n"
and wa_lt_n: "∀x∈ set wa. x < n"
by (auto simp add:wf_dom_def)
then have ssa_inA: "ssa∈ nlists n A" and set_ssa: "set ssa ⊆ A"by (auto intro:nlistsI)
then have ssa_nth_inA: "∀i<length ssa. ssa!i ∈ A" by auto
then have ssa_p_subset: "∀p< length ssa. set (ssa!p) ⊆ set nodes" by (auto simp add:inpow_subset_nodes A_def)
from len_ss0 len_ssa have len_ss0_ssa: "length ss0 = length ssa" by simp
from len_ss0 len_ss have len_ss0_ss: "length ss0 = length ss" by simp
have "∀(q, τ)∈set ?qs. τ = transf (hd w) (ss!(hd w))" by (simp add:step_def exec_def)
then have transf_ss_hd_w: "∀(q, τ)∈set ?qs. τ = (hd w # ?ss_hdw)"
by (simp add:transf_def)
from set_ss step_pres_bounded sorted_tl_w' len_ss dist have "∀(q, τ) ∈ set ?qs. (fst(propa f ?qs ss (tl w)))!q = τ ⊔⇘f⇙ss!q"
by (auto dest:propa_property1)
with propa have propa_ss: "∀(q, τ) ∈ set ?qs. ssa!q = τ ⊔⇘f⇙ss!q" by simp
with transf_ss_hd_w have propa_ss1: "∀(q, τ) ∈ set ?qs. ssa!q = (hd w # ?ss_hdw) ⊔⇘f⇙ss!q" by auto
from ss_nth_inA step_pres_bounded have "∀(q, τ) ∈ set ?qs. ss!q ∈ A" using hd_w_suc_lt_n fin_succ_hd_w
by (auto simp add:step_def exec_def)
from hd_w_ss_in_A this propa_ss1 have ss_lt_ssa_q: "∀(q, τ) ∈ set ?qs. ss!q ⊑⇘r⇙ ssa!q"
by (fastforce dest:Semilat.ub2[OF Semilat.intro, OF is_semi])
from step_pres_bounded sorted_tl_w' set_ss len_ss dist
have "⋀q. q ∉ set(map fst ?qs) ⟹ q < length ss ⟹ (fst(propa f ?qs ss (tl w)))!q = ss!q"
by (auto intro:propa_property2)
with propa have exec2: "⋀q. q ∉ set(map fst ?qs) ⟹ q < length ss ⟹ ssa!q = ss!q" by auto
have tran_ss_ssa: "∀p<length ss. ss!p ⊑⇘r⇙ ssa!p"
proof(intro strip)
fix p
assume "p < length ss"
with ssa_nth_inA have ssa_p_inA: "ssa!p ∈ A" using ‹length ssa = n› ‹length ss = n› by auto
from ss_nth_inA have ss_p_inA: "ss!p ∈ A" using ‹length ss = n› ‹p < length ss› by auto
show " ss ! p ⊑⇘r⇙ ssa ! p"
proof(cases "p ∈ succs (hd w)")
case True
then show "ss!p ⊑⇘r⇙ ssa!p" using ss_lt_ssa_q using fin_succ_hd_w by (auto simp add:step_def exec_def)
next
case False
then have "p ∉ set (map fst ?qs)" using fin_succ_hd_w by (auto simp add:step_def exec_def)
then show ?thesis using exec2 ‹p < length ss› using ssa_p_inA ss_p_inA
by(auto simp add:step_def exec_def intro: Semilat.orderI[OF Semilat.intro, OF is_semi])
qed
qed
then have "∀p<length ss0. ss ! p ⊑⇘r⇙ ssa ! p" using len_ss0_ss by auto
with lt1 have "∀p<length ss0. ss0!p ⊑⇘r⇙ ssa!p" using ss0_nth_inA ssa_nth_inA ss_nth_inA using len_ss0_ss len_ss0_ssa
by (auto intro: order_trans Semilat.orderI[OF Semilat.intro, OF is_semi])
with len_ss0_ssa
have g1: "ss0 [⊑⇘r⇙] ssa" by (auto simp only:Listn.le_def lesssub_def lesub_def intro:list_all2_all_nthI)
have "(∀ts∈nlists n A. ss0 [⊑⇘r⇙] ts ∧ (∀p<n. stable r step ts p) ⟶ ssa [⊑⇘r⇙] ts)"
proof(intro strip)
fix ts
assume ts_inA: "ts ∈ nlists n A" and ass: "ss0 [⊑⇘r⇙] ts ∧ (∀p<n. stable r step ts p)"
let ?ts_hdw = "ts!(hd w)"
from ts_inA sta ass have ss_ts: "ss [⊑⇘r⇙] ts" and sta_ts: "(∀p<n. stable r step ts p)" by auto
then have len_ss_ts: "length ss = length ts" and
ss_ts_hdw: "?ss_hdw ⊑⇘r⇙ ?ts_hdw "using le_listD len_ss hd_w_lt_n by auto
then have "sorted (rev (?ts_hdw)) ∧ set ?ts_hdw ⊆ set ?ss_hdw ∨ ?ss_hdw =?ts_hdw "
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def)
then have sorted_ts_hdw: "sorted (rev (?ts_hdw))"
and ts_ss_subset: "set ?ts_hdw ⊆ set ?ss_hdw" using sorted_ss_hdw
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def)
then have "∀x∈ set ?ts_hdw. x < hd w" using ss_lt_hd_w by auto
with sorted_ts_hdw have sorted_hd_w_ts: "sorted (rev (hd w # ?ts_hdw))"
by (auto simp add:sorted_wrt_append)
with sorted_hd_w_ss ts_ss_subset
have "(hd w # ?ss_hdw) ⊑⇘r⇙ (hd w # ?ts_hdw)"
by (auto simp add:transf_def lesssub_def lesub_def r_def nodes_le_def)
then have transf_ss_ts: "transf (hd w) ?ss_hdw ⊑⇘r⇙ transf (hd w) ?ts_hdw" by (auto simp add:transf_def)
from sta_ts hd_w_lt_n have sta_ts_hdw: "stable r step ts (hd w)" by auto
from ss_hdw_nodes ts_ss_subset have "set ?ts_hdw ⊆ set nodes" by auto
with hd_w_lt_n have hdw_ts_subset_nodes: "set (hd w # ?ts_hdw) ⊆ set nodes" using nodes_def n_def verts_set by auto
with sorted_hd_w_ts have "(hd w # ?ts_hdw) ∈ ( (rev ∘ sorted_list_of_set) ` (Pow (set nodes)))"
by (fastforce intro: subset_nodes_inpow)
then have transf_ts_inA: "(hd w #?ts_hdw) ∈ A" by (simp add:A_def)
then have sorted_hdw_ts_hdw: "sorted (rev (hd w # ?ts_hdw))" by (rule inA_is_sorted)
have "∀p<length ssa. ssa!p ⊑⇘r⇙ ts!p"
proof(intro strip)
fix p
assume p_lt_len_ssa: "p < length ssa"
then have "p < length ss" and "p < n" using len_ssa len_ss by auto
with ss_ts have ss_ts_p: "ss!p ⊑⇘r⇙ ts!p " using le_listD by auto
show "ssa ! p ⊑⇘r⇙ ts ! p"
proof(cases "p ∈ succs (hd w)")
case True note p_in_succs_hdw = this
then have "ss!p ⊑⇘r⇙ ssa!p" using ss_lt_ssa_q using fin_succ_hd_w by (auto simp add:step_def exec_def)
from p_in_succs_hdw have ssa_p: "ssa!p = transf (hd w) (ss!hd w) ⊔⇘f⇙ss!p" using propa_ss fin_succ_hd_w
by (auto simp add:step_def exec_def)
from sta_ts_hdw have transf_hdw_ts_hdw: "transf (hd w) (ts!hd w) ⊑⇘r⇙ ts!p" using p_in_succs_hdw fin_succ_hd_w
by (auto simp add:step_def exec_def stable_def)
then have ts_p_subset: "(hd w # ?ts_hdw) ⊑⇘r⇙ ts!p" by (auto simp add:transf_def)
then have "(sorted (rev (ts!p)) ∧ set (ts!p)⊆ set (hd w # ?ts_hdw)∧ sorted (rev (hd w # ?ts_hdw))) ∨
hd w # ?ts_hdw = ts!p"
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def)
then have "sorted (rev (ts!p)) ∧ set (ts!p)⊆ set (hd w # ?ts_hdw)"
proof
assume "sorted (rev (ts ! p)) ∧ set (ts ! p) ⊆ set (hd w # ts ! hd w) ∧ sorted (rev (hd w # ts ! hd w))"
then show ?thesis by auto
next
assume " hd w # ts ! hd w = ts ! p"
with sorted_hdw_ts_hdw show ?thesis by auto
qed
then have sorted_ts_p: "sorted (rev (ts!p))"
and ts_as_subset: "set (ts!p)⊆ set (hd w # ?ts_hdw)"
by auto
with hdw_ts_subset_nodes have "set (ts!p) ⊆ set nodes" by auto
with sorted_ts_p have "(ts!p) ∈ ( (rev ∘ sorted_list_of_set) ` (Pow (set nodes)))"
by (fastforce intro: subset_nodes_inpow)
then have ts_p_inA: "ts!p ∈ A" by (simp add:A_def)
from sorted_hdw_ts_hdw have "∀x∈ set ?ts_hdw. x < hd w" by (auto simp add:sorted_wrt_append)
with ‹hd w < n› have "∀x∈ set ?ts_hdw. x < n" by auto
then have "set(hd w # ?ts_hdw) ⊆ set nodes"using ‹hd w < n› n_def verts_set nodes_def by auto
with sorted_hdw_ts_hdw have "hd w # ?ts_hdw ∈ ( (rev ∘ sorted_list_of_set) ` (Pow (set nodes)))"
by (fastforce intro: subset_nodes_inpow)
then have "(hd w # ?ts_hdw) ∈ A" by (auto simp add:A_def)
then have trans_hdw_ts_inA: "transf (hd w) (ts!hd w) ∈ A" by (auto simp add:transf_def)
have transf_hdw_ss_inA: "transf (hd w) ?ss_hdw ∈ A" using hd_w_ss_in_A by (auto simp add:transf_def)
have ss_p_inA: "ss!p ∈ A" using ‹p<length ss› ss_inA by auto
from transf_ss_ts transf_hdw_ts_hdw transf_hdw_ss_inA trans_hdw_ts_inA ts_p_inA have "transf (hd w) ?ss_hdw ⊑⇘r⇙ ts ! p"
by (auto intro: order_trans Semilat.orderI[OF Semilat.intro, OF is_semi])
with ‹ss!p ⊑⇘r⇙ ts ! p› trans_hdw_ts_inA ss_p_inA transf_hdw_ss_inA ssa_p ts_p_inA
show "ssa ! p ⊑⇘r⇙ ts ! p" by (auto intro: Semilat.lub[OF Semilat.intro, OF is_semi])
next
case False
then have "p ∉ set (map fst ?qs)" using fin_succ_hd_w by (auto simp add:step_def exec_def)
then have "ssa!p = ss!p"using exec2 p_lt_len_ssa len_ss len_ssa
by(auto simp add:step_def exec_def)
with ss_ts_p show ?thesis by auto
qed
qed
with ‹length ss = length ts› len_ss len_ssa
show "ssa [⊑⇘r⇙] ts" by (auto simp only:Listn.le_def lesssub_def lesub_def intro:list_all2_all_nthI)
qed
with g1 show ?thesis by auto
qed
lemma in_list_nA_refl: "ss ∈ nlists n A ⟹ ss [⊑⇘r⇙] ss"
apply (unfold Listn.le_def lesssub_def lesub_def)
proof-
assume "ss ∈ nlists n A"
then have "set ss ⊆ A" and "length ss = n" by auto
then have "∀i<n. ss!i ∈ A" by auto
then have "∀i<length ss. ss!i ⊑⇘r⇙ ss!i"
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def )
then show " list_all2 r ss ss" by (auto simp add:lesssub_def lesub_def intro: list_all2_all_nthI)
qed
lemma iter_dom:
assumes "wf_dom ss0 w0"
shows "iter f step ss0 w0 = (ss',w') ⟶
wf_dom ss' w' ∧
stables r step ss' ∧
ss0 [⊑⇩r] ss' ∧
(∀ts∈nlists n A. ss0 [⊑⇩r] ts ∧ stables r step ts ⟶ ss' [⊑⇩r] ts)"
using assms
apply (unfold iter_def stables_def)
apply (rule_tac P = "λ(ss,w). wf_dom ss w ∧ ss0 [⊑⇩r] ss ∧ (∀ts∈nlists n A. ss0 [⊑⇩r] ts ∧ stables r step ts ⟶ ss [⊑⇩r] ts)"
and r = "{(ss',ss). ss [⊏⇩r] ss'} <*lex*> (λ(x,y). (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset"
in while_rule)
apply(fastforce simp add: wf_dom_def intro:wf_dom_le)
apply clarsimp
apply (rule conjI)
apply(fastforce dest:propa_dom_invariant)
apply(simp add:stables_def)
apply (rule propa_dom_invariant_aux2)
apply assumption+
apply(clarsimp simp add: stables_def split_paired_all)
apply(subgoal_tac "length ss0 = n")
apply(simp add:wf_dom_def)+
apply clarsimp
apply(simp add:wf_listn_termination_rel)
apply clarsimp
apply (fastforce intro:propa_termination)
done
lemma wf_start: "wf_dom start (unstables r step start)"
proof-
let ?w0 = "unstables r step start"
have sorted_w: "sorted ?w0" using unstables_def by (simp add:sorted_less_sorted_list_of_set)
have w0_lt_n: "∀x∈set ?w0. x < n" using unstables_def len_start_is_n by auto
have neq_all: "∀p < n. start!p ≠ rev [0..< n] ⟶ (∀x∈set (start!p). x < p) "
proof(intro strip)
fix p x
assume p_lt_n: "p < n" and p_neq_all: "start ! p ≠ rev [0..< n]" and x_in: "x ∈ set (start ! p)"
then have "p = 0" using start_nth_lt0_all len_start_is_n by auto
with start_nth0_empty show "x < p" using x_in by auto
qed
have eq_all:"(∀p < n. start!p = rev [0..< n] ⟶ (∃x∈ set ?w0. (x,p)∈ g_E G ∧ x < p))"
proof(intro strip)
fix p
assume p_lt_n: "p < n" and p_eq_all: "start ! p = rev [0..< n]"
from ‹p < n› have "p = 0 ∨ p > 0 ∧ p < length start" using len_start_is_n by auto
with p_eq_all have "p > 0" and p_lt_len_start: "p < length start" using start_nth0_empty n_def nodes_def len_verts_gt0 by auto
then have "p ∈ set (g_V G) - {0}" using len_start_is_n n_def nodes_def verts_set by auto
with dfst obtain prev where "(prev, p) ∈ g_E G" and "prev < p" by auto
then have "succs prev ≠ {}" and "prev < length start" using p_lt_len_start by (auto simp add:succs_def)
with unstable_start have "prev ∈ set ?w0" by auto
with ‹(prev, p) ∈ g_E G› ‹prev < p›
show "∃x∈set (unstables r step start). (x, p) ∈ g_E G ∧ x < p" by auto
qed
have "∀p<n. (p ∉ set (unstables r step start)⟶ stable r step start p)"
by (unfold unstables_def) (simp add:n_def start_def nodes_def)
with sorted_start_nth neq_all eq_all start_subset_A sorted_w len_start_is_n w0_lt_n show ?thesis by (auto simp only:wf_dom_def)
qed
lemma iter_dom_properties:
"iter f step start (unstables r step start) = (ss',w') ⟶
wf_dom ss' w' ∧
stables r step ss' ∧
start [⊑⇩r] ss' ∧
(∀ts∈nlists n A. start [⊑⇩r] ts ∧ stables r step ts ⟶ ss' [⊑⇩r] ts)"
using iter_dom[OF wf_start] by auto
lemma iter_dom_properties2:
"iter f step start (unstables r step start) = (ss',w') ⟶ ss' ∈ nlists n A"
using iter_dom_properties by (auto simp only:wf_dom_def nlists_def)
lemma iter_dom_termination:
"iter f step start (unstables r step start) = (ss,w) ⟶
w ≠ [] ⟶
propa f (step (hd w) (ss!(hd w))) ss (tl w) = (ss, tl w)"
proof (intro strip)
assume iter: "iter f step start (unstables r step start) = (ss, w)" and w_n_nil: "w ≠ []"
with iter_dom_properties
have stas: "stables r step ss"
and wf_ss_w: "wf_dom ss w"
and start_le_ss: "start [⊑⇩r] ss" by auto
from stas have sta_p: "(∀p < size ss. stable r step ss p)"by (auto simp add:stables_def)
from wf_ss_w have n_w_sta: "∀p<n. p ∉set w ⟶ stable r step ss p"
and len_eq: "length ss = n"
and w_lt_n: "∀x∈ set w. x < n"
and ss_inA: "∀x∈set ss. x ∈ A"
and sorted_w: "sorted w " by (auto simp add:wf_dom_def)
from w_lt_n have hd_w_lt_n: "hd w < n" using w_n_nil by auto
then have hd_w_in_verts: "hd w ∈ set (g_V G)" using n_def nodes_def verts_set by auto
then have fin_succ_hd_w: "finite (succs (hd w))" using fin_succs hd_w_in_verts by auto
let ?ss_hdw = "ss!hd w"
let ?qs = "step (hd w) ?ss_hdw"
from hd_w_lt_n have dist: "distinct (map fst ?qs)" using distinct_p by auto
from wf_ss_w w_n_nil have hdw_ss_subset_nodes: "set (hd w # ?ss_hdw) ⊆ set nodes"
and sorted_hd_w_ss: "sorted (rev (hd w # ?ss_hdw))"
and hd_w_ss_in_A: " ((hd w # ?ss_hdw)) ∈ A"
and step_pres_bounded: "∀(q, τ)∈set ?qs. q < length ss ∧ τ ∈ A"
using propa_dom_invariant_auxi by auto
let ?res = "propa f (step (hd w) (ss!(hd w))) ss (tl w) "
have "propa f (step (hd w) (ss!(hd w))) ss (tl w) = ?res" by simp
then obtain ss' w' where propa: "propa f (step (hd w) (ss!(hd w))) ss (tl w) = (ss', w')" by (cases ?res) auto
from sorted_w have sorted_tl_b: "sorted (tl w)" by (induct w) auto
from ss_inA have set_a: "set ss ⊆ A" by auto
with step_pres_bounded sorted_tl_b len_eq dist have "∀(q, τ) ∈ set ?qs. (fst(propa f ?qs ss (tl w)))!q = τ ⊔⇘f⇙ss!q"
by (auto dest:propa_property1)
with propa have propa_ss1: "∀(q, τ) ∈ set ?qs. ss'!q = (hd w # ?ss_hdw) ⊔⇘f⇙ss!q" by (simp add:step_def exec_def transf_def)
from step_pres_bounded sorted_tl_b set_a len_eq dist
have "⋀q. q ∉ set(map fst ?qs) ⟹ q < length ss ⟹ (fst(propa f ?qs ss (tl w)))!q = ss!q"
by (auto intro:propa_property2)
with propa have g2: "⋀q. q ∉ set(map fst ?qs) ⟹ q < length ss ⟹ ss'!q = ss!q" by auto
from sorted_w have sorted_tl_w: "sorted (tl w)" by (induct w) auto
with step_pres_bounded set_a
have fst_propa: "fst (propa f ?qs ss (tl w)) = (merges f ?qs ss)"
and snd_propa: "snd (propa f ?qs ss (tl w)) = (sorted_list_of_set ({q. ∃t.(q,t)∈set ?qs ∧ t ⊔⇘f⇙ (ss!q) ≠ ss!q} ∪ set (tl w)))"
using decomp_propa by auto
with propa have len_ss_eq_ss': "length ss' = length ss" using length_merges by auto
have ss_ss'_eq: "∀i<n. (fst (propa f ?qs ss (tl w)))!i = ss!i"
proof(intro strip)
fix i
assume "i < n"
then have i_lt_len_ss: "i < length ss" using ‹length ss = n› by auto
show "fst (propa f ?qs ss (tl w)) ! i = ss ! i "
proof(cases "i ∈ set(map fst ?qs)")
case True
assume ass1: "i ∈ set (map fst ?qs)"
with propa_ss1 have ss': "ss'!i = (hd w # ?ss_hdw) ⊔⇘f⇙ss!i" by (auto simp add: step_def exec_def)
from ass1 have "i ∈ set (g_V G)" using succ_in_G fin_succ_hd_w by (auto simp add:step_def exec_def)
then have q_lt_len_ss: "i < length ss" using len_eq by (auto simp add:n_def nodes_def verts_set)
from hd_w_lt_n len_eq stas have "stable r step ss (hd w)" by (auto simp add:stables_def)
with ass1 have "(hd w # ?ss_hdw) ⊑⇩r ss!i" by (auto simp add:stables_def stable_def step_def exec_def transf_def)
then have "set (ss!i) ⊆ set (hd w # ?ss_hdw) ∨ (hd w # ?ss_hdw) = ss!i" by (auto simp add:lesssub_def lesub_def r_def nodes_le_def)
then have set_ss_q_subst_hdw_ss: "set (ss!i) ⊆ set (hd w # ?ss_hdw)" by (rule disjE)(auto simp add:lesssub_def lesub_def r_def nodes_le_def)
then have ss_q: "set (ss!i) ∩ set (hd w # ?ss_hdw) = set (ss!i)" by auto
from wf_ss_w q_lt_len_ss have sorted_ss_q: "sorted (rev (ss!i))" by (simp add:wf_dom_def)
with sorted_hd_w_ss have ss_q': "set (ss'!i) = set (ss!i) ∩ set (hd w # ?ss_hdw)"
and sorrted_ss_q': "sorted (rev (ss'!i))" using ss'
by (auto simp add:plussub_def f_def nodes_sup_def inter_sorted_correct)
with ss_q sorted_ss_q sorrted_ss_q' show ?thesis using sorted_less_rev_set_unique propa by auto
next
case False note i_nin = this
from step_pres_bounded sorted_tl_b set_a len_eq dist propa i_lt_len_ss i_nin
show ?thesis by (fastforce dest:propa_property2)
qed
qed
with len_ss_eq_ss' have eq_ss: "ss' = ss" using len_eq propa by (auto simp add:list_eq_iff_nth_eq)
then have qs_empty: "(({q. ∃t.(q,t)∈set ?qs ∧ t ⊔⇘f⇙ (ss!q) ≠ ss!q} ∪ set (tl w))) = (set (tl w))"
using propa_ss1 propa transf_def step_def exec_def by fastforce
with snd_propa have "snd (propa f ?qs ss (tl w)) = sorted_list_of_set (set (tl w))" using sorted_w by auto
with sorted_tl_w have "snd (propa f ?qs ss (tl w)) = tl w" by (fastforce dest:sorted_less_set_eq)
with propa have "w' = tl w" by simp
with eq_ss show "propa f (step (hd w) (ss ! hd w)) ss (tl w) = (ss, tl w)" using propa by auto
qed
lemma dom_iter_properties:
"iter f step start (unstables r step start) = (ss, w) ⟶
ss!0 = [] ∧
(∀p<n. p ≠ 0 ⟶ ss!p ≠ (rev [0..<n]))"
proof(intro strip)
assume iter: "iter f step start (unstables r step start) = (ss, w)"
with iter_dom_properties iter_dom_properties2
have "wf_dom ss w"
and stas: "stables r step ss"
and start_le_ss: "start [⊑⇩r] ss"
and ss_inA: "ss ∈ nlists n A" by auto
then have len_ss_n: "length ss = n" by (auto simp only:nlists_def)
from start_le_ss have "start!0 ⊑⇩r ss!0" using start_len_gt_0
by (unfold Listn.le_def lesssub_def lesub_def) (auto simp add:lesssub_def lesub_def intro:list_all2_nthD)
then have ss_0th: "ss!0 = []" by (auto simp add:r_def nodes_le_def lesssub_def lesub_def start_def)
have "(∀p<n. p ≠ 0 ⟶ ss ! p ≠ (rev [0..<n]))"
proof(intro strip, rule ccontr)
fix p
assume p_lt_n: "p < n" and p_neq_0: "p≠0" and ss_p_eq_all: "¬ ss ! p ≠ rev [0..<n]"
with stas len_ss_n have step_sta: "∀(q,τ) ∈ set (step p (ss!p)). τ ⊑⇩r ss!q" by (simp add: stables_def stable_def)
from p_lt_n len_start_is_n verts_set have p_is_vert: "p ∈ set (g_V G)" by (auto simp add:n_def nodes_def)
then have step_p: "∀(q,τ) ∈ set (step p (ss!p)). q ∈ succs p" using fin_succs by (auto simp add:step_def exec_def)
from p_is_vert p_neq_0 dfst obtain prev where "(prev, p) ∈ g_E G" and prev_lt_p: "prev < p" by auto
then have prev_lt_n: "prev < n"
and prev_p: "p ∈ succs prev"
and "prev ∈ set (g_V G)" using p_lt_n tail_is_vert by (auto simp add:succs_def)
then have fin_suc_prev : "finite (succs prev)" using fin_succs by auto
let ?prev_τ = "ss!prev"
from prev_lt_n stas ‹length ss = n› have "stable r step ss prev" by (auto simp add:stables_def)
then have "∀(q,τ) ∈ set (step prev ?prev_τ). (prev # ?prev_τ) ⊑⇩r ss!q"
by (auto simp add: stable_def transf_def step_def exec_def)
with prev_p have "(prev # ?prev_τ) ⊑⇘r⇙ ss ! p" using fin_suc_prev by (auto simp add: stable_def transf_def step_def exec_def)
with ss_p_eq_all have "sorted (rev (prev # ?prev_τ)) ∧ {0..<n} ⊆ set (prev # ?prev_τ) ∨ (prev # ss ! prev) = (rev [0..<n])"
by (auto simp add:r_def lesssub_def lesub_def nodes_le_def)
then have "sorted (rev (prev # ?prev_τ)) ∧ {0..<n} ⊆ set (prev # ?prev_τ)" by(rule disjE) auto
then have sorted_rev: "sorted (rev (prev # ?prev_τ))"
and pres_subset: "{0..<n} ⊆ set (prev # ?prev_τ)" by auto
then have prev_set: "∀x∈ set ?prev_τ. x < prev" by (induct ?prev_τ) (auto simp add:sorted_wrt_append)
from p_lt_n prev_lt_p have "prev < n - 1" using n_def nodes_def len_verts_gt0 by auto
with prev_set have prev_lt_n: "∀x∈set(prev # ?prev_τ). x < n - 1" by auto
from pres_subset have "n - 1 ∈ set (prev # ?prev_τ)" using n_def nodes_def len_verts_gt0 by fastforce
with prev_lt_n show False by auto
qed
with ss_0th show " ss ! 0 = [] ∧ (∀p<n. p ≠ 0 ⟶ ss ! p ≠ rev [0..<n])" by auto
qed
lemma dom_iter_properties2:
"iter f step start (unstables r step start) = (ss,w) ⟶ (∀p<n. ss!p ≠ (rev [0..<n]))"
proof(intro strip)
fix p
assume iter: "iter f step start (unstables r step start) = (ss, w)" and p: "p < n"
show "ss ! p ≠ (rev [0..<n])"
proof(cases "p = 0")
case True
with iter have "ss!p = []" by (auto simp add:dom_iter_properties)
then show ?thesis using n_def nodes_def len_verts_gt0 by auto
next
case False
with iter p show ?thesis by (auto simp add:dom_iter_properties)
qed
qed
lemma kildall_dom_properties:
"kildall r f step start ∈ nlists n A ∧
stables r step (kildall r f step start) ∧
start [⊑⇩r] (kildall r f step start) ∧
(∀ts∈nlists n A. start [⊑⇩r] ts ∧ stables r step ts ⟶ (kildall r f step start) [⊑⇩r] ts)" (is "PROP ?P")
by (case_tac "iter f step start (unstables r step start)")(simp add: kildall_def iter_dom_properties iter_dom_properties2)
lemma dom_kildall_stables: "stables r step (dom_kildall start)"
using kildall_dom_properties
by(unfold dom_kildall_def nodes_semi_def) (simp add: r_def f_def step_def)
lemma dom_kildall_entry: "dom_kildall start !0 = []"
by (case_tac "iter f step start (unstables r step start)")
(auto simp add:dom_kildall_def nodes_semi_def dom_iter_properties r_def f_def step_def kildall_def)
lemma zero_dom_zero: "dom i 0 ⟷ i = 0"
using start_def n_def nodes_def dom_kildall_entry by (simp add:dom_def)
lemma sdom_dom_succs: "strict_dom i j ⟹ j ∈ succs k ⟹ dom i k"
proof -
assume sdom_i_j: "strict_dom i j" and k_j: "j ∈ succs k"
then have j: "j ∈ set (g_V G)"
and k: "k ∈ set (g_V G)" using verts_set succ_in_verts by auto
then have j_lt_n: "j < n" and k_lt_n: "k < n" using n_def nodes_def verts_set by auto
have fin_succs_k: "finite (succs k)" using fin_succs k by auto
with k_j have k_j2: "j ∈ set (rev (sorted_list_of_set(succs k)))" by auto
let ?ss0 = "start"
let ?w0 = "unstables r step start"
let ?res = "dom_kildall start"
have dom_kil: "?res = kildall r f step ?ss0"
by (auto simp add:dom_kildall_def r_def f_def step_def nodes_semi_def)
have sorted_unstables: "sorted ?w0" by (auto simp add:unstables_def sorted_less_sorted_list_of_set)
have ss: "?res = fst (iter f step ?ss0 ?w0)" by (auto simp add:dom_kildall_def kildall_def f_def step_def nodes_semi_def start_def r_def)
then obtain ww where dom_iter: "iter f step ?ss0 ?w0 = (?res, ww)" by (cases "iter f step ?ss0 ?w0") auto
with iter_dom_properties have wf_res: "wf_dom (dom_kildall start) ww" by auto
with sdom_i_j have i_dom_j: "i ∈ set (?res!j)" by (auto simp add:strict_dom_def start_def n_def nodes_def)
from wf_res have len_res: "length ?res = n" by (auto simp add:wf_dom_def)
show "dom i k"
proof(rule ccontr)
assume ass: "¬ dom i k"
then have i_neq_k: "i ≠ k" by (auto simp add:dom_refl)
with ass have "(∃res. ?res!k = res ∧ i ∉ set res)" using ass by (auto simp add:dom_def start_def nodes_def n_def)
then show False
proof -
assume "∃res. ?res ! k = res ∧ i ∉ set res"
then obtain rs where k_dom: "?res ! k = rs" and i_notin_rs: "i ∉ set rs" by auto
from iter_dom_properties dom_iter have "(∀p < length ?res. stable r step ?res p)" by (auto simp add:stables_def)
with k_lt_n have "stable r step ?res k" using len_res by auto
with k_dom have aux: "∀(q,τ) ∈ set (map (λpc. (pc, (k # rs))) (rev (sorted_list_of_set(succs k)))). τ ⊑⇩r ?res!q"
by (simp add:stable_def r_def step_def exec_def transf_def)
with k_j2 have "(k # rs) ⊑⇩r ?res!j" by auto
then have "set (?res!j) ⊆ set (k # rs) ∨ ?res!j = k#rs"
by (auto simp add:lesssub_def lesub_def nodes_semi_def nodes_le_def r_def f_def)
then have "set (?res!j) ⊆ set (k # rs)" by auto
with i_dom_j i_neq_k have " i ∈ set rs" by auto
with i_notin_rs show False by auto
qed
qed
qed
lemma adom_succs: "dom i j ⟹ i ≠ j ⟹ j ∈ succs k ⟹ dom i k"
by (auto intro: dom_sdom sdom_dom_succs)
lemma dom_kildall_is_strict: "j < length start ⟹ dom_kildall start ! j = res ⟹ j ∉ set res"
proof -
assume j_dom: "dom_kildall start ! j = res" and j_lt: "j < length start"
from j_dom have iter_fst: "(fst (iter f step start (unstables r step start))) ! j = res"
by (auto simp add:dom_kildall_def r_def f_def step_def start_def nodes_semi_def kildall_def)
then obtain ss w where iter: "iter f step start (unstables r step start) = (ss, w)" by fastforce
with iter_fst have res: "ss!j = res" by auto
with dom_iter_properties2 iter have res_neq_all: "res ≠ rev [0..<n]" using len_start_is_n j_lt len_start_is_n by auto
with iter iter_dom_properties have "∀p < n. (ss!p) ≠ rev [0..< n] ⟶ (∀x∈set ( (ss!p)). x < p)" by (auto simp add:wf_dom_def)
with j_lt len_start_is_n res res_neq_all have "(∀x∈set res. x < j)" by (auto simp add:wf_dom_def)
then show "j ∉ set res" by auto
qed
lemma sdom_asyc: "strict_dom i j ⟹ j ∈ set (g_V G) ⟹ i ≠ j"
proof-
assume sdom_i_j: "strict_dom i j" and "j ∈ set (g_V G)"
then have j_lt: "j < length start" using start_def n_def nodes_def verts_set by auto
let ?start = " [] # (replicate (length (g_V G) - 1) ( (rev[0..<length(g_V G)])))"
have eq_start: "?start = start" using n_def nodes_def start_def by simp
from sdom_i_j have i_in: "i ∈ set (dom_kildall ?start !j)" by (auto simp add:strict_dom_def)
from j_lt have j_nin: "j ∉ set (dom_kildall ?start !j)" using eq_start by (simp add: dom_kildall_is_strict)
with i_in show "i ≠ j" by auto
qed
lemma propa_dom_invariant_complete:
fixes i a b ss w
assumes b_n_nil: "b ≠ [] "
and propa: "propa f (step (hd b) (a ! hd b)) a (tl b) = (ss, w) "
and wf_a_b: "wf_dom a b"
and non_strict: "∀i. i < n ∧ k ∉ set (a!i) ⟶ non_strict_dominate k i "
shows "wf_dom ss w ∧ (∀i. i < n ∧ k ∉ set ( ss ! i) ⟶ non_strict_dominate k i)" (is "?PROP ?P")
using assms
proof-
let ?a_hdb = "a!hd b"
let ?qs = "step (hd b) (a!hd b)"
from wf_a_b b_n_nil propa have wf_ss_w: "wf_dom ss w" using propa_dom_invariant by auto
from wf_a_b have "∀τ∈set a. τ ∈ A"
and sorted_b: "sorted b"
and len_a: "length a = n"
and b_lt_n: "∀x∈set b. x < n "by (auto simp add:wf_dom_def)
then have set_a: "set a ⊆ A" by (auto intro:nlistsI)
from sorted_b have sorted_tl_b: "sorted (tl b)" using b_n_nil by (induct b) auto
from b_lt_n b_n_nil have hd_b_lt_n: "hd b < n" by auto
with n_def nodes_def verts_set have "hd b ∈ set (g_V G)" using b_n_nil by auto
then have fin_succ_hd_b: "finite (succs (hd b))" using fin_succs by auto
from wf_a_b b_n_nil have sorted_hd_b_a: "sorted (rev (hd b # ?a_hdb))"
and step_pres_bounded: " ∀(q, τ)∈set (step (hd b) ?a_hdb). q < length a ∧ τ ∈ A"
using propa_dom_invariant_auxi by auto
from hd_b_lt_n have dist: "distinct (map fst ?qs)" using distinct_p by auto
with set_a step_pres_bounded sorted_tl_b len_a have "∀(q, τ) ∈ set ?qs. (fst(propa f ?qs a (tl b)))!q = τ ⊔⇘f⇙a!q"
by (auto dest:propa_property1)
with propa have propa_ss1: "∀(q, τ) ∈ set ?qs. ss!q = (hd b # ?a_hdb) ⊔⇘f⇙a!q" by (auto simp add:step_def exec_def transf_def)
from step_pres_bounded sorted_tl_b set_a len_a dist
have "⋀q. q ∉ set(map fst ?qs) ⟹ q < length a ⟹ (fst(propa f ?qs a (tl b)))!q = a!q"
by (auto intro:propa_property2)
with propa have exec2: "⋀q. q ∉ set(map fst ?qs) ⟹ q < length a ⟹ ss!q = a!q" by auto
have "(∀i. i < n ∧ k ∉ set ( ss ! i) ⟶ non_strict_dominate k i)"
proof(intro strip)
fix i
let ?a_i = "a!i"
assume "i < n ∧ k ∉ set ( ss ! i) "
then have i_lt_n: "i < n" and k_nin_ss: "k ∉ set (ss ! i) " by auto
from non_strict have g: "i < n ∧ a ! i = ?a_i ∧ k ∉ set ?a_i ⟹ non_strict_dominate k i" by auto
have sorted_a_i: "sorted (rev ?a_i)" using wf_a_b i_lt_n by (auto simp add:_wf_dom_def)
show "non_strict_dominate k i"
proof(cases "i ∈ (succs (hd b))")
case True note i_succ_hdb = this
with propa_ss1 have ss_i: "ss!i = (hd b # ?a_hdb) ⊔⇘f⇙ a!i" using fin_succ_hd_b by (auto simp add:step_def exec_def)
then have "ss!i = (hd b # ?a_hdb ) ⊔⇘f⇙ ?a_i" by auto
with sorted_hd_b_a sorted_a_i have "set (ss!i) = set (hd b # ?a_hdb) ∩ set ?a_i"
and ss_i_merge: "ss!i = ((inter_sorted_rev (hd b # ?a_hdb) ?a_i))"
by (auto simp add:inter_sorted_correct f_def nodes_sup_def plussub_def)
with k_nin_ss have k_nin': "k ∉ set (hd b # ?a_hdb) ∩ set ?a_i" by auto
show ?thesis
proof(cases "k ∉ set ?a_i")
case True
then show ?thesis using i_lt_n g by auto
next
case False
with k_nin' have "k ∉ set ?a_hdb" and k_neq_hdb: "k ≠ hd b" by auto
with hd_b_lt_n non_strict have n_k_hdb: "non_strict_dominate k (hd b)" by auto
from i_succ_hdb have "(hd b, i)∈ g_E G" by (auto simp add:succs_def)
with n_k_hdb k_neq_hdb show ?thesis using non_sdominate_succ by auto
qed
next
case False
with exec2 have "ss!i = a!i" using fin_succ_hd_b len_a i_lt_n by (auto simp add:step_def exec_def)
with k_nin_ss have "k ∉ set (a!i)" by auto
with non_strict show ?thesis using i_lt_n by fastforce
qed
qed
with wf_ss_w show "?PROP ?P" by auto
qed
lemma start_non_sdom: " i < n ∧ start!i = res ∧ k ∉ set res ⟶ non_strict_dominate k i"
proof(auto)
assume i_lt_n: "i < n" and k_nin: "k ∉ set (start ! i)"
then have reach_i: "reachable i" using n_def nodes_def verts_set len_verts_gt0 reachable by (simp add:reachable_def)
then obtain pa where pa_i: "path_entry (g_E G) pa i" using reachable_path_entry by auto
show "non_strict_dominate k i"
proof(cases "k ∈ set (g_V G)")
case True
then have "k < n" using verts_set by (auto simp add:n_def nodes_def)
then have k_in_verts: "k ∈ set (g_V G)" and k_in_verts': "k ∈ {0..<n}" using verts_set n_def nodes_def by auto
show "non_strict_dominate k i"
proof(cases "i = 0")
case True then show ?thesis using any_sdominate_0 k_in_verts by auto
next
case False
then have "start!i = (rev [0..<n])" using start_def i_lt_n n_def nodes_def by (simp add:start_def)
with k_nin k_in_verts' show ?thesis by auto
qed
next
case False note k_nin_verts = this
have "∀pa. path_entry (g_E G) pa i ⟶ set pa ⊆ set (g_V G)" using path_in_verts nodes_def by auto
with k_nin_verts have k_nin: "∀pa. path_entry (g_E G) pa i ⟶ k ∉ set pa"
by (fastforce dest: contra_subsetD)
with pa_i have "k ∉ set pa" by auto
with pa_i show ?thesis by (auto simp add: non_strict_dominate_def)
qed
qed
lemma iter_dom_invariant_complete:
shows "⋀res. iter f step start (unstables r step start) = (ss',w') ⟶ i < n ∧ ss'!i = res ∧ k ∉ set res ⟶ non_strict_dominate k i"
apply (unfold iter_def)
apply(rule_tac
P = "(λ(ss, w). wf_dom ss w ∧ (∀i. (∃rs. i < n ∧ ss!i = rs ∧ k ∉ set rs) ⟶ non_strict_dominate k i))" and
r = "{(ss',ss). ss [⊏⇩r] ss'} <*lex*> (λ(x,y). (sorted_list_of_set x, sorted_list_of_set y)) ` finite_psubset"
in while_rule)
apply clarsimp
apply (fastforce simp add:start_non_sdom wf_start)
apply (fastforce dest:propa_dom_invariant_complete)
apply clarsimp
apply (simp add:wf_listn_termination_rel)
apply clarsimp
apply (fastforce dest:propa_termination)
done
end
end