| 
24326
 | 
     1  | 
(*  Title:      HOL/ex/MT.thy
  | 
| 
969
 | 
     2  | 
    ID:         $Id$
  | 
| 
1476
 | 
     3  | 
    Author:     Jacob Frost, Cambridge University Computer Laboratory
  | 
| 
969
 | 
     4  | 
    Copyright   1993  University of Cambridge
  | 
| 
 | 
     5  | 
  | 
| 
 | 
     6  | 
Based upon the article
  | 
| 
 | 
     7  | 
    Robin Milner and Mads Tofte,
  | 
| 
 | 
     8  | 
    Co-induction in Relational Semantics,
  | 
| 
 | 
     9  | 
    Theoretical Computer Science 87 (1991), pages 209-220.
  | 
| 
 | 
    10  | 
  | 
| 
 | 
    11  | 
Written up as
  | 
| 
 | 
    12  | 
    Jacob Frost, A Case Study of Co_induction in Isabelle/HOL
  | 
| 
 | 
    13  | 
    Report 308, Computer Lab, University of Cambridge (1993).
  | 
| 
 | 
    14  | 
*)
  | 
| 
 | 
    15  | 
  | 
| 
24326
 | 
    16  | 
header {* Milner-Tofte: Co-induction in Relational Semantics *}
 | 
| 
 | 
    17  | 
  | 
| 
17289
 | 
    18  | 
theory MT
  | 
| 
 | 
    19  | 
imports Main
  | 
| 
 | 
    20  | 
begin
  | 
| 
969
 | 
    21  | 
  | 
| 
17289
 | 
    22  | 
typedecl Const
  | 
| 
969
 | 
    23  | 
  | 
| 
17289
 | 
    24  | 
typedecl ExVar
  | 
| 
 | 
    25  | 
typedecl Ex
  | 
| 
969
 | 
    26  | 
  | 
| 
17289
 | 
    27  | 
typedecl TyConst
  | 
| 
 | 
    28  | 
typedecl Ty
  | 
| 
969
 | 
    29  | 
  | 
| 
17289
 | 
    30  | 
typedecl Clos
  | 
| 
 | 
    31  | 
typedecl Val
  | 
| 
969
 | 
    32  | 
  | 
| 
17289
 | 
    33  | 
typedecl ValEnv
  | 
| 
 | 
    34  | 
typedecl TyEnv
  | 
| 
969
 | 
    35  | 
  | 
| 
 | 
    36  | 
consts
  | 
| 
15450
 | 
    37  | 
  c_app :: "[Const, Const] => Const"
  | 
| 
969
 | 
    38  | 
  | 
| 
15450
 | 
    39  | 
  e_const :: "Const => Ex"
  | 
| 
 | 
    40  | 
  e_var :: "ExVar => Ex"
  | 
| 
 | 
    41  | 
  e_fn :: "[ExVar, Ex] => Ex" ("fn _ => _" [0,51] 1000)
 | 
| 
 | 
    42  | 
  e_fix :: "[ExVar, ExVar, Ex] => Ex" ("fix _ ( _ ) = _" [0,51,51] 1000)
 | 
| 
17289
 | 
    43  | 
  e_app :: "[Ex, Ex] => Ex" ("_ @@ _" [51,51] 1000)
 | 
| 
15450
 | 
    44  | 
  e_const_fst :: "Ex => Const"
  | 
| 
969
 | 
    45  | 
  | 
| 
15450
 | 
    46  | 
  t_const :: "TyConst => Ty"
  | 
| 
 | 
    47  | 
  t_fun :: "[Ty, Ty] => Ty" ("_ -> _" [51,51] 1000)
 | 
| 
969
 | 
    48  | 
  | 
| 
15450
 | 
    49  | 
  v_const :: "Const => Val"
  | 
| 
 | 
    50  | 
  v_clos :: "Clos => Val"
  | 
| 
17289
 | 
    51  | 
  | 
| 
1376
 | 
    52  | 
  ve_emp :: ValEnv
  | 
| 
15450
 | 
    53  | 
  ve_owr :: "[ValEnv, ExVar, Val] => ValEnv" ("_ + { _ |-> _ }" [36,0,0] 50)
 | 
| 
 | 
    54  | 
  ve_dom :: "ValEnv => ExVar set"
  | 
| 
 | 
    55  | 
  ve_app :: "[ValEnv, ExVar] => Val"
  | 
| 
969
 | 
    56  | 
  | 
| 
15450
 | 
    57  | 
  clos_mk :: "[ExVar, Ex, ValEnv] => Clos" ("<| _ , _ , _ |>" [0,0,0] 1000)
 | 
| 
969
 | 
    58  | 
  | 
| 
1376
 | 
    59  | 
  te_emp :: TyEnv
  | 
| 
15450
 | 
    60  | 
  te_owr :: "[TyEnv, ExVar, Ty] => TyEnv" ("_ + { _ |=> _ }" [36,0,0] 50)
 | 
| 
 | 
    61  | 
  te_app :: "[TyEnv, ExVar] => Ty"
  | 
| 
 | 
    62  | 
  te_dom :: "TyEnv => ExVar set"
  | 
| 
969
 | 
    63  | 
  | 
| 
 | 
    64  | 
  eval_fun :: "((ValEnv * Ex) * Val) set => ((ValEnv * Ex) * Val) set"
  | 
| 
 | 
    65  | 
  eval_rel :: "((ValEnv * Ex) * Val) set"
  | 
| 
15450
 | 
    66  | 
  eval :: "[ValEnv, Ex, Val] => bool" ("_ |- _ ---> _" [36,0,36] 50)
 | 
| 
969
 | 
    67  | 
  | 
| 
 | 
    68  | 
  elab_fun :: "((TyEnv * Ex) * Ty) set => ((TyEnv * Ex) * Ty) set"
  | 
| 
 | 
    69  | 
  elab_rel :: "((TyEnv * Ex) * Ty) set"
  | 
| 
15450
 | 
    70  | 
  elab :: "[TyEnv, Ex, Ty] => bool" ("_ |- _ ===> _" [36,0,36] 50)
 | 
| 
17289
 | 
    71  | 
  | 
| 
15450
 | 
    72  | 
  isof :: "[Const, Ty] => bool" ("_ isof _" [36,36] 50)
 | 
| 
 | 
    73  | 
  isof_env :: "[ValEnv,TyEnv] => bool" ("_ isofenv _")
 | 
| 
969
 | 
    74  | 
  | 
| 
 | 
    75  | 
  hasty_fun :: "(Val * Ty) set => (Val * Ty) set"
  | 
| 
 | 
    76  | 
  hasty_rel :: "(Val * Ty) set"
  | 
| 
15450
 | 
    77  | 
  hasty :: "[Val, Ty] => bool" ("_ hasty _" [36,36] 50)
 | 
| 
 | 
    78  | 
  hasty_env :: "[ValEnv,TyEnv] => bool" ("_ hastyenv _ " [36,36] 35)
 | 
| 
969
 | 
    79  | 
  | 
| 
17289
 | 
    80  | 
axioms
  | 
| 
969
 | 
    81  | 
  | 
| 
17289
 | 
    82  | 
(*
  | 
| 
969
 | 
    83  | 
  Expression constructors must be injective, distinct and it must be possible
  | 
| 
 | 
    84  | 
  to do induction over expressions.
  | 
| 
 | 
    85  | 
*)
  | 
| 
 | 
    86  | 
  | 
| 
 | 
    87  | 
(* All the constructors are injective *)
  | 
| 
 | 
    88  | 
  | 
| 
17289
 | 
    89  | 
  e_const_inj: "e_const(c1) = e_const(c2) ==> c1 = c2"
  | 
| 
 | 
    90  | 
  e_var_inj: "e_var(ev1) = e_var(ev2) ==> ev1 = ev2"
  | 
| 
 | 
    91  | 
  e_fn_inj: "fn ev1 => e1 = fn ev2 => e2 ==> ev1 = ev2 & e1 = e2"
  | 
| 
 | 
    92  | 
  e_fix_inj:
  | 
| 
 | 
    93  | 
    " fix ev11e(v12) = e1 = fix ev21(ev22) = e2 ==>
  | 
| 
 | 
    94  | 
     ev11 = ev21 & ev12 = ev22 & e1 = e2
  | 
| 
1151
 | 
    95  | 
   "
  | 
| 
17289
 | 
    96  | 
  e_app_inj: "e11 @@ e12 = e21 @@ e22 ==> e11 = e21 & e12 = e22"
  | 
| 
969
 | 
    97  | 
  | 
| 
 | 
    98  | 
(* All constructors are distinct *)
  | 
| 
 | 
    99  | 
  | 
| 
17289
 | 
   100  | 
  e_disj_const_var: "~e_const(c) = e_var(ev)"
  | 
| 
 | 
   101  | 
  e_disj_const_fn: "~e_const(c) = fn ev => e"
  | 
| 
 | 
   102  | 
  e_disj_const_fix: "~e_const(c) = fix ev1(ev2) = e"
  | 
| 
 | 
   103  | 
  e_disj_const_app: "~e_const(c) = e1 @@ e2"
  | 
| 
 | 
   104  | 
  e_disj_var_fn: "~e_var(ev1) = fn ev2 => e"
  | 
| 
 | 
   105  | 
  e_disj_var_fix: "~e_var(ev) = fix ev1(ev2) = e"
  | 
| 
 | 
   106  | 
  e_disj_var_app: "~e_var(ev) = e1 @@ e2"
  | 
| 
 | 
   107  | 
  e_disj_fn_fix: "~fn ev1 => e1 = fix ev21(ev22) = e2"
  | 
| 
 | 
   108  | 
  e_disj_fn_app: "~fn ev1 => e1 = e21 @@ e22"
  | 
| 
 | 
   109  | 
  e_disj_fix_app: "~fix ev11(ev12) = e1 = e21 @@ e22"
  | 
