(*
Author : Norbert Schirmer
Maintainer : Norbert Schirmer , norbert . schirmer at web de
Copyright ( C ) 2006 - 2008 Norbert Schirmer
*)
section "Example: Quicksort on Heap Lists"
theory Quicksort
imports "../Vcg" "../HeapList" "HOL-Library.Multiset"
begin
record globals_heap =
next_' :: "ref ==> ref"
cont_' :: "ref ==> nat"
record 'g vars = "'g state" +
p_' :: "ref"
q_' :: "ref"
le_' :: "ref"
gt_' :: "ref"
hd_' :: "ref"
tl_' :: "ref"
procedures
append(p,q|p) =
"IF π p=Null THEN π p :== π q ELSE π p→ π next :== CALL append(π p→ π next,π q) FI"
append_spec:
"β σ Ps Qs.
Γβ¨ { σ. List π p π next Ps β§ List π q π next Qs β§ set Ps β© set Qs = {}}
π p :== PROC append(π p,π q)
{ List π p π next (Ps@Qs) β§ (β x. xβ set Ps βΆ π next x = <sigma> next x)} "
append_modifies:
"β σ. Γβ¨ {σ} π p :== PROC append(π p,π q){t. t may_only_modify_globals σ in [next]}"
lemma (in append_impl) append_modifies:
shows
"β σ. Γβ¨ {σ} π p :== PROC append(π p,π q){t. t may_only_modify_globals σ in [next]}"
apply (hoare_rule HoarePartial.ProcRec1)
apply (vcg spec=modifies)
done
lemma (in append_impl) append_spec:
shows "β σ Ps Qs. Γβ¨
{ σ. List π p π next Ps β§ List π q π next Qs β§ set Ps β© set Qs = {}}
π p :== PROC append(π p,π q)
{ List π p π next (Ps@Qs) β§ (β x. xβ set Ps βΆ π next x = <sigma> next x)} "
apply (hoare_rule HoarePartial.ProcRec1)
apply vcg
apply fastforce
done
primrec sorted:: "('a ==> 'a ==> bool) ==> 'a list ==> bool"
where
"sorted le [] = True" |
"sorted le (x#xs) = ((β yβ set xs. le x y) β§ sorted le xs)"
lemma sorted_append[simp]:
"sorted le (xs@ys) = (sorted le xs β§ sorted le ys β§
(β x β set xs. β y β set ys. le x y))"
by (induct xs, auto)
procedures quickSort(p|p) =
"IF π p=Null THEN SKIP
ELSE π tl :== π p→ π next;;
π le :== Null;;
π gt :== Null;;
WHILE π tlβ Null DO
π hd :== π tl;;
π tl :== π tl→ π next;;
IF π hd→ π cont β€ π p→ π cont
THEN π hd→ π next :== π le;;
π le :== π hd
ELSE π hd→ π next :== π gt;;
π gt :== π hd
FI
OD;;
π le :== CALL quickSort(π le);;
π gt :== CALL quickSort(π gt);;
π p→ π next :== π gt;;
π le :== CALL append(π le,π p);;
π p :== π le
FI"
quickSort_spec:
"β σ Ps. Γβ¨ { σ. List π p π next Ps} π p :== PROC quickSort(π p)
{ (β sortedPs. List π p π next sortedPs β§
sorted (β€ ) (map <sigma> cont sortedPs) β§
mset Ps = mset sortedPs) β§
(β x. xβ set Ps βΆ π next x = <sigma> next x)} "
quickSort_modifies:
"β σ. Γβ¨ {σ} π p :== PROC quickSort(π p) {t. t may_only_modify_globals σ in [next]}"
lemma (in quickSort_impl) quickSort_modifies:
shows
"β σ. Γβ¨ {σ} π p :== PROC quickSort(π p) {t. t may_only_modify_globals σ in [next]}"
apply (hoare_rule HoarePartial.ProcRec1)
apply (vcg spec=modifies)
done
lemma (in quickSort_impl) quickSort_spec:
shows
"β σ Ps. Γβ¨ { σ. List π p π next Ps}
π p :== PROC quickSort(π p)
{ (β sortedPs. List π p π next sortedPs β§
sorted (β€ ) (map <sigma> cont sortedPs) β§
mset Ps = mset sortedPs) β§
(β x. xβ set Ps βΆ π next x = <sigma> next x)} "
apply (hoare_rule HoarePartial.ProcRec1)
apply (hoare_rule anno =
"IF π p=Null THEN SKIP
ELSE π tl :== π p→ π next;;
π le :== Null;;
π gt :== Null;;
WHILE π tlβ Null
INV { (β les grs tls. List π le π next les β§ List π gt π next grs β§
List π tl π next tls β§
mset Ps = mset (π p#tls@les@grs) β§
distinct(π p#tls@les@grs) β§
(β xβ set les. x→ π cont β€ π p→ π cont) β§
(β xβ set grs. π p→ π cont < x→ π cont)) β§
π p=<sigma> p β§
π cont=<sigma> cont β§
List <sigma> p <sigma> next Ps β§
(β x. xβ set Ps βΆ π next x = <sigma> next x)}
DO
π hd :== π tl;;
π tl :== π tl→ π next;;
IF π hd→ π cont β€ π p→ π cont
THEN π hd→ π next :== π le;;
π le :== π hd
ELSE π hd→ π next :== π gt;;
π gt :== π hd
FI
OD;;
π le :== CALL quickSort(π le);;
π gt :== CALL quickSort(π gt);;
π p→ π next :== π gt;;
π le :== CALL append(π le,π p);;
π p :== π le
FI" in HoarePartial.annotateI)
apply vcg
apply fastforce
apply clarsimp
apply (rule conjI)
apply clarify
apply (rule conjI)
apply (rule_tac x="tl#les" in exI)
apply simp
apply (rule_tac x="grs" in exI)
apply simp
apply (rule_tac x="ps" in exI)
apply simp
apply (metis insertCI set_mset_add_mset_insert set_mset_mset)
apply clarify
apply (rule conjI)
apply (rule_tac x="les" in exI)
apply simp
apply (rule_tac x="tl#grs" in exI)
apply simp
apply (rule_tac x="ps" in exI)
apply simp
apply (metis insertCI set_mset_add_mset_insert set_mset_mset)
apply clarsimp
apply (rule_tac ?x=grs in exI)
apply (rule conjI)
apply (erule heap_eq_ListI1)
apply clarify
apply (erule_tac x=x in allE) back
apply blast
apply clarsimp
apply (rule_tac x="sortedPs" in exI)
apply (rule conjI)
apply (erule heap_eq_ListI1)
apply (clarsimp)
apply (erule_tac x=x in allE) back back
apply (metis IntI empty_iff set_mset_mset)
apply (rule_tac x="p#sortedPsa" in exI)
apply (rule conjI)
apply (metis List_cons List_updateI Null_notin_List fun_upd_same insert_iff set_mset_add_mset_insert set_mset_mset)
apply (rule conjI)
apply (metis disjoint_iff mset_eq_setD set_ConsD)
apply clarsimp
apply (rule conjI)
apply (metis less_or_eq_imp_le mset_eq_setD)
apply (rule conjI)
apply (metis leD less_le_trans mset_eq_setD nat_le_linear)
apply clarsimp
apply (erule_tac x=x in allE)+
apply (metis Un_iff insert_iff list.set(2 ) mset.simps(2 ) mset_append set_append set_mset_mset)
done
end
Messung V0.5 in Prozent C=100 H=-187 G=149
Β€ Dauer der Verarbeitung: 0.8 Sekunden
Β€
*© Formatika GbR, Deutschland