src/CCL/coinduction.ML
author clasohm
Thu Sep 16 12:20:38 1993 +0200 (1993-09-16)
changeset 0 a5a9c433f639
child 8 c3d2c6dcf3f0
permissions -rw-r--r--
Initial revision
clasohm@0
     1
(*  Title: 	92/CCL/coinduction
clasohm@0
     2
    ID:         $Id$
clasohm@0
     3
    Author: 	Martin Coen, Cambridge University Computer Laboratory
clasohm@0
     4
    Copyright   1993  University of Cambridge
clasohm@0
     5
clasohm@0
     6
Lemmas and tactics for using the rule coinduct3 on [= and =.
clasohm@0
     7
*)
clasohm@0
     8
clasohm@0
     9
val [mono,prem] = goal Lfp.thy "[| mono(f);  a : f(lfp(f)) |] ==> a : lfp(f)";
clasohm@0
    10
br ((mono RS lfp_Tarski) RS ssubst) 1;
clasohm@0
    11
br prem 1;
clasohm@0
    12
val lfpI = result();
clasohm@0
    13
clasohm@0
    14
val prems = goal CCL.thy "[| a=a';  a' : A |] ==> a : A";
clasohm@0
    15
by (SIMP_TAC (term_ss addrews prems) 1);
clasohm@0
    16
val ssubst_single = result();
clasohm@0
    17
clasohm@0
    18
val prems = goal CCL.thy "[| a=a';  b=b';  <a',b'> : A |] ==> <a,b> : A";
clasohm@0
    19
by (SIMP_TAC (term_ss addrews prems) 1);
clasohm@0
    20
val ssubst_pair = result();
clasohm@0
    21
clasohm@0
    22
(***)
clasohm@0
    23
clasohm@0
    24
local 
clasohm@0
    25
fun mk_thm s = prove_goal Term.thy s (fn mono::prems => 
clasohm@0
    26
       [fast_tac (term_cs addIs ((mono RS coinduct3_mono_lemma RS lfpI)::prems)) 1]);
clasohm@0
    27
in
clasohm@0
    28
val ci3_RI    = mk_thm "[|  mono(Agen);  a : R |] ==> a : lfp(%x. Agen(x) Un R Un A)";
clasohm@0
    29
val ci3_AgenI = mk_thm "[|  mono(Agen);  a : Agen(lfp(%x. Agen(x) Un R Un A)) |] ==> \
clasohm@0
    30
\                       a : lfp(%x. Agen(x) Un R Un A)";
clasohm@0
    31
val ci3_AI    = mk_thm "[|  mono(Agen);  a : A |] ==> a : lfp(%x. Agen(x) Un R Un A)";
clasohm@0
    32
end;
clasohm@0
    33
clasohm@0
    34
fun mk_genIs thy defs genXH gen_mono s = prove_goalw thy defs s 
clasohm@0
    35
      (fn prems => [rtac (genXH RS iffD2) 1,
clasohm@0
    36
                    (SIMP_TAC term_ss 1),
clasohm@0
    37
                    TRY (fast_tac (term_cs addIs 
clasohm@0
    38
                            ([genXH RS iffD2,gen_mono RS coinduct3_mono_lemma RS lfpI]
clasohm@0
    39
                             @ prems)) 1)]);
clasohm@0
    40
clasohm@0
    41
(** POgen **)
clasohm@0
    42
clasohm@0
    43
goal Term.thy "<a,a> : PO";
clasohm@0
    44
br (po_refl RS (XH_to_D PO_iff)) 1;
clasohm@0
    45
val PO_refl = result();
clasohm@0
    46
clasohm@0
    47
val POgenIs = map (mk_genIs Term.thy data_defs POgenXH POgen_mono)
clasohm@0
    48
      ["<true,true> : POgen(R)",
clasohm@0
    49
       "<false,false> : POgen(R)",
clasohm@0
    50
       "[| <a,a'> : R;  <b,b'> : R |] ==> <<a,b>,<a',b'>> : POgen(R)",
clasohm@0
    51
       "[|!!x. <b(x),b'(x)> : R |] ==><lam x.b(x),lam x.b'(x)> : POgen(R)",
clasohm@0
    52
       "<one,one> : POgen(R)",
clasohm@0
    53
       "<a,a'> : lfp(%x. POgen(x) Un R Un PO) ==> \
clasohm@0
    54
\                         <inl(a),inl(a')> : POgen(lfp(%x. POgen(x) Un R Un PO))",
clasohm@0
    55
       "<b,b'> : lfp(%x. POgen(x) Un R Un PO) ==> \
clasohm@0
    56
\                         <inr(b),inr(b')> : POgen(lfp(%x. POgen(x) Un R Un PO))",
clasohm@0
    57
       "<zero,zero> : POgen(lfp(%x. POgen(x) Un R Un PO))",
clasohm@0
    58
       "<n,n'> : lfp(%x. POgen(x) Un R Un PO) ==> \
clasohm@0
    59
\                         <succ(n),succ(n')> : POgen(lfp(%x. POgen(x) Un R Un PO))",
clasohm@0
    60
       "<[],[]> : POgen(lfp(%x. POgen(x) Un R Un PO))",
clasohm@0
    61
       "[| <h,h'> : lfp(%x. POgen(x) Un R Un PO); \
clasohm@0
    62
\          <t,t'> : lfp(%x. POgen(x) Un R Un PO) |] ==> \
clasohm@0
    63
\       <h.t,h'.t'> : POgen(lfp(%x. POgen(x) Un R Un PO))"];
clasohm@0
    64
clasohm@0
    65
fun POgen_tac (rla,rlb) i =
clasohm@0
    66
       SELECT_GOAL (safe_tac ccl_cs) i THEN
clasohm@0
    67
       rtac (rlb RS (rla RS ssubst_pair)) i THEN
clasohm@0
    68
       (REPEAT (resolve_tac (POgenIs @ [PO_refl RS (POgen_mono RS ci3_AI)] @ 
clasohm@0
    69
                   (POgenIs RL [POgen_mono RS ci3_AgenI]) @ [POgen_mono RS ci3_RI]) i));
clasohm@0
    70
clasohm@0
    71
(** EQgen **)
clasohm@0
    72
clasohm@0
    73
goal Term.thy "<a,a> : EQ";
clasohm@0
    74
br (refl RS (EQ_iff RS iffD1)) 1;
clasohm@0
    75
val EQ_refl = result();
clasohm@0
    76
clasohm@0
    77
val EQgenIs = map (mk_genIs Term.thy data_defs EQgenXH EQgen_mono)
clasohm@0
    78
      ["<true,true> : EQgen(R)",
clasohm@0
    79
       "<false,false> : EQgen(R)",
clasohm@0
    80
       "[| <a,a'> : R;  <b,b'> : R |] ==> <<a,b>,<a',b'>> : EQgen(R)",
clasohm@0
    81
       "[|!!x. <b(x),b'(x)> : R |] ==> <lam x.b(x),lam x.b'(x)> : EQgen(R)",
clasohm@0
    82
       "<one,one> : EQgen(R)",
clasohm@0
    83
       "<a,a'> : lfp(%x. EQgen(x) Un R Un EQ) ==> \
clasohm@0
    84
\                         <inl(a),inl(a')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))",
clasohm@0
    85
       "<b,b'> : lfp(%x. EQgen(x) Un R Un EQ) ==> \
clasohm@0
    86
\                         <inr(b),inr(b')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))",
clasohm@0
    87
       "<zero,zero> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))",
clasohm@0
    88
       "<n,n'> : lfp(%x. EQgen(x) Un R Un EQ) ==> \
clasohm@0
    89
\                         <succ(n),succ(n')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))",
clasohm@0
    90
       "<[],[]> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))",
clasohm@0
    91
       "[| <h,h'> : lfp(%x. EQgen(x) Un R Un EQ); \
clasohm@0
    92
\          <t,t'> : lfp(%x. EQgen(x) Un R Un EQ) |] ==> \
clasohm@0
    93
\       <h.t,h'.t'> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))"];
clasohm@0
    94
clasohm@0
    95
fun EQgen_raw_tac i =
clasohm@0
    96
       (REPEAT (resolve_tac (EQgenIs @ [EQ_refl RS (EQgen_mono RS ci3_AI)] @ 
clasohm@0
    97
                   (EQgenIs RL [EQgen_mono RS ci3_AgenI]) @ [EQgen_mono RS ci3_RI]) i));
clasohm@0
    98
clasohm@0
    99
(* Goals of the form R <= EQgen(R) - rewrite elements <a,b> : EQgen(R) using rews and *)
clasohm@0
   100
(* then reduce this to a goal <a',b'> : R (hopefully?)                                *)
clasohm@0
   101
(*      rews are rewrite rules that would cause looping in the simpifier              *)
clasohm@0
   102
clasohm@0
   103
fun EQgen_tac simp_set rews i = 
clasohm@0
   104
       SELECT_GOAL (TRY (safe_tac ccl_cs) THEN
clasohm@0
   105
                    resolve_tac ((rews@[refl]) RL ((rews@[refl]) RL [ssubst_pair])) i THEN
clasohm@0
   106
                    ALLGOALS (SIMP_TAC simp_set) THEN
clasohm@0
   107
                    ALLGOALS EQgen_raw_tac) i;