| 
969
 | 
   110  | 
  | 
| 
 | 
   111  | 
(* Strong elimination, induction on expressions  *)
  | 
| 
 | 
   112  | 
  | 
| 
17289
 | 
   113  | 
  e_ind:
  | 
| 
 | 
   114  | 
    " [|  !!ev. P(e_var(ev));
  | 
| 
 | 
   115  | 
         !!c. P(e_const(c));
  | 
| 
 | 
   116  | 
         !!ev e. P(e) ==> P(fn ev => e);
  | 
| 
 | 
   117  | 
         !!ev1 ev2 e. P(e) ==> P(fix ev1(ev2) = e);
  | 
| 
 | 
   118  | 
         !!e1 e2. P(e1) ==> P(e2) ==> P(e1 @@ e2)
  | 
| 
 | 
   119  | 
     |] ==>
  | 
| 
 | 
   120  | 
   P(e)
  | 
| 
1151
 | 
   121  | 
   "
  | 
| 
969
 | 
   122  | 
  | 
| 
 | 
   123  | 
(* Types - same scheme as for expressions *)
  | 
| 
 | 
   124  | 
  | 
| 
17289
 | 
   125  | 
(* All constructors are injective *)
  | 
| 
969
 | 
   126  | 
  | 
| 
17289
 | 
   127  | 
  t_const_inj: "t_const(c1) = t_const(c2) ==> c1 = c2"
  | 
| 
 | 
   128  | 
  t_fun_inj: "t11 -> t12 = t21 -> t22 ==> t11 = t21 & t12 = t22"
  | 
| 
969
 | 
   129  | 
  | 
| 
 | 
   130  | 
(* All constructors are distinct, not needed so far ... *)
  | 
| 
 | 
   131  | 
  | 
| 
 | 
   132  | 
(* Strong elimination, induction on types *)
  | 
| 
 | 
   133  | 
  | 
| 
17289
 | 
   134  | 
 t_ind:
  | 
| 
 | 
   135  | 
    "[| !!p. P(t_const p); !!t1 t2. P(t1) ==> P(t2) ==> P(t_fun t1 t2) |]
  | 
| 
1151
 | 
   136  | 
    ==> P(t)"
  | 
| 
969
 | 
   137  | 
  | 
| 
 | 
   138  | 
  | 
| 
 | 
   139  | 
(* Values - same scheme again *)
  | 
| 
 | 
   140  | 
  | 
| 
17289
 | 
   141  | 
(* All constructors are injective *)
  | 
| 
969
 | 
   142  | 
  | 
| 
17289
 | 
   143  | 
  v_const_inj: "v_const(c1) = v_const(c2) ==> c1 = c2"
  | 
| 
 | 
   144  | 
  v_clos_inj:
  | 
| 
 | 
   145  | 
    " v_clos(<|ev1,e1,ve1|>) = v_clos(<|ev2,e2,ve2|>) ==>
  | 
| 
1151
 | 
   146  | 
     ev1 = ev2 & e1 = e2 & ve1 = ve2"
  | 
| 
17289
 | 
   147  | 
  | 
| 
969
 | 
   148  | 
(* All constructors are distinct *)
  | 
| 
 | 
   149  | 
  | 
| 
17289
 | 
   150  | 
  v_disj_const_clos: "~v_const(c) = v_clos(cl)"
  | 
| 
969
 | 
   151  | 
  | 
| 
15450
 | 
   152  | 
(* No induction on values: they are a codatatype! ... *)
  | 
| 
969
 | 
   153  | 
  | 
| 
 | 
   154  | 
  | 
| 
17289
 | 
   155  | 
(*
  | 
| 
969
 | 
   156  | 
  Value environments bind variables to values. Only the following trivial
  | 
| 
 | 
   157  | 
  properties are needed.
  | 
| 
 | 
   158  | 
*)
  | 
| 
 | 
   159  | 
  | 
| 
17289
 | 
   160  | 
  ve_dom_owr: "ve_dom(ve + {ev |-> v}) = ve_dom(ve) Un {ev}"
 | 
| 
 | 
   161  | 
  | 
| 
 | 
   162  | 
  ve_app_owr1: "ve_app (ve + {ev |-> v}) ev=v"
 | 
| 
 | 
   163  | 
  ve_app_owr2: "~ev1=ev2 ==> ve_app (ve+{ev1 |-> v}) ev2=ve_app ve ev2"
 | 
| 
969
 | 
   164  | 
  | 
| 
 | 
   165  | 
  | 
| 
 | 
   166  | 
(* Type Environments bind variables to types. The following trivial
  | 
| 
 | 
   167  | 
properties are needed.  *)
  | 
| 
 | 
   168  | 
  | 
| 
17289
 | 
   169  | 
  te_dom_owr: "te_dom(te + {ev |=> t}) = te_dom(te) Un {ev}"
 | 
| 
 | 
   170  | 
  | 
| 
 | 
   171  | 
  te_app_owr1: "te_app (te + {ev |=> t}) ev=t"
 | 
| 
 | 
   172  | 
  te_app_owr2: "~ev1=ev2 ==> te_app (te+{ev1 |=> t}) ev2=te_app te ev2"
 | 
| 
969
 | 
   173  | 
  | 
| 
 | 
   174  | 
  | 
| 
 | 
   175  | 
(* The dynamic semantics is defined inductively by a set of inference
  | 
| 
 | 
   176  | 
rules.  These inference rules allows one to draw conclusions of the form ve
  | 
| 
 | 
   177  | 
|- e ---> v, read the expression e evaluates to the value v in the value
  | 
| 
 | 
   178  | 
environment ve.  Therefore the relation _ |- _ ---> _ is defined in Isabelle
  | 
| 
 | 
   179  | 
as the least fixpoint of the functor eval_fun below.  From this definition
  | 
| 
 | 
   180  | 
introduction rules and a strong elimination (induction) rule can be
  | 
| 
17289
 | 
   181  | 
derived.
  | 
| 
969
 | 
   182  | 
*)
  | 
| 
 | 
   183  | 
  | 
| 
17289
 | 
   184  | 
defs
  | 
| 
 | 
   185  | 
  eval_fun_def:
  | 
| 
 | 
   186  | 
    " eval_fun(s) ==
  | 
| 
 | 
   187  | 
     { pp.
 | 
| 
 | 
   188  | 
       (? ve c. pp=((ve,e_const(c)),v_const(c))) |
  | 
| 
1151
 | 
   189  | 
       (? ve x. pp=((ve,e_var(x)),ve_app ve x) & x:ve_dom(ve)) |
  | 
| 
17289
 | 
   190  | 
       (? ve e x. pp=((ve,fn x => e),v_clos(<|x,e,ve|>)))|
  | 
| 
 | 
   191  | 
       ( ? ve e x f cl.
  | 
| 
 | 
   192  | 
           pp=((ve,fix f(x) = e),v_clos(cl)) &
  | 
| 
 | 
   193  | 
           cl=<|x, e, ve+{f |-> v_clos(cl)} |>
 | 
| 
 | 
   194  | 
       ) |
  | 
| 
 | 
   195  | 
       ( ? ve e1 e2 c1 c2.
  | 
| 
 | 
   196  | 
           pp=((ve,e1 @@ e2),v_const(c_app c1 c2)) &
  | 
| 
 | 
   197  | 
           ((ve,e1),v_const(c1)):s & ((ve,e2),v_const(c2)):s
  | 
| 
 | 
   198  | 
       ) |
  | 
| 
 | 
   199  | 
       ( ? ve vem e1 e2 em xm v v2.
  | 
| 
 | 
   200  | 
           pp=((ve,e1 @@ e2),v) &
  | 
| 
 | 
   201  | 
           ((ve,e1),v_clos(<|xm,em,vem|>)):s &
  | 
| 
 | 
   202  | 
           ((ve,e2),v2):s &
  | 
| 
 | 
   203  | 
           ((vem+{xm |-> v2},em),v):s
 | 
| 
 | 
   204  | 
       )
  | 
| 
1151
 | 
   205  | 
     }"
  | 
| 
969
 | 
   206  | 
  | 
| 
17289
 | 
   207  | 
  eval_rel_def: "eval_rel == lfp(eval_fun)"
  | 
| 
 | 
   208  | 
  eval_def: "ve |- e ---> v == ((ve,e),v):eval_rel"
  | 
| 
969
 | 
   209  | 
  | 
| 
 | 
   210  | 
(* The static semantics is defined in the same way as the dynamic
  | 
| 
 | 
   211  | 
semantics.  The relation te |- e ===> t express the expression e has the
  | 
| 
 | 
   212  | 
type t in the type environment te.
  | 
| 
 | 
   213  | 
*)
  | 
| 
 | 
   214  | 
  | 
| 
17289
 | 
   215  | 
  elab_fun_def:
  | 
| 
 | 
   216  | 
  "elab_fun(s) ==
  | 
| 
 | 
   217  | 
  { pp.
 | 
| 
 | 
   218  | 
    (? te c t. pp=((te,e_const(c)),t) & c isof t) |
  | 
| 
 | 
   219  | 
    (? te x. pp=((te,e_var(x)),te_app te x) & x:te_dom(te)) |
  | 
| 
 | 
   220  | 
    (? te x e t1 t2. pp=((te,fn x => e),t1->t2) & ((te+{x |=> t1},e),t2):s) |
 | 
| 
 | 
   221  | 
    (? te f x e t1 t2.
  | 
| 
 | 
   222  | 
       pp=((te,fix f(x)=e),t1->t2) & ((te+{f |=> t1->t2}+{x |=> t1},e),t2):s
 | 
| 
 | 
   223  | 
    ) |
  | 
| 
 | 
   224  | 
    (? te e1 e2 t1 t2.
  | 
| 
 | 
   225  | 
       pp=((te,e1 @@ e2),t2) & ((te,e1),t1->t2):s & ((te,e2),t1):s
  | 
| 
 | 
   226  | 
    )
  | 
| 
1151
 | 
   227  | 
  }"
  | 
