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