src/ZF/UNITY/SubstAx.ML
changeset 12195 ed2893765a08
parent 11479 697dcaaf478f
child 12215 55c084921240
equal deleted inserted replaced
12194:13909cb72129 12195:ed2893765a08
     8 *)
     8 *)
     9 
     9 
    10 
    10 
    11 (*Resembles the previous definition of LeadsTo*)
    11 (*Resembles the previous definition of LeadsTo*)
    12 
    12 
       
    13 (* Equivalence with the HOL-like definition *)
    13 Goalw [LeadsTo_def]
    14 Goalw [LeadsTo_def]
    14      "A LeadsTo B = \
    15 "st_set(B)==> A LeadsTo B = {F:program. F:(reachable(F) Int A) leadsTo B}";
    15 \ {F:program. F : (reachable(F) Int A) leadsTo (reachable(F) Int B) & \
    16 by (blast_tac (claset() addDs [psp_stable2, leadsToD2, constrainsD2] 
    16 \    A:condition & B:condition}";
       
    17 by (blast_tac (claset() addDs [psp_stable2, leadsToD, constrainsD2] 
       
    18                         addIs [leadsTo_weaken]) 1);
    17                         addIs [leadsTo_weaken]) 1);
    19 qed "LeadsTo_eq_leadsTo";
    18 qed "LeadsTo_eq";
    20 
    19 
    21 Goalw [LeadsTo_def]
    20 Goalw [LeadsTo_def] "A LeadsTo B <=program";
    22 "F: A LeadsTo B ==> F:program & A:condition & B:condition";
    21 by Auto_tac;
    23 by (Blast_tac 1);
    22 qed "LeadsTo_type";
    24 qed "LeadsToD";
       
    25 
    23 
    26 (*** Specialized laws for handling invariants ***)
    24 (*** Specialized laws for handling invariants ***)
    27 
    25 
    28 (** Conjoining an Always property **)
    26 (** Conjoining an Always property **)
    29 Goal "[| F : Always(INV); A:condition |] ==> \
    27 Goal "F : Always(I) ==> (F:(I Int A) LeadsTo A') <-> (F: A LeadsTo A')";
    30 \  (F : (INV Int A) LeadsTo A') <-> (F : A LeadsTo A')";
       
    31 by (asm_full_simp_tac
    28 by (asm_full_simp_tac
    32     (simpset() addsimps [LeadsTo_def, Always_eq_includes_reachable,
    29     (simpset() addsimps [LeadsTo_def, Always_eq_includes_reachable,
    33               Int_absorb2, Int_assoc RS sym, leadsToD]) 1);
    30               Int_absorb2, Int_assoc RS sym, leadsToD2]) 1);
    34 qed "Always_LeadsTo_pre";
    31 qed "Always_LeadsTo_pre";
    35 
    32 
    36 Goal "[| F : Always(INV); A':condition |] \
    33 Goalw [LeadsTo_def] "F:Always(I) ==> (F : A LeadsTo (I Int A')) <-> (F : A LeadsTo A')";
    37   \ ==> (F : A LeadsTo (INV Int A')) <-> (F : A LeadsTo A')";
    34 by (asm_full_simp_tac (simpset() addsimps [Always_eq_includes_reachable, 
    38 by (asm_full_simp_tac
    35           Int_absorb2, Int_assoc RS sym,leadsToD2]) 1);
    39     (simpset() addsimps [LeadsTo_eq_leadsTo, Always_eq_includes_reachable, 
       
    40           Int_absorb2, Int_assoc RS sym,leadsToD]) 1);
       
    41 qed "Always_LeadsTo_post";
    36 qed "Always_LeadsTo_post";
    42 
    37 
    43 (* Like 'Always_LeadsTo_pre RS iffD1', but with premises in the good order *)
    38 (* Like 'Always_LeadsTo_pre RS iffD1', but with premises in the good order *)
    44 Goal "[| F:Always(C); F : (C Int A) LeadsTo A'; A:condition |] \
    39 Goal "[| F:Always(C); F : (C Int A) LeadsTo A' |] ==> F: A LeadsTo A'";
    45 \ ==> F: A LeadsTo A'";
       
    46 by (blast_tac (claset() addIs [Always_LeadsTo_pre RS iffD1]) 1);
    40 by (blast_tac (claset() addIs [Always_LeadsTo_pre RS iffD1]) 1);
    47 qed "Always_LeadsToI";
    41 qed "Always_LeadsToI";
    48 
    42 
    49 (* Like 'Always_LeadsTo_post RS iffD2', but with premises in the good order *)
    43 (* Like 'Always_LeadsTo_post RS iffD2', but with premises in the good order *)
    50 Goal
    44 Goal "[| F:Always(C);  F:A LeadsTo A' |] ==> F : A LeadsTo (C Int A')";
    51 "[| F : Always(C);  F : A LeadsTo A'; A':condition |] \
       
    52 \  ==> F : A LeadsTo (C Int A')";
       
    53 by (blast_tac (claset() addIs [Always_LeadsTo_post RS iffD2]) 1);
    45 by (blast_tac (claset() addIs [Always_LeadsTo_post RS iffD2]) 1);
    54 qed "Always_LeadsToD";
    46 qed "Always_LeadsToD";
    55 
    47 
    56 (*** Introduction rules: Basis, Trans, Union ***)
    48 (*** Introduction rules: Basis, Trans, Union ***)
    57 
    49 
    58 Goal "F : A leadsTo B ==> F : A LeadsTo B";
    50 Goal "F : A Ensures B ==> F : A LeadsTo B";
    59 by (simp_tac (simpset() addsimps [LeadsTo_def]) 1);
    51 by (auto_tac (claset(), simpset() addsimps 
    60 by (blast_tac (claset() addIs [leadsTo_weaken_L]
    52                    [Ensures_def, LeadsTo_def]));
    61                         addDs [leadsToD]) 1);
    53 qed "LeadsTo_Basis";
    62 qed "leadsTo_imp_LeadsTo";
       
    63 
    54 
    64 Goal "[| F : A LeadsTo B;  F : B LeadsTo C |] ==> F : A LeadsTo C";
    55 Goal "[| F : A LeadsTo B;  F : B LeadsTo C |] ==> F : A LeadsTo C";
    65 by (full_simp_tac (simpset() addsimps [LeadsTo_eq_leadsTo]) 1);
    56 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1);
    66 by (blast_tac (claset() addIs [leadsTo_Trans]) 1);
    57 by (blast_tac (claset() addIs [leadsTo_Trans]) 1);
    67 qed "LeadsTo_Trans";
    58 qed "LeadsTo_Trans";
    68 
    59 
    69 Goalw [LeadsTo_def]
    60 val [major, program] = Goalw [LeadsTo_def]
    70      "[| ALL A:S. F : A LeadsTo B; F:program; B:condition |] \
    61 "[|(!!A. A:S ==> F : A LeadsTo B); F:program|]==>F:Union(S) LeadsTo B";
    71 \ ==> F : Union(S) LeadsTo B";
    62 by (cut_facts_tac [program] 1);
    72 by Auto_tac;
    63 by Auto_tac;
    73 by (stac Int_Union_Union2 1);
    64 by (stac Int_Union_Union2 1);
    74 by (blast_tac (claset() addIs [leadsTo_UN]) 1);
    65 by (rtac leadsTo_UN 1);
    75 bind_thm("LeadsTo_Union", ballI RS result());
    66 by (dtac major 1);
    76 
    67 by Auto_tac;
       
    68 qed "LeadsTo_Union";
    77 
    69 
    78 (*** Derived rules ***)
    70 (*** Derived rules ***)
    79 
    71 
    80 Goalw [LeadsTo_def] 
    72 Goal "F : A leadsTo B ==> F : A LeadsTo B";
    81 "[| F:program; A:condition |] ==>F : A LeadsTo state";
    73 by (forward_tac [leadsToD2] 1);
    82 by (blast_tac (claset() addIs [leadsTo_state]) 1);
    74 by (Clarify_tac 1);
    83 qed "LeadsTo_state";
    75 by (asm_simp_tac (simpset() addsimps [LeadsTo_eq]) 1);
    84 Addsimps [LeadsTo_state];
    76 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1);
       
    77 qed "leadsTo_imp_LeadsTo";
    85 
    78 
    86 (*Useful with cancellation, disjunction*)
    79 (*Useful with cancellation, disjunction*)
    87 Goal "F : A LeadsTo (A' Un A') ==> F : A LeadsTo A'";
    80 Goal "F : A LeadsTo (A' Un A') ==> F : A LeadsTo A'";
    88 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1);
    81 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1);
    89 qed "LeadsTo_Un_duplicate";
    82 qed "LeadsTo_Un_duplicate";
    90 
    83 
    91 Goal "F : A LeadsTo (A' Un C Un C) ==> F : A LeadsTo (A' Un C)";
    84 Goal "F : A LeadsTo (A' Un C Un C) ==> F : A LeadsTo (A' Un C)";
    92 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1);
    85 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1);
    93 qed "LeadsTo_Un_duplicate2";
    86 qed "LeadsTo_Un_duplicate2";
    94 
    87 
    95 Goal "[| ALL i:I. F : A(i) LeadsTo B; F:program; B:condition |] \
    88 val [major, program] = Goalw [LeadsTo_def] 
       
    89 "[|(!!i. i:I ==> F : A(i) LeadsTo B); F:program|] \
    96 \  ==> F : (UN i:I. A(i)) LeadsTo B";
    90 \  ==> F : (UN i:I. A(i)) LeadsTo B";
    97 by (simp_tac (simpset() addsimps [Int_Union_Union]) 1);
    91 by (cut_facts_tac [program] 1);
    98 by (blast_tac (claset() addIs [LeadsTo_Union]) 1);
    92 by (asm_simp_tac (simpset() addsimps [Int_Union_Union2]) 1);
    99 bind_thm("LeadsTo_UN", ballI RS result());
    93 by (rtac leadsTo_UN 1);
       
    94 by (dtac major 1);
       
    95 by Auto_tac;
       
    96 qed "LeadsTo_UN";
   100 
    97 
   101 (*Binary union introduction rule*)
    98 (*Binary union introduction rule*)
   102 Goal "[| F : A LeadsTo C; F : B LeadsTo C |] ==> F : (A Un B) LeadsTo C";
    99 Goal "[| F : A LeadsTo C; F : B LeadsTo C |] ==> F : (A Un B) LeadsTo C";
   103 by (stac Un_eq_Union 1);
   100 by (stac Un_eq_Union 1);
   104 by (blast_tac (claset() addIs [LeadsTo_Union] 
   101 by (rtac LeadsTo_Union 1);
   105                         addDs [LeadsToD]) 1);
   102 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD], simpset()));
   106 qed "LeadsTo_Un";
   103 qed "LeadsTo_Un";
   107 
   104 
   108 (*Lets us look at the starting state*)
   105 (*Lets us look at the starting state*)
   109 Goal "[| ALL s:A. F : {s} LeadsTo B; F:program; B:condition |]\
   106 val [major, program] = Goal 
   110 \  ==> F : A LeadsTo B";
   107 "[|(!!s. s:A ==> F:{s} LeadsTo B); F:program|]==>F:A LeadsTo B";
       
   108 by (cut_facts_tac [program] 1);
   111 by (stac (UN_singleton RS sym) 1 THEN rtac LeadsTo_UN 1);
   109 by (stac (UN_singleton RS sym) 1 THEN rtac LeadsTo_UN 1);
   112 by (REPEAT(Blast_tac 1));
   110 by (forward_tac [major] 1);
   113 bind_thm("single_LeadsTo_I", ballI RS result());
   111 by Auto_tac;
   114 
   112 qed "single_LeadsTo_I";
   115 Goal "[| A <= B; B:condition; F:program |] ==> F : A LeadsTo B";
   113 
   116 by (subgoal_tac "A:condition" 1);
   114 Goal "[| A <= B; F:program |] ==> F : A LeadsTo B";
   117 by (force_tac (claset(), 
   115 by (asm_simp_tac (simpset() addsimps [LeadsTo_def]) 1);
   118          simpset() addsimps [condition_def]) 2);
       
   119 by (simp_tac (simpset() addsimps [LeadsTo_def]) 1);
       
   120 by (blast_tac (claset() addIs [subset_imp_leadsTo]) 1);
   116 by (blast_tac (claset() addIs [subset_imp_leadsTo]) 1);
   121 qed "subset_imp_LeadsTo";
   117 qed "subset_imp_LeadsTo";
   122 
   118 
   123 bind_thm ("empty_LeadsTo", empty_subsetI RS subset_imp_LeadsTo);
   119 Goal "F:0 LeadsTo A <-> F:program";
   124 Addsimps [empty_LeadsTo];
   120 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD]
   125 
   121                        addIs [empty_subsetI RS subset_imp_LeadsTo], simpset()));
   126 Goal "[| F : A LeadsTo A';  A' <= B'; B':condition |] ==> F : A LeadsTo B'";
   122 qed "empty_LeadsTo";
   127 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1);
   123 AddIffs [empty_LeadsTo];
   128 by (blast_tac (claset() addIs [leadsTo_weaken_R]) 1);
   124 
       
   125 Goal "F : A LeadsTo state <-> F:program";
       
   126 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD], 
       
   127               simpset() addsimps [LeadsTo_eq]));
       
   128 qed "LeadsTo_state";
       
   129 AddIffs [LeadsTo_state];
       
   130 
       
   131 Goalw [LeadsTo_def]
       
   132  "[| F:A LeadsTo A';  A'<=B'|] ==> F : A LeadsTo B'";
       
   133 by (auto_tac (claset() addIs[leadsTo_weaken_R], simpset()));
   129 qed_spec_mp "LeadsTo_weaken_R";
   134 qed_spec_mp "LeadsTo_weaken_R";
   130 
   135 
   131 
   136 Goalw [LeadsTo_def] "[| F : A LeadsTo A'; B <= A |] ==> F : B LeadsTo A'";
   132 Goal "[| F : A LeadsTo A';  B <= A |]  \
   137 by (auto_tac (claset() addIs[leadsTo_weaken_L], simpset()));
   133 \     ==> F : B LeadsTo A'";
       
   134 by (subgoal_tac "B:condition" 1);
       
   135 by (force_tac (claset() addSDs [LeadsToD],
       
   136                simpset() addsimps [condition_def]) 2);
       
   137 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1);
       
   138 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1);
       
   139 qed_spec_mp "LeadsTo_weaken_L";
   138 qed_spec_mp "LeadsTo_weaken_L";
   140 
   139 
   141 Goal "[| F : A LeadsTo A';   \
   140 Goal "[| F : A LeadsTo A'; B<=A; A'<=B' |] ==> F : B LeadsTo B'";
   142 \        B  <= A;   A' <= B'; B':condition |] \
       
   143 \     ==> F : B LeadsTo B'";
       
   144 by (blast_tac (claset() addIs [LeadsTo_weaken_R, 
   141 by (blast_tac (claset() addIs [LeadsTo_weaken_R, 
   145                     LeadsTo_weaken_L, LeadsTo_Trans]) 1);
   142                     LeadsTo_weaken_L, LeadsTo_Trans]) 1);
   146 qed "LeadsTo_weaken";
   143 qed "LeadsTo_weaken";
   147 
   144 
   148 Goal "[| F : Always(C);  F : A LeadsTo A';   \
   145 Goal 
   149 \        C Int B <= A;   C Int A' <= B'; B:condition; B':condition |] \
   146 "[| F:Always(C);  F:A LeadsTo A'; C Int B <= A;   C Int A' <= B' |] \
   150 \     ==> F : B LeadsTo B'";
   147 \     ==> F : B LeadsTo B'";
   151 by (blast_tac (claset() 
   148 by (blast_tac (claset() addDs [Always_LeadsToI]
   152       addDs [AlwaysD2, LeadsToD, Always_LeadsToI]
   149                         addIs [LeadsTo_weaken, Always_LeadsToD]) 1);
   153       addIs [LeadsTo_weaken, Always_LeadsToD]) 1);
       
   154 qed "Always_LeadsTo_weaken";
   150 qed "Always_LeadsTo_weaken";
   155 
   151 
   156 (** Two theorems for "proof lattices" **)
   152 (** Two theorems for "proof lattices" **)
   157 
   153 
   158 Goal "F : A LeadsTo B ==> F:(A Un B) LeadsTo B";
   154 Goal "F : A LeadsTo B ==> F:(A Un B) LeadsTo B";
   159 by (blast_tac (claset() 
   155 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD]
   160          addIs [LeadsTo_Un, subset_imp_LeadsTo]
   156                          addIs [LeadsTo_Un, subset_imp_LeadsTo]) 1);
   161          addDs [LeadsToD]) 1);
       
   162 qed "LeadsTo_Un_post";
   157 qed "LeadsTo_Un_post";
   163 
   158 
   164 Goal "[| F : A LeadsTo B;  F : B LeadsTo C |] \
   159 Goal "[| F : A LeadsTo B;  F : B LeadsTo C |] \
   165 \     ==> F : (A Un B) LeadsTo C";
   160 \     ==> F : (A Un B) LeadsTo C";
   166 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo, 
   161 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo, 
   167                                LeadsTo_weaken_L, LeadsTo_Trans]
   162                                LeadsTo_weaken_L, LeadsTo_Trans]
   168                         addDs [LeadsToD]) 1);
   163                         addDs [LeadsTo_type RS subsetD]) 1);
   169 qed "LeadsTo_Trans_Un";
   164 qed "LeadsTo_Trans_Un";
   170 
   165 
   171 
       
   172 (** Distributive laws **)
   166 (** Distributive laws **)
   173 
       
   174 Goal "(F : (A Un B) LeadsTo C)  <-> (F : A LeadsTo C & F : B LeadsTo C)";
   167 Goal "(F : (A Un B) LeadsTo C)  <-> (F : A LeadsTo C & F : B LeadsTo C)";
   175 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1);
   168 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1);
   176 qed "LeadsTo_Un_distrib";
   169 qed "LeadsTo_Un_distrib";
   177 
   170 
   178 Goal "[| F:program; B:condition |] ==> \
   171 Goal "(F : (UN i:I. A(i)) LeadsTo B) <->  (ALL i : I. F : A(i) LeadsTo B) & F:program";
   179 \ (F : (UN i:I. A(i)) LeadsTo B) <->  (ALL i : I. F : A(i) LeadsTo B)";
   172 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD]
   180 by (blast_tac (claset() addIs [LeadsTo_UN, LeadsTo_weaken_L]) 1);
   173                         addIs [LeadsTo_UN, LeadsTo_weaken_L]) 1);
   181 qed "LeadsTo_UN_distrib";
   174 qed "LeadsTo_UN_distrib";
   182 
   175 
   183 Goal "[| F:program; B:condition |] ==> \
   176 Goal "(F:Union(S) LeadsTo B)  <->  (ALL A : S. F : A LeadsTo B) & F:program";
   184 \ (F : Union(S) LeadsTo B)  <->  (ALL A : S. F : A LeadsTo B)";
   177 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD] 
   185 by (blast_tac (claset() addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1);
   178                         addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1);
   186 qed "LeadsTo_Union_distrib";
   179 qed "LeadsTo_Union_distrib";
   187 
   180 
   188 (** More rules using the premise "Always INV" **)
   181 (** More rules using the premise "Always(I)" **)
   189 
   182 
   190 Goal "F : A Ensures B ==> F : A LeadsTo B";
   183 Goal "[| F:(A-B) Co (A Un B);  F:transient (A-B) |] ==> F : A Ensures B";
   191 by (asm_full_simp_tac
       
   192     (simpset() addsimps [Ensures_def, LeadsTo_def, leadsTo_Basis]) 1);
       
   193 qed "LeadsTo_Basis";
       
   194 
       
   195 Goal "[| F : (A-B) Co (A Un B);  F : transient (A-B) |]   \
       
   196 \     ==> F : A Ensures B";
       
   197 by (asm_full_simp_tac
   184 by (asm_full_simp_tac
   198     (simpset() addsimps [Ensures_def, Constrains_eq_constrains]) 1);
   185     (simpset() addsimps [Ensures_def, Constrains_eq_constrains]) 1);
   199 by (blast_tac (claset() addIs [ensuresI, constrains_weaken, 
   186 by (blast_tac (claset() addIs [ensuresI, constrains_weaken, 
   200                                transient_strengthen]
   187                                transient_strengthen]
   201                         addDs [constrainsD2]) 1);
   188                         addDs [constrainsD2]) 1);
   202 qed "EnsuresI";
   189 qed "EnsuresI";
   203 
   190 
   204 Goal "[| F : Always(INV);      \
   191 Goal "[| F : Always(I); F : (I Int (A-A')) Co (A Un A'); \
   205 \        F : (INV Int (A-A')) Co (A Un A'); \
   192 \        F : transient (I Int (A-A')) |]   \
   206 \        F : transient (INV Int (A-A')) |]   \
       
   207 \ ==> F : A LeadsTo A'";
   193 \ ==> F : A LeadsTo A'";
   208 by (rtac Always_LeadsToI 1);
   194 by (rtac Always_LeadsToI 1);
   209 by (assume_tac 1);
   195 by (assume_tac 1);
   210 by (blast_tac (claset() addDs [ConstrainsD]) 2);
       
   211 by (blast_tac (claset() addIs [EnsuresI, LeadsTo_Basis,
   196 by (blast_tac (claset() addIs [EnsuresI, LeadsTo_Basis,
   212                                Always_ConstrainsD RS Constrains_weaken, 
   197                                Always_ConstrainsD RS Constrains_weaken, 
   213                                transient_strengthen]
   198                                transient_strengthen]) 1);
   214                         addDs [AlwaysD2, ConstrainsD]) 1);
       
   215 qed "Always_LeadsTo_Basis";
   199 qed "Always_LeadsTo_Basis";
   216 
   200 
   217 (*Set difference: maybe combine with leadsTo_weaken_L??
   201 (*Set difference: maybe combine with leadsTo_weaken_L??
   218   This is the most useful form of the "disjunction" rule*)
   202   This is the most useful form of the "disjunction" rule*)
   219 Goal "[| F : (A-B) LeadsTo C;  F : (A Int B) LeadsTo C; \
   203 Goal "[| F : (A-B) LeadsTo C;  F : (A Int B) LeadsTo C |] ==> F : A LeadsTo C";
   220 \ A:condition; B:condition |] \
   204 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken]) 1);
   221 \     ==> F : A LeadsTo C";
       
   222 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken]
       
   223                 addDs [LeadsToD]) 1);
       
   224 qed "LeadsTo_Diff";
   205 qed "LeadsTo_Diff";
   225 
   206 
   226 
   207 val [major, minor] = Goal 
   227 Goal "[| ALL i:I. F: A(i) LeadsTo A'(i); F:program |] \
   208 "[|(!!i. i:I ==> F: A(i) LeadsTo A'(i)); F:program |] \
   228 \     ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))";
   209 \     ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))";
       
   210 by (cut_facts_tac [minor] 1);
   229 by (rtac LeadsTo_Union 1);
   211 by (rtac LeadsTo_Union 1);
   230 by (ALLGOALS(Clarify_tac));
   212 by (ALLGOALS(Clarify_tac));
   231 by (blast_tac (claset() addDs [LeadsToD]) 2);
   213 by (forward_tac [major] 1);
   232 by (blast_tac (claset()  addIs [LeadsTo_weaken_R]
   214 by (blast_tac (claset()  addIs [LeadsTo_weaken_R]) 1);
   233                          addDs [LeadsToD]) 1);
   215 qed "LeadsTo_UN_UN";
   234 bind_thm ("LeadsTo_UN_UN", ballI RS result());
       
   235 
       
   236 
       
   237 (*Version with no index set*)
       
   238 Goal "[| ALL i. F: A(i) LeadsTo A'(i); F:program |] \
       
   239 \     ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))";
       
   240 by (blast_tac (claset() addIs [LeadsTo_UN_UN]) 1);
       
   241 qed "all_LeadsTo_UN_UN";
       
   242 
       
   243 bind_thm ("LeadsTo_UN_UN_noindex", allI RS all_LeadsTo_UN_UN);
       
   244 
   216 
   245 (*Binary union version*)
   217 (*Binary union version*)
   246 Goal "[| F : A LeadsTo A'; F : B LeadsTo B' |] \
   218 Goal "[| F:A LeadsTo A'; F:B LeadsTo B' |] ==> F:(A Un B) LeadsTo (A' Un B')";
   247 \           ==> F : (A Un B) LeadsTo (A' Un B')";
   219 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_R]) 1);
   248 by (blast_tac (claset() 
       
   249         addIs [LeadsTo_Un, LeadsTo_weaken_R]
       
   250         addDs [LeadsToD]) 1);
       
   251 qed "LeadsTo_Un_Un";
   220 qed "LeadsTo_Un_Un";
   252 
   221 
   253 (** The cancellation law **)
   222 (** The cancellation law **)
   254 
   223 
   255 Goal "[| F : A LeadsTo (A' Un B); F : B LeadsTo B' |]    \
   224 Goal "[| F: A LeadsTo(A' Un B); F: B LeadsTo B' |] ==> F:A LeadsTo (A' Un B')";
   256 \     ==> F : A LeadsTo (A' Un B')";
   225 by (blast_tac (claset() addIs [LeadsTo_Un_Un, subset_imp_LeadsTo, LeadsTo_Trans]
   257 by (blast_tac (claset() addIs [LeadsTo_Un_Un, 
   226                         addDs [LeadsTo_type RS subsetD]) 1);
   258                                subset_imp_LeadsTo, LeadsTo_Trans]
       
   259                     addDs [LeadsToD]) 1);
       
   260 qed "LeadsTo_cancel2";
   227 qed "LeadsTo_cancel2";
   261 
   228 
   262 Goal "A Un (B - A) = A Un B";
   229 Goal "A Un (B - A) = A Un B";
   263 by Auto_tac;
   230 by Auto_tac;
   264 qed "Un_Diff";
   231 qed "Un_Diff";
   265 
   232 
   266 Goal "[| F : A LeadsTo (A' Un B); F : (B-A') LeadsTo B' |] \
   233 Goal "[| F : A LeadsTo (A' Un B); F : (B-A') LeadsTo B' |] ==> F : A LeadsTo (A' Un B')";
   267 \     ==> F : A LeadsTo (A' Un B')";
       
   268 by (rtac LeadsTo_cancel2 1);
   234 by (rtac LeadsTo_cancel2 1);
   269 by (assume_tac 2);
   235 by (assume_tac 2);
   270 by (asm_simp_tac (simpset() addsimps [Un_Diff]) 1);
   236 by (asm_simp_tac (simpset() addsimps [Un_Diff]) 1);
   271 qed "LeadsTo_cancel_Diff2";
   237 qed "LeadsTo_cancel_Diff2";
   272 
   238 
   273 Goal "[| F : A LeadsTo (B Un A'); F : B LeadsTo B' |] \
   239 Goal "[| F : A LeadsTo (B Un A'); F : B LeadsTo B' |] ==> F : A LeadsTo (B' Un A')";
   274 \     ==> F : A LeadsTo (B' Un A')";
       
   275 by (asm_full_simp_tac (simpset() addsimps [Un_commute]) 1);
   240 by (asm_full_simp_tac (simpset() addsimps [Un_commute]) 1);
   276 by (blast_tac (claset() addSIs [LeadsTo_cancel2]) 1);
   241 by (blast_tac (claset() addSIs [LeadsTo_cancel2]) 1);
   277 qed "LeadsTo_cancel1";
   242 qed "LeadsTo_cancel1";
   278 
   243 
   279 
       
   280 Goal "(B - A) Un A = B Un A";
   244 Goal "(B - A) Un A = B Un A";
   281 by Auto_tac;
   245 by Auto_tac;
   282 qed "Diff_Un2";
   246 qed "Diff_Un2";
   283 
   247 
   284 Goal "[| F : A LeadsTo (B Un A'); F : (B-A') LeadsTo B' |] \
   248 Goal "[| F : A LeadsTo (B Un A'); F : (B-A') LeadsTo B' |] ==> F : A LeadsTo (B' Un A')";
   285 \     ==> F : A LeadsTo (B' Un A')";
       
   286 by (rtac LeadsTo_cancel1 1);
   249 by (rtac LeadsTo_cancel1 1);
   287 by (assume_tac 2);
   250 by (assume_tac 2);
   288 by (asm_simp_tac (simpset() addsimps [Diff_Un2]) 1);
   251 by (asm_simp_tac (simpset() addsimps [Diff_Un2]) 1);
   289 qed "LeadsTo_cancel_Diff1";
   252 qed "LeadsTo_cancel_Diff1";
   290 
   253 
   291 
       
   292 (** The impossibility law **)
   254 (** The impossibility law **)
   293 
   255 
   294 (*The set "A" may be non-empty, but it contains no reachable states*)
   256 (*The set "A" may be non-empty, but it contains no reachable states*)
   295 Goal "F : A LeadsTo 0 ==> F : Always (state -A)";
   257 Goal "F : A LeadsTo 0 ==> F : Always (state -A)";
   296 by (full_simp_tac (simpset() 
   258 by (full_simp_tac (simpset() 
   297            addsimps [LeadsTo_def,Always_eq_includes_reachable]) 1);
   259            addsimps [LeadsTo_def,Always_eq_includes_reachable]) 1);
   298 by (Clarify_tac 1);
   260 by (cut_facts_tac [reachable_type] 1);
   299 by (forward_tac [reachableD] 1);
   261 by (auto_tac (claset() addSDs [leadsTo_empty], simpset()));
   300 by (auto_tac (claset() addSDs [leadsTo_empty],
       
   301               simpset() addsimps [condition_def]));
       
   302 qed "LeadsTo_empty";
   262 qed "LeadsTo_empty";
   303 
   263 
   304 (** PSP: Progress-Safety-Progress **)
   264 (** PSP: Progress-Safety-Progress **)
   305 
   265 
   306 (*Special case of PSP: Misra's "stable conjunction"*)
   266 (*Special case of PSP: Misra's "stable conjunction"*)
   307 Goal "[| F : A LeadsTo A';  F : Stable(B) |] \
   267 Goal "[| F : A LeadsTo A';  F : Stable(B) |]==> F:(A Int B) LeadsTo (A' Int B)";
   308 \     ==> F : (A Int B) LeadsTo (A' Int B)";
   268 by (asm_full_simp_tac (simpset() addsimps [LeadsTo_def, Stable_eq_stable]) 1);
   309 by (forward_tac [StableD2] 1);
       
   310 by (rotate_tac ~1 1);
       
   311 by (asm_full_simp_tac
       
   312     (simpset() addsimps [LeadsTo_eq_leadsTo, Stable_eq_stable]) 1);
       
   313 by (Clarify_tac 1);
   269 by (Clarify_tac 1);
   314 by (dtac psp_stable 1);
   270 by (dtac psp_stable 1);
   315 by (assume_tac 1);
   271 by (REPEAT(asm_full_simp_tac (simpset() addsimps (Int_absorb::Int_ac)) 1));
   316 by (asm_full_simp_tac (simpset() addsimps (Int_absorb::Int_ac)) 1);
       
   317 qed "PSP_Stable";
   272 qed "PSP_Stable";
   318 
   273 
   319 Goal "[| F : A LeadsTo A'; F : Stable(B) |] \
   274 Goal "[| F : A LeadsTo A'; F : Stable(B) |] ==> F : (B Int A) LeadsTo (B Int A')";
   320 \     ==> F : (B Int A) LeadsTo (B Int A')";
       
   321 by (asm_simp_tac (simpset() addsimps PSP_Stable::Int_ac) 1);
   275 by (asm_simp_tac (simpset() addsimps PSP_Stable::Int_ac) 1);
   322 qed "PSP_Stable2";
   276 qed "PSP_Stable2";
   323 
   277 
   324 Goal "[| F : A LeadsTo A'; F : B Co B' |] \
   278 Goal "[| F:A LeadsTo A'; F:B Co B'|]==> F : (A Int B') LeadsTo ((A' Int B) Un (B' - B))";
   325 \     ==> F : (A Int B') LeadsTo ((A' Int B) Un (B' - B))";
   279 by (full_simp_tac (simpset() addsimps [LeadsTo_def, Constrains_eq_constrains]) 1);
   326 by (full_simp_tac
       
   327     (simpset() addsimps [LeadsTo_def, Constrains_eq_constrains]) 1);
       
   328 by (blast_tac (claset() addDs [psp] addIs [leadsTo_weaken]) 1);
   280 by (blast_tac (claset() addDs [psp] addIs [leadsTo_weaken]) 1);
   329 qed "PSP";
   281 qed "PSP";
   330 
   282 
   331 Goal "[| F : A LeadsTo A'; F : B Co B' |] \
   283 Goal "[| F : A LeadsTo A'; F : B Co B' |]==> F:(B' Int A) LeadsTo ((B Int A') Un (B' - B))";
   332 \     ==> F : (B' Int A) LeadsTo ((B Int A') Un (B' - B))";
       
   333 by (asm_simp_tac (simpset() addsimps PSP::Int_ac) 1);
   284 by (asm_simp_tac (simpset() addsimps PSP::Int_ac) 1);
   334 qed "PSP2";
   285 qed "PSP2";
   335 
   286 
   336 
       
   337 Goal
   287 Goal
   338 "[| F : A LeadsTo A'; F : B Unless B' |] \
   288 "[| F : A LeadsTo A'; F : B Unless B'|]==> F:(A Int B) LeadsTo ((A' Int B) Un B')";
   339 \     ==> F : (A Int B) LeadsTo ((A' Int B) Un B')";
       
   340 by (forward_tac [LeadsToD] 1);
       
   341 by (forward_tac [UnlessD] 1);
       
   342 by (rewrite_goals_tac [Unless_def]);
   289 by (rewrite_goals_tac [Unless_def]);
   343 by (dtac PSP 1);
   290 by (dtac PSP 1);
   344 by (assume_tac 1);
   291 by (assume_tac 1);
   345 by (blast_tac (claset() 
   292 by (blast_tac (claset() addIs [LeadsTo_Diff, LeadsTo_weaken, subset_imp_LeadsTo]) 1);
   346         addIs [LeadsTo_Diff, 
       
   347                LeadsTo_weaken, subset_imp_LeadsTo]) 1);
       
   348 qed "PSP_Unless";
   293 qed "PSP_Unless";
   349 
   294 
   350 (*** Induction rules ***)
   295 (*** Induction rules ***)
   351 
   296 
   352 (** Meta or object quantifier ????? **)
   297 (** Meta or object quantifier ????? **)
   353 Goal "[| wf(r);     \
   298 Goal "[| wf(r);     \
   354 \        ALL m:I. F : (A Int f-``{m}) LeadsTo                     \
   299 \        ALL m:I. F : (A Int f-``{m}) LeadsTo                     \
   355 \                           ((A Int f-``(converse(r) `` {m})) Un B); \
   300 \                           ((A Int f-``(converse(r) `` {m})) Un B); \
   356 \        field(r)<=I; A<=f-``I; F:program; A:condition; B:condition |] \
   301 \        field(r)<=I; A<=f-``I; F:program |] \
   357 \     ==> F : A LeadsTo B";
   302 \     ==> F : A LeadsTo B";
   358 by (full_simp_tac (simpset() addsimps [LeadsTo_eq_leadsTo]) 1);
   303 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1);
   359 by Safe_tac;
   304 by Safe_tac;
   360 by (eres_inst_tac [("I", "I"), ("f", "f")] leadsTo_wf_induct 1);
   305 by (eres_inst_tac [("I", "I"), ("f", "f")] leadsTo_wf_induct 1);
   361 by (ALLGOALS(Clarify_tac));
   306 by (ALLGOALS(Clarify_tac));
   362 by (dres_inst_tac [("x", "m")] bspec 4);
   307 by (dres_inst_tac [("x", "m")] bspec 2);
   363 by Safe_tac;
   308 by Safe_tac;
   364 by (res_inst_tac [("A'", 
   309 by (res_inst_tac 
   365            "reachable(F) Int (A Int f -``(converse(r)``{m}) Un B)")]  
   310 [("A'", "reachable(F) Int (A Int f -``(converse(r)``{m}) Un B)")]leadsTo_weaken_R 2);
   366         leadsTo_weaken_R 4);
   311 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 2);
   367 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 4);
   312 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 3);
   368 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 5);
       
   369 by (REPEAT(Blast_tac 1));
   313 by (REPEAT(Blast_tac 1));
   370 qed "LeadsTo_wf_induct";
   314 qed "LeadsTo_wf_induct";
   371 
   315 
   372 
   316 
   373 
   317 
   374 Goal "[| ALL m:nat. F:(A Int f-``{m}) LeadsTo ((A Int f-``lessThan(m,nat)) Un B); \
   318 Goal "[| ALL m:nat. F:(A Int f-``{m}) LeadsTo ((A Int f-``lessThan(m,nat)) Un B); \
   375 \     A<=f-``nat; F:program; A:condition; B:condition |] \
   319 \     A<=f-``nat; F:program |] ==> F : A LeadsTo B";
   376 \     ==> F : A LeadsTo B";
       
   377 by (res_inst_tac [("A1", "nat"), ("I", "nat")] (wf_less_than RS LeadsTo_wf_induct) 1);
   320 by (res_inst_tac [("A1", "nat"), ("I", "nat")] (wf_less_than RS LeadsTo_wf_induct) 1);
   378 by (ALLGOALS(asm_full_simp_tac 
   321 by (ALLGOALS(asm_full_simp_tac 
   379           (simpset() addsimps [nat_less_than_field])));
   322           (simpset() addsimps [nat_less_than_field])));
   380 by (Clarify_tac 1);
   323 by (Clarify_tac 1);
   381 by (ALLGOALS(asm_full_simp_tac 
   324 by (ALLGOALS(asm_full_simp_tac 
   396 
   339 
   397 Goal "[| F : A LeadsTo (A' Un C);  F : A' Co (A' Un C); \
   340 Goal "[| F : A LeadsTo (A' Un C);  F : A' Co (A' Un C); \
   398 \        F : B LeadsTo (B' Un C);  F : B' Co (B' Un C) |] \
   341 \        F : B LeadsTo (B' Un C);  F : B' Co (B' Un C) |] \
   399 \     ==> F : (A Int B) LeadsTo ((A' Int B') Un C)";
   342 \     ==> F : (A Int B) LeadsTo ((A' Int B') Un C)";
   400 by (full_simp_tac
   343 by (full_simp_tac
   401     (simpset() addsimps [LeadsTo_eq_leadsTo, Constrains_eq_constrains, 
   344     (simpset() addsimps [LeadsTo_def, Constrains_eq_constrains, 
   402                          Int_Un_distrib2 RS sym]) 1);
   345                          Int_Un_distrib2 RS sym]) 1);
   403 by Safe_tac;
   346 by Safe_tac;
   404 by (REPEAT(Blast_tac 2));
   347 by (REPEAT(Blast_tac 2));
   405 by (blast_tac (claset() addIs [completion, leadsTo_weaken]) 1);
   348 by (blast_tac (claset() addIs [completion, leadsTo_weaken]) 1);
   406 qed "Completion";
   349 qed "Completion";
   407 
   350 
   408 
   351 Goal "[| I:Fin(X);F:program |] \
   409 Goal "[| I:Fin(X);F:program; C:condition |] \
       
   410 \     ==> (ALL i:I. F : (A(i)) LeadsTo (A'(i) Un C)) -->  \
   352 \     ==> (ALL i:I. F : (A(i)) LeadsTo (A'(i) Un C)) -->  \
   411 \         (ALL i:I. F : (A'(i)) Co (A'(i) Un C)) --> \
   353 \         (ALL i:I. F : (A'(i)) Co (A'(i) Un C)) --> \
   412 \         F : (INT i:I. A(i)) LeadsTo ((INT i:I. A'(i)) Un C)";
   354 \         F : (INT i:I. A(i)) LeadsTo ((INT i:I. A'(i)) Un C)";
   413 by (etac Fin_induct 1);
   355 by (etac Fin_induct 1);
   414 by Auto_tac;
   356 by (auto_tac (claset(), simpset() addsimps [Inter_0]));
   415 by (case_tac "y=0" 1);
   357 by (case_tac "y=0" 1);
   416 by Auto_tac;
   358 by Auto_tac;
   417 by (etac not_emptyE 1);
   359 by (etac not_emptyE 1);
   418 by (subgoal_tac "Inter(cons(A(x), RepFun(y, A)))= A(x) Int Inter(RepFun(y,A)) &\
   360 by (subgoal_tac "Inter(cons(A(x), RepFun(y, A)))= A(x) Int Inter(RepFun(y,A)) &\
   419                \ Inter(cons(A'(x), RepFun(y, A')))= A'(x) Int Inter(RepFun(y,A'))" 1);
   361                \ Inter(cons(A'(x), RepFun(y, A')))= A'(x) Int Inter(RepFun(y,A'))" 1);
   420 by (Blast_tac 2);
   362 by (Blast_tac 2);
   421 by (Asm_simp_tac 1);
   363 by (Asm_simp_tac 1);
   422 by (rtac Completion 1);
   364 by (rtac Completion 1);
   423 by (subgoal_tac "Inter(RepFun(y, A')) Un C = (INT x:RepFun(y, A'). x Un C)" 4);
   365 by (subgoal_tac "Inter(RepFun(y, A')) Un C = (INT x:RepFun(y, A'). x Un C)" 4);
   424 by (Blast_tac 5);
       
   425 by (Asm_simp_tac 4);
   366 by (Asm_simp_tac 4);
   426 by (rtac Constrains_INT 4);
   367 by (rtac Constrains_INT 4);
   427 by (REPEAT(Blast_tac 1));
   368 by (REPEAT(Blast_tac 1));
   428 val lemma = result();
   369 val lemma = result();
   429 
   370 
   430 
       
   431 val prems = Goal
   371 val prems = Goal
   432      "[| I:Fin(X); !!i. i:I ==> F : A(i) LeadsTo (A'(i) Un C); \
   372      "[| I:Fin(X); !!i. i:I ==> F : A(i) LeadsTo (A'(i) Un C); \
   433 \        !!i. i:I ==> F : A'(i) Co (A'(i) Un C); \
   373 \        !!i. i:I ==> F : A'(i) Co (A'(i) Un C); \
   434 \        F:program; C:condition |]   \
   374 \        F:program |]   \
   435 \     ==> F : (INT i:I. A(i)) LeadsTo ((INT i:I. A'(i)) Un C)";
   375 \     ==> F : (INT i:I. A(i)) LeadsTo ((INT i:I. A'(i)) Un C)";
   436 by (blast_tac (claset() addIs (lemma RS mp RS mp)::prems) 1);
   376 by (blast_tac (claset() addIs (lemma RS mp RS mp)::prems) 1);
   437 qed "Finite_completion";
   377 qed "Finite_completion";
   438 
   378 
   439 Goalw [Stable_def]
   379 Goalw [Stable_def]
   440      "[| F : A LeadsTo A';  F : Stable(A');   \
   380      "[| F : A LeadsTo A';  F : Stable(A');   \
   441 \        F : B LeadsTo B';  F : Stable(B') |] \
   381 \        F : B LeadsTo B';  F : Stable(B') |] \
   442 \   ==> F : (A Int B) LeadsTo (A' Int B')";
   382 \   ==> F : (A Int B) LeadsTo (A' Int B')";
   443 by (res_inst_tac [("C1", "0")] (Completion RS LeadsTo_weaken_R) 1);
   383 by (res_inst_tac [("C1", "0")] (Completion RS LeadsTo_weaken_R) 1);
   444 by (REPEAT(blast_tac (claset() addDs [LeadsToD,ConstrainsD]) 5));
   384 by (Asm_full_simp_tac 5);
   445 by (ALLGOALS(Asm_full_simp_tac));
   385 by (rtac subset_refl 5);
       
   386 by Auto_tac;
   446 qed "Stable_completion";
   387 qed "Stable_completion";
   447 
       
   448 
   388 
   449 val prems = Goalw [Stable_def]
   389 val prems = Goalw [Stable_def]
   450      "[| I:Fin(X); \
   390      "[| I:Fin(X); \
   451 \        ALL i:I. F : A(i) LeadsTo A'(i); \
   391 \        (!!i. i:I ==> F : A(i) LeadsTo A'(i)); \
   452 \        ALL i:I.  F: Stable(A'(i));   F:program  |] \
   392 \        (!!i. i:I ==>F: Stable(A'(i)));   F:program  |] \
   453 \     ==> F : (INT i:I. A(i)) LeadsTo (INT i:I. A'(i))";
   393 \     ==> F : (INT i:I. A(i)) LeadsTo (INT i:I. A'(i))";
   454 by (subgoal_tac "(INT i:I. A'(i)):condition" 1);
       
   455 by (blast_tac (claset() addDs  [LeadsToD,ConstrainsD]) 2);
       
   456 by (res_inst_tac [("C1", "0")] (Finite_completion RS LeadsTo_weaken_R) 1);
   394 by (res_inst_tac [("C1", "0")] (Finite_completion RS LeadsTo_weaken_R) 1);
   457 by (assume_tac 7);
   395 by (ALLGOALS(Simp_tac));
   458 by (ALLGOALS(Asm_full_simp_tac));
   396 by (rtac subset_refl 5);
   459 by (ALLGOALS (Blast_tac));
   397 by (REPEAT(blast_tac (claset() addIs prems) 1));
   460 qed "Finite_stable_completion";
   398 qed "Finite_stable_completion";
   461 
   399 
   462 
   400 
   463 (*proves "ensures/leadsTo" properties when the program is specified*)
   401 (*proves "ensures/leadsTo" properties when the program is specified*)
   464 fun ensures_tac sact = 
   402 fun ensures_tac sact = 
   479              Asm_full_simp_tac 3, rtac conjI 3, Simp_tac 4,
   417              Asm_full_simp_tac 3, rtac conjI 3, Simp_tac 4,
   480              REPEAT (rtac update_type2 3),
   418              REPEAT (rtac update_type2 3),
   481              constrains_tac 1,
   419              constrains_tac 1,
   482              ALLGOALS Clarify_tac,
   420              ALLGOALS Clarify_tac,
   483              ALLGOALS (asm_full_simp_tac 
   421              ALLGOALS (asm_full_simp_tac 
   484             (simpset() addsimps [condition_def])),
   422             (simpset() addsimps [st_set_def])),
   485             ALLGOALS Clarify_tac]);
   423                         ALLGOALS Clarify_tac,
   486 
   424             ALLGOALS (Asm_full_simp_tac)]);
       
   425