(*
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=-474 G=342
Β€ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-07-06)
Β€
*© Formatika GbR, Deutschland