src/HOL/UNITY/ELT.thy
changeset 67613 ce654b0e6d69
parent 63146 f1ecba0272f9
equal deleted inserted replaced
67610:4939494ed791 67613:ce654b0e6d69
    29   (*LEADS-TO constant for the inductive definition*)
    29   (*LEADS-TO constant for the inductive definition*)
    30   elt :: "['a set set, 'a program] => ('a set * 'a set) set"
    30   elt :: "['a set set, 'a program] => ('a set * 'a set) set"
    31   for CC :: "'a set set" and F :: "'a program"
    31   for CC :: "'a set set" and F :: "'a program"
    32  where
    32  where
    33 
    33 
    34    Basis:  "[| F : A ensures B;  A-B : (insert {} CC) |] ==> (A,B) : elt CC F"
    34    Basis:  "[| F \<in> A ensures B;  A-B \<in> (insert {} CC) |] ==> (A,B) \<in> elt CC F"
    35 
    35 
    36  | Trans:  "[| (A,B) : elt CC F;  (B,C) : elt CC F |] ==> (A,C) : elt CC F"
    36  | Trans:  "[| (A,B) \<in> elt CC F;  (B,C) \<in> elt CC F |] ==> (A,C) \<in> elt CC F"
    37 
    37 
    38  | Union:  "ALL A: S. (A,B) : elt CC F ==> (Union S, B) : elt CC F"
    38  | Union:  "\<forall>A\<in>S. (A,B) \<in> elt CC F ==> (Union S, B) \<in> elt CC F"
    39 
    39 
    40 
    40 
    41 definition  
    41 definition  
    42   (*the set of all sets determined by f alone*)
    42   (*the set of all sets determined by f alone*)
    43   givenBy :: "['a => 'b] => 'a set set"
    43   givenBy :: "['a => 'b] => 'a set set"
    45 
    45 
    46 definition
    46 definition
    47   (*visible version of the LEADS-TO relation*)
    47   (*visible version of the LEADS-TO relation*)
    48   leadsETo :: "['a set, 'a set set, 'a set] => 'a program set"
    48   leadsETo :: "['a set, 'a set set, 'a set] => 'a program set"
    49                                         ("(3_/ leadsTo[_]/ _)" [80,0,80] 80)
    49                                         ("(3_/ leadsTo[_]/ _)" [80,0,80] 80)
    50   where "leadsETo A CC B = {F. (A,B) : elt CC F}"
    50   where "leadsETo A CC B = {F. (A,B) \<in> elt CC F}"
    51 
    51 
    52 definition
    52 definition
    53   LeadsETo :: "['a set, 'a set set, 'a set] => 'a program set"
    53   LeadsETo :: "['a set, 'a set set, 'a set] => 'a program set"
    54                                         ("(3_/ LeadsTo[_]/ _)" [80,0,80] 80)
    54                                         ("(3_/ LeadsTo[_]/ _)" [80,0,80] 80)
    55   where "LeadsETo A CC B =
    55   where "LeadsETo A CC B =
    56       {F. F : (reachable F Int A) leadsTo[(%C. reachable F Int C) ` CC] B}"
    56       {F. F \<in> (reachable F Int A) leadsTo[(%C. reachable F Int C) ` CC] B}"
    57 
    57 
    58 
    58 
    59 (*** givenBy ***)
    59 (*** givenBy ***)
    60 
    60 
    61 lemma givenBy_id [simp]: "givenBy id = UNIV"
    61 lemma givenBy_id [simp]: "givenBy id = UNIV"
    62 by (unfold givenBy_def, auto)
    62 by (unfold givenBy_def, auto)
    63 
    63 
    64 lemma givenBy_eq_all: "(givenBy v) = {A. ALL x:A. ALL y. v x = v y --> y: A}"
    64 lemma givenBy_eq_all: "(givenBy v) = {A. \<forall>x\<in>A. \<forall>y. v x = v y \<longrightarrow> y \<in> A}"
    65 apply (unfold givenBy_def, safe)
    65 apply (unfold givenBy_def, safe)
    66 apply (rule_tac [2] x = "v ` _" in image_eqI, auto)
    66 apply (rule_tac [2] x = "v ` _" in image_eqI, auto)
    67 done
    67 done
    68 
    68 
    69 lemma givenByI: "(!!x y. [| x:A;  v x = v y |] ==> y: A) ==> A: givenBy v"
    69 lemma givenByI: "(\<And>x y. [| x \<in> A;  v x = v y |] ==> y \<in> A) ==> A \<in> givenBy v"
    70 by (subst givenBy_eq_all, blast)
    70 by (subst givenBy_eq_all, blast)
    71 
    71 
    72 lemma givenByD: "[| A: givenBy v;  x:A;  v x = v y |] ==> y: A"
    72 lemma givenByD: "[| A \<in> givenBy v;  x \<in> A;  v x = v y |] ==> y \<in> A"
    73 by (unfold givenBy_def, auto)
    73 by (unfold givenBy_def, auto)
    74 
    74 
    75 lemma empty_mem_givenBy [iff]: "{} : givenBy v"
    75 lemma empty_mem_givenBy [iff]: "{} \<in> givenBy v"
    76 by (blast intro!: givenByI)
    76 by (blast intro!: givenByI)
    77 
    77 
    78 lemma givenBy_imp_eq_Collect: "A: givenBy v ==> EX P. A = {s. P(v s)}"
    78 lemma givenBy_imp_eq_Collect: "A \<in> givenBy v ==> \<exists>P. A = {s. P(v s)}"
    79 apply (rule_tac x = "%n. EX s. v s = n & s : A" in exI)
    79 apply (rule_tac x = "\<lambda>n. \<exists>s. v s = n \<and> s \<in> A" in exI)
    80 apply (simp (no_asm_use) add: givenBy_eq_all)
    80 apply (simp (no_asm_use) add: givenBy_eq_all)
    81 apply blast
    81 apply blast
    82 done
    82 done
    83 
    83 
    84 lemma Collect_mem_givenBy: "{s. P(v s)} : givenBy v"
    84 lemma Collect_mem_givenBy: "{s. P(v s)} \<in> givenBy v"
    85 by (unfold givenBy_def, best)
    85 by (unfold givenBy_def, best)
    86 
    86 
    87 lemma givenBy_eq_Collect: "givenBy v = {A. EX P. A = {s. P(v s)}}"
    87 lemma givenBy_eq_Collect: "givenBy v = {A. \<exists>P. A = {s. P(v s)}}"
    88 by (blast intro: Collect_mem_givenBy givenBy_imp_eq_Collect)
    88 by (blast intro: Collect_mem_givenBy givenBy_imp_eq_Collect)
    89 
    89 
    90 (*preserving v preserves properties given by v*)
    90 (*preserving v preserves properties given by v*)
    91 lemma preserves_givenBy_imp_stable:
    91 lemma preserves_givenBy_imp_stable:
    92      "[| F : preserves v;  D : givenBy v |] ==> F : stable D"
    92      "[| F \<in> preserves v;  D \<in> givenBy v |] ==> F \<in> stable D"
    93 by (force simp add: preserves_subset_stable [THEN subsetD] givenBy_eq_Collect)
    93 by (force simp add: preserves_subset_stable [THEN subsetD] givenBy_eq_Collect)
    94 
    94 
    95 lemma givenBy_o_subset: "givenBy (w o v) <= givenBy v"
    95 lemma givenBy_o_subset: "givenBy (w o v) <= givenBy v"
    96 apply (simp (no_asm) add: givenBy_eq_Collect)
    96 apply (simp (no_asm) add: givenBy_eq_Collect)
    97 apply best 
    97 apply best 
    98 done
    98 done
    99 
    99 
   100 lemma givenBy_DiffI:
   100 lemma givenBy_DiffI:
   101      "[| A : givenBy v;  B : givenBy v |] ==> A-B : givenBy v"
   101      "[| A \<in> givenBy v;  B \<in> givenBy v |] ==> A-B \<in> givenBy v"
   102 apply (simp (no_asm_use) add: givenBy_eq_Collect)
   102 apply (simp (no_asm_use) add: givenBy_eq_Collect)
   103 apply safe
   103 apply safe
   104 apply (rule_tac x = "%z. R z & ~ Q z" for R Q in exI)
   104 apply (rule_tac x = "%z. R z & ~ Q z" for R Q in exI)
   105 unfolding set_diff_eq
   105 unfolding set_diff_eq
   106 apply auto
   106 apply auto
   108 
   108 
   109 
   109 
   110 (** Standard leadsTo rules **)
   110 (** Standard leadsTo rules **)
   111 
   111 
   112 lemma leadsETo_Basis [intro]: 
   112 lemma leadsETo_Basis [intro]: 
   113      "[| F: A ensures B;  A-B: insert {} CC |] ==> F : A leadsTo[CC] B"
   113      "[| F \<in> A ensures B;  A-B \<in> insert {} CC |] ==> F \<in> A leadsTo[CC] B"
   114 apply (unfold leadsETo_def)
   114 apply (unfold leadsETo_def)
   115 apply (blast intro: elt.Basis)
   115 apply (blast intro: elt.Basis)
   116 done
   116 done
   117 
   117 
   118 lemma leadsETo_Trans: 
   118 lemma leadsETo_Trans: 
   119      "[| F : A leadsTo[CC] B;  F : B leadsTo[CC] C |] ==> F : A leadsTo[CC] C"
   119      "[| F \<in> A leadsTo[CC] B;  F \<in> B leadsTo[CC] C |] ==> F \<in> A leadsTo[CC] C"
   120 apply (unfold leadsETo_def)
   120 apply (unfold leadsETo_def)
   121 apply (blast intro: elt.Trans)
   121 apply (blast intro: elt.Trans)
   122 done
   122 done
   123 
   123 
   124 
   124 
   125 (*Useful with cancellation, disjunction*)
   125 (*Useful with cancellation, disjunction*)
   126 lemma leadsETo_Un_duplicate:
   126 lemma leadsETo_Un_duplicate:
   127      "F : A leadsTo[CC] (A' Un A') ==> F : A leadsTo[CC] A'"
   127      "F \<in> A leadsTo[CC] (A' \<union> A') \<Longrightarrow> F \<in> A leadsTo[CC] A'"
   128 by (simp add: Un_ac)
   128 by (simp add: Un_ac)
   129 
   129 
   130 lemma leadsETo_Un_duplicate2:
   130 lemma leadsETo_Un_duplicate2:
   131      "F : A leadsTo[CC] (A' Un C Un C) ==> F : A leadsTo[CC] (A' Un C)"
   131      "F \<in> A leadsTo[CC] (A' \<union> C \<union> C) ==> F \<in> A leadsTo[CC] (A' Un C)"
   132 by (simp add: Un_ac)
   132 by (simp add: Un_ac)
   133 
   133 
   134 (*The Union introduction rule as we should have liked to state it*)
   134 (*The Union introduction rule as we should have liked to state it*)
   135 lemma leadsETo_Union:
   135 lemma leadsETo_Union:
   136     "(!!A. A : S ==> F : A leadsTo[CC] B) ==> F : (\<Union>S) leadsTo[CC] B"
   136     "(\<And>A. A \<in> S \<Longrightarrow> F \<in> A leadsTo[CC] B) \<Longrightarrow> F \<in> (\<Union>S) leadsTo[CC] B"
   137 apply (unfold leadsETo_def)
   137 apply (unfold leadsETo_def)
   138 apply (blast intro: elt.Union)
   138 apply (blast intro: elt.Union)
   139 done
   139 done
   140 
   140 
   141 lemma leadsETo_UN:
   141 lemma leadsETo_UN:
   142     "(!!i. i : I ==> F : (A i) leadsTo[CC] B)  
   142     "(\<And>i. i \<in> I \<Longrightarrow> F \<in> (A i) leadsTo[CC] B)  
   143      ==> F : (UN i:I. A i) leadsTo[CC] B"
   143      ==> F \<in> (UN i:I. A i) leadsTo[CC] B"
   144 apply (blast intro: leadsETo_Union)
   144 apply (blast intro: leadsETo_Union)
   145 done
   145 done
   146 
   146 
   147 (*The INDUCTION rule as we should have liked to state it*)
   147 (*The INDUCTION rule as we should have liked to state it*)
   148 lemma leadsETo_induct:
   148 lemma leadsETo_induct:
   149   "[| F : za leadsTo[CC] zb;   
   149   "[| F \<in> za leadsTo[CC] zb;   
   150       !!A B. [| F : A ensures B;  A-B : insert {} CC |] ==> P A B;  
   150       !!A B. [| F \<in> A ensures B;  A-B \<in> insert {} CC |] ==> P A B;  
   151       !!A B C. [| F : A leadsTo[CC] B; P A B; F : B leadsTo[CC] C; P B C |]  
   151       !!A B C. [| F \<in> A leadsTo[CC] B; P A B; F \<in> B leadsTo[CC] C; P B C |]  
   152                ==> P A C;  
   152                ==> P A C;  
   153       !!B S. ALL A:S. F : A leadsTo[CC] B & P A B ==> P (\<Union>S) B  
   153       !!B S. \<forall>A\<in>S. F \<in> A leadsTo[CC] B & P A B ==> P (\<Union>S) B  
   154    |] ==> P za zb"
   154    |] ==> P za zb"
   155 apply (unfold leadsETo_def)
   155 apply (unfold leadsETo_def)
   156 apply (drule CollectD) 
   156 apply (drule CollectD) 
   157 apply (erule elt.induct, blast+)
   157 apply (erule elt.induct, blast+)
   158 done
   158 done
   167 prefer 2 apply (blast intro: leadsETo_Trans)
   167 prefer 2 apply (blast intro: leadsETo_Trans)
   168 apply blast
   168 apply blast
   169 done
   169 done
   170 
   170 
   171 lemma leadsETo_Trans_Un:
   171 lemma leadsETo_Trans_Un:
   172      "[| F : A leadsTo[CC] B;  F : B leadsTo[DD] C |]  
   172      "[| F \<in> A leadsTo[CC] B;  F \<in> B leadsTo[DD] C |]  
   173       ==> F : A leadsTo[CC Un DD] C"
   173       ==> F \<in> A leadsTo[CC Un DD] C"
   174 by (blast intro: leadsETo_mono [THEN subsetD] leadsETo_Trans)
   174 by (blast intro: leadsETo_mono [THEN subsetD] leadsETo_Trans)
   175 
   175 
   176 lemma leadsETo_Union_Int:
   176 lemma leadsETo_Union_Int:
   177  "(!!A. A : S ==> F : (A Int C) leadsTo[CC] B) 
   177  "(!!A. A \<in> S ==> F \<in> (A Int C) leadsTo[CC] B) 
   178   ==> F : (\<Union>S Int C) leadsTo[CC] B"
   178   ==> F \<in> (\<Union>S Int C) leadsTo[CC] B"
   179 apply (unfold leadsETo_def)
   179 apply (unfold leadsETo_def)
   180 apply (simp only: Int_Union_Union)
   180 apply (simp only: Int_Union_Union)
   181 apply (blast intro: elt.Union)
   181 apply (blast intro: elt.Union)
   182 done
   182 done
   183 
   183 
   184 (*Binary union introduction rule*)
   184 (*Binary union introduction rule*)
   185 lemma leadsETo_Un:
   185 lemma leadsETo_Un:
   186      "[| F : A leadsTo[CC] C; F : B leadsTo[CC] C |] 
   186      "[| F \<in> A leadsTo[CC] C; F \<in> B leadsTo[CC] C |] 
   187       ==> F : (A Un B) leadsTo[CC] C"
   187       ==> F \<in> (A Un B) leadsTo[CC] C"
   188   using leadsETo_Union [of "{A, B}" F CC C] by auto
   188   using leadsETo_Union [of "{A, B}" F CC C] by auto
   189 
   189 
   190 lemma single_leadsETo_I:
   190 lemma single_leadsETo_I:
   191      "(!!x. x : A ==> F : {x} leadsTo[CC] B) ==> F : A leadsTo[CC] B"
   191      "(\<And>x. x \<in> A ==> F \<in> {x} leadsTo[CC] B) \<Longrightarrow> F \<in> A leadsTo[CC] B"
   192 by (subst UN_singleton [symmetric], rule leadsETo_UN, blast)
   192 by (subst UN_singleton [symmetric], rule leadsETo_UN, blast)
   193 
   193 
   194 
   194 
   195 lemma subset_imp_leadsETo: "A<=B ==> F : A leadsTo[CC] B"
   195 lemma subset_imp_leadsETo: "A<=B \<Longrightarrow> F \<in> A leadsTo[CC] B"
   196 by (simp add: subset_imp_ensures [THEN leadsETo_Basis] 
   196 by (simp add: subset_imp_ensures [THEN leadsETo_Basis] 
   197               Diff_eq_empty_iff [THEN iffD2])
   197               Diff_eq_empty_iff [THEN iffD2])
   198 
   198 
   199 lemmas empty_leadsETo = empty_subsetI [THEN subset_imp_leadsETo, simp]
   199 lemmas empty_leadsETo = empty_subsetI [THEN subset_imp_leadsETo, simp]
   200 
   200 
   201 
   201 
   202 
   202 
   203 (** Weakening laws **)
   203 (** Weakening laws **)
   204 
   204 
   205 lemma leadsETo_weaken_R:
   205 lemma leadsETo_weaken_R:
   206      "[| F : A leadsTo[CC] A';  A'<=B' |] ==> F : A leadsTo[CC] B'"
   206      "[| F \<in> A leadsTo[CC] A';  A'<=B' |] ==> F \<in> A leadsTo[CC] B'"
   207 by (blast intro: subset_imp_leadsETo leadsETo_Trans)
   207 by (blast intro: subset_imp_leadsETo leadsETo_Trans)
   208 
   208 
   209 lemma leadsETo_weaken_L:
   209 lemma leadsETo_weaken_L:
   210      "[| F : A leadsTo[CC] A'; B<=A |] ==> F : B leadsTo[CC] A'"
   210      "[| F \<in> A leadsTo[CC] A'; B<=A |] ==> F \<in> B leadsTo[CC] A'"
   211 by (blast intro: leadsETo_Trans subset_imp_leadsETo)
   211 by (blast intro: leadsETo_Trans subset_imp_leadsETo)
   212 
   212 
   213 (*Distributes over binary unions*)
   213 (*Distributes over binary unions*)
   214 lemma leadsETo_Un_distrib:
   214 lemma leadsETo_Un_distrib:
   215      "F : (A Un B) leadsTo[CC] C  =   
   215      "F \<in> (A Un B) leadsTo[CC] C  =   
   216       (F : A leadsTo[CC] C & F : B leadsTo[CC] C)"
   216       (F \<in> A leadsTo[CC] C \<and> F \<in> B leadsTo[CC] C)"
   217 by (blast intro: leadsETo_Un leadsETo_weaken_L)
   217 by (blast intro: leadsETo_Un leadsETo_weaken_L)
   218 
   218 
   219 lemma leadsETo_UN_distrib:
   219 lemma leadsETo_UN_distrib:
   220      "F : (UN i:I. A i) leadsTo[CC] B  =   
   220      "F \<in> (UN i:I. A i) leadsTo[CC] B  =   
   221       (ALL i : I. F : (A i) leadsTo[CC] B)"
   221       (\<forall>i\<in>I. F \<in> (A i) leadsTo[CC] B)"
   222 by (blast intro: leadsETo_UN leadsETo_weaken_L)
   222 by (blast intro: leadsETo_UN leadsETo_weaken_L)
   223 
   223 
   224 lemma leadsETo_Union_distrib:
   224 lemma leadsETo_Union_distrib:
   225      "F : (\<Union>S) leadsTo[CC] B  =  (ALL A : S. F : A leadsTo[CC] B)"
   225      "F \<in> (\<Union>S) leadsTo[CC] B  =  (\<forall>A\<in>S. F \<in> A leadsTo[CC] B)"
   226 by (blast intro: leadsETo_Union leadsETo_weaken_L)
   226 by (blast intro: leadsETo_Union leadsETo_weaken_L)
   227 
   227 
   228 lemma leadsETo_weaken:
   228 lemma leadsETo_weaken:
   229      "[| F : A leadsTo[CC'] A'; B<=A; A'<=B';  CC' <= CC |]  
   229      "[| F \<in> A leadsTo[CC'] A'; B<=A; A'<=B';  CC' <= CC |]  
   230       ==> F : B leadsTo[CC] B'"
   230       ==> F \<in> B leadsTo[CC] B'"
   231 apply (drule leadsETo_mono [THEN subsetD], assumption)
   231 apply (drule leadsETo_mono [THEN subsetD], assumption)
   232 apply (blast del: subsetCE 
   232 apply (blast del: subsetCE 
   233              intro: leadsETo_weaken_R leadsETo_weaken_L leadsETo_Trans)
   233              intro: leadsETo_weaken_R leadsETo_weaken_L leadsETo_Trans)
   234 done
   234 done
   235 
   235 
   236 lemma leadsETo_givenBy:
   236 lemma leadsETo_givenBy:
   237      "[| F : A leadsTo[CC] A';  CC <= givenBy v |]  
   237      "[| F \<in> A leadsTo[CC] A';  CC <= givenBy v |]  
   238       ==> F : A leadsTo[givenBy v] A'"
   238       ==> F \<in> A leadsTo[givenBy v] A'"
   239 by (blast intro: leadsETo_weaken)
   239 by (blast intro: leadsETo_weaken)
   240 
   240 
   241 
   241 
   242 (*Set difference*)
   242 (*Set difference*)
   243 lemma leadsETo_Diff:
   243 lemma leadsETo_Diff:
   244      "[| F : (A-B) leadsTo[CC] C; F : B leadsTo[CC] C |]  
   244      "[| F \<in> (A-B) leadsTo[CC] C; F \<in> B leadsTo[CC] C |]  
   245       ==> F : A leadsTo[CC] C"
   245       ==> F \<in> A leadsTo[CC] C"
   246 by (blast intro: leadsETo_Un leadsETo_weaken)
   246 by (blast intro: leadsETo_Un leadsETo_weaken)
   247 
   247 
   248 
   248 
   249 (*Binary union version*)
   249 (*Binary union version*)
   250 lemma leadsETo_Un_Un:
   250 lemma leadsETo_Un_Un:
   251      "[| F : A leadsTo[CC] A';  F : B leadsTo[CC] B' |]  
   251      "[| F \<in> A leadsTo[CC] A';  F \<in> B leadsTo[CC] B' |]  
   252       ==> F : (A Un B) leadsTo[CC] (A' Un B')"
   252       ==> F \<in> (A Un B) leadsTo[CC] (A' Un B')"
   253 by (blast intro: leadsETo_Un leadsETo_weaken_R)
   253 by (blast intro: leadsETo_Un leadsETo_weaken_R)
   254 
   254 
   255 
   255 
   256 (** The cancellation law **)
   256 (** The cancellation law **)
   257 
   257 
   258 lemma leadsETo_cancel2:
   258 lemma leadsETo_cancel2:
   259      "[| F : A leadsTo[CC] (A' Un B); F : B leadsTo[CC] B' |]  
   259      "[| F \<in> A leadsTo[CC] (A' Un B); F \<in> B leadsTo[CC] B' |]  
   260       ==> F : A leadsTo[CC] (A' Un B')"
   260       ==> F \<in> A leadsTo[CC] (A' Un B')"
   261 by (blast intro: leadsETo_Un_Un subset_imp_leadsETo leadsETo_Trans)
   261 by (blast intro: leadsETo_Un_Un subset_imp_leadsETo leadsETo_Trans)
   262 
   262 
   263 lemma leadsETo_cancel1:
   263 lemma leadsETo_cancel1:
   264      "[| F : A leadsTo[CC] (B Un A'); F : B leadsTo[CC] B' |]  
   264      "[| F \<in> A leadsTo[CC] (B Un A'); F \<in> B leadsTo[CC] B' |]  
   265     ==> F : A leadsTo[CC] (B' Un A')"
   265     ==> F \<in> A leadsTo[CC] (B' Un A')"
   266 apply (simp add: Un_commute)
   266 apply (simp add: Un_commute)
   267 apply (blast intro!: leadsETo_cancel2)
   267 apply (blast intro!: leadsETo_cancel2)
   268 done
   268 done
   269 
   269 
   270 lemma leadsETo_cancel_Diff1:
   270 lemma leadsETo_cancel_Diff1:
   271      "[| F : A leadsTo[CC] (B Un A'); F : (B-A') leadsTo[CC] B' |]  
   271      "[| F \<in> A leadsTo[CC] (B Un A'); F \<in> (B-A') leadsTo[CC] B' |]  
   272     ==> F : A leadsTo[CC] (B' Un A')"
   272     ==> F \<in> A leadsTo[CC] (B' Un A')"
   273 apply (rule leadsETo_cancel1)
   273 apply (rule leadsETo_cancel1)
   274  prefer 2 apply assumption
   274  prefer 2 apply assumption
   275 apply simp_all
   275 apply simp_all
   276 done
   276 done
   277 
   277 
   278 
   278 
   279 (** PSP: Progress-Safety-Progress **)
   279 (** PSP: Progress-Safety-Progress **)
   280 
   280 
   281 (*Special case of PSP: Misra's "stable conjunction"*)
   281 (*Special case of PSP: Misra's "stable conjunction"*)
   282 lemma e_psp_stable: 
   282 lemma e_psp_stable: 
   283    "[| F : A leadsTo[CC] A';  F : stable B;  ALL C:CC. C Int B : CC |]  
   283    "[| F \<in> A leadsTo[CC] A';  F \<in> stable B;  \<forall>C\<in>CC. C Int B \<in> CC |]  
   284     ==> F : (A Int B) leadsTo[CC] (A' Int B)"
   284     ==> F \<in> (A Int B) leadsTo[CC] (A' Int B)"
   285 apply (unfold stable_def)
   285 apply (unfold stable_def)
   286 apply (erule leadsETo_induct)
   286 apply (erule leadsETo_induct)
   287 prefer 3 apply (blast intro: leadsETo_Union_Int)
   287 prefer 3 apply (blast intro: leadsETo_Union_Int)
   288 prefer 2 apply (blast intro: leadsETo_Trans)
   288 prefer 2 apply (blast intro: leadsETo_Trans)
   289 apply (rule leadsETo_Basis)
   289 apply (rule leadsETo_Basis)
   292                  Int_Un_distrib2 [symmetric])
   292                  Int_Un_distrib2 [symmetric])
   293 apply (blast intro: transient_strengthen constrains_Int)
   293 apply (blast intro: transient_strengthen constrains_Int)
   294 done
   294 done
   295 
   295 
   296 lemma e_psp_stable2:
   296 lemma e_psp_stable2:
   297      "[| F : A leadsTo[CC] A'; F : stable B;  ALL C:CC. C Int B : CC |]  
   297      "[| F \<in> A leadsTo[CC] A'; F \<in> stable B;  \<forall>C\<in>CC. C Int B \<in> CC |]  
   298       ==> F : (B Int A) leadsTo[CC] (B Int A')"
   298       ==> F \<in> (B Int A) leadsTo[CC] (B Int A')"
   299 by (simp (no_asm_simp) add: e_psp_stable Int_ac)
   299 by (simp (no_asm_simp) add: e_psp_stable Int_ac)
   300 
   300 
   301 lemma e_psp:
   301 lemma e_psp:
   302      "[| F : A leadsTo[CC] A'; F : B co B';   
   302      "[| F \<in> A leadsTo[CC] A'; F \<in> B co B';   
   303          ALL C:CC. C Int B Int B' : CC |]  
   303          \<forall>C\<in>CC. C Int B Int B' \<in> CC |]  
   304       ==> F : (A Int B') leadsTo[CC] ((A' Int B) Un (B' - B))"
   304       ==> F \<in> (A Int B') leadsTo[CC] ((A' Int B) Un (B' - B))"
   305 apply (erule leadsETo_induct)
   305 apply (erule leadsETo_induct)
   306 prefer 3 apply (blast intro: leadsETo_Union_Int)
   306 prefer 3 apply (blast intro: leadsETo_Union_Int)
   307 (*Transitivity case has a delicate argument involving "cancellation"*)
   307 (*Transitivity case has a delicate argument involving "cancellation"*)
   308 apply (rule_tac [2] leadsETo_Un_duplicate2)
   308 apply (rule_tac [2] leadsETo_Un_duplicate2)
   309 apply (erule_tac [2] leadsETo_cancel_Diff1)
   309 apply (erule_tac [2] leadsETo_cancel_Diff1)
   316 apply (subgoal_tac "A Int B' - (Ba Int B Un (B' - B)) = (A - Ba) Int B Int B'")
   316 apply (subgoal_tac "A Int B' - (Ba Int B Un (B' - B)) = (A - Ba) Int B Int B'")
   317 apply auto
   317 apply auto
   318 done
   318 done
   319 
   319 
   320 lemma e_psp2:
   320 lemma e_psp2:
   321      "[| F : A leadsTo[CC] A'; F : B co B';   
   321      "[| F \<in> A leadsTo[CC] A'; F \<in> B co B';   
   322          ALL C:CC. C Int B Int B' : CC |]  
   322          \<forall>C\<in>CC. C Int B Int B' \<in> CC |]  
   323       ==> F : (B' Int A) leadsTo[CC] ((B Int A') Un (B' - B))"
   323       ==> F \<in> (B' Int A) leadsTo[CC] ((B Int A') Un (B' - B))"
   324 by (simp add: e_psp Int_ac)
   324 by (simp add: e_psp Int_ac)
   325 
   325 
   326 
   326 
   327 (*** Special properties involving the parameter [CC] ***)
   327 (*** Special properties involving the parameter [CC] ***)
   328 
   328 
   329 (*??IS THIS NEEDED?? or is it just an example of what's provable??*)
   329 (*??IS THIS NEEDED?? or is it just an example of what's provable??*)
   330 lemma gen_leadsETo_imp_Join_leadsETo:
   330 lemma gen_leadsETo_imp_Join_leadsETo:
   331      "[| F: (A leadsTo[givenBy v] B);  G : preserves v;   
   331      "[| F \<in> (A leadsTo[givenBy v] B);  G \<in> preserves v;   
   332          F\<squnion>G : stable C |]  
   332          F\<squnion>G \<in> stable C |]  
   333       ==> F\<squnion>G : ((C Int A) leadsTo[(%D. C Int D) ` givenBy v] B)"
   333       ==> F\<squnion>G \<in> ((C Int A) leadsTo[(%D. C Int D) ` givenBy v] B)"
   334 apply (erule leadsETo_induct)
   334 apply (erule leadsETo_induct)
   335   prefer 3
   335   prefer 3
   336   apply (subst Int_Union) 
   336   apply (subst Int_Union) 
   337   apply (blast intro: leadsETo_UN)
   337   apply (blast intro: leadsETo_UN)
   338 prefer 2
   338 prefer 2
   369 
   369 
   370 (**** weak ****)
   370 (**** weak ****)
   371 
   371 
   372 lemma LeadsETo_eq_leadsETo: 
   372 lemma LeadsETo_eq_leadsETo: 
   373      "A LeadsTo[CC] B =  
   373      "A LeadsTo[CC] B =  
   374         {F. F : (reachable F Int A) leadsTo[(%C. reachable F Int C) ` CC]  
   374         {F. F \<in> (reachable F Int A) leadsTo[(%C. reachable F Int C) ` CC]  
   375         (reachable F Int B)}"
   375         (reachable F Int B)}"
   376 apply (unfold LeadsETo_def)
   376 apply (unfold LeadsETo_def)
   377 apply (blast dest: e_psp_stable2 intro: leadsETo_weaken)
   377 apply (blast dest: e_psp_stable2 intro: leadsETo_weaken)
   378 done
   378 done
   379 
   379 
   380 (*** Introduction rules: Basis, Trans, Union ***)
   380 (*** Introduction rules: Basis, Trans, Union ***)
   381 
   381 
   382 lemma LeadsETo_Trans:
   382 lemma LeadsETo_Trans:
   383      "[| F : A LeadsTo[CC] B;  F : B LeadsTo[CC] C |]  
   383      "[| F \<in> A LeadsTo[CC] B;  F \<in> B LeadsTo[CC] C |]  
   384       ==> F : A LeadsTo[CC] C"
   384       ==> F \<in> A LeadsTo[CC] C"
   385 apply (simp add: LeadsETo_eq_leadsETo)
   385 apply (simp add: LeadsETo_eq_leadsETo)
   386 apply (blast intro: leadsETo_Trans)
   386 apply (blast intro: leadsETo_Trans)
   387 done
   387 done
   388 
   388 
   389 lemma LeadsETo_Union:
   389 lemma LeadsETo_Union:
   390      "(!!A. A : S ==> F : A LeadsTo[CC] B) ==> F : (\<Union>S) LeadsTo[CC] B"
   390      "(\<And>A. A \<in> S \<Longrightarrow> F \<in> A LeadsTo[CC] B) \<Longrightarrow> F \<in> (\<Union>S) LeadsTo[CC] B"
   391 apply (simp add: LeadsETo_def)
   391 apply (simp add: LeadsETo_def)
   392 apply (subst Int_Union)
   392 apply (subst Int_Union)
   393 apply (blast intro: leadsETo_UN)
   393 apply (blast intro: leadsETo_UN)
   394 done
   394 done
   395 
   395 
   396 lemma LeadsETo_UN:
   396 lemma LeadsETo_UN:
   397      "(!!i. i : I ==> F : (A i) LeadsTo[CC] B)  
   397      "(\<And>i. i \<in> I \<Longrightarrow> F \<in> (A i) LeadsTo[CC] B)  
   398       ==> F : (UN i:I. A i) LeadsTo[CC] B"
   398       \<Longrightarrow> F \<in> (UN i:I. A i) LeadsTo[CC] B"
   399 apply (blast intro: LeadsETo_Union)
   399 apply (blast intro: LeadsETo_Union)
   400 done
   400 done
   401 
   401 
   402 (*Binary union introduction rule*)
   402 (*Binary union introduction rule*)
   403 lemma LeadsETo_Un:
   403 lemma LeadsETo_Un:
   404      "[| F : A LeadsTo[CC] C; F : B LeadsTo[CC] C |]  
   404      "[| F \<in> A LeadsTo[CC] C; F \<in> B LeadsTo[CC] C |]  
   405       ==> F : (A Un B) LeadsTo[CC] C"
   405       ==> F \<in> (A Un B) LeadsTo[CC] C"
   406   using LeadsETo_Union [of "{A, B}" F CC C] by auto
   406   using LeadsETo_Union [of "{A, B}" F CC C] by auto
   407 
   407 
   408 (*Lets us look at the starting state*)
   408 (*Lets us look at the starting state*)
   409 lemma single_LeadsETo_I:
   409 lemma single_LeadsETo_I:
   410      "(!!s. s : A ==> F : {s} LeadsTo[CC] B) ==> F : A LeadsTo[CC] B"
   410      "(\<And>s. s \<in> A ==> F \<in> {s} LeadsTo[CC] B) \<Longrightarrow> F \<in> A LeadsTo[CC] B"
   411 by (subst UN_singleton [symmetric], rule LeadsETo_UN, blast)
   411 by (subst UN_singleton [symmetric], rule LeadsETo_UN, blast)
   412 
   412 
   413 lemma subset_imp_LeadsETo:
   413 lemma subset_imp_LeadsETo:
   414      "A <= B ==> F : A LeadsTo[CC] B"
   414      "A <= B \<Longrightarrow> F \<in> A LeadsTo[CC] B"
   415 apply (simp (no_asm) add: LeadsETo_def)
   415 apply (simp (no_asm) add: LeadsETo_def)
   416 apply (blast intro: subset_imp_leadsETo)
   416 apply (blast intro: subset_imp_leadsETo)
   417 done
   417 done
   418 
   418 
   419 lemmas empty_LeadsETo = empty_subsetI [THEN subset_imp_LeadsETo]
   419 lemmas empty_LeadsETo = empty_subsetI [THEN subset_imp_LeadsETo]
   420 
   420 
   421 lemma LeadsETo_weaken_R:
   421 lemma LeadsETo_weaken_R:
   422      "[| F : A LeadsTo[CC] A';  A' <= B' |] ==> F : A LeadsTo[CC] B'"
   422      "[| F \<in> A LeadsTo[CC] A';  A' <= B' |] ==> F \<in> A LeadsTo[CC] B'"
   423 apply (simp add: LeadsETo_def)
   423 apply (simp add: LeadsETo_def)
   424 apply (blast intro: leadsETo_weaken_R)
   424 apply (blast intro: leadsETo_weaken_R)
   425 done
   425 done
   426 
   426 
   427 lemma LeadsETo_weaken_L:
   427 lemma LeadsETo_weaken_L:
   428      "[| F : A LeadsTo[CC] A';  B <= A |] ==> F : B LeadsTo[CC] A'"
   428      "[| F \<in> A LeadsTo[CC] A';  B <= A |] ==> F \<in> B LeadsTo[CC] A'"
   429 apply (simp add: LeadsETo_def)
   429 apply (simp add: LeadsETo_def)
   430 apply (blast intro: leadsETo_weaken_L)
   430 apply (blast intro: leadsETo_weaken_L)
   431 done
   431 done
   432 
   432 
   433 lemma LeadsETo_weaken:
   433 lemma LeadsETo_weaken:
   434      "[| F : A LeadsTo[CC'] A';    
   434      "[| F \<in> A LeadsTo[CC'] A';    
   435          B <= A;  A' <= B';  CC' <= CC |]  
   435          B <= A;  A' <= B';  CC' <= CC |]  
   436       ==> F : B LeadsTo[CC] B'"
   436       ==> F \<in> B LeadsTo[CC] B'"
   437 apply (simp (no_asm_use) add: LeadsETo_def)
   437 apply (simp (no_asm_use) add: LeadsETo_def)
   438 apply (blast intro: leadsETo_weaken)
   438 apply (blast intro: leadsETo_weaken)
   439 done
   439 done
   440 
   440 
   441 lemma LeadsETo_subset_LeadsTo: "(A LeadsTo[CC] B) <= (A LeadsTo B)"
   441 lemma LeadsETo_subset_LeadsTo: "(A LeadsTo[CC] B) <= (A LeadsTo B)"
   443 apply (blast intro: leadsETo_subset_leadsTo [THEN subsetD])
   443 apply (blast intro: leadsETo_subset_leadsTo [THEN subsetD])
   444 done
   444 done
   445 
   445 
   446 (*Postcondition can be strengthened to (reachable F Int B) *)
   446 (*Postcondition can be strengthened to (reachable F Int B) *)
   447 lemma reachable_ensures:
   447 lemma reachable_ensures:
   448      "F : A ensures B ==> F : (reachable F Int A) ensures B"
   448      "F \<in> A ensures B \<Longrightarrow> F \<in> (reachable F Int A) ensures B"
   449 apply (rule stable_ensures_Int [THEN ensures_weaken_R], auto)
   449 apply (rule stable_ensures_Int [THEN ensures_weaken_R], auto)
   450 done
   450 done
   451 
   451 
   452 lemma lel_lemma:
   452 lemma lel_lemma:
   453      "F : A leadsTo B ==> F : (reachable F Int A) leadsTo[Pow(reachable F)] B"
   453      "F \<in> A leadsTo B \<Longrightarrow> F \<in> (reachable F Int A) leadsTo[Pow(reachable F)] B"
   454 apply (erule leadsTo_induct)
   454 apply (erule leadsTo_induct)
   455   apply (blast intro: reachable_ensures)
   455   apply (blast intro: reachable_ensures)
   456  apply (blast dest: e_psp_stable2 intro: leadsETo_Trans leadsETo_weaken_L)
   456  apply (blast dest: e_psp_stable2 intro: leadsETo_Trans leadsETo_weaken_L)
   457 apply (subst Int_Union)
   457 apply (subst Int_Union)
   458 apply (blast intro: leadsETo_UN)
   458 apply (blast intro: leadsETo_UN)
   481 
   481 
   482 lemma givenBy_eq_extend_set: "givenBy f = range (extend_set h)"
   482 lemma givenBy_eq_extend_set: "givenBy f = range (extend_set h)"
   483 by (simp add: givenBy_eq_Collect, best)
   483 by (simp add: givenBy_eq_Collect, best)
   484 
   484 
   485 lemma extend_set_givenBy_I:
   485 lemma extend_set_givenBy_I:
   486      "D : givenBy v ==> extend_set h D : givenBy (v o f)"
   486      "D \<in> givenBy v ==> extend_set h D \<in> givenBy (v o f)"
   487 apply (simp (no_asm_use) add: givenBy_eq_all, blast)
   487 apply (simp (no_asm_use) add: givenBy_eq_all, blast)
   488 done
   488 done
   489 
   489 
   490 lemma leadsETo_imp_extend_leadsETo:
   490 lemma leadsETo_imp_extend_leadsETo:
   491      "F : A leadsTo[CC] B  
   491      "F \<in> A leadsTo[CC] B  
   492       ==> extend h F : (extend_set h A) leadsTo[extend_set h ` CC]  
   492       ==> extend h F \<in> (extend_set h A) leadsTo[extend_set h ` CC]  
   493                        (extend_set h B)"
   493                        (extend_set h B)"
   494 apply (erule leadsETo_induct)
   494 apply (erule leadsETo_induct)
   495   apply (force intro: subset_imp_ensures 
   495   apply (force intro: subset_imp_ensures 
   496                simp add: extend_ensures extend_set_Diff_distrib [symmetric])
   496                simp add: extend_ensures extend_set_Diff_distrib [symmetric])
   497  apply (blast intro: leadsETo_Trans)
   497  apply (blast intro: leadsETo_Trans)
   500 
   500 
   501 
   501 
   502 (*This version's stronger in the "ensures" precondition
   502 (*This version's stronger in the "ensures" precondition
   503   BUT there's no ensures_weaken_L*)
   503   BUT there's no ensures_weaken_L*)
   504 lemma Join_project_ensures_strong:
   504 lemma Join_project_ensures_strong:
   505      "[| project h C G ~: transient (project_set h C Int (A-B)) |  
   505      "[| project h C G \<notin> transient (project_set h C Int (A-B)) |  
   506            project_set h C Int (A - B) = {};   
   506            project_set h C Int (A - B) = {};   
   507          extend h F\<squnion>G : stable C;   
   507          extend h F\<squnion>G \<in> stable C;   
   508          F\<squnion>project h C G : (project_set h C Int A) ensures B |]  
   508          F\<squnion>project h C G \<in> (project_set h C Int A) ensures B |]  
   509       ==> extend h F\<squnion>G : (C Int extend_set h A) ensures (extend_set h B)"
   509       ==> extend h F\<squnion>G \<in> (C Int extend_set h A) ensures (extend_set h B)"
   510 apply (subst Int_extend_set_lemma [symmetric])
   510 apply (subst Int_extend_set_lemma [symmetric])
   511 apply (rule Join_project_ensures)
   511 apply (rule Join_project_ensures)
   512 apply (auto simp add: Int_Diff)
   512 apply (auto simp add: Int_Diff)
   513 done
   513 done
   514 
   514 
   593 
   593 
   594 (*** leadsETo in the precondition ***)
   594 (*** leadsETo in the precondition ***)
   595 
   595 
   596 (*Lemma for the Trans case*)
   596 (*Lemma for the Trans case*)
   597 lemma pli_lemma:
   597 lemma pli_lemma:
   598      "[| extend h F\<squnion>G : stable C;     
   598      "[| extend h F\<squnion>G \<in> stable C;     
   599          F\<squnion>project h C G     
   599          F\<squnion>project h C G     
   600            : project_set h C Int project_set h A leadsTo project_set h B |]  
   600            \<in> project_set h C Int project_set h A leadsTo project_set h B |]  
   601       ==> F\<squnion>project h C G     
   601       ==> F\<squnion>project h C G     
   602             : project_set h C Int project_set h A leadsTo     
   602             \<in> project_set h C Int project_set h A leadsTo     
   603               project_set h C Int project_set h B"
   603               project_set h C Int project_set h B"
   604 apply (rule psp_stable2 [THEN leadsTo_weaken_L])
   604 apply (rule psp_stable2 [THEN leadsTo_weaken_L])
   605 apply (auto simp add: project_stable_project_set extend_stable_project_set)
   605 apply (auto simp add: project_stable_project_set extend_stable_project_set)
   606 done
   606 done
   607 
   607 
   608 lemma project_leadsETo_I_lemma:
   608 lemma project_leadsETo_I_lemma:
   609      "[| extend h F\<squnion>G : stable C;   
   609      "[| extend h F\<squnion>G \<in> stable C;   
   610          extend h F\<squnion>G :  
   610          extend h F\<squnion>G \<in>  
   611            (C Int A) leadsTo[(%D. C Int D)`givenBy f]  B |]   
   611            (C Int A) leadsTo[(%D. C Int D)`givenBy f]  B |]   
   612   ==> F\<squnion>project h C G   
   612   ==> F\<squnion>project h C G   
   613     : (project_set h C Int project_set h (C Int A)) leadsTo (project_set h B)"
   613     \<in> (project_set h C Int project_set h (C Int A)) leadsTo (project_set h B)"
   614 apply (erule leadsETo_induct)
   614 apply (erule leadsETo_induct)
   615   prefer 3
   615   prefer 3
   616   apply (simp only: Int_UN_distrib project_set_Union)
   616   apply (simp only: Int_UN_distrib project_set_Union)
   617   apply (blast intro: leadsTo_UN)
   617   apply (blast intro: leadsTo_UN)
   618  prefer 2 apply (blast intro: leadsTo_Trans pli_lemma)
   618  prefer 2 apply (blast intro: leadsTo_Trans pli_lemma)
   620 apply (rule leadsTo_Basis)
   620 apply (rule leadsTo_Basis)
   621 apply (blast intro: ensures_extend_set_imp_project_ensures)
   621 apply (blast intro: ensures_extend_set_imp_project_ensures)
   622 done
   622 done
   623 
   623 
   624 lemma project_leadsETo_I:
   624 lemma project_leadsETo_I:
   625      "extend h F\<squnion>G : (extend_set h A) leadsTo[givenBy f] (extend_set h B)
   625      "extend h F\<squnion>G \<in> (extend_set h A) leadsTo[givenBy f] (extend_set h B)
   626       ==> F\<squnion>project h UNIV G : A leadsTo B"
   626       \<Longrightarrow> F\<squnion>project h UNIV G \<in> A leadsTo B"
   627 apply (rule project_leadsETo_I_lemma [THEN leadsTo_weaken], auto)
   627 apply (rule project_leadsETo_I_lemma [THEN leadsTo_weaken], auto)
   628 done
   628 done
   629 
   629 
   630 lemma project_LeadsETo_I:
   630 lemma project_LeadsETo_I:
   631      "extend h F\<squnion>G : (extend_set h A) LeadsTo[givenBy f] (extend_set h B) 
   631      "extend h F\<squnion>G \<in> (extend_set h A) LeadsTo[givenBy f] (extend_set h B) 
   632       ==> F\<squnion>project h (reachable (extend h F\<squnion>G)) G   
   632       \<Longrightarrow> F\<squnion>project h (reachable (extend h F\<squnion>G)) G   
   633            : A LeadsTo B"
   633            \<in> A LeadsTo B"
   634 apply (simp (no_asm_use) add: LeadsTo_def LeadsETo_def)
   634 apply (simp (no_asm_use) add: LeadsTo_def LeadsETo_def)
   635 apply (rule project_leadsETo_I_lemma [THEN leadsTo_weaken])
   635 apply (rule project_leadsETo_I_lemma [THEN leadsTo_weaken])
   636 apply (auto simp add: project_set_reachable_extend_eq [symmetric])
   636 apply (auto simp add: project_set_reachable_extend_eq [symmetric])
   637 done
   637 done
   638 
   638 
   639 lemma projecting_leadsTo: 
   639 lemma projecting_leadsTo: 
   640      "projecting (%G. UNIV) h F  
   640      "projecting (\<lambda>G. UNIV) h F  
   641                  (extend_set h A leadsTo[givenBy f] extend_set h B)  
   641                  (extend_set h A leadsTo[givenBy f] extend_set h B)  
   642                  (A leadsTo B)"
   642                  (A leadsTo B)"
   643 apply (unfold projecting_def)
   643 apply (unfold projecting_def)
   644 apply (force dest: project_leadsETo_I)
   644 apply (force dest: project_leadsETo_I)
   645 done
   645 done
   646 
   646 
   647 lemma projecting_LeadsTo: 
   647 lemma projecting_LeadsTo: 
   648      "projecting (%G. reachable (extend h F\<squnion>G)) h F  
   648      "projecting (\<lambda>G. reachable (extend h F\<squnion>G)) h F  
   649                  (extend_set h A LeadsTo[givenBy f] extend_set h B)  
   649                  (extend_set h A LeadsTo[givenBy f] extend_set h B)  
   650                  (A LeadsTo B)"
   650                  (A LeadsTo B)"
   651 apply (unfold projecting_def)
   651 apply (unfold projecting_def)
   652 apply (force dest: project_LeadsETo_I)
   652 apply (force dest: project_LeadsETo_I)
   653 done
   653 done