definition
― ‹A short form for the stack mapping function for List›
S :: "('a ==> bool) ==> ('a ==> 'a ref) ==> ('a ==> 'a ref) ==> ('a ==> 'a ref)" where"S c l r = (λx. if c x then r x else l x)"
text‹Rewrite rules for Lists using S as their mapping›
lemma [rule_format,simp]: "∀p. a ∉ set stack ⟶ List (S c l r) p stack = List (S (c(a:=x)) (l(a:=y)) (r(a:=z))) p stack" apply(induct_tac stack) apply(simp add:fun_upd_apply S_def)+ done
lemma [rule_format,simp]: "∀p. a ∉ set stack ⟶ List (S c l (r(a:=z))) p stack = List (S c l r) p stack" apply(induct_tac stack) apply(simp add:fun_upd_apply S_def)+ done
lemma [rule_format,simp]: "∀p. a ∉ set stack ⟶ List (S c (l(a:=z)) r) p stack = List (S c l r) p stack" apply(induct_tac stack) apply(simp add:fun_upd_apply S_def)+ done
lemma [rule_format,simp]: "∀p. a ∉ set stack ⟶ List (S (c(a:=z)) l r) p stack = List (S c l r) p stack" apply(induct_tac stack) apply(simp add:fun_upd_apply S_def)+ done
primrec
― ‹Recursive definition of what is means for a the graph/stack structure to be reconstructible›
stkOk :: "('a ==> bool) ==> ('a ==> 'a ref) ==> ('a ==> 'a ref) ==> ('a ==> 'a ref) ==> ('a ==> 'a ref) ==> 'a ref ==>'a list ==> bool" where
stkOk_nil: "stkOk c l r iL iR t [] = True"
| stkOk_cons: "stkOk c l r iL iR t (p#stk) = (stkOk c l r iL iR (Ref p) (stk) ∧ iL p = (if c p then l p else t) ∧ iR p = (if c p then t else r p))"
text‹Rewrite rules for stkOk›
lemma [simp]: "∧t. [ x ∉ set xs; Ref x≠t ]==> stkOk (c(x := f)) l r iL iR t xs = stkOk c l r iL iR t xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
lemma [simp]: "∧t. [ x ∉ set xs; Ref x≠t ]==> stkOk c (l(x := g)) r iL iR t xs = stkOk c l r iL iR t xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
lemma [simp]: "∧t. [ x ∉ set xs; Ref x≠t ]==> stkOk c l (r(x := g)) iL iR t xs = stkOk c l r iL iR t xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
lemma stkOk_r_rewrite [simp]: "∧x. x ∉ set xs ==> stkOk c l (r(x := g)) iL iR (Ref x) xs = stkOk c l r iL iR (Ref x) xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
lemma [simp]: "∧x. x ∉ set xs ==> stkOk c (l(x := g)) r iL iR (Ref x) xs = stkOk c l r iL iR (Ref x) xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
lemma [simp]: "∧x. x ∉ set xs ==> stkOk (c(x := g)) l r iL iR (Ref x) xs = stkOk c l r iL iR (Ref x) xs" apply (induct xs) apply (auto simp:eq_sym_conv) done
subsection‹The Schorr-Waite algorithm›
theorem SchorrWaiteAlgorithm: "VARS c m l r t p q root {R = reachable (relS {l, r}) {root} ∧ (∀x. ¬ m x) ∧ iR = r ∧ iL = l} t := root; p := Null; WHILE p ≠ Null ∨ t ≠ Null ∧¬ t^.m INV {∃stack. List (S c l r) p stack ∧ ― ‹‹i1›› (∀x ∈ set stack. m x) ∧ ― ‹‹i2›› R = reachable (relS{l, r}) {t,p} ∧ ― ‹‹i3›› (∀x. x ∈ R ∧¬m x ⟶ ― ‹‹i4›› x ∈ reachable (relS{l,r}|m) ({t}∪set(map r stack))) ∧ (∀x. m x ⟶ x ∈ R) ∧ ― ‹‹i5›› (∀x. x ∉ set stack ⟶ r x = iR x ∧ l x = iL x) ∧ ― ‹‹i6›› (stkOk c l r iL iR t stack) ― ‹‹i7››} DO IF t = Null ∨ t^.m THEN IF p^.c THEN q := t; t := p; p := p^.r; t^.r := q ― ‹‹pop›› ELSE q := t; t := p^.r; p^.r := p^.l; ― ‹‹swing›› p^.l := q; p^.c := True FI ELSE q := p; p := t; t := t^.l; p^.l := q; ― ‹‹push›› p^.m := True; p^.c := False FI OD {(∀x. (x ∈ R) = m x) ∧ (r = iR ∧ l = iL) }"
(is"Valid {(c, m, l, r, t, p, q, root). ?Pre c m l r root} (Seq _ (Seq _ (While {(c, m, l, r, t, p, q, root). ?whileB m t p} _))) (Aseq _ (Aseq _ (Awhile {(c, m, l, r, t, p, q, root). ?inv c m l r t p} _ _))) _") proof (vcg)
{ fix c m l r t p q root assume"?Pre c m l r root" thus"?inv c m l r root Null"by (auto simp add: reachable_def addrs_def) next fix c m l r t p q let"∃stack. ?Inv stack" = "?inv c m l r t p" assume a: "?inv c m l r t p ∧¬(p ≠ Null ∨ t ≠ Null ∧¬ t^.m)" thenobtain stack where inv: "?Inv stack"by blast from a have pNull: "p = Null"and tDisj: "t=Null ∨ (t≠Null ∧ t^.m )"by auto let"?I1 ∧ _ ∧ _ ∧ ?I4 ∧ ?I5 ∧ ?I6 ∧ _" = "?Inv stack" from inv have i1: "?I1"and i4: "?I4"and i5: "?I5"and i6: "?I6"by simp+ from pNull i1 have stackEmpty: "stack = []"by simp from tDisj i4 have RisMarked[rule_format]: "∀x. x ∈ R ⟶ m x"by(auto simp: reachable_def addrs_def stackEmpty) from i5 i6 show"(∀x.(x ∈ R) = m x) ∧ r = iR ∧ l = iL"by(auto simp: stackEmpty fun_eq_iff intro:RisMarked) next fix c m l r t p q root let"∃stack. ?Inv stack" = "?inv c m l r t p" let"∃stack. ?popInv stack" = "?inv c m l (r(p → t)) p (p^.r)" let"∃stack. ?swInv stack" = "?inv (c(p → True)) m (l(p → t)) (r(p → p^.l)) (p^.r) p" let"∃stack. ?puInv stack" = "?inv (c(t → False)) (m(t → True)) (l(t → p)) r (t^.l) t" let"?ifB1" = "(t = Null ∨ t^.m)" let"?ifB2" = "p^.c"
assume"(∃stack.?Inv stack) ∧ ?whileB m t p" thenobtain stack where inv: "?Inv stack"and whileB: "?whileB m t p"by blast let"?I1 ∧ ?I2 ∧ ?I3 ∧ ?I4 ∧ ?I5 ∧ ?I6 ∧ ?I7" = "?Inv stack" from inv have i1: "?I1"and i2: "?I2"and i3: "?I3"and i4: "?I4" and i5: "?I5"and i6: "?I6"and i7: "?I7"by simp+ have stackDist: "distinct (stack)"using i1 by (rule List_distinct)
show"(?ifB1 ⟶ (?ifB2 ⟶ (∃stack.?popInv stack)) ∧ (¬?ifB2 ⟶ (∃stack.?swInv stack)) ) ∧ (¬?ifB1 ⟶ (∃stack.?puInv stack))" proof -
{ assume ifB1: "t = Null ∨ t^.m"and ifB2: "p^.c" from ifB1 whileB have pNotNull: "p ≠ Null"by auto thenobtain addr_p where addr_p_eq: "p = Ref addr_p"by auto with i1 obtain stack_tl where stack_eq: "stack = (addr p) # stack_tl" by auto with i2 have m_addr_p: "p^.m"by auto have stackDist: "distinct (stack)"using i1 by (rule List_distinct) from stack_eq stackDist have p_notin_stack_tl: "addr p ∉ set stack_tl"by simp let"?poI1∧ ?poI2∧ ?poI3∧ ?poI4∧ ?poI5∧ ?poI6∧ ?poI7" = "?popInv stack_tl" have"?popInv stack_tl" proof -
― ‹List property is maintained:› from i1 p_notin_stack_tl ifB2 have poI1: "List (S c l (r(p → t))) (p^.r) stack_tl" by(simp add: addr_p_eq stack_eq, simp add: S_def)
moreover
― ‹Everything on the stack is marked:› from i2 have poI2: "∀ x ∈ set stack_tl. m x"by (simp add:stack_eq) moreover
― ‹If it is reachable and not marked, it is still reachable using...› let"∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Ra ?A" = ?I4 let"?Rb" = "relS {l, r(p → t)} | m" let"?B" = "{p} ∪ set (map (r(p → t)) stack_tl)"
― ‹Our goal is ‹∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Rb ?B›.› let ?T = "{t, p^.r}"
have"?Ra* `` addrs ?A ⊆ ?Rb* `` (addrs ?B ∪ addrs ?T)" proof (rule still_reachable) have rewrite: "∀s∈set stack_tl. (r(p → t)) s = r s" by (auto simp add:p_notin_stack_tl intro:fun_upd_other) show"addrs ?A ⊆ ?Rb* `` (addrs ?B ∪ addrs ?T)" by (fastforce cong:map_cong simp:stack_eq addrs_def rewrite intro:self_reachable) show"∀(x, y)∈?Ra-?Rb. y∈(?Rb*``(addrs ?B ∪ addrs ?T))" by (clarsimp simp:restr_def relS_def)
(fastforce simp add:rel_def Image_iff addrs_def dest:rel_upd1) qed
― ‹We now bring a term from the right to the left of the subset relation.› hence subset: "?Ra* `` addrs ?A - ?Rb* `` addrs ?T ⊆ ?Rb* `` addrs ?B" by blast have poI4: "∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Rb ?B" proof (rule allI, rule impI) fix x assume a: "x ∈ R ∧¬ m x"
― ‹First, a disjunction on term‹p^.r› used later in the proof› have pDisj:"p^.r = Null ∨ (p^.r ≠ Null ∧ p^.r^.m)"using poI1 poI2 by auto
― ‹term‹x› belongs to the left hand side of @{thm[source] subset}:› have incl: "x ∈ ?Ra*``addrs ?A"using a i4 by (simp only:reachable_def, clarsimp) have excl: "x ∉ ?Rb*`` addrs ?T"using pDisj ifB1 a by (auto simp add:addrs_def)
― ‹And therefore also belongs to the right hand side of @{thm[source]subset},›
― ‹which corresponds to our goal.› from incl excl subset show"x ∈ reachable ?Rb ?B"by (auto simp add:reachable_def) qed moreover
― ‹If it is marked, then it is reachable› from i5 have poI5: "∀x. m x ⟶ x ∈ R" . moreover
― ‹If it is not on the stack, then its term‹l› and term‹r› fields are unchanged› from i7 i6 ifB2 have poI6: "∀x. x ∉ set stack_tl ⟶ (r(p → t)) x = iR x ∧ l x = iL x" by(auto simp: addr_p_eq stack_eq fun_upd_apply)
moreover
― ‹If it is on the stack, then its term‹l› and term‹r› fields can be reconstructed› from p_notin_stack_tl i7 have poI7: "stkOk c l (r(p → t)) iL iR p stack_tl" by (clarsimp simp:stack_eq addr_p_eq)
ultimatelyshow"?popInv stack_tl"by simp qed hence"∃stack. ?popInv stack" ..
} moreover
― ‹Proofs of the Swing and Push arm follow.›
― ‹Since they are in principle simmilar to the Pop arm proof,›
― ‹we show fewer comments and use frequent pattern matching.›
{
― ‹Swing arm› assume ifB1: "?ifB1"and nifB2: "¬?ifB2" from ifB1 whileB have pNotNull: "p ≠ Null"by clarsimp thenobtain addr_p where addr_p_eq: "p = Ref addr_p"by clarsimp with i1 obtain stack_tl where stack_eq: "stack = (addr p) # stack_tl"by clarsimp with i2 have m_addr_p: "p^.m"by clarsimp from stack_eq stackDist have p_notin_stack_tl: "(addr p) ∉ set stack_tl" by simp let"?swI1∧?swI2∧?swI3∧?swI4∧?swI5∧?swI6∧?swI7" = "?swInv stack" have"?swInv stack" proof -
― ‹List property is maintained:› from i1 p_notin_stack_tl nifB2 have swI1: "?swI1" by (simp add:addr_p_eq stack_eq, simp add:S_def) moreover
― ‹Everything on the stack is marked:› from i2 have swI2: "?swI2" . moreover
― ‹Everything is still reachable:› let"R = reachable ?Ra ?A" = "?I3" let"R = reachable ?Rb ?B" = "?swI3" have"?Ra* `` addrs ?A = ?Rb* `` addrs ?B" proof (rule still_reachable_eq) show"addrs ?A ⊆ ?Rb* `` addrs ?B" by(fastforce simp:addrs_def rel_defs addr_p_eq intro:oneStep_reachable Image_iff[THENiffD2]) next show"addrs ?B ⊆ ?Ra* `` addrs ?A" by(fastforce simp:addrs_def rel_defs addr_p_eq intro:oneStep_reachable Image_iff[THENiffD2]) next show"∀(x, y)∈?Ra-?Rb. y∈(?Rb*``addrs ?B)" by (clarsimp simp:relS_def) (fastforce simp add:rel_def Image_iff addrs_def fun_upd_apply dest:rel_upd1) next show"∀(x, y)∈?Rb-?Ra. y∈(?Ra*``addrs ?A)" by (clarsimp simp:relS_def) (fastforce simp add:rel_def Image_iff addrs_def fun_upd_apply dest:rel_upd2) qed with i3 have swI3: "?swI3"by (simp add:reachable_def) moreover
― ‹If it is reachable and not marked, it is still reachable using...› let"∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Ra ?A" = ?I4 let"∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Rb ?B" = ?swI4 let ?T = "{t}" have"?Ra*``addrs ?A ⊆ ?Rb*``(addrs ?B ∪ addrs ?T)" proof (rule still_reachable) have rewrite: "(∀s∈set stack_tl. (r(addr p := l(addr p))) s = r s)" by (auto simp add:p_notin_stack_tl intro:fun_upd_other) show"addrs ?A ⊆ ?Rb* `` (addrs ?B ∪ addrs ?T)" by (fastforce cong:map_cong simp:stack_eq addrs_def rewrite intro:self_reachable) next show"∀(x, y)∈?Ra-?Rb. y∈(?Rb*``(addrs ?B ∪ addrs ?T))" by (clarsimp simp:relS_def restr_def) (fastforce simp add:rel_def Image_iff addrs_def fun_upd_apply dest:rel_upd1) qed thenhave subset: "?Ra*``addrs ?A - ?Rb*``addrs ?T ⊆ ?Rb*``addrs ?B" by blast have ?swI4 proof (rule allI, rule impI) fix x assume a: "x ∈ R ∧¬ m x" with i4 addr_p_eq stack_eq have inc: "x ∈ ?Ra*``addrs ?A" by (simp only:reachable_def, clarsimp) with ifB1 a have exc: "x ∉ ?Rb*`` addrs ?T" by (auto simp add:addrs_def) from inc exc subset show"x ∈ reachable ?Rb ?B" by (auto simp add:reachable_def) qed moreover
― ‹If it is marked, then it is reachable› from i5 have"?swI5" . moreover
― ‹If it is not on the stack, then its term‹l› and term‹r› fields are unchanged› from i6 stack_eq have"?swI6" by clarsimp moreover
― ‹If it is on the stack, then its term‹l› and term‹r› fields can be reconstructed› from stackDist i7 nifB2 have"?swI7" by (clarsimp simp:addr_p_eq stack_eq)
ultimatelyshow ?thesis by auto qed thenhave"∃stack. ?swInv stack"by blast
} moreover
{
― ‹Push arm› assume nifB1: "¬?ifB1" from nifB1 whileB have tNotNull: "t ≠ Null"by clarsimp thenobtain addr_t where addr_t_eq: "t = Ref addr_t"by clarsimp with i1 obtain new_stack where new_stack_eq: "new_stack = (addr t) # stack"by clarsimp from tNotNull nifB1 have n_m_addr_t: "¬ (t^.m)"by clarsimp with i2 have t_notin_stack: "(addr t) ∉ set stack"by blast let"?puI1∧?puI2∧?puI3∧?puI4∧?puI5∧?puI6∧?puI7" = "?puInv new_stack" have"?puInv new_stack" proof -
― ‹List property is maintained:› from i1 t_notin_stack have puI1: "?puI1" by (simp add:addr_t_eq new_stack_eq, simp add:S_def) moreover
― ‹Everything on the stack is marked:› from i2 have puI2: "?puI2" by (simp add:new_stack_eq fun_upd_apply) moreover
― ‹Everything is still reachable:› let"R = reachable ?Ra ?A" = "?I3" let"R = reachable ?Rb ?B" = "?puI3" have"?Ra* `` addrs ?A = ?Rb* `` addrs ?B" proof (rule still_reachable_eq) show"addrs ?A ⊆ ?Rb* `` addrs ?B" by(fastforce simp:addrs_def rel_defs addr_t_eq intro:oneStep_reachable Image_iff[THENiffD2]) next show"addrs ?B ⊆ ?Ra* `` addrs ?A" by(fastforce simp:addrs_def rel_defs addr_t_eq intro:oneStep_reachable Image_iff[THENiffD2]) next show"∀(x, y)∈?Ra-?Rb. y∈(?Rb*``addrs ?B)" by (clarsimp simp:relS_def) (fastforce simp add:rel_def Image_iff addrs_def dest:rel_upd1) next show"∀(x, y)∈?Rb-?Ra. y∈(?Ra*``addrs ?A)" by (clarsimp simp:relS_def) (fastforce simp add:rel_def Image_iff addrs_def fun_upd_apply dest:rel_upd2) qed with i3 have puI3: "?puI3"by (simp add:reachable_def) moreover
― ‹If it is reachable and not marked, it is still reachable using...› let"∀x. x ∈ R ∧¬ m x ⟶ x ∈ reachable ?Ra ?A" = ?I4 let"∀x. x ∈ R ∧¬ ?new_m x ⟶ x ∈ reachable ?Rb ?B" = ?puI4 let ?T = "{t}" have"?Ra*``addrs ?A ⊆ ?Rb*``(addrs ?B ∪ addrs ?T)" proof (rule still_reachable) show"addrs ?A ⊆ ?Rb* `` (addrs ?B ∪ addrs ?T)" by (fastforce simp:new_stack_eq addrs_def intro:self_reachable) next show"∀(x, y)∈?Ra-?Rb. y∈(?Rb*``(addrs ?B ∪ addrs ?T))" by (clarsimp simp:relS_def new_stack_eq restr_un restr_upd)
(fastforce simp add:rel_def Image_iff restr_def addrs_def fun_upd_apply addr_t_eq dest:rel_upd3) qed thenhave subset: "?Ra*``addrs ?A - ?Rb*``addrs ?T ⊆ ?Rb*``addrs ?B" by blast have ?puI4 proof (rule allI, rule impI) fix x assume a: "x ∈ R ∧¬ ?new_m x" have xDisj: "x=(addr t) ∨ x≠(addr t)"by simp with i4 a have inc: "x ∈ ?Ra*``addrs ?A" by (fastforce simp:addr_t_eq addrs_def reachable_def intro:self_reachable) have exc: "x ∉ ?Rb*`` addrs ?T" using xDisj a n_m_addr_t by (clarsimp simp add:addrs_def addr_t_eq) from inc exc subset show"x ∈ reachable ?Rb ?B" by (auto simp add:reachable_def) qed moreover
― ‹If it is marked, then it is reachable› from i5 have"?puI5" by (auto simp:addrs_def i3 reachable_def addr_t_eq fun_upd_apply intro:self_reachable) moreover
― ‹If it is not on the stack, then its term‹l› and term‹r› fields are unchanged› from i6 have"?puI6" by (simp add:new_stack_eq) moreover
― ‹If it is on the stack, then its term‹l› and term‹r› fields can be reconstructed› from stackDist i6 t_notin_stack i7 have"?puI7"by (clarsimp simp:addr_t_eq new_stack_eq)
ultimatelyshow ?thesis by auto qed thenhave"∃stack. ?puInv stack"by blast
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.