(* Title: BDD
Author: Veronika Ortner and Norbert Schirmer, 2004
Maintainer: Norbert Schirmer, norbert.schirmer at web de
License: LGPL
*)
(*
ShareRepProof.thy
Copyright (C) 2004-2008 Veronika Ortner and Norbert Schirmer
Some rights reserved, TU Muenchen
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*)
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)
{ (<sigma>p → 🚫rep = hd (filter (λ sn. repNodes_eq sn <sigma>p <sigma>low <sigma>high <sigma>rep) ns)) ∧
(∀pt. pt ≠ <sigma>p ⟶ pt→<sigma>rep = pt→🚫rep) ∧
(<sigma>p→🚫rep→<sigma>var = <sigma>p → <sigma>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→<sigma>low = Null) = (no→<sigma>high = Null)) ∧
(isLeaf_pt <sigma>p <sigma>low <sigma>high ⟶ isLeaf_pt no <sigma>low <sigma>high) ∧
no→<sigma>var = <sigma>p→<sigma>var) ∧
<sigma>p ∈ set ns ∧
((∃pt ∈ set prx. repNodes_eq pt <sigma>p <sigma>low <sigma>high <sigma>rep)
⟶ 🚫rep <sigma>p = hd (filter (λ sn. repNodes_eq sn <sigma>p <sigma>low <sigma>high <sigma>rep) prx) ∧
(∀pt. pt ≠ <sigma>p ⟶ pt→<sigma>rep = pt→🚫rep)) ∧
((∀pt ∈ set prx. ¬ repNodes_eq pt <sigma>p <sigma>low <sigma>high <sigma>rep) ⟶ <sigma>rep = 🚫rep) ∧
(🚫nodeslist ≠ Null ⟶
(∀pt ∈ set prx. ¬ repNodes_eq pt <sigma>p <sigma>low <sigma>high <sigma>rep)) ∧
(🚫p = <sigma>p ∧ 🚫high = <sigma>high ∧ 🚫low = <sigma>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) (* solving termination contraint *)
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) (* solving termination constraint *)
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 -
(* IF-THEN to postcondition *)
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
(* From invariant to postcondition *)
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
(* Invariant to invariant; ELSE part *)
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
(* Invariant to invariant: THEN part *)
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
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland