4 Copyright 1994 TU Muenchen |
4 Copyright 1994 TU Muenchen |
5 |
5 |
6 Two verifications of Quicksort |
6 Two verifications of Quicksort |
7 *) |
7 *) |
8 |
8 |
|
9 |
|
10 Addsimps [Ball_insert,Ball_Un]; |
|
11 |
|
12 (* Towards a proof of qsort_ind |
|
13 |
|
14 A short proof of Konrad's wf_minimal in WF1.ML: |
|
15 |
|
16 val [p1] = goalw WF.thy [wf_def] |
|
17 "wf(R) ==> (!Q. (? x. Q x) --> (? min. Q min & (!b. (b,min):R --> (~ Q b))))"; |
|
18 by (rtac allI 1); |
|
19 by(cut_inst_tac[("x","%u.~Q u")](p1 RS spec) 1); |
|
20 by (fast_tac HOL_cs 1); |
|
21 val wf_minimal = result(); |
|
22 |
|
23 *) |
|
24 |
|
25 |
9 Addsimps ([Qsort.qsort_Nil,Qsort.qsort_Cons]@conj_comms); |
26 Addsimps ([Qsort.qsort_Nil,Qsort.qsort_Cons]@conj_comms); |
10 |
27 |
11 goal Qsort.thy "!x. mset (qsort le xs) x = mset xs x"; |
28 goal Qsort.thy "!x. mset (qsort le xs) x = mset xs x"; |
12 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
29 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
13 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
30 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
14 result(); |
31 qed "qsort_permutes"; |
15 |
32 |
16 |
33 goal Sorting.thy "set_of_list xs = {x.mset xs x ~= 0}"; |
17 goal Qsort.thy "(Alls x:[x:xs.P(x)].Q(x)) = (Alls x:xs. P(x)-->Q(x))"; |
|
18 by (list.induct_tac "xs" 1); |
34 by (list.induct_tac "xs" 1); |
19 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
35 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
20 Addsimps [result()]; |
36 by (Fast_tac 1); |
|
37 qed "set_of_list_via_mset"; |
21 |
38 |
22 goal Qsort.thy |
39 goal Qsort.thy "set_of_list(qsort le xs) = set_of_list xs"; |
23 "((Alls x:xs.P(x)) & (Alls x:xs.Q(x))) = (Alls x:xs. P(x)&Q(x))"; |
40 by(simp_tac (!simpset addsimps [set_of_list_via_mset,qsort_permutes]) 1); |
|
41 qed "set_of_list_qsort"; |
|
42 Addsimps [set_of_list_qsort]; |
|
43 |
|
44 goal List.thy |
|
45 "(!x:set_of_list[x:xs.P(x)].Q(x)) = (!x:set_of_list xs. P(x)-->Q(x))"; |
24 by (list.induct_tac "xs" 1); |
46 by (list.induct_tac "xs" 1); |
25 by (ALLGOALS Asm_simp_tac); |
47 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
26 val alls_lemma=result(); |
48 qed"Ball_set_of_list_filter"; |
27 Addsimps [alls_lemma]; |
49 Addsimps [Ball_set_of_list_filter]; |
28 |
|
29 goal HOL.thy "((P --> Q) & (~P --> Q)) = Q"; |
|
30 by (Fast_tac 1); |
|
31 val lemma = result(); |
|
32 |
|
33 goal Qsort.thy "(Alls x:qsort le xs.P(x)) = (Alls x:xs.P(x))"; |
|
34 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
|
35 by (Asm_simp_tac 1); |
|
36 by (asm_simp_tac (!simpset delsimps [alls_lemma, list_all_Cons])1); |
|
37 by (asm_simp_tac (!simpset addsimps [lemma]) 1); |
|
38 Addsimps [result()]; |
|
39 |
50 |
40 goal Qsort.thy |
51 goal Qsort.thy |
41 "sorted le (xs@ys) = (sorted le xs & sorted le ys & \ |
52 "sorted le (xs@ys) = (sorted le xs & sorted le ys & \ |
42 \ (Alls x:xs. Alls y:ys. le x y))"; |
53 \ (!x:set_of_list xs. !y:set_of_list ys. le x y))"; |
43 by (list.induct_tac "xs" 1); |
54 by (list.induct_tac "xs" 1); |
44 by (Asm_simp_tac 1); |
55 by (ALLGOALS Asm_simp_tac); |
45 by (asm_simp_tac (!simpset delsimps [alls_lemma]) 1); |
56 qed "sorted_append"; |
46 Addsimps [result()]; |
57 Addsimps [sorted_append]; |
47 |
|
48 |
|
49 |
|
50 |
58 |
51 goal Qsort.thy |
59 goal Qsort.thy |
52 "!!le. [| total(le); transf(le) |] ==> sorted le (qsort le xs)"; |
60 "!!le. [| total(le); transf(le) |] ==> sorted le (qsort le xs)"; |
53 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
61 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
54 by (Asm_simp_tac 1); |
62 by (ALLGOALS Asm_simp_tac); |
55 by (asm_full_simp_tac (!simpset addsimps []) 1); |
|
56 by (asm_full_simp_tac (!simpset addsimps [list_all_mem_conv]) 1); |
|
57 by (rewrite_goals_tac [Sorting.total_def,Sorting.transf_def]); |
63 by (rewrite_goals_tac [Sorting.total_def,Sorting.transf_def]); |
58 by (Fast_tac 1); |
64 by (Fast_tac 1); |
59 result(); |
65 qed "sorted_qsort"; |
60 |
|
61 (* A verification based on predicate calculus rather than combinators *) |
|
62 |
|
63 val sorted_Cons = |
|
64 rewrite_rule [list_all_mem_conv RS eq_reflection] Sorting.sorted_Cons; |
|
65 |
|
66 Addsimps [sorted_Cons]; |
|
67 |
|
68 |
|
69 goal Qsort.thy "x mem qsort le xs = x mem xs"; |
|
70 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
|
71 by (ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
|
72 by (Fast_tac 1); |
|
73 Addsimps [result()]; |
|
74 |
|
75 goal Qsort.thy |
|
76 "sorted le (xs@ys) = (sorted le xs & sorted le ys & \ |
|
77 \ (!x. x mem xs --> (!y. y mem ys --> le x y)))"; |
|
78 by (list.induct_tac "xs" 1); |
|
79 by (Asm_simp_tac 1); |
|
80 by (asm_simp_tac (!simpset setloop (split_tac [expand_if]) |
|
81 delsimps [list_all_conj] |
|
82 addsimps [list_all_mem_conv]) 1); |
|
83 by (Fast_tac 1); |
|
84 Addsimps [result()]; |
|
85 |
|
86 goal Qsort.thy |
|
87 "!!xs. [| total(le); transf(le) |] ==> sorted le (qsort le xs)"; |
|
88 by (res_inst_tac[("xs","xs"),("p","le")]Qsort.qsort_ind 1); |
|
89 by (Simp_tac 1); |
|
90 by (asm_simp_tac (!simpset setloop (split_tac [expand_if]) |
|
91 delsimps [list_all_conj] |
|
92 addsimps [list_all_mem_conv]) 1); |
|
93 by (rewrite_goals_tac [Sorting.total_def,Sorting.transf_def]); |
|
94 by (Fast_tac 1); |
|
95 result(); |
|
96 |
|
97 |
|