| author | wenzelm | 
| Fri, 23 Aug 2013 20:53:00 +0200 | |
| changeset 53172 | 31e24d6ff1ea | 
| parent 51717 | 9e7d1c139569 | 
| child 55414 | eab03e9cee8a | 
| permissions | -rw-r--r-- | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
1  | 
(* Title: HOL/Hoare/hoare_tac.ML  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
2  | 
Author: Leonor Prensa Nieto & Tobias Nipkow  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
4  | 
Derivation of the proof rules and, most importantly, the VCG tactic.  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 41449 | 7  | 
(* FIXME structure Hoare: HOARE *)  | 
8  | 
||
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
9  | 
(*** The tactics ***)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
10  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
11  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
12  | 
(** The function Mset makes the theorem **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
13  | 
(** "?Mset <= {(x1,...,xn). ?P (x1,...,xn)} ==> ?Mset <= {s. ?P s}",        **)
 | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
14  | 
(** where (x1,...,xn) are the variables of the particular program we are **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
15  | 
(** working on at the moment of the call **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
16  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
17  | 
|
| 41449 | 18  | 
local  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
19  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
20  | 
(** maps (%x1 ... xn. t) to [x1,...,xn] **)  | 
| 37591 | 21  | 
fun abs2list (Const (@{const_name prod_case}, _) $ Abs (x, T, t)) = Free (x, T) :: abs2list t
 | 
| 37135 | 22  | 
| abs2list (Abs (x, T, t)) = [Free (x, T)]  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
23  | 
| abs2list _ = [];  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
25  | 
(** maps {(x1,...,xn). t} to [x1,...,xn] **)
 | 
| 37677 | 26  | 
fun mk_vars (Const (@{const_name Collect},_) $ T) = abs2list T
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
27  | 
| mk_vars _ = [];  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
28  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
29  | 
(** abstraction of body over a tuple formed from a list of free variables.  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
30  | 
Types are also built **)  | 
| 44241 | 31  | 
fun mk_abstupleC [] body = absfree ("x", HOLogic.unitT) body
 | 
32  | 
| mk_abstupleC [v] body = absfree (dest_Free v) body  | 
|
33  | 
| mk_abstupleC (v :: w) body =  | 
|
34  | 
let  | 
|
35  | 
val (x, T) = dest_Free v;  | 
|
36  | 
val z = mk_abstupleC w body;  | 
|
37  | 
val T2 =  | 
|
38  | 
(case z of  | 
|
39  | 
Abs (_, T, _) => T  | 
|
40  | 
| Const (_, Type (_, [_, Type (_, [T, _])])) $ _ => T);  | 
|
41  | 
in  | 
|
| 41449 | 42  | 
        Const (@{const_name prod_case},
 | 
| 44241 | 43  | 
(T --> T2 --> HOLogic.boolT) --> HOLogic.mk_prodT (T, T2) --> HOLogic.boolT) $  | 
44  | 
absfree (x, T) z  | 
|
45  | 
end;  | 
|
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
46  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
47  | 
(** maps [x1,...,xn] to (x1,...,xn) and types**)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
48  | 
fun mk_bodyC [] = HOLogic.unit  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
49  | 
| mk_bodyC (x::xs) = if xs=[] then x  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
50  | 
else let val (n, T) = dest_Free x ;  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
51  | 
val z = mk_bodyC xs;  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
52  | 
val T2 = case z of Free(_, T) => T  | 
| 37391 | 53  | 
                                         | Const (@{const_name Pair}, Type ("fun", [_, Type
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
54  | 
                                            ("fun", [_, T])])) $ _ $ _ => T;
 | 
| 41449 | 55  | 
                 in Const (@{const_name Pair}, [T, T2] ---> HOLogic.mk_prodT (T, T2)) $ x $ z end;
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
56  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
57  | 
(** maps a subgoal of the form:  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
58  | 
        VARS x1 ... xn {._.} _ {._.} or to [x1,...,xn]**)
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
59  | 
fun get_vars c =  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
60  | 
let  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
61  | 
val d = Logic.strip_assums_concl c;  | 
| 41449 | 62  | 
val Const _ $ pre $ _ $ _ = HOLogic.dest_Trueprop d;  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
63  | 
in mk_vars pre end;  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
64  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
65  | 
fun mk_CollectC trm =  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
66  | 
  let val T as Type ("fun",[t,_]) = fastype_of trm
 | 
| 41449 | 67  | 
in HOLogic.Collect_const t $ trm end;  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
68  | 
|
| 41449 | 69  | 
fun inclt ty = Const (@{const_name Orderings.less_eq}, [ty,ty] ---> HOLogic.boolT);
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
70  | 
|
| 41449 | 71  | 
in  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
72  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
73  | 
fun Mset ctxt prop =  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
74  | 
let  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
75  | 
    val [(Mset, _), (P, _)] = Variable.variant_frees ctxt [] [("Mset", ()), ("P", ())];
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
76  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
77  | 
val vars = get_vars prop;  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
78  | 
val varsT = fastype_of (mk_bodyC vars);  | 
| 41449 | 79  | 
val big_Collect = mk_CollectC (mk_abstupleC vars (Free (P, varsT --> HOLogic.boolT) $ mk_bodyC vars));  | 
80  | 
    val small_Collect = mk_CollectC (Abs ("x", varsT, Free (P, varsT --> HOLogic.boolT) $ Bound 0));
 | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
81  | 
|
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
82  | 
val MsetT = fastype_of big_Collect;  | 
| 41449 | 83  | 
fun Mset_incl t = HOLogic.mk_Trueprop (inclt MsetT $ Free (Mset, MsetT) $ t);  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
84  | 
val impl = Logic.mk_implies (Mset_incl big_Collect, Mset_incl small_Collect);  | 
| 42793 | 85  | 
val th = Goal.prove ctxt [Mset, P] [] impl (fn _ => blast_tac ctxt 1);  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
86  | 
in (vars, th) end;  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
87  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
88  | 
end;  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
89  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
90  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
91  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
92  | 
(** Simplifying: **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
93  | 
(** Some useful lemmata, lists and simplification tactics to control which **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
94  | 
(** theorems are used to simplify at each moment, so that the original **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
95  | 
(** input does not suffer any unexpected transformation **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
96  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
97  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
98  | 
(**Simp_tacs**)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
99  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
100  | 
fun before_set2pred_simp_tac ctxt =  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
101  | 
  simp_tac (put_simpset HOL_basic_ss ctxt addsimps [Collect_conj_eq RS sym, @{thm Compl_Collect}]);
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
102  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
103  | 
fun split_simp_tac ctxt =  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
104  | 
  simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm split_conv}]);
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
105  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
106  | 
(*****************************************************************************)  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
107  | 
(** set2pred_tac transforms sets inclusion into predicates implication, **)  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
108  | 
(** maintaining the original variable names. **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
109  | 
(** Ex. "{x. x=0} <= {x. x <= 1}" -set2pred-> "x=0 --> x <= 1"              **)
 | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
110  | 
(** Subgoals containing intersections (A Int B) or complement sets (-A) **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
111  | 
(** are first simplified by "before_set2pred_simp_tac", that returns only **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
112  | 
(** subgoals of the form "{x. P x} <= {x. Q x}", which are easily           **)
 | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
113  | 
(** transformed. **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
114  | 
(** This transformation may solve very easy subgoals due to a ligth **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
115  | 
(** simplification done by (split_all_tac) **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
116  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
117  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
118  | 
fun set2pred_tac ctxt var_names = SUBGOAL (fn (goal, i) =>  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
119  | 
before_set2pred_simp_tac ctxt i THEN_MAYBE  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
120  | 
EVERY [  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
121  | 
rtac subsetI i,  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
122  | 
rtac CollectI i,  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
123  | 
dtac CollectD i,  | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
124  | 
TRY (split_all_tac ctxt i) THEN_MAYBE  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
125  | 
(rename_tac var_names i THEN  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
126  | 
      full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm split_conv}]) i)]);
 | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
127  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
128  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
129  | 
(** BasicSimpTac is called to simplify all verification conditions. It does **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
130  | 
(** a light simplification by applying "mem_Collect_eq", then it calls **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
131  | 
(** MaxSimpTac, which solves subgoals of the form "A <= A", **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
132  | 
(** and transforms any other into predicates, applying then **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
133  | 
(** the tactic chosen by the user, which may solve the subgoal completely. **)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
134  | 
(*****************************************************************************)  | 
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
135  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
136  | 
fun MaxSimpTac ctxt var_names tac =  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
137  | 
FIRST'[rtac subset_refl, set2pred_tac ctxt var_names THEN_MAYBE' tac];  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
138  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
139  | 
fun BasicSimpTac ctxt var_names tac =  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
140  | 
simp_tac  | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
141  | 
(put_simpset HOL_basic_ss ctxt  | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
142  | 
      addsimps [mem_Collect_eq, @{thm split_conv}] addsimprocs [Record.simproc])
 | 
| 
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
143  | 
THEN_MAYBE' MaxSimpTac ctxt var_names tac;  | 
| 
24475
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
144  | 
|
| 
 
a297ae4ff188
added Hoare/hoare_tac.ML (code from Hoare/Hoare.thy, also required in Isar_examples/Hoare.thy);
 
wenzelm 
parents:  
diff
changeset
 | 
145  | 
|
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
146  | 
(** hoare_rule_tac **)  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
147  | 
|
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
148  | 
fun hoare_rule_tac ctxt (vars, Mlem) tac =  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
149  | 
let  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
150  | 
val var_names = map (fst o dest_Free) vars;  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
151  | 
fun wlp_tac i =  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
152  | 
      rtac @{thm SeqRule} i THEN rule_tac false (i + 1)
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
153  | 
and rule_tac pre_cond i st = st |> (*abstraction over st prevents looping*)  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
154  | 
((wlp_tac i THEN rule_tac pre_cond i)  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
155  | 
ORELSE  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
156  | 
(FIRST [  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
157  | 
          rtac @{thm SkipRule} i,
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
158  | 
          rtac @{thm AbortRule} i,
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
159  | 
EVERY [  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
160  | 
            rtac @{thm BasicRule} i,
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
161  | 
rtac Mlem i,  | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
162  | 
split_simp_tac ctxt i],  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
163  | 
EVERY [  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
164  | 
            rtac @{thm CondRule} i,
 | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
165  | 
rule_tac false (i + 2),  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
166  | 
rule_tac false (i + 1)],  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
167  | 
EVERY [  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
168  | 
            rtac @{thm WhileRule} i,
 | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
169  | 
BasicSimpTac ctxt var_names tac (i + 2),  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
170  | 
rule_tac true (i + 1)]]  | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
171  | 
THEN (if pre_cond then BasicSimpTac ctxt var_names tac i else rtac subset_refl i)));  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
172  | 
in rule_tac end;  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
173  | 
|
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
174  | 
|
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
175  | 
(** tac is the tactic the user chooses to solve or simplify **)  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
176  | 
(** the final verification conditions **)  | 
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
177  | 
|
| 
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
178  | 
fun hoare_tac ctxt (tac: int -> tactic) = SUBGOAL (fn (goal, i) =>  | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
44241 
diff
changeset
 | 
179  | 
SELECT_GOAL (hoare_rule_tac ctxt (Mset ctxt goal) tac true 1) i);  | 
| 
28457
 
25669513fd4c
major cleanup of hoare_tac.ML: just one copy for Hoare.thy and HoareAbort.thy (only 1 line different), refrain from inspecting the main goal, proper context;
 
wenzelm 
parents: 
27330 
diff
changeset
 | 
180  |