| author | wenzelm | 
| Wed, 03 Oct 2007 00:02:56 +0200 | |
| changeset 24819 | 7d8e0a47392e | 
| parent 21710 | 4e4b7c801142 | 
| child 32689 | 860e1a2317bd | 
| permissions | -rw-r--r-- | 
| 6706 | 1  | 
(* Title: HOL/UNITY/Follows  | 
2  | 
ID: $Id$  | 
|
3  | 
Author: Lawrence C Paulson, Cambridge University Computer Laboratory  | 
|
4  | 
Copyright 1998 University of Cambridge  | 
|
| 13798 | 5  | 
*)  | 
| 6706 | 6  | 
|
| 13798 | 7  | 
header{*The Follows Relation of Charpentier and Sivilotte*}
 | 
| 6706 | 8  | 
|
| 16417 | 9  | 
theory Follows imports SubstAx ListOrder Multiset begin  | 
| 6706 | 10  | 
|
11  | 
constdefs  | 
|
12  | 
||
13  | 
  Follows :: "['a => 'b::{order}, 'a => 'b::{order}] => 'a program set"
 | 
|
| 6809 | 14  | 
(infixl "Fols" 65)  | 
| 13805 | 15  | 
"f Fols g == Increasing g \<inter> Increasing f Int  | 
16  | 
                Always {s. f s \<le> g s} Int
 | 
|
17  | 
                (\<Inter>k. {s. k \<le> g s} LeadsTo {s. k \<le> f s})"
 | 
|
| 6706 | 18  | 
|
19  | 
||
| 13796 | 20  | 
(*Does this hold for "invariant"?*)  | 
21  | 
lemma mono_Always_o:  | 
|
| 13805 | 22  | 
     "mono h ==> Always {s. f s \<le> g s} \<subseteq> Always {s. h (f s) \<le> h (g s)}"
 | 
| 13796 | 23  | 
apply (simp add: Always_eq_includes_reachable)  | 
24  | 
apply (blast intro: monoD)  | 
|
25  | 
done  | 
|
26  | 
||
27  | 
lemma mono_LeadsTo_o:  | 
|
28  | 
"mono (h::'a::order => 'b::order)  | 
|
| 13805 | 29  | 
      ==> (\<Inter>j. {s. j \<le> g s} LeadsTo {s. j \<le> f s}) \<subseteq>  
 | 
30  | 
          (\<Inter>k. {s. k \<le> h (g s)} LeadsTo {s. k \<le> h (f s)})"
 | 
|
| 13796 | 31  | 
apply auto  | 
32  | 
apply (rule single_LeadsTo_I)  | 
|
33  | 
apply (drule_tac x = "g s" in spec)  | 
|
34  | 
apply (erule LeadsTo_weaken)  | 
|
35  | 
apply (blast intro: monoD order_trans)+  | 
|
36  | 
done  | 
|
37  | 
||
| 13805 | 38  | 
lemma Follows_constant [iff]: "F \<in> (%s. c) Fols (%s. c)"  | 
| 15102 | 39  | 
by (simp add: Follows_def)  | 
| 13796 | 40  | 
|
| 13805 | 41  | 
lemma mono_Follows_o: "mono h ==> f Fols g \<subseteq> (h o f) Fols (h o g)"  | 
| 15102 | 42  | 
by (auto simp add: Follows_def mono_Increasing_o [THEN [2] rev_subsetD]  | 
43  | 
mono_Always_o [THEN [2] rev_subsetD]  | 
|
44  | 
mono_LeadsTo_o [THEN [2] rev_subsetD, THEN INT_D])  | 
|
| 13796 | 45  | 
|
46  | 
lemma mono_Follows_apply:  | 
|
| 13805 | 47  | 
"mono h ==> f Fols g \<subseteq> (%x. h (f x)) Fols (%x. h (g x))"  | 
| 13796 | 48  | 
apply (drule mono_Follows_o)  | 
49  | 
apply (force simp add: o_def)  | 
|
50  | 
done  | 
|
51  | 
||
52  | 
lemma Follows_trans:  | 
|
| 13805 | 53  | 
"[| F \<in> f Fols g; F \<in> g Fols h |] ==> F \<in> f Fols h"  | 
| 15102 | 54  | 
apply (simp add: Follows_def)  | 
| 13796 | 55  | 
apply (simp add: Always_eq_includes_reachable)  | 
56  | 
apply (blast intro: order_trans LeadsTo_Trans)  | 
|
57  | 
done  | 
|
58  | 
||
59  | 
||
| 13798 | 60  | 
subsection{*Destruction rules*}
 | 