| 
969
 | 
   228  | 
  | 
| 
17289
 | 
   229  | 
  elab_rel_def: "elab_rel == lfp(elab_fun)"
  | 
| 
 | 
   230  | 
  elab_def: "te |- e ===> t == ((te,e),t):elab_rel"
  | 
| 
969
 | 
   231  | 
  | 
| 
 | 
   232  | 
(* The original correspondence relation *)
  | 
| 
 | 
   233  | 
  | 
| 
17289
 | 
   234  | 
  isof_env_def:
  | 
| 
 | 
   235  | 
    " ve isofenv te ==
  | 
| 
 | 
   236  | 
     ve_dom(ve) = te_dom(te) &
  | 
| 
 | 
   237  | 
     ( ! x.
  | 
| 
 | 
   238  | 
         x:ve_dom(ve) -->
  | 
| 
 | 
   239  | 
         (? c. ve_app ve x = v_const(c) & c isof te_app te x)
  | 
| 
 | 
   240  | 
     )
  | 
| 
1151
 | 
   241  | 
   "
  | 
| 
969
 | 
   242  | 
  | 
| 
17289
 | 
   243  | 
axioms
  | 
| 
 | 
   244  | 
  isof_app: "[| c1 isof t1->t2; c2 isof t1 |] ==> c_app c1 c2 isof t2"
  | 
| 
969
 | 
   245  | 
  | 
| 
17289
 | 
   246  | 
defs
  | 
| 
969
 | 
   247  | 
(* The extented correspondence relation *)
  | 
| 
 | 
   248  | 
  | 
| 
17289
 | 
   249  | 
  hasty_fun_def:
  | 
| 
 | 
   250  | 
    " hasty_fun(r) ==
  | 
| 
 | 
   251  | 
     { p.
 | 
| 
 | 
   252  | 
       ( ? c t. p = (v_const(c),t) & c isof t) |
  | 
| 
 | 
   253  | 
       ( ? ev e ve t te.
  | 
| 
 | 
   254  | 
           p = (v_clos(<|ev,e,ve|>),t) &
  | 
| 
 | 
   255  | 
           te |- fn ev => e ===> t &
  | 
| 
 | 
   256  | 
           ve_dom(ve) = te_dom(te) &
  | 
| 
 | 
   257  | 
           (! ev1. ev1:ve_dom(ve) --> (ve_app ve ev1,te_app te ev1) : r)
  | 
| 
 | 
   258  | 
       )
  | 
| 
 | 
   259  | 
     }
  | 
| 
1151
 | 
   260  | 
   "
  | 
| 
969
 | 
   261  | 
  | 
| 
17289
 | 
   262  | 
  hasty_rel_def: "hasty_rel == gfp(hasty_fun)"
  | 
| 
 | 
   263  | 
  hasty_def: "v hasty t == (v,t) : hasty_rel"
  | 
| 
 | 
   264  | 
  hasty_env_def:
  | 
| 
 | 
   265  | 
    " ve hastyenv te ==
  | 
| 
 | 
   266  | 
     ve_dom(ve) = te_dom(te) &
  | 
| 
1151
 | 
   267  | 
     (! x. x: ve_dom(ve) --> ve_app ve x hasty te_app te x)"
  | 
| 
969
 | 
   268  | 
  | 
| 
24326
 | 
   269  | 
  | 
| 
 | 
   270  | 
