src/HOL/Tools/transfer.ML
author huffman
Tue, 17 Apr 2012 11:03:08 +0200
changeset 47503 cb44d09d9d22
parent 47356 19fb95255ec9
child 47523 1bf0e92c1ca0
permissions -rw-r--r--
add theory data for relator identity rules; preprocess transfer rules generated by lift_definition using relator rules
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     1
(*  Title:      HOL/Tools/transfer.ML
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     2
    Author:     Brian Huffman, TU Muenchen
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     3
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     4
Generic theorem transfer method.
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     5
*)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     6
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     7
signature TRANSFER =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     8
sig
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
     9
  val fo_conv: Proof.context -> conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    10
  val prep_conv: conv
47503
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    11
  val get_relator_eq: Proof.context -> thm list
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    12
  val transfer_add: attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    13
  val transfer_del: attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    14
  val transfer_tac: Proof.context -> int -> tactic
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    15
  val correspondence_tac: Proof.context -> int -> tactic
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    16
  val setup: theory -> theory
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    17
end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    18
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    19
structure Transfer : TRANSFER =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    20
struct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    21
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    22
structure Data = Named_Thms
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    23
(
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    24
  val name = @{binding transfer_raw}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    25
  val description = "raw correspondence rule for transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    26
)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    27
47503
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    28
structure Relator_Eq = Named_Thms
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    29
(
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    30
  val name = @{binding relator_eq}
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    31
  val description = "relator equality rule (used by transfer method)"
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    32
)
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    33
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    34
fun get_relator_eq ctxt =
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    35
  map (Thm.symmetric o mk_meta_eq) (Relator_Eq.get ctxt)
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
    36
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    37
(** Conversions **)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    38
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    39
val App_rule = Thm.symmetric @{thm App_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    40
val Abs_rule = Thm.symmetric @{thm Abs_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    41
val Rel_rule = Thm.symmetric @{thm Rel_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    42
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    43
fun dest_funcT cT =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    44
  (case Thm.dest_ctyp cT of [T, U] => (T, U)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    45
    | _ => raise TYPE ("dest_funcT", [Thm.typ_of cT], []))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    46
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    47
fun App_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    48
  let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    49
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] App_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    50
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    51
fun Abs_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    52
  let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    53
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Abs_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    54
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    55
fun Rel_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    56
  let val (cT, cT') = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    57
      val (cU, _) = dest_funcT cT'
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    58
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Rel_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    59
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    60
fun Trueprop_conv cv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    61
  (case Thm.term_of ct of
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    62
    Const (@{const_name Trueprop}, _) $ _ => Conv.arg_conv cv ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    63
  | _ => raise CTERM ("Trueprop_conv", [ct]))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    64
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    65
(* Conversion to insert tags on every application and abstraction. *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    66
fun fo_conv ctxt ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    67
      Conv.combination_conv (fo_conv ctxt then_conv App_conv) (fo_conv ctxt)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    68
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    69
      Conv.abs_conv (fo_conv o snd) ctxt then_conv Abs_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    70
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    71
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    72
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    73
(* Conversion to preprocess a correspondence rule *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    74
fun prep_conv ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    75
      Conv.implies_conv Conv.all_conv prep_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    76
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    77
      Trueprop_conv (Conv.fun_conv (Conv.fun_conv Rel_conv))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    78
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    79
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    80
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    81
(* Conversion to prep a proof goal containing a correspondence rule *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    82
fun correspond_conv ctxt ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    83
      Conv.forall_conv (correspond_conv o snd) ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    84
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    85
      Conv.implies_conv Conv.all_conv (correspond_conv ctxt)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    86
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    87
      Trueprop_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    88
      (Conv.combination_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    89
         (Conv.combination_conv Rel_conv (fo_conv ctxt)) (fo_conv ctxt))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    90
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    91
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    92
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    93
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    94
(** Transfer proof method **)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    95
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    96
fun bnames (t $ u) = bnames t @ bnames u
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    97
  | bnames (Abs (x,_,t)) = x :: bnames t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    98
  | bnames _ = []
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    99
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   100
fun rename [] t = (t, [])
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   101
  | rename (x::xs) ((c as Const (@{const_name Abs}, _)) $ Abs (_, T, t)) =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   102
    let val (t', xs') = rename xs t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   103
    in (c $ Abs (x, T, t'), xs') end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   104
  | rename xs0 (t $ u) =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   105
    let val (t', xs1) = rename xs0 t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   106
        val (u', xs2) = rename xs1 u
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   107
    in (t' $ u', xs2) end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   108
  | rename xs t = (t, xs)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   109
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   110
fun cert ctxt t = cterm_of (Proof_Context.theory_of ctxt) t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   111
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   112
fun RelT (Const (@{const_name Rel}, _) $ _ $ _ $ y) = fastype_of y
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   113
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   114
(* Tactic to correspond a value to itself *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   115
fun eq_tac ctxt = SUBGOAL (fn (t, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   116
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   117
    val T = RelT (HOLogic.dest_Trueprop (Logic.strip_assums_concl t))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   118
    val cT = ctyp_of (Proof_Context.theory_of ctxt) T
47503
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
   119
    val rews = get_relator_eq ctxt
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   120
    val thm1 = Drule.instantiate' [SOME cT] [] @{thm Rel_eq_refl}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   121
    val thm2 = Raw_Simplifier.rewrite_rule rews thm1
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   122
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   123
    rtac thm2 i
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   124
  end handle Match => no_tac | TERM _ => no_tac)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   125
47355
3d9d98e0f1a4 add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents: 47327
diff changeset
   126
val post_simps =
3d9d98e0f1a4 add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents: 47327
diff changeset
   127
  @{thms App_def Abs_def transfer_forall_eq [symmetric]
3d9d98e0f1a4 add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents: 47327
diff changeset
   128
    transfer_implies_eq [symmetric] transfer_bforall_unfold}
3d9d98e0f1a4 add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents: 47327
diff changeset
   129
47356
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   130
fun gen_frees_tac keepers ctxt = SUBGOAL (fn (t, i) =>
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   131
  let
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   132
    val vs = rev (Term.add_frees t [])
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   133
    val vs' = filter_out (member (op =) keepers o fst) vs
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   134
  in
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   135
    Induct.arbitrary_tac ctxt 0 vs' i
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   136
  end)
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   137
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   138
fun transfer_tac ctxt = SUBGOAL (fn (t, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   139
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   140
    val bs = bnames t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   141
    val rules = Data.get ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   142
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   143
    EVERY
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   144
      [rewrite_goal_tac @{thms transfer_forall_eq transfer_implies_eq} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   145
       CONVERSION (Trueprop_conv (fo_conv ctxt)) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   146
       rtac @{thm transfer_start [rotated]} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   147
       REPEAT_ALL_NEW (resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) (i + 1),
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   148
       (* Alpha-rename bound variables in goal *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   149
       SUBGOAL (fn (u, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   150
         rtac @{thm equal_elim_rule1} i THEN
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   151
         rtac (Thm.reflexive (cert ctxt (fst (rename bs u)))) i) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   152
       (* FIXME: rewrite_goal_tac does unwanted eta-contraction *)
47355
3d9d98e0f1a4 add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents: 47327
diff changeset
   153
       rewrite_goal_tac post_simps i,
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   154
       rtac @{thm _} i]
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   155
  end)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   156
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   157
fun correspondence_tac ctxt i =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   158
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   159
    val rules = Data.get ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   160
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   161
    EVERY
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   162
      [CONVERSION (correspond_conv ctxt) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   163
       REPEAT_ALL_NEW
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   164
         (resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) i]
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   165
  end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   166
47327
600e6b07a693 add type annotations to make SML happy (cf. ec6187036495)
huffman
parents: 47325
diff changeset
   167
val transfer_method : (Proof.context -> Method.method) context_parser =
47356
19fb95255ec9 transfer method generalizes over free variables in goal
huffman
parents: 47355
diff changeset
   168
  Scan.succeed (fn ctxt => SIMPLE_METHOD' (gen_frees_tac [] ctxt THEN' transfer_tac ctxt))
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   169
47327
600e6b07a693 add type annotations to make SML happy (cf. ec6187036495)
huffman
parents: 47325
diff changeset
   170
val correspondence_method : (Proof.context -> Method.method) context_parser =
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   171
  Scan.succeed (fn ctxt => SIMPLE_METHOD' (correspondence_tac ctxt))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   172
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   173
(* Attribute for correspondence rules *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   174
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   175
val prep_rule = Conv.fconv_rule prep_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   176
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   177
val transfer_add =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   178
  Thm.declaration_attribute (Data.add_thm o prep_rule)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   179
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   180
val transfer_del =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   181
  Thm.declaration_attribute (Data.del_thm o prep_rule)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   182
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   183
val transfer_attribute =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   184
  Attrib.add_del transfer_add transfer_del
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   185
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   186
(* Theory setup *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   187
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   188
val setup =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   189
  Data.setup
47503
cb44d09d9d22 add theory data for relator identity rules;
huffman
parents: 47356
diff changeset
   190
  #> Relator_Eq.setup
47325
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   191
  #> Attrib.setup @{binding transfer_rule} transfer_attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   192
     "correspondence rule for transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   193
  #> Method.setup @{binding transfer} transfer_method
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   194
     "generic theorem transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   195
  #> Method.setup @{binding correspondence} correspondence_method
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   196
     "for proving correspondence rules"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   197
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   198
end