| 13796 | 61  | 
|
| 13805 | 62  | 
lemma Follows_Increasing1: "F \<in> f Fols g ==> F \<in> Increasing f"  | 
| 15102 | 63  | 
by (simp add: Follows_def)  | 
| 13796 | 64  | 
|
| 13805 | 65  | 
lemma Follows_Increasing2: "F \<in> f Fols g ==> F \<in> Increasing g"  | 
| 15102 | 66  | 
by (simp add: Follows_def)  | 
| 13796 | 67  | 
|
| 21710 | 68  | 
lemma Follows_Bounded: "F \<in> f Fols g ==> F \<in> Always {s. f s \<le> g s}"
 | 
| 15102 | 69  | 
by (simp add: Follows_def)  | 
| 13796 | 70  | 
|
71  | 
lemma Follows_LeadsTo:  | 
|
| 13805 | 72  | 
     "F \<in> f Fols g ==> F \<in> {s. k \<le> g s} LeadsTo {s. k \<le> f s}"
 | 
| 15102 | 73  | 
by (simp add: Follows_def)  | 
| 13796 | 74  | 
|
75  | 
lemma Follows_LeadsTo_pfixLe:  | 
|
| 13805 | 76  | 
     "F \<in> f Fols g ==> F \<in> {s. k pfixLe g s} LeadsTo {s. k pfixLe f s}"
 | 
| 13796 | 77  | 
apply (rule single_LeadsTo_I, clarify)  | 
78  | 
apply (drule_tac k="g s" in Follows_LeadsTo)  | 
|
79  | 
apply (erule LeadsTo_weaken)  | 
|
80  | 
apply blast  | 
|
81  | 
apply (blast intro: pfixLe_trans prefix_imp_pfixLe)  | 
|
82  | 
done  | 
|
83  | 
||
84  | 
lemma Follows_LeadsTo_pfixGe:  | 
|
| 13805 | 85  | 
     "F \<in> f Fols g ==> F \<in> {s. k pfixGe g s} LeadsTo {s. k pfixGe f s}"
 | 
| 13796 | 86  | 
apply (rule single_LeadsTo_I, clarify)  | 
87  | 
apply (drule_tac k="g s" in Follows_LeadsTo)  | 
|
88  | 
apply (erule LeadsTo_weaken)  | 
|
89  | 
apply blast  | 
|
90  | 
apply (blast intro: pfixGe_trans prefix_imp_pfixGe)  | 
|
91  | 
done  | 
|
92  | 
||
93  | 
||
94  | 
lemma Always_Follows1:  | 
|
| 13805 | 95  | 
     "[| F \<in> Always {s. f s = f' s}; F \<in> f Fols g |] ==> F \<in> f' Fols g"
 | 
| 13796 | 96  | 
|
| 15102 | 97  | 
apply (simp add: Follows_def Increasing_def Stable_def, auto)  | 
| 13796 | 98  | 
apply (erule_tac [3] Always_LeadsTo_weaken)  | 
| 13805 | 99  | 
apply (erule_tac A = "{s. z \<le> f s}" and A' = "{s. z \<le> f s}" 
 | 
| 13798 | 100  | 
in Always_Constrains_weaken, auto)  | 
| 13796 | 101  | 
apply (drule Always_Int_I, assumption)  | 
102  | 
apply (force intro: Always_weaken)  | 
|
103  | 
done  | 
|
104  | 
||
105  | 
lemma Always_Follows2:  | 
|
| 13805 | 106  | 
     "[| F \<in> Always {s. g s = g' s}; F \<in> f Fols g |] ==> F \<in> f Fols g'"
 | 
