Theory ShareRepProof
section ‹Proof of Procedure ShareRep›
theory ShareRepProof imports ProcedureSpecs Simpl.HeapList begin
lemma (in ShareRep_impl) ShareRep_modifies:
shows "∀σ. Γ⊢{σ} PROC ShareRep (´nodeslist, ´p)
{t. t may_only_modify_globals σ in [rep]}"
apply (hoare_rule HoarePartial.ProcRec1)
apply (vcg spec=modifies)
done
lemma hd_filter_cons:
"⋀ i. ⟦ P (xs ! i) p; i < length xs; ∀ no ∈ set (take i xs). ¬ P no p; ∀ a b. P a b = P b a⟧
⟹ xs ! i = hd (filter (P p) xs)"
apply (induct xs)
apply simp
apply (case_tac "P a p")
apply simp
apply (case_tac i)
apply simp
apply simp
apply (case_tac i)
apply simp
apply auto
done
lemma (in ShareRep_impl) ShareRep_spec_total:
shows
"∀σ ns. Γ,Θ⊢⇩t
⦃σ. List ´nodeslist ´next ns ∧
(∀no ∈ set ns. no ≠ Null ∧
((no→´low = Null) = (no→´high = Null)) ∧
(isLeaf_pt ´p ´low ´high ⟶ isLeaf_pt no ´low ´high) ∧
no→´var = ´p→´var) ∧
´p ∈ set ns⦄
PROC ShareRep (´nodeslist, ´p)
⦃ (⇗σ⇖p → ´rep = hd (filter (λ sn. repNodes_eq sn ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⇗σ⇖rep) ns)) ∧
(∀pt. pt ≠ ⇗σ⇖p ⟶ pt→⇗σ⇖rep = pt→´rep) ∧
(⇗σ⇖p→´rep→⇗σ⇖var = ⇗σ⇖p → ⇗σ⇖var)⦄"
apply (hoare_rule HoareTotal.ProcNoRec1)
apply (hoare_rule anno=
"IF (isLeaf_pt ´p ´low ´high)
THEN ´p → ´rep :== ´nodeslist
ELSE
WHILE (´nodeslist ≠ Null)
INV ⦃∃prx sfx. List ´nodeslist ´next sfx ∧ ns=prx@sfx ∧
¬ isLeaf_pt ´p ´low ´high ∧
(∀no ∈ set ns. no ≠ Null ∧
((no→⇗σ⇖low = Null) = (no→⇗σ⇖high = Null)) ∧
(isLeaf_pt ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⟶ isLeaf_pt no ⇗σ⇖low ⇗σ⇖high) ∧
no→⇗σ⇖var = ⇗σ⇖p→⇗σ⇖var) ∧
⇗σ⇖p ∈ set ns ∧
((∃pt ∈ set prx. repNodes_eq pt ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⇗σ⇖rep)
⟶ ´rep ⇗σ⇖p = hd (filter (λ sn. repNodes_eq sn ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⇗σ⇖rep) prx) ∧
(∀pt. pt ≠ ⇗σ⇖p ⟶ pt→⇗σ⇖rep = pt→´rep)) ∧
((∀pt ∈ set prx. ¬ repNodes_eq pt ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⇗σ⇖rep) ⟶ ⇗σ⇖rep = ´rep) ∧
(´nodeslist ≠ Null ⟶
(∀pt ∈ set prx. ¬ repNodes_eq pt ⇗σ⇖p ⇗σ⇖low ⇗σ⇖high ⇗σ⇖rep)) ∧
(´p = ⇗σ⇖p ∧ ´high = ⇗σ⇖high ∧ ´low = ⇗σ⇖low)⦄
VAR MEASURE (length (list ´nodeslist ´next))
DO
IF (repNodes_eq ´nodeslist ´p ´low ´high ´rep)
THEN ´p→´rep :== ´nodeslist;; ´nodeslist :== Null
ELSE ´nodeslist :== ´nodeslist→´next
FI
OD
FI" in HoareTotal.annotateI)
apply vcg
using [[simp_depth_limit = 2]]
apply (rule conjI)
apply clarify
apply (simp (no_asm_use))
prefer 2
apply clarify
apply (rule_tac x="[]" in exI)
apply (rule_tac x=ns in exI)
apply (simp (no_asm_use))
prefer 2
apply clarify
apply (rule conjI)
apply clarify
apply (rule conjI)
apply (clarsimp simp add: List_list)
apply (simp (no_asm_use))
apply (rule conjI)
apply assumption
prefer 2
apply clarify
apply (simp (no_asm_use))
apply (rule conjI)
apply (clarsimp simp add: List_list)
apply (simp only: List_not_Null simp_thms triv_forall_equality)
apply clarify
apply (simp only: triv_forall_equality)
apply (rename_tac sfx)
apply (rule_tac x="prx@[nodeslist]" in exI)
apply (rule_tac x="sfx" in exI)
apply (rule conjI)
apply assumption
apply (rule conjI)
apply simp
prefer 4
apply (elim exE conjE)
apply (simp (no_asm_use))
apply hypsubst
using [[simp_depth_limit = 100]]
proof -
fix ns var low high rep "next" p nodeslist
assume ns: "List nodeslist next ns"
assume no_prop: "∀no∈set ns.
no ≠ Null ∧
(low no = Null) = (high no = Null) ∧
(isLeaf_pt p low high ⟶ isLeaf_pt no low high) ∧ var no = var p"
assume p_in_ns: "p ∈ set ns"
assume p_Leaf: "isLeaf_pt p low high"
show "nodeslist = hd [sn←ns . repNodes_eq sn p low high rep] ∧
var nodeslist = var p"
proof -
from p_in_ns no_prop have p_not_Null: "p≠Null"
using [[simp_depth_limit=2]]
by auto
from p_in_ns have "ns ≠ []"
by (cases ns) auto
with ns obtain ns' where ns': "ns = nodeslist#ns'"
by (cases "nodeslist=Null") auto
with no_prop p_Leaf obtain
"isLeaf_pt nodeslist low high" and
var_eq: "var nodeslist = var p" and
"nodeslist≠Null"
using [[simp_depth_limit=2]]
by auto
with p_not_Null p_Leaf have "repNodes_eq nodeslist p low high rep"
by (simp add: repNodes_eq_def isLeaf_pt_def null_comp_def)
with ns' var_eq
show ?thesis
by simp
qed
next
fix var::"ref⇒nat" and low high rep repa p prx sfx "next"
assume sfx: "List Null next sfx"
assume p_in_ns: "p ∈ set (prx @ sfx)"
assume no_props: "∀no∈set (prx @ sfx).
no ≠ Null ∧
(low no = Null) = (high no = Null) ∧
(isLeaf_pt p low high ⟶ isLeaf_pt no low high) ∧ var no = var p"
assume match_prx: "(∃pt∈set prx. repNodes_eq pt p low high rep) ⟶
repa p = hd [sn←prx . repNodes_eq sn p low high rep] ∧
(∀pt. pt ≠ p ⟶ rep pt = repa pt)"
show "repa p = hd [sn←prx @ sfx . repNodes_eq sn p low high rep] ∧
(∀pt. pt ≠ p ⟶ rep pt = repa pt) ∧ var (repa p) = var p"
proof -
from sfx
have sfx_Nil: "sfx=[]"
by simp
with p_in_ns have ex_match: "(∃pt∈set prx. repNodes_eq pt p low high rep)"
apply -
apply (rule_tac x=p in bexI)
apply (simp add: repNodes_eq_def)
apply simp
done
hence not_empty: "[sn←prx . repNodes_eq sn p low high rep] ≠ []"
apply -
apply (erule bexE)
apply (rule filter_not_empty)
apply auto
done
from ex_match match_prx obtain
found: "repa p = hd [sn←prx . repNodes_eq sn p low high rep]" and
unmodif: "∀pt. pt ≠ p ⟶ rep pt = repa pt"
by blast
from hd_filter_in_list [OF not_empty] found
have "repa p ∈ set prx"
by simp
with no_props
have "var (repa p) = var p"
using [[simp_depth_limit=2]]
by simp
with found unmodif sfx_Nil
show ?thesis
by simp
qed
next
fix var low high p repa "next" nodeslist prx sfx
assume nodeslist_not_Null: "nodeslist ≠ Null"
assume p_no_Leaf: "¬ isLeaf_pt p low high"
assume no_props: "∀no∈set prx ∪ set (nodeslist # sfx).
no ≠ Null ∧ (low no = Null) = (high no = Null) ∧ var no = var p"
assume p_in_ns: "p ∈ set prx ∨ p ∈ set (nodeslist # sfx)"
assume match_prx: "(∃pt∈set prx. repNodes_eq pt p low high repa) ⟶
repa p = hd [sn←prx . repNodes_eq sn p low high repa]"
assume nomatch_prx: "∀pt∈set prx. ¬ repNodes_eq pt p low high repa"
assume nomatch_nodeslist: "¬ repNodes_eq nodeslist p low high repa"
assume sfx: "List (next nodeslist) next sfx"
show "(∀no∈set prx ∪ set (nodeslist # sfx).
no ≠ Null ∧ (low no = Null) = (high no = Null) ∧ var no = var p) ∧
((∃pt∈set (prx @ [nodeslist]). repNodes_eq pt p low high repa) ⟶
repa p = hd [sn←prx @ [nodeslist] . repNodes_eq sn p low high repa]) ∧
(next nodeslist ≠ Null ⟶
(∀pt∈set (prx @ [nodeslist]). ¬ repNodes_eq pt p low high repa))"
proof -
from nomatch_prx nomatch_nodeslist
have "((∃pt∈set (prx @ [nodeslist]). repNodes_eq pt p low high repa) ⟶
repa p = hd [sn←prx @ [nodeslist] . repNodes_eq sn p low high repa])"
by auto
moreover
from nomatch_prx nomatch_nodeslist
have "(next nodeslist ≠ Null ⟶
(∀pt∈set (prx @ [nodeslist]). ¬ repNodes_eq pt p low high repa))"
by auto
ultimately show ?thesis
using no_props
by (intro conjI)
qed
next
fix var low high p repa "next" nodeslist prx sfx
assume nodeslist_not_Null: "nodeslist ≠ Null"
assume sfx: "List nodeslist next sfx"
assume p_not_Leaf: "¬ isLeaf_pt p low high"
assume no_props: "∀no∈set prx ∪ set sfx.
no ≠ Null ∧
(low no = Null) = (high no = Null) ∧
(isLeaf_pt p low high ⟶ isLeaf_pt no low high) ∧ var no = var p"
assume p_in_ns: "p ∈ set prx ∨ p ∈ set sfx"
assume match_prx: "(∃pt∈set prx. repNodes_eq pt p low high repa) ⟶
repa p = hd [sn←prx . repNodes_eq sn p low high repa]"
assume nomatch_prx: "∀pt∈set prx. ¬ repNodes_eq pt p low high repa"
assume match: "repNodes_eq nodeslist p low high repa"
show "(∀no∈set prx ∪ set sfx.
no ≠ Null ∧
(low no = Null) = (high no = Null) ∧
(isLeaf_pt p low high ⟶ isLeaf_pt no low high) ∧ var no = var p) ∧
(p ∈ set prx ∨ p ∈ set sfx) ∧
((∃pt∈set prx ∪ set sfx. repNodes_eq pt p low high repa) ⟶
nodeslist =
hd ([sn←prx . repNodes_eq sn p low high repa] @
[sn←sfx . repNodes_eq sn p low high repa])) ∧
((∀pt∈set prx ∪ set sfx. ¬ repNodes_eq pt p low high repa) ⟶
repa = repa(p := nodeslist))"
proof -
from nodeslist_not_Null sfx
obtain sfx' where sfx': "sfx=nodeslist#sfx'"
by (cases "nodeslist=Null") auto
from nomatch_prx match sfx'
have hd: "hd ([sn←prx . repNodes_eq sn p low high repa] @
[sn←sfx . repNodes_eq sn p low high repa]) = nodeslist"
by simp
from match sfx'
have triv: "((∀pt∈set prx ∪ set sfx. ¬ repNodes_eq pt p low high repa) ⟶
repa = repa(p := nodeslist))"
by simp
show ?thesis
apply (rule conjI)
apply (rule no_props)
apply (intro conjI)
apply (rule p_in_ns)
apply (simp add: hd)
apply (rule triv)
done
qed
qed
end