(* ############################################################ *)
  | 
| 
 | 
   271  | 
(* Inference systems                                            *)
  | 
| 
 | 
   272  | 
(* ############################################################ *)
  | 
| 
 | 
   273  | 
  | 
| 
 | 
   274  | 
ML {*
 | 
| 
 | 
   275  | 
val infsys_mono_tac = REPEAT (ares_tac (@{thms basic_monos} @ [allI, impI]) 1)
 | 
| 
 | 
   276  | 
*}
  | 
| 
 | 
   277  | 
  | 
| 
 | 
   278  | 
lemma infsys_p1: "P a b ==> P (fst (a,b)) (snd (a,b))"
  | 
| 
 | 
   279  | 
  by simp
  | 
| 
 | 
   280  | 
  | 
| 
 | 
   281  | 
lemma infsys_p2: "P (fst (a,b)) (snd (a,b)) ==> P a b"
  | 
| 
 | 
   282  | 
  by simp
  | 
| 
 | 
   283  | 
  | 
| 
 | 
   284  | 
lemma infsys_pp1: "P a b c ==> P (fst(fst((a,b),c))) (snd(fst ((a,b),c))) (snd ((a,b),c))"
  | 
| 
 | 
   285  | 
  by simp
  | 
| 
 | 
   286  | 
  | 
| 
 | 
   287  | 
lemma infsys_pp2: "P (fst(fst((a,b),c))) (snd(fst((a,b),c))) (snd((a,b),c)) ==> P a b c"
  | 
| 
 | 
   288  | 
  by simp
  | 
| 
 | 
   289  | 
  | 
| 
 | 
   290  | 
  | 
| 
 | 
   291  | 
(* ############################################################ *)
  | 
| 
 | 
   292  | 
(* Fixpoints                                                    *)
  | 
| 
 | 
   293  | 
(* ############################################################ *)
  | 
| 
 | 
   294  | 
  | 
| 
 | 
   295  | 
(* Least fixpoints *)
  | 
| 
 | 
   296  | 
  | 
| 
 | 
   297  | 
lemma lfp_intro2: "[| mono(f); x:f(lfp(f)) |] ==> x:lfp(f)"
  | 
| 
 | 
   298  | 
apply (rule subsetD)
  | 
| 
 | 
   299  | 
apply (rule lfp_lemma2)
  | 
| 
 | 
   300  | 
apply assumption+
  | 
| 
 | 
   301  | 
done
  | 
| 
 | 
   302  | 
  | 
| 
 | 
   303  | 
lemma lfp_elim2:
  | 
| 
 | 
   304  | 
  assumes lfp: "x:lfp(f)"
  | 
| 
 | 
   305  | 
    and mono: "mono(f)"
  | 
| 
 | 
   306  | 
    and r: "!!y. y:f(lfp(f)) ==> P(y)"
  | 
| 
 | 
   307  | 
  shows "P(x)"
  | 
| 
 | 
   308  | 
apply (rule r)
  | 
| 
 | 
   309  | 
apply (rule subsetD)
  | 
| 
 | 
   310  | 
apply (rule lfp_lemma3)
  | 
| 
 | 
   311  | 
apply (rule mono)
  | 
| 
 | 
   312  | 
apply (rule lfp)
  | 
| 
 | 
   313  | 
done
  | 
| 
 | 
   314  | 
  | 
| 
 | 
   315  | 
lemma lfp_ind2:
  | 
| 
 | 
   316  | 
  assumes lfp: "x:lfp(f)"
  | 
| 
 | 
   317  | 
    and mono: "mono(f)"
  | 
| 
 | 
   318  | 
    and r: "!!y. y:f(lfp(f) Int {x. P(x)}) ==> P(y)"
 | 
| 
 | 
   319  | 
  shows "P(x)"
  | 
| 
 | 
   320  | 
apply (rule lfp_induct_set [OF lfp mono])
  | 
| 
 | 
   321  | 
apply (erule r)
  | 
| 
 | 
   322  | 
done
  | 
| 
 | 
   323  | 
  | 
| 
 | 
   324  | 
(* Greatest fixpoints *)
  | 
| 
 | 
   325  | 
  | 
| 
 | 
   326  | 
(* Note : "[| x:S; S <= f(S Un gfp(f)); mono(f) |] ==> x:gfp(f)" *)
  | 
| 
 | 
   327  | 
  | 
| 
 | 
   328  | 
lemma gfp_coind2:
  | 
| 
 | 
   329  | 
  assumes cih: "x:f({x} Un gfp(f))"
 | 
| 
 | 
   330  | 
    and monoh: "mono(f)"
  | 
| 
 | 
   331  | 
  shows "x:gfp(f)"
  | 
| 
 | 
   332  | 
apply (rule cih [THEN [2] gfp_upperbound [THEN subsetD]])
  | 
| 
 | 
   333  | 
apply (rule monoh [THEN monoD])
  | 
| 
 | 
   334  | 
apply (rule UnE [THEN subsetI])
  | 
| 
 | 
   335  | 
apply assumption
  | 
| 
 | 
   336  | 
apply (blast intro!: cih)
  | 
| 
 | 
   337  | 
apply (rule monoh [THEN monoD [THEN subsetD]])
  | 
| 
 | 
   338  | 
apply (rule Un_upper2)
  | 
| 
 | 
   339  | 
apply (erule monoh [THEN gfp_lemma2, THEN subsetD])
  | 
| 
 | 
   340  | 
done
  | 
| 
 | 
   341  | 
  | 
| 
 | 
   342  | 
lemma gfp_elim2:
  | 
| 
 | 
   343  | 
  assumes gfph: "x:gfp(f)"
  | 
| 
 | 
   344  | 
    and monoh: "mono(f)"
  | 
| 
 | 
   345  | 
    and caseh: "!!y. y:f(gfp(f)) ==> P(y)"
  | 
| 
 | 
   346  | 
  shows "P(x)"
  | 
| 
 | 
   347  | 
apply (rule caseh)
  | 
| 
 | 
   348  | 
apply (rule subsetD)
  | 
| 
 | 
   349  | 
apply (rule gfp_lemma2)
  | 
| 
 | 
   350  | 
apply (rule monoh)
  | 
| 
 | 
   351  | 
apply (rule gfph)
  | 
| 
 | 
   352  | 
done
  | 
| 
 | 
   353  | 
  | 
| 
 | 
   354  | 
(* ############################################################ *)
  | 
| 
 | 
   355  | 
(* Expressions                                                  *)
  | 
| 
 | 
   356  | 
(* ############################################################ *)
  | 
| 
 | 
   357  | 
  | 
| 
 | 
   358  | 
lemmas e_injs = e_const_inj e_var_inj e_fn_inj e_fix_inj e_app_inj
  | 
| 
 | 
   359  | 
  | 
| 
 | 
   360  | 
lemmas e_disjs =
  | 
| 
 | 
   361  | 
  e_disj_const_var
  | 
| 
 | 
   362  | 
  e_disj_const_fn
  | 
| 
 | 
   363  | 
  e_disj_const_fix
  | 
| 
 | 
   364  | 
  e_disj_const_app
  | 
| 
 | 
   365  | 
  e_disj_var_fn
  | 
| 
 | 
   366  | 
  e_disj_var_fix
  | 
| 
 | 
   367  | 
  e_disj_var_app
  | 
| 
 | 
   368  | 
  e_disj_fn_fix
  | 
| 
 | 
   369  | 
  e_disj_fn_app
  | 
| 
 | 
   370  | 
  e_disj_fix_app
  | 
| 
 | 
   371  | 
  | 
| 
 | 
   372  | 
lemmas e_disj_si = e_disjs  e_disjs [symmetric]
  | 
| 
 | 
   373  | 
  | 
| 
 | 
   374  | 
lemmas e_disj_se = e_disj_si [THEN notE]
  | 
| 
 | 
   375  | 
  | 
| 
 | 
   376  | 
(* ############################################################ *)
  | 
| 
 | 
   377  | 
(* Values                                                      *)
  | 
| 
 | 
   378  | 
(* ############################################################ *)
  | 
| 
 | 
   379  | 
  | 
| 
 | 
   380  | 
lemmas v_disjs = v_disj_const_clos
  | 
| 
 | 
   381  | 
lemmas v_disj_si = v_disjs  v_disjs [symmetric]
  | 
| 
 | 
   382  | 
lemmas v_disj_se = v_disj_si [THEN notE]
  | 
| 
 | 
   383  | 
  | 
| 
 | 
   384  | 
lemmas v_injs = v_const_inj v_clos_inj
  | 
| 
 | 
   385  | 
  | 
| 
 | 
   386  | 
(* ############################################################ *)
  | 
| 
 | 
   387  | 
(* Evaluations                                                  *)
  | 
| 
 | 
   388  | 
(* ############################################################ *)
  | 
| 
 | 
   389  | 
  | 
| 
 | 
   390  | 
(* Monotonicity of eval_fun *)
  | 
| 
 | 
   391  | 
  | 
| 
 | 
   392  | 
lemma eval_fun_mono: "mono(eval_fun)"
  | 
| 
 | 
   393  | 
unfolding mono_def eval_fun_def
  | 
| 
 | 
   394  | 
apply (tactic infsys_mono_tac)
  | 
| 
 | 
   395  | 
done
  | 
| 
 | 
   396  | 
  | 
| 
 | 
   397  | 
(* Introduction rules *)
  | 
| 
 | 
   398  | 
  | 
| 
 | 
   399  | 
lemma eval_const: "ve |- e_const(c) ---> v_const(c)"
  | 
| 
 | 
   400  | 
unfolding eval_def eval_rel_def
  | 
| 
 | 
   401  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   402  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   403  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   404  | 
        (*Naughty!  But the quantifiers are nested VERY deeply...*)
  | 
| 
 | 
   405  | 
apply (blast intro!: exI)
  | 
| 
 | 
   406  | 
done
  | 
| 
 | 
   407  | 
  | 
| 
 | 
   408  | 
lemma eval_var2:
  | 
| 
 | 
   409  | 
  "ev:ve_dom(ve) ==> ve |- e_var(ev) ---> ve_app ve ev"
  | 
| 
 | 
   410  | 
apply (unfold eval_def eval_rel_def)
  | 
| 
 | 
   411  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   412  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   413  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   414  | 
apply (blast intro!: exI)
  | 
| 
 | 
   415  | 
done
  | 
| 
 | 
   416  | 
  | 
| 
 | 
   417  | 
lemma eval_fn:
  | 
| 
 | 
   418  | 
  "ve |- fn ev => e ---> v_clos(<|ev,e,ve|>)"
  | 
| 
 | 
   419  | 
apply (unfold eval_def eval_rel_def)
  | 
| 
 | 
   420  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   421  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   422  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   423  | 
apply (blast intro!: exI)
  | 
| 
 | 
   424  | 
done
  | 
| 
 | 
   425  | 
  | 
| 
 | 
   426  | 
lemma eval_fix:
  | 
| 
 | 
   427  | 
  " cl = <| ev1, e, ve + {ev2 |-> v_clos(cl)} |> ==>
 | 
| 
 | 
   428  | 
    ve |- fix ev2(ev1) = e ---> v_clos(cl)"
  | 
| 
 | 
   429  | 
apply (unfold eval_def eval_rel_def)
  | 
| 
 | 
   430  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   431  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   432  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   433  | 
apply (blast intro!: exI)
  | 
| 
 | 
   434  | 
done
  | 
| 
 | 
   435  | 
  | 
| 
 | 
   436  | 
lemma eval_app1:
  | 
| 
 | 
   437  | 
  " [| ve |- e1 ---> v_const(c1); ve |- e2 ---> v_const(c2) |] ==>
  | 
| 
 | 
   438  | 
    ve |- e1 @@ e2 ---> v_const(c_app c1 c2)"
  | 
| 
 | 
   439  | 
apply (unfold eval_def eval_rel_def)
  | 
| 
 | 
   440  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   441  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   442  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   443  | 
apply (blast intro!: exI)
  | 
| 
 | 
   444  | 
done
  | 
| 
 | 
   445  | 
  | 
| 
 | 
   446  | 
lemma eval_app2:
  | 
| 
 | 
   447  | 
  " [|  ve |- e1 ---> v_clos(<|xm,em,vem|>);
  | 
| 
 | 
   448  | 
        ve |- e2 ---> v2;
  | 
| 
 | 
   449  | 
        vem + {xm |-> v2} |- em ---> v
 | 
| 
 | 
   450  | 
    |] ==>
  | 
| 
 | 
   451  | 
    ve |- e1 @@ e2 ---> v"
  | 
| 
 | 
   452  | 
apply (unfold eval_def eval_rel_def)
  | 
| 
 | 
   453  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   454  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   455  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   456  | 
apply (blast intro!: disjI2)
  | 
| 
 | 
   457  | 
done
  | 
| 
 | 
   458  | 
  | 
| 
 | 
   459  | 
(* Strong elimination, induction on evaluations *)
  | 
| 
 | 
   460  | 
  | 
| 
 | 
   461  | 
lemma eval_ind0:
  | 
| 
 | 
   462  | 
  " [| ve |- e ---> v;
  | 
| 
 | 
   463  | 
       !!ve c. P(((ve,e_const(c)),v_const(c)));
  | 
| 
 | 
   464  | 
       !!ev ve. ev:ve_dom(ve) ==> P(((ve,e_var(ev)),ve_app ve ev));
  | 
| 
 | 
   465  | 
       !!ev ve e. P(((ve,fn ev => e),v_clos(<|ev,e,ve|>)));
  | 
| 
 | 
   466  | 
       !!ev1 ev2 ve cl e.
  | 
| 
 | 
   467  | 
         cl = <| ev1, e, ve + {ev2 |-> v_clos(cl)} |> ==>
 | 
| 
 | 
   468  | 
         P(((ve,fix ev2(ev1) = e),v_clos(cl)));
  | 
| 
 | 
   469  | 
       !!ve c1 c2 e1 e2.
  | 
| 
 | 
   470  | 
         [| P(((ve,e1),v_const(c1))); P(((ve,e2),v_const(c2))) |] ==>
  | 
| 
 | 
   471  | 
         P(((ve,e1 @@ e2),v_const(c_app c1 c2)));
  | 
| 
 | 
   472  | 
       !!ve vem xm e1 e2 em v v2.
  | 
| 
 | 
   473  | 
         [|  P(((ve,e1),v_clos(<|xm,em,vem|>)));
  | 
| 
 | 
   474  | 
             P(((ve,e2),v2));
  | 
| 
 | 
   475  | 
             P(((vem + {xm |-> v2},em),v))
 | 
| 
 | 
   476  | 
         |] ==>
  | 
| 
 | 
   477  | 
         P(((ve,e1 @@ e2),v))
  | 
| 
 | 
   478  | 
    |] ==>
  | 
| 
 | 
   479  | 
    P(((ve,e),v))"
  | 
| 
 | 
   480  | 
unfolding eval_def eval_rel_def
  | 
| 
 | 
   481  | 
apply (erule lfp_ind2)
  | 
| 
 | 
   482  | 
apply (rule eval_fun_mono)
  | 
| 
 | 
   483  | 
apply (unfold eval_fun_def)
  | 
| 
 | 
   484  | 
apply (drule CollectD)
  | 
| 
 | 
   485  | 
apply safe
  | 
| 
 | 
   486  | 
apply auto
  | 
| 
 | 
   487  | 
done
  | 
| 
 | 
   488  | 
  | 
| 
 | 
   489  | 
lemma eval_ind:
  | 
| 
 | 
   490  | 
  " [| ve |- e ---> v;
  | 
| 
 | 
   491  | 
       !!ve c. P ve (e_const c) (v_const c);
  | 
| 
 | 
   492  | 
       !!ev ve. ev:ve_dom(ve) ==> P ve (e_var ev) (ve_app ve ev);
  | 
| 
 | 
   493  | 
       !!ev ve e. P ve (fn ev => e) (v_clos <|ev,e,ve|>);
  | 
| 
 | 
   494  | 
       !!ev1 ev2 ve cl e.
  | 
| 
 | 
   495  | 
         cl = <| ev1, e, ve + {ev2 |-> v_clos(cl)} |> ==>
 | 
| 
 | 
   496  | 
         P ve (fix ev2(ev1) = e) (v_clos cl);
  | 
| 
 | 
   497  | 
       !!ve c1 c2 e1 e2.
  | 
| 
 | 
   498  | 
         [| P ve e1 (v_const c1); P ve e2 (v_const c2) |] ==>
  | 
| 
 | 
   499  | 
         P ve (e1 @@ e2) (v_const(c_app c1 c2));
  | 
| 
 | 
   500  | 
       !!ve vem evm e1 e2 em v v2.
  | 
| 
 | 
   501  | 
         [|  P ve e1 (v_clos <|evm,em,vem|>);
  | 
| 
 | 
   502  | 
             P ve e2 v2;
  | 
| 
 | 
   503  | 
             P (vem + {evm |-> v2}) em v
 | 
| 
 | 
   504  | 
         |] ==> P ve (e1 @@ e2) v
  | 
| 
 | 
   505  | 
    |] ==> P ve e v"
  | 
| 
 | 
   506  | 
apply (rule_tac P = "P" in infsys_pp2)
  | 
| 
 | 
   507  | 
apply (rule eval_ind0)
  | 
| 
 | 
   508  | 
apply (rule infsys_pp1)
  | 
| 
 | 
   509  | 
apply auto
  | 
| 
 | 
   510  | 
done
  | 
| 
 | 
   511  | 
  | 
| 
 | 
   512  | 
(* ############################################################ *)
  | 
| 
 | 
   513  | 
(* Elaborations                                                 *)
  | 
| 
 | 
   514  | 
(* ############################################################ *)
  | 
| 
 | 
   515  | 
  | 
| 
 | 
   516  | 
lemma elab_fun_mono: "mono(elab_fun)"
  | 
| 
 | 
   517  | 
unfolding mono_def elab_fun_def
  | 
| 
 | 
   518  | 
apply (tactic infsys_mono_tac)
  | 
| 
 | 
   519  | 
done
  | 
| 
 | 
   520  | 
  | 
| 
 | 
   521  | 
(* Introduction rules *)
  | 
| 
 | 
   522  | 
  | 
| 
 | 
   523  | 
lemma elab_const:
  | 
| 
 | 
   524  | 
  "c isof ty ==> te |- e_const(c) ===> ty"
  | 
| 
 | 
   525  | 
apply (unfold elab_def elab_rel_def)
  | 
| 
 | 
   526  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   527  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   528  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   529  | 
apply (blast intro!: exI)
  | 
| 
 | 
   530  | 
done
  | 
| 
 | 
   531  | 
  | 
| 
 | 
   532  | 
lemma elab_var:
  | 
| 
 | 
   533  | 
  "x:te_dom(te) ==> te |- e_var(x) ===> te_app te x"
  | 
| 
 | 
   534  | 
apply (unfold elab_def elab_rel_def)
  | 
| 
 | 
   535  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   536  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   537  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   538  | 
apply (blast intro!: exI)
  | 
| 
 | 
   539  | 
done
  | 
| 
 | 
   540  | 
  | 
| 
 | 
   541  | 
lemma elab_fn:
  | 
| 
 | 
   542  | 
  "te + {x |=> ty1} |- e ===> ty2 ==> te |- fn x => e ===> ty1->ty2"
 | 
| 
 | 
   543  | 
apply (unfold elab_def elab_rel_def)
  | 
| 
 | 
   544  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   545  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   546  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   547  | 
apply (blast intro!: exI)
  | 
| 
 | 
   548  | 
done
  | 
| 
 | 
   549  | 
  | 
| 
 | 
   550  | 
lemma elab_fix:
  | 
| 
 | 
   551  | 
  "te + {f |=> ty1->ty2} + {x |=> ty1} |- e ===> ty2 ==>
 | 
| 
 | 
   552  | 
         te |- fix f(x) = e ===> ty1->ty2"
  | 
| 
 | 
   553  | 
apply (unfold elab_def elab_rel_def)
  | 
| 
 | 
   554  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   555  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   556  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   557  | 
apply (blast intro!: exI)
  | 
| 
 | 
   558  | 
done
  | 
| 
 | 
   559  | 
  | 
| 
 | 
   560  | 
lemma elab_app:
  | 
| 
 | 
   561  | 
  "[| te |- e1 ===> ty1->ty2; te |- e2 ===> ty1 |] ==>
  | 
| 
 | 
   562  | 
         te |- e1 @@ e2 ===> ty2"
  | 
| 
 | 
   563  | 
apply (unfold elab_def elab_rel_def)
  | 
| 
 | 
   564  | 
apply (rule lfp_intro2)
  | 
| 
 | 
   565  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   566  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   567  | 
apply (blast intro!: disjI2)
  | 
| 
 | 
   568  | 
done
  | 
| 
 | 
   569  | 
  | 
| 
 | 
   570  | 
(* Strong elimination, induction on elaborations *)
  | 
| 
 | 
   571  | 
  | 
| 
 | 
   572  | 
lemma elab_ind0:
  | 
| 
 | 
   573  | 
  assumes 1: "te |- e ===> t"
  | 
| 
 | 
   574  | 
    and 2: "!!te c t. c isof t ==> P(((te,e_const(c)),t))"
  | 
| 
 | 
   575  | 
    and 3: "!!te x. x:te_dom(te) ==> P(((te,e_var(x)),te_app te x))"
  | 
| 
 | 
   576  | 
    and 4: "!!te x e t1 t2.
  | 
| 
 | 
   577  | 
       [| te + {x |=> t1} |- e ===> t2; P(((te + {x |=> t1},e),t2)) |] ==>
 | 
| 
 | 
   578  | 
       P(((te,fn x => e),t1->t2))"
  | 
| 
 | 
   579  | 
    and 5: "!!te f x e t1 t2.
  | 
| 
 | 
   580  | 
       [| te + {f |=> t1->t2} + {x |=> t1} |- e ===> t2;
 | 
| 
 | 
   581  | 
          P(((te + {f |=> t1->t2} + {x |=> t1},e),t2))
 | 
| 
 | 
   582  | 
       |] ==>
  | 
| 
 | 
   583  | 
       P(((te,fix f(x) = e),t1->t2))"
  | 
| 
 | 
   584  | 
    and 6: "!!te e1 e2 t1 t2.
  | 
| 
 | 
   585  | 
       [| te |- e1 ===> t1->t2; P(((te,e1),t1->t2));
  | 
| 
 | 
   586  | 
          te |- e2 ===> t1; P(((te,e2),t1))
  | 
| 
 | 
   587  | 
       |] ==>
  | 
| 
 | 
   588  | 
       P(((te,e1 @@ e2),t2))"
  | 
| 
 | 
   589  | 
  shows "P(((te,e),t))"
  | 
| 
 | 
   590  | 
apply (rule lfp_ind2 [OF 1 [unfolded elab_def elab_rel_def]])
  | 
| 
 | 
   591  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   592  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   593  | 
apply (drule CollectD)
  | 
| 
 | 
   594  | 
apply safe
  | 
| 
 | 
   595  | 
apply (erule 2)
  | 
| 
 | 
   596  | 
apply (erule 3)
  | 
| 
 | 
   597  | 
apply (rule 4 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   598  | 
apply (rule 5 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   599  | 
apply (rule 6 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   600  | 
done
  | 
| 
 | 
   601  | 
  | 
| 
 | 
   602  | 
lemma elab_ind:
  | 
| 
 | 
   603  | 
  " [| te |- e ===> t;
  | 
| 
 | 
   604  | 
        !!te c t. c isof t ==> P te (e_const c) t;
  | 
| 
 | 
   605  | 
       !!te x. x:te_dom(te) ==> P te (e_var x) (te_app te x);
  | 
| 
 | 
   606  | 
       !!te x e t1 t2.
  | 
| 
 | 
   607  | 
         [| te + {x |=> t1} |- e ===> t2; P (te + {x |=> t1}) e t2 |] ==>
 | 
| 
 | 
   608  | 
         P te (fn x => e) (t1->t2);
  | 
| 
 | 
   609  | 
       !!te f x e t1 t2.
  | 
| 
 | 
   610  | 
         [| te + {f |=> t1->t2} + {x |=> t1} |- e ===> t2;
 | 
| 
 | 
   611  | 
            P (te + {f |=> t1->t2} + {x |=> t1}) e t2
 | 
| 
 | 
   612  | 
         |] ==>
  | 
| 
 | 
   613  | 
         P te (fix f(x) = e) (t1->t2);
  | 
| 
 | 
   614  | 
       !!te e1 e2 t1 t2.
  | 
| 
 | 
   615  | 
         [| te |- e1 ===> t1->t2; P te e1 (t1->t2);
  | 
| 
 | 
   616  | 
            te |- e2 ===> t1; P te e2 t1
  | 
| 
 | 
   617  | 
         |] ==>
  | 
| 
 | 
   618  | 
         P te (e1 @@ e2) t2
  | 
| 
 | 
   619  | 
    |] ==>
  | 
| 
 | 
   620  | 
    P te e t"
  | 
| 
 | 
   621  | 
apply (rule_tac P = "P" in infsys_pp2)
  | 
| 
 | 
   622  | 
apply (erule elab_ind0)
  | 
| 
 | 
   623  | 
apply (rule_tac [!] infsys_pp1)
  | 
| 
 | 
   624  | 
apply auto
  | 
| 
 | 
   625  | 
done
  | 
| 
 | 
   626  | 
  | 
| 
 | 
   627  | 
(* Weak elimination, case analysis on elaborations *)
  | 
| 
 | 
   628  | 
  | 
| 
 | 
   629  | 
lemma elab_elim0:
  | 
| 
 | 
   630  | 
  assumes 1: "te |- e ===> t"
  | 
| 
 | 
   631  | 
    and 2: "!!te c t. c isof t ==> P(((te,e_const(c)),t))"
  | 
| 
 | 
   632  | 
    and 3: "!!te x. x:te_dom(te) ==> P(((te,e_var(x)),te_app te x))"
  | 
| 
 | 
   633  | 
    and 4: "!!te x e t1 t2.
  | 
| 
 | 
   634  | 
         te + {x |=> t1} |- e ===> t2 ==> P(((te,fn x => e),t1->t2))"
 | 
| 
 | 
   635  | 
    and 5: "!!te f x e t1 t2.
  | 
| 
 | 
   636  | 
         te + {f |=> t1->t2} + {x |=> t1} |- e ===> t2 ==>
 | 
| 
 | 
   637  | 
         P(((te,fix f(x) = e),t1->t2))"
  | 
| 
 | 
   638  | 
    and 6: "!!te e1 e2 t1 t2.
  | 
| 
 | 
   639  | 
         [| te |- e1 ===> t1->t2; te |- e2 ===> t1 |] ==>
  | 
| 
 | 
   640  | 
         P(((te,e1 @@ e2),t2))"
  | 
| 
 | 
   641  | 
  shows "P(((te,e),t))"
  | 
| 
 | 
   642  | 
apply (rule lfp_elim2 [OF 1 [unfolded elab_def elab_rel_def]])
  | 
| 
 | 
   643  | 
apply (rule elab_fun_mono)
  | 
| 
 | 
   644  | 
apply (unfold elab_fun_def)
  | 
| 
 | 
   645  | 
apply (drule CollectD)
  | 
| 
 | 
   646  | 
apply safe
  | 
| 
 | 
   647  | 
apply (erule 2)
  | 
| 
 | 
   648  | 
apply (erule 3)
  | 
| 
 | 
   649  | 
apply (rule 4 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   650  | 
apply (rule 5 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   651  | 
apply (rule 6 [unfolded elab_def elab_rel_def]) apply blast+
  | 
| 
 | 
   652  | 
done
  | 
| 
 | 
   653  | 
  | 
| 
 | 
   654  | 
lemma elab_elim:
  | 
| 
 | 
   655  | 
  " [| te |- e ===> t;
  | 
| 
 | 
   656  | 
        !!te c t. c isof t ==> P te (e_const c) t;
  | 
| 
 | 
   657  | 
       !!te x. x:te_dom(te) ==> P te (e_var x) (te_app te x);
  | 
| 
 | 
   658  | 
       !!te x e t1 t2.
  | 
| 
 | 
   659  | 
         te + {x |=> t1} |- e ===> t2 ==> P te (fn x => e) (t1->t2);
 | 
| 
 | 
   660  | 
       !!te f x e t1 t2.
  | 
| 
 | 
   661  | 
         te + {f |=> t1->t2} + {x |=> t1} |- e ===> t2 ==>
 | 
| 
 | 
   662  | 
         P te (fix f(x) = e) (t1->t2);
  | 
| 
 | 
   663  | 
       !!te e1 e2 t1 t2.
  | 
| 
 | 
   664  | 
         [| te |- e1 ===> t1->t2; te |- e2 ===> t1 |] ==>
  | 
| 
 | 
   665  | 
         P te (e1 @@ e2) t2
  | 
| 
 | 
   666  | 
    |] ==>
  | 
| 
 | 
   667  | 
    P te e t"
  | 
| 
 | 
   668  | 
apply (rule_tac P = "P" in infsys_pp2)
  | 
| 
 | 
   669  | 
apply (rule elab_elim0)
  | 
| 
 | 
   670  | 
apply auto
  | 
| 
 | 
   671  | 
done
  | 
| 
 | 
   672  | 
  | 
| 
 | 
   673  | 
(* Elimination rules for each expression *)
  | 
| 
 | 
   674  | 
  | 
| 
 | 
   675  | 
lemma elab_const_elim_lem:
  | 
| 
 | 
   676  | 
    "te |- e ===> t ==> (e = e_const(c) --> c isof t)"
  | 
| 
 | 
   677  | 
apply (erule elab_elim)
  | 
| 
 | 
   678  | 
apply (fast intro!: e_disj_si elim!: e_disj_se dest!: e_injs)+
  | 
| 
 | 
   679  | 
done
  | 
| 
 | 
   680  | 
  | 
| 
 | 
   681  | 
lemma elab_const_elim: "te |- e_const(c) ===> t ==> c isof t"
  | 
| 
 | 
   682  | 
apply (drule elab_const_elim_lem)
  | 
| 
 | 
   683  | 
apply blast
  | 
| 
 | 
   684  | 
done
  | 
| 
 | 
   685  | 
  | 
| 
 | 
   686  | 
lemma elab_var_elim_lem:
  | 
| 
 | 
   687  | 
  "te |- e ===> t ==> (e = e_var(x) --> t=te_app te x & x:te_dom(te))"
  | 
| 
 | 
   688  | 
apply (erule elab_elim)
  | 
| 
 | 
   689  | 
apply (fast intro!: e_disj_si elim!: e_disj_se dest!: e_injs)+
  | 
| 
 | 
   690  | 
done
  | 
| 
 | 
   691  | 
  | 
| 
 | 
   692  | 
lemma elab_var_elim: "te |- e_var(ev) ===> t ==> t=te_app te ev & ev : te_dom(te)"
  | 
| 
 | 
   693  | 
apply (drule elab_var_elim_lem)
  | 
| 
 | 
   694  | 
apply blast
  | 
| 
 | 
   695  | 
done
  | 
| 
 | 
   696  | 
  | 
| 
 | 
   697  | 
lemma elab_fn_elim_lem:
  | 
| 
 | 
   698  | 
  " te |- e ===> t ==>
  | 
| 
 | 
   699  | 
    ( e = fn x1 => e1 -->
  | 
| 
 | 
   700  | 
      (? t1 t2. t=t_fun t1 t2 & te + {x1 |=> t1} |- e1 ===> t2)
 | 
| 
 | 
   701  | 
    )"
  | 
| 
 | 
   702  | 
apply (erule elab_elim)
  | 
| 
 | 
   703  | 
apply (fast intro!: e_disj_si elim!: e_disj_se dest!: e_injs)+
  | 
| 
 | 
   704  | 
done
  | 
| 
 | 
   705  | 
  | 
| 
 | 
   706  | 
lemma elab_fn_elim: " te |- fn x1 => e1 ===> t ==>
  | 
| 
 | 
   707  | 
    (? t1 t2. t=t1->t2 & te + {x1 |=> t1} |- e1 ===> t2)"
 | 
| 
 | 
   708  | 
apply (drule elab_fn_elim_lem)
  | 
| 
 | 
   709  | 
apply blast
  | 
| 
 | 
   710  | 
done
  | 
| 
 | 
   711  | 
  | 
| 
 | 
   712  | 
lemma elab_fix_elim_lem:
  | 
| 
 | 
   713  | 
  " te |- e ===> t ==>
  | 
| 
 | 
   714  | 
    (e = fix f(x) = e1 -->
  | 
| 
 | 
   715  | 
    (? t1 t2. t=t1->t2 & te + {f |=> t1->t2} + {x |=> t1} |- e1 ===> t2))"
 | 
| 
 | 
   716  | 
apply (erule elab_elim)
  | 
| 
 | 
   717  | 
apply (fast intro!: e_disj_si elim!: e_disj_se dest!: e_injs)+
  | 
| 
 | 
   718  | 
done
  | 
| 
 | 
   719  | 
  | 
| 
 | 
   720  | 
lemma elab_fix_elim: " te |- fix ev1(ev2) = e1 ===> t ==>
  | 
| 
 | 
   721  | 
    (? t1 t2. t=t1->t2 & te + {ev1 |=> t1->t2} + {ev2 |=> t1} |- e1 ===> t2)"
 | 
| 
 | 
   722  | 
apply (drule elab_fix_elim_lem)
  | 
| 
 | 
   723  | 
apply blast
  | 
| 
 | 
   724  | 
done
  | 
| 
 | 
   725  | 
  | 
| 
 | 
   726  | 
lemma elab_app_elim_lem:
  | 
| 
 | 
   727  | 
  " te |- e ===> t2 ==>
  | 
| 
 | 
   728  | 
    (e = e1 @@ e2 --> (? t1 . te |- e1 ===> t1->t2 & te |- e2 ===> t1))"
  | 
| 
 | 
   729  | 
apply (erule elab_elim)
  | 
| 
 | 
   730  | 
apply (fast intro!: e_disj_si elim!: e_disj_se dest!: e_injs)+
  | 
| 
 | 
   731  | 
done
  | 
| 
 | 
   732  | 
  | 
| 
 | 
   733  | 
lemma elab_app_elim: "te |- e1 @@ e2 ===> t2 ==> (? t1 . te |- e1 ===> t1->t2 & te |- e2 ===> t1)"
  | 
| 
 | 
   734  | 
apply (drule elab_app_elim_lem)
  | 
| 
 | 
   735  | 
apply blast
  | 
| 
 | 
   736  | 
done
  | 
| 
 | 
   737  | 
  | 
| 
 | 
   738  | 
(* ############################################################ *)
  | 
| 
 | 
   739  | 
(* The extended correspondence relation                       *)
  | 
| 
 | 
   740  | 
(* ############################################################ *)
  | 
| 
 | 
   741  | 
  | 
| 
 | 
   742  | 
(* Monotonicity of hasty_fun *)
  | 
| 
 | 
   743  | 
  | 
| 
 | 
   744  | 
lemma mono_hasty_fun: "mono(hasty_fun)"
  | 
| 
 | 
   745  | 
unfolding mono_def hasty_fun_def
  | 
| 
 | 
   746  | 
apply (tactic infsys_mono_tac)
  | 
| 
 | 
   747  | 
apply blast
  | 
| 
 | 
   748  | 
done
  | 
| 
 | 
   749  | 
  | 
| 
 | 
   750  | 
(*
  | 
| 
 | 
   751  | 
  Because hasty_rel has been defined as the greatest fixpoint of hasty_fun it
  | 
| 
 | 
   752  | 
  enjoys two strong indtroduction (co-induction) rules and an elimination rule.
  | 
| 
 | 
   753  | 
*)
  | 
| 
 | 
   754  | 
  | 
| 
 | 
   755  | 
(* First strong indtroduction (co-induction) rule for hasty_rel *)
  | 
| 
 | 
   756  | 
  | 
| 
 | 
   757  | 
lemma hasty_rel_const_coind: "c isof t ==> (v_const(c),t) : hasty_rel"
  | 
| 
 | 
   758  | 
apply (unfold hasty_rel_def)
  | 
| 
 | 
   759  | 
apply (rule gfp_coind2)
  | 
| 
 | 
   760  | 
apply (unfold hasty_fun_def)
  | 
| 
 | 
   761  | 
apply (rule CollectI)
  | 
| 
 | 
   762  | 
apply (rule disjI1)
  | 
| 
 | 
   763  | 
apply blast
  | 
| 
 | 
   764  | 
apply (rule mono_hasty_fun)
  | 
| 
 | 
   765  | 
done
  | 
| 
 | 
   766  | 
  | 
| 
 | 
   767  | 
(* Second strong introduction (co-induction) rule for hasty_rel *)
  | 
| 
 | 
   768  | 
  | 
| 
 | 
   769  | 
lemma hasty_rel_clos_coind:
  | 
| 
 | 
   770  | 
  " [|  te |- fn ev => e ===> t;
  | 
| 
 | 
   771  | 
        ve_dom(ve) = te_dom(te);
  | 
| 
 | 
   772  | 
        ! ev1.
  | 
| 
 | 
   773  | 
          ev1:ve_dom(ve) -->
  | 
| 
 | 
   774  | 
          (ve_app ve ev1,te_app te ev1) : {(v_clos(<|ev,e,ve|>),t)} Un hasty_rel
 | 
| 
 | 
   775  | 
    |] ==>
  | 
| 
 | 
   776  | 
    (v_clos(<|ev,e,ve|>),t) : hasty_rel"
  | 
| 
 | 
   777  | 
apply (unfold hasty_rel_def)
  | 
| 
 | 
   778  | 
apply (rule gfp_coind2)
  | 
| 
 | 
   779  | 
apply (unfold hasty_fun_def)
  | 
| 
 | 
   780  | 
apply (rule CollectI)
  | 
| 
 | 
   781  | 
apply (rule disjI2)
  | 
| 
 | 
   782  | 
apply blast
  | 
| 
 | 
   783  | 
apply (rule mono_hasty_fun)
  | 
| 
 | 
   784  | 
done
  | 
| 
 | 
   785  | 
  | 
| 
 | 
   786  | 
(* Elimination rule for hasty_rel *)
  | 
| 
 | 
   787  | 
  | 
| 
 | 
   788  | 
lemma hasty_rel_elim0:
  | 
| 
 | 
   789  | 
  " [| !! c t. c isof t ==> P((v_const(c),t));
  | 
| 
 | 
   790  | 
       !! te ev e t ve.
  | 
| 
 | 
   791  | 
         [| te |- fn ev => e ===> t;
  | 
| 
 | 
   792  | 
            ve_dom(ve) = te_dom(te);
  | 
| 
 | 
   793  | 
            !ev1. ev1:ve_dom(ve) --> (ve_app ve ev1,te_app te ev1) : hasty_rel
  | 
| 
 | 
   794  | 
         |] ==> P((v_clos(<|ev,e,ve|>),t));
  | 
| 
 | 
   795  | 
       (v,t) : hasty_rel
  | 
| 
 | 
   796  | 
    |] ==> P(v,t)"
  | 
| 
 | 
   797  | 
unfolding hasty_rel_def
  | 
| 
 | 
   798  | 
apply (erule gfp_elim2)
  | 
| 
 | 
   799  | 
apply (rule mono_hasty_fun)
  | 
| 
 | 
   800  | 
apply (unfold hasty_fun_def)
  | 
| 
 | 
   801  | 
apply (drule CollectD)
  | 
| 
 | 
   802  | 
apply (fold hasty_fun_def)
  | 
| 
 | 
   803  | 
apply auto
  | 
| 
 | 
   804  | 
done
  | 
| 
 | 
   805  | 
  | 
| 
 | 
   806  | 
lemma hasty_rel_elim:
  | 
| 
 | 
   807  | 
  " [| (v,t) : hasty_rel;
  | 
| 
 | 
   808  | 
       !! c t. c isof t ==> P (v_const c) t;
  | 
| 
 | 
   809  | 
       !! te ev e t ve.
  | 
| 
 | 
   810  | 
         [| te |- fn ev => e ===> t;
  | 
| 
 | 
   811  | 
            ve_dom(ve) = te_dom(te);
  | 
| 
 | 
   812  | 
            !ev1. ev1:ve_dom(ve) --> (ve_app ve ev1,te_app te ev1) : hasty_rel
  | 
| 
 | 
   813  | 
         |] ==> P (v_clos <|ev,e,ve|>) t
  | 
| 
 | 
   814  | 
    |] ==> P v t"
  | 
| 
 | 
   815  | 
apply (rule_tac P = "P" in infsys_p2)
  | 
| 
 | 
   816  | 
apply (rule hasty_rel_elim0)
  | 
| 
 | 
   817  | 
apply auto
  | 
| 
 | 
   818  | 
done
  | 
| 
 | 
   819  | 
  | 
| 
 | 
   820  | 
(* Introduction rules for hasty *)
  | 
| 
 | 
   821  | 
  | 
| 
 | 
   822  | 
lemma hasty_const: "c isof t ==> v_const(c) hasty t"
  | 
| 
 | 
   823  | 
apply (unfold hasty_def)
  | 
| 
 | 
   824  | 
apply (erule hasty_rel_const_coind)
  | 
| 
 | 
   825  | 
done
  | 
| 
 | 
   826  | 
  | 
| 
 | 
   827  | 
lemma hasty_clos:
  | 
| 
 | 
   828  | 
 "te |- fn ev => e ===> t & ve hastyenv te ==> v_clos(<|ev,e,ve|>) hasty t"
  | 
| 
 | 
   829  | 
apply (unfold hasty_def hasty_env_def)
  | 
| 
 | 
   830  | 
apply (rule hasty_rel_clos_coind)
  | 
| 
 | 
   831  | 
apply (blast del: equalityI)+
  | 
| 
 | 
   832  | 
done
  | 
| 
 | 
   833  | 
  | 
| 
 | 
   834  | 
(* Elimination on constants for hasty *)
  | 
| 
 | 
   835  | 
  | 
| 
 | 
   836  | 
lemma hasty_elim_const_lem:
  | 
| 
 | 
   837  | 
  "v hasty t ==> (!c.(v = v_const(c) --> c isof t))"
  | 
| 
 | 
   838  | 
apply (unfold hasty_def)
  | 
| 
 | 
   839  | 
apply (rule hasty_rel_elim)
  | 
| 
 | 
   840  | 
apply (blast intro!: v_disj_si elim!: v_disj_se dest!: v_injs)+
  | 
| 
 | 
   841  | 
done
  | 
| 
 | 
   842  | 
  | 
| 
 | 
   843  | 
lemma hasty_elim_const: "v_const(c) hasty t ==> c isof t"
  | 
| 
 | 
   844  | 
apply (drule hasty_elim_const_lem)
  | 
| 
 | 
   845  | 
apply blast
  | 
| 
 | 
   846  | 
done
  | 
| 
 | 
   847  | 
  | 
| 
 | 
   848  | 
(* Elimination on closures for hasty *)
  | 
| 
 | 
   849  | 
  | 
| 
 | 
   850  | 
lemma hasty_elim_clos_lem:
  | 
| 
 | 
   851  | 
  " v hasty t ==>
  | 
| 
 | 
   852  | 
    ! x e ve.
  | 
| 
 | 
   853  | 
      v=v_clos(<|x,e,ve|>) --> (? te. te |- fn x => e ===> t & ve hastyenv te)"
  | 
| 
 | 
   854  | 
apply (unfold hasty_env_def hasty_def)
  | 
| 
 | 
   855  | 
apply (rule hasty_rel_elim)
  | 
| 
 | 
   856  | 
apply (blast intro!: v_disj_si elim!: v_disj_se dest!: v_injs)+
  | 
| 
 | 
   857  | 
done
  | 
| 
 | 
   858  | 
  | 
| 
 | 
   859  | 
lemma hasty_elim_clos: "v_clos(<|ev,e,ve|>) hasty t ==>
  | 
| 
 | 
   860  | 
        ? te. te |- fn ev => e ===> t & ve hastyenv te "
  | 
| 
 | 
   861  | 
apply (drule hasty_elim_clos_lem)
  | 
| 
 | 
   862  | 
apply blast
  | 
| 
 | 
   863  | 
done
  | 
| 
 | 
   864  | 
  | 
| 
 | 
   865  | 
(* ############################################################ *)
  | 
| 
 | 
   866  | 
(* The pointwise extension of hasty to environments             *)
  | 
| 
 | 
   867  | 
(* ############################################################ *)
  | 
| 
 | 
   868  | 
  | 
| 
 | 
   869  | 
lemma hasty_env1: "[| ve hastyenv te; v hasty t |] ==>
  | 
| 
 | 
   870  | 
         ve + {ev |-> v} hastyenv te + {ev |=> t}"
 | 
| 
 | 
   871  | 
apply (unfold hasty_env_def)
  | 
| 
 | 
   872  | 
apply (simp del: mem_simps add: ve_dom_owr te_dom_owr)
  | 
| 
 | 
   873  | 
apply (tactic {* safe_tac HOL_cs *})
 | 
| 
 | 
   874  | 
apply (case_tac "ev=x")
  | 
| 
 | 
   875  | 
apply (simp (no_asm_simp) add: ve_app_owr1 te_app_owr1)
  | 
| 
 | 
   876  | 
apply (simp add: ve_app_owr2 te_app_owr2)
  | 
| 
 | 
   877  | 
done
  | 
| 
 | 
   878  | 
  | 
| 
 | 
   879  | 
(* ############################################################ *)
  | 
| 
 | 
   880  | 
(* The Consistency theorem                                      *)
  | 
| 
 | 
   881  | 
(* ############################################################ *)
  | 
| 
 | 
   882  | 
  | 
| 
 | 
   883  | 
lemma consistency_const: "[| ve hastyenv te ; te |- e_const(c) ===> t |] ==> v_const(c) hasty t"
  | 
| 
 | 
   884  | 
apply (drule elab_const_elim)
  | 
| 
 | 
   885  | 
apply (erule hasty_const)
  | 
| 
 | 
   886  | 
done
  | 
| 
 | 
   887  | 
  | 
| 
 | 
   888  | 
lemma consistency_var:
  | 
| 
 | 
   889  | 
  "[| ev : ve_dom(ve); ve hastyenv te ; te |- e_var(ev) ===> t |] ==>
  | 
| 
 | 
   890  | 
        ve_app ve ev hasty t"
  | 
| 
 | 
   891  | 
apply (unfold hasty_env_def)
  | 
| 
 | 
   892  | 
apply (drule elab_var_elim)
  | 
| 
 | 
   893  | 
apply blast
  | 
| 
 | 
   894  | 
done
  | 
| 
 | 
   895  | 
  | 
| 
 | 
   896  | 
lemma consistency_fn: "[| ve hastyenv te ; te |- fn ev => e ===> t |] ==>
  | 
| 
 | 
   897  | 
        v_clos(<| ev, e, ve |>) hasty t"
  | 
| 
 | 
   898  | 
apply (rule hasty_clos)
  | 
| 
 | 
   899  | 
apply blast
  | 
| 
 | 
   900  | 
done
  | 
| 
 | 
   901  | 
  | 
| 
 | 
   902  | 
lemma consistency_fix:
  | 
| 
 | 
   903  | 
  "[| cl = <| ev1, e, ve + { ev2 |-> v_clos(cl) } |>;
 | 
| 
 | 
   904  | 
       ve hastyenv te ;
  | 
| 
 | 
   905  | 
       te |- fix ev2  ev1  = e ===> t
  | 
| 
 | 
   906  | 
    |] ==>
  | 
| 
 | 
   907  | 
    v_clos(cl) hasty t"
  | 
| 
 | 
   908  | 
apply (unfold hasty_env_def hasty_def)
  | 
| 
 | 
   909  | 
apply (drule elab_fix_elim)
  | 
| 
 | 
   910  | 
apply (tactic {* safe_tac HOL_cs *})
 | 
| 
 | 
   911  | 
(*Do a single unfolding of cl*)
  | 
| 
 | 
   912  | 
apply (frule ssubst) prefer 2 apply assumption
  | 
| 
 | 
   913  | 
apply (rule hasty_rel_clos_coind)
  | 
| 
 | 
   914  | 
apply (erule elab_fn)
  | 
| 
 | 
   915  | 
apply (simp (no_asm_simp) add: ve_dom_owr te_dom_owr)
  | 
| 
 | 
   916  | 
  | 
| 
 | 
   917  | 
apply (simp (no_asm_simp) del: mem_simps add: ve_dom_owr)
  | 
| 
 | 
   918  | 
apply (tactic {* safe_tac HOL_cs *})
 | 
| 
 | 
   919  | 
apply (case_tac "ev2=ev1a")
  | 
| 
 | 
   920  | 
apply (simp (no_asm_simp) del: mem_simps add: ve_app_owr1 te_app_owr1)
  | 
| 
 | 
   921  | 
apply blast
  | 
| 
 | 
   922  | 
apply (simp add: ve_app_owr2 te_app_owr2)
  | 
| 
 | 
   923  | 
done
  | 
| 
 | 
   924  | 
  | 
| 
 | 
   925  | 
lemma consistency_app1: "[| ! t te. ve hastyenv te --> te |- e1 ===> t --> v_const(c1) hasty t;
  | 
| 
 | 
   926  | 
       ! t te. ve hastyenv te  --> te |- e2 ===> t --> v_const(c2) hasty t;
  | 
| 
 | 
   927  | 
       ve hastyenv te ; te |- e1 @@ e2 ===> t
  | 
| 
 | 
   928  | 
    |] ==>
  | 
| 
 | 
   929  | 
    v_const(c_app c1 c2) hasty t"
  | 
| 
 | 
   930  | 
apply (drule elab_app_elim)
  | 
| 
 | 
   931  | 
apply safe
  | 
| 
 | 
   932  | 
apply (rule hasty_const)
  | 
| 
 | 
   933  | 
apply (rule isof_app)
  | 
| 
 | 
   934  | 
apply (rule hasty_elim_const)
  | 
| 
 | 
   935  | 
apply blast
  | 
| 
 | 
   936  | 
apply (rule hasty_elim_const)
  | 
| 
 | 
   937  | 
apply blast
  | 
| 
 | 
   938  | 
done
  | 
| 
 | 
   939  | 
  | 
| 
 | 
   940  | 
lemma consistency_app2: "[| ! t te.
  | 
| 
 | 
   941  | 
         ve hastyenv te  -->
  | 
| 
 | 
   942  | 
         te |- e1 ===> t --> v_clos(<|evm, em, vem|>) hasty t;
  | 
| 
 | 
   943  | 
       ! t te. ve hastyenv te  --> te |- e2 ===> t --> v2 hasty t;
  | 
| 
 | 
   944  | 
       ! t te.
  | 
| 
 | 
   945  | 
         vem + { evm |-> v2 } hastyenv te  --> te |- em ===> t --> v hasty t;
 | 
| 
 | 
   946  | 
       ve hastyenv te ;
  | 
| 
 | 
   947  | 
       te |- e1 @@ e2 ===> t
  | 
| 
 | 
   948  | 
    |] ==>
  | 
| 
 | 
   949  | 
    v hasty t"
  | 
| 
 | 
   950  | 
apply (drule elab_app_elim)
  | 
| 
 | 
   951  | 
apply safe
  | 
| 
 | 
   952  | 
apply (erule allE, erule allE, erule impE)
  | 
| 
 | 
   953  | 
apply assumption
  | 
| 
 | 
   954  | 
apply (erule impE)
  | 
| 
 | 
   955  | 
apply assumption
  | 
| 
 | 
   956  | 
apply (erule allE, erule allE, erule impE)
  | 
| 
 | 
   957  | 
apply assumption
  | 
| 
 | 
   958  | 
apply (erule impE)
  | 
| 
 | 
   959  | 
apply assumption
  | 
| 
 | 
   960  | 
apply (drule hasty_elim_clos)
  | 
| 
 | 
   961  | 
apply safe
  | 
| 
 | 
   962  | 
apply (drule elab_fn_elim)
  | 
| 
 | 
   963  | 
apply (blast intro: hasty_env1 dest!: t_fun_inj)
  | 
| 
 | 
   964  | 
done
  | 
| 
 | 
   965  | 
  | 
| 
 | 
   966  | 
lemma consistency: "ve |- e ---> v ==>
  | 
| 
 | 
   967  | 
   (! t te. ve hastyenv te --> te |- e ===> t --> v hasty t)"
  | 
| 
 | 
   968  | 
  | 
| 
 | 
   969  | 
(* Proof by induction on the structure of evaluations *)
  | 
| 
 | 
   970  | 
  | 
| 
 | 
   971  | 
apply (erule eval_ind)
  | 
| 
 | 
   972  | 
apply safe
  | 
| 
 | 
   973  | 
apply (blast intro: consistency_const consistency_var consistency_fn consistency_fix consistency_app1 consistency_app2)+
  | 
| 
 | 
   974  | 
done
  | 
| 
 | 
   975  | 
  | 
| 
 | 
   976  | 
(* ############################################################ *)
  | 
| 
 | 
   977  | 
(* The Basic Consistency theorem                                *)
  | 
| 
 | 
   978  | 
(* ############################################################ *)
  | 
| 
 | 
   979  | 
  | 
| 
 | 
   980  | 
lemma basic_consistency_lem:
  | 
| 
 | 
   981  | 
  "ve isofenv te ==> ve hastyenv te"
  | 
| 
 | 
   982  | 
apply (unfold isof_env_def hasty_env_def)
  | 
| 
 | 
   983  | 
apply safe
  | 
| 
 | 
   984  | 
apply (erule allE)
  | 
| 
 | 
   985  | 
apply (erule impE)
  | 
| 
 | 
   986  | 
apply assumption
  | 
| 
 | 
   987  | 
apply (erule exE)
  | 
| 
 | 
   988  | 
apply (erule conjE)
  | 
| 
 | 
   989  | 
apply (drule hasty_const)
  | 
| 
 | 
   990  | 
apply (simp (no_asm_simp))
  | 
| 
 | 
   991  | 
done
  | 
| 
 | 
   992  | 
  | 
| 
 | 
   993  | 
lemma basic_consistency:
  | 
| 
 | 
   994  | 
  "[| ve isofenv te; ve |- e ---> v_const(c); te |- e ===> t |] ==> c isof t"
  | 
| 
 | 
   995  | 
apply (rule hasty_elim_const)
  | 
| 
 | 
   996  | 
apply (drule consistency)
  | 
| 
 | 
   997  | 
apply (blast intro!: basic_consistency_lem)
  | 
| 
 | 
   998  | 
done
  | 
| 
17289
 | 
   999  | 
  | 
| 
969
 | 
  1000  | 
end
  |