| 15102 | 107  | 
apply (simp add: Follows_def Increasing_def Stable_def, auto)  | 
| 13796 | 108  | 
apply (erule_tac [3] Always_LeadsTo_weaken)  | 
| 13805 | 109  | 
apply (erule_tac A = "{s. z \<le> g s}" and A' = "{s. z \<le> g s}"
 | 
| 13798 | 110  | 
in Always_Constrains_weaken, auto)  | 
| 13796 | 111  | 
apply (drule Always_Int_I, assumption)  | 
112  | 
apply (force intro: Always_weaken)  | 
|
113  | 
done  | 
|
114  | 
||
115  | 
||
| 13798 | 116  | 
subsection{*Union properties (with the subset ordering)*}
 | 
| 13796 | 117  | 
|
118  | 
(*Can replace "Un" by any sup. But existing max only works for linorders.*)  | 
|
119  | 
lemma increasing_Un:  | 
|
| 13805 | 120  | 
"[| F \<in> increasing f; F \<in> increasing g |]  | 
121  | 
==> F \<in> increasing (%s. (f s) \<union> (g s))"  | 
|
| 15102 | 122  | 
apply (simp add: increasing_def stable_def constrains_def, auto)  | 
| 13796 | 123  | 
apply (drule_tac x = "f xa" in spec)  | 
124  | 
apply (drule_tac x = "g xa" in spec)  | 
|
125  | 
apply (blast dest!: bspec)  | 
|
126  | 
done  | 
|
127  | 
||
128  | 
lemma Increasing_Un:  | 
|
| 13805 | 129  | 
"[| F \<in> Increasing f; F \<in> Increasing g |]  | 
130  | 
==> F \<in> Increasing (%s. (f s) \<union> (g s))"  | 
|
| 13798 | 131  | 
apply (auto simp add: Increasing_def Stable_def Constrains_def  | 
132  | 
stable_def constrains_def)  | 
|
| 13796 | 133  | 
apply (drule_tac x = "f xa" in spec)  | 
134  | 
apply (drule_tac x = "g xa" in spec)  | 
|
135  | 
apply (blast dest!: bspec)  | 
|
136  | 
done  | 
|
137  | 
||
138  | 
||
139  | 
lemma Always_Un:  | 
|
| 13805 | 140  | 
     "[| F \<in> Always {s. f' s \<le> f s}; F \<in> Always {s. g' s \<le> g s} |]  
 | 
141  | 
      ==> F \<in> Always {s. f' s \<union> g' s \<le> f s \<union> g s}"
 | 
|
| 13798 | 142  | 
by (simp add: Always_eq_includes_reachable, blast)  | 
| 13796 | 143  | 
|
144  | 
(*Lemma to re-use the argument that one variable increases (progress)  | 
|
145  | 
while the other variable doesn't decrease (safety)*)  | 
|
146  | 
lemma Follows_Un_lemma:  | 
|
| 13805 | 147  | 
"[| F \<in> Increasing f; F \<in> Increasing g;  | 
148  | 
         F \<in> Increasing g'; F \<in> Always {s. f' s \<le> f s}; 
 | 
|
149  | 
         \<forall>k. F \<in> {s. k \<le> f s} LeadsTo {s. k \<le> f' s} |] 
 | 
|
150  | 
      ==> F \<in> {s. k \<le> f s \<union> g s} LeadsTo {s. k \<le> f' s \<union> g s}"
 | 
|
| 13796 | 151  | 
apply (rule single_LeadsTo_I)  | 
152  | 
apply (drule_tac x = "f s" in IncreasingD)  | 
|
153  | 
apply (drule_tac x = "g s" in IncreasingD)  | 
|
154  | 
apply (rule LeadsTo_weaken)  | 
|
155  | 
apply (rule PSP_Stable)  | 
|
156  | 
apply (erule_tac x = "f s" in spec)  | 
|
| 
13812
 
91713a1915ee
converting HOL/UNITY to use unconditional fairness
 
paulson 
parents: 
13805 
diff
changeset
 | 
157  | 
apply (erule Stable_Int, assumption, blast+)  | 
| 13796 | 158  | 
done  | 
159  | 
||
160  | 
lemma Follows_Un:  | 
|
| 13805 | 161  | 
"[| F \<in> f' Fols f; F \<in> g' Fols g |]  | 
162  | 
==> F \<in> (%s. (f' s) \<union> (g' s)) Fols (%s. (f s) \<union> (g s))"  | 
|
| 15102 | 163  | 
apply (simp add: Follows_def Increasing_Un Always_Un del: Un_subset_iff, auto)  | 
| 13796 | 164  | 
apply (rule LeadsTo_Trans)  | 
165  | 
apply (blast intro: Follows_Un_lemma)  | 
|
166  | 
(*Weakening is used to exchange Un's arguments*)  | 
|
167  | 
apply (blast intro: Follows_Un_lemma [THEN LeadsTo_weaken])  | 
|
168  | 
done  | 
|
169  | 
||
170  | 
||
| 13798 | 171  | 
subsection{*Multiset union properties (with the multiset ordering)*}
 | 
| 13796 | 172  | 
|
173  | 
lemma increasing_union:  | 
|
| 13805 | 174  | 
"[| F \<in> increasing f; F \<in> increasing g |]  | 
175  | 
     ==> F \<in> increasing (%s. (f s) + (g s :: ('a::order) multiset))"
 | 
|
| 15102 | 176  | 
apply (simp add: increasing_def stable_def constrains_def, auto)  | 
| 13796 | 177  | 
apply (drule_tac x = "f xa" in spec)  | 
178  | 
apply (drule_tac x = "g xa" in spec)  | 
|
179  | 
apply (drule bspec, assumption)  | 
|
180  | 
apply (blast intro: union_le_mono order_trans)  | 
|
181  | 
done  | 
|
182  | 
||
183  | 
lemma Increasing_union:  | 
|
| 13805 | 184  | 
"[| F \<in> Increasing f; F \<in> Increasing g |]  | 
185  | 
     ==> F \<in> Increasing (%s. (f s) + (g s :: ('a::order) multiset))"
 | 
|
| 13798 | 186  | 
apply (auto simp add: Increasing_def Stable_def Constrains_def  | 
187  | 
stable_def constrains_def)  | 
|
| 13796 | 188  | 
apply (drule_tac x = "f xa" in spec)  | 
189  | 
apply (drule_tac x = "g xa" in spec)  | 
|
190  | 
apply (drule bspec, assumption)  | 
|
191  | 
apply (blast intro: union_le_mono order_trans)  | 
|
192  | 
done  | 
|
193  | 
||
194  | 
lemma Always_union:  | 
|
| 13805 | 195  | 
     "[| F \<in> Always {s. f' s \<le> f s}; F \<in> Always {s. g' s \<le> g s} |]  
 | 
196  | 
      ==> F \<in> Always {s. f' s + g' s \<le> f s + (g s :: ('a::order) multiset)}"
 | 
|
| 13796 | 197  | 
apply (simp add: Always_eq_includes_reachable)  | 
198  | 
apply (blast intro: union_le_mono)  | 
|
199  | 
done  | 
|
200  | 
||
201  | 
(*Except the last line, IDENTICAL to the proof script for Follows_Un_lemma*)  | 
|
202  | 
lemma Follows_union_lemma:  | 
|
| 13805 | 203  | 
"[| F \<in> Increasing f; F \<in> Increasing g;  | 
204  | 
         F \<in> Increasing g'; F \<in> Always {s. f' s \<le> f s}; 
 | 
|
205  | 
         \<forall>k::('a::order) multiset.  
 | 
|
206  | 
           F \<in> {s. k \<le> f s} LeadsTo {s. k \<le> f' s} |] 
 | 
|
207  | 
      ==> F \<in> {s. k \<le> f s + g s} LeadsTo {s. k \<le> f' s + g s}"
 | 
|
| 13796 | 208  | 
apply (rule single_LeadsTo_I)  | 
209  | 
apply (drule_tac x = "f s" in IncreasingD)  | 
|
210  | 
apply (drule_tac x = "g s" in IncreasingD)  | 
|
211  | 
apply (rule LeadsTo_weaken)  | 
|
212  | 
apply (rule PSP_Stable)  | 
|
213  | 
apply (erule_tac x = "f s" in spec)  | 
|
| 
13812
 
91713a1915ee
converting HOL/UNITY to use unconditional fairness
 
paulson 
parents: 
13805 
diff
changeset
 | 
214  | 
apply (erule Stable_Int, assumption, blast)  | 
| 13796 | 215  | 
apply (blast intro: union_le_mono order_trans)  | 
216  | 
done  | 
|
217  | 
||
218  | 
(*The !! is there to influence to effect of permutative rewriting at the end*)  | 
|
219  | 
lemma Follows_union:  | 
|
220  | 
     "!!g g' ::'b => ('a::order) multiset.  
 | 
|
| 13805 | 221  | 
[| F \<in> f' Fols f; F \<in> g' Fols g |]  | 
222  | 
==> F \<in> (%s. (f' s) + (g' s)) Fols (%s. (f s) + (g s))"  | 
|
| 15102 | 223  | 
apply (simp add: Follows_def)  | 
| 13796 | 224  | 
apply (simp add: Increasing_union Always_union, auto)  | 
225  | 
apply (rule LeadsTo_Trans)  | 
|
226  | 
apply (blast intro: Follows_union_lemma)  | 
|
227  | 
(*now exchange union's arguments*)  | 
|
228  | 
apply (simp add: union_commute)  | 
|
229  | 
apply (blast intro: Follows_union_lemma)  | 
|
230  | 
done  | 
|
231  | 
||
232  | 
lemma Follows_setsum:  | 
|
233  | 
     "!!f ::['c,'b] => ('a::order) multiset.  
 | 
|
| 13805 | 234  | 
[| \<forall>i \<in> I. F \<in> f' i Fols f i; finite I |]  | 
235  | 
==> F \<in> (%s. \<Sum>i \<in> I. f' i s) Fols (%s. \<Sum>i \<in> I. f i s)"  | 
|
| 13796 | 236  | 
apply (erule rev_mp)  | 
237  | 
apply (erule finite_induct, simp)  | 
|
238  | 
apply (simp add: Follows_union)  | 
|
239  | 
done  | 
|
240  | 
||
241  | 
||
242  | 
(*Currently UNUSED, but possibly of interest*)  | 
|
243  | 
lemma Increasing_imp_Stable_pfixGe:  | 
|
| 13805 | 244  | 
     "F \<in> Increasing func ==> F \<in> Stable {s. h pfixGe (func s)}"
 | 
| 13796 | 245  | 
apply (simp add: Increasing_def Stable_def Constrains_def constrains_def)  | 
246  | 
apply (blast intro: trans_Ge [THEN trans_genPrefix, THEN transD]  | 
|
247  | 
prefix_imp_pfixGe)  | 
|
248  | 
done  | 
|
249  | 
||
250  | 
(*Currently UNUSED, but possibly of interest*)  | 
|
251  | 
lemma LeadsTo_le_imp_pfixGe:  | 
|
| 13805 | 252  | 
     "\<forall>z. F \<in> {s. z \<le> f s} LeadsTo {s. z \<le> g s}  
 | 
253  | 
      ==> F \<in> {s. z pfixGe f s} LeadsTo {s. z pfixGe g s}"
 | 
|
| 13796 | 254  | 
apply (rule single_LeadsTo_I)  | 
255  | 
apply (drule_tac x = "f s" in spec)  | 
|
256  | 
apply (erule LeadsTo_weaken)  | 
|
257  | 
prefer 2  | 
|
258  | 
apply (blast intro: trans_Ge [THEN trans_genPrefix, THEN transD]  | 
|
259  | 
prefix_imp_pfixGe, blast)  | 
|
260  | 
done  | 
|
261  | 
||
| 6706 | 262  | 
end  |