src/HOL/Tools/transfer.ML
author huffman
Tue, 03 Apr 2012 22:31:00 +0200
changeset 47325 ec6187036495
child 47327 600e6b07a693
permissions -rw-r--r--
new transfer proof method
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
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    11
  val transfer_add: attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    12
  val transfer_del: attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    13
  val transfer_tac: Proof.context -> int -> tactic
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    14
  val correspondence_tac: Proof.context -> int -> tactic
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    15
  val setup: theory -> theory
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    16
end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    17
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    18
structure Transfer : TRANSFER =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    19
struct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    20
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    21
structure Data = Named_Thms
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    22
(
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    23
  val name = @{binding transfer_raw}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    24
  val description = "raw correspondence rule for transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    25
)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    26
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    27
(** Conversions **)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    28
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    29
val App_rule = Thm.symmetric @{thm App_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    30
val Abs_rule = Thm.symmetric @{thm Abs_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    31
val Rel_rule = Thm.symmetric @{thm Rel_def}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    32
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    33
fun dest_funcT cT =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    34
  (case Thm.dest_ctyp cT of [T, U] => (T, U)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    35
    | _ => raise TYPE ("dest_funcT", [Thm.typ_of cT], []))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    36
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    37
fun App_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    38
  let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    39
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] App_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    40
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    41
fun Abs_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    42
  let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    43
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Abs_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    44
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    45
fun Rel_conv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    46
  let val (cT, cT') = dest_funcT (Thm.ctyp_of_term ct)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    47
      val (cU, _) = dest_funcT cT'
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    48
  in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Rel_rule end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    49
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    50
fun Trueprop_conv cv ct =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    51
  (case Thm.term_of ct of
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    52
    Const (@{const_name Trueprop}, _) $ _ => Conv.arg_conv cv ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    53
  | _ => raise CTERM ("Trueprop_conv", [ct]))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    54
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    55
(* Conversion to insert tags on every application and abstraction. *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    56
fun fo_conv ctxt ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    57
      Conv.combination_conv (fo_conv ctxt then_conv App_conv) (fo_conv ctxt)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    58
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    59
      Conv.abs_conv (fo_conv o snd) ctxt then_conv Abs_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    60
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    61
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    62
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    63
(* Conversion to preprocess a correspondence rule *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    64
fun prep_conv ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    65
      Conv.implies_conv Conv.all_conv prep_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    66
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    67
      Trueprop_conv (Conv.fun_conv (Conv.fun_conv Rel_conv))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    68
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    69
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    70
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    71
(* Conversion to prep a proof goal containing a correspondence rule *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    72
fun correspond_conv ctxt ct = (
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    73
      Conv.forall_conv (correspond_conv o snd) ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    74
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    75
      Conv.implies_conv Conv.all_conv (correspond_conv ctxt)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    76
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    77
      Trueprop_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    78
      (Conv.combination_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    79
         (Conv.combination_conv Rel_conv (fo_conv ctxt)) (fo_conv ctxt))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    80
      else_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    81
      Conv.all_conv) ct
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    82
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    83
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    84
(** Transfer proof method **)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    85
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    86
fun bnames (t $ u) = bnames t @ bnames u
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    87
  | bnames (Abs (x,_,t)) = x :: bnames t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    88
  | bnames _ = []
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    89
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    90
fun rename [] t = (t, [])
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    91
  | rename (x::xs) ((c as Const (@{const_name Abs}, _)) $ Abs (_, T, t)) =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    92
    let val (t', xs') = rename xs t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    93
    in (c $ Abs (x, T, t'), xs') end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    94
  | rename xs0 (t $ u) =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    95
    let val (t', xs1) = rename xs0 t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    96
        val (u', xs2) = rename xs1 u
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    97
    in (t' $ u', xs2) end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    98
  | rename xs t = (t, xs)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
    99
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   100
fun cert ctxt t = cterm_of (Proof_Context.theory_of ctxt) t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   101
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   102
fun RelT (Const (@{const_name Rel}, _) $ _ $ _ $ y) = fastype_of y
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   103
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   104
(* Tactic to correspond a value to itself *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   105
fun eq_tac ctxt = SUBGOAL (fn (t, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   106
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   107
    val T = RelT (HOLogic.dest_Trueprop (Logic.strip_assums_concl t))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   108
    val cT = ctyp_of (Proof_Context.theory_of ctxt) T
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   109
    val rews = [@{thm fun_rel_eq [symmetric, THEN eq_reflection]}]
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   110
    val thm1 = Drule.instantiate' [SOME cT] [] @{thm Rel_eq_refl}
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   111
    val thm2 = Raw_Simplifier.rewrite_rule rews thm1
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   112
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   113
    rtac thm2 i
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   114
  end handle Match => no_tac | TERM _ => no_tac)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   115
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   116
fun transfer_tac ctxt = SUBGOAL (fn (t, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   117
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   118
    val bs = bnames t
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   119
    val rules = Data.get ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   120
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   121
    EVERY
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   122
      [rewrite_goal_tac @{thms transfer_forall_eq transfer_implies_eq} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   123
       CONVERSION (Trueprop_conv (fo_conv ctxt)) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   124
       rtac @{thm transfer_start [rotated]} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   125
       REPEAT_ALL_NEW (resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) (i + 1),
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   126
       (* Alpha-rename bound variables in goal *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   127
       SUBGOAL (fn (u, i) =>
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   128
         rtac @{thm equal_elim_rule1} i THEN
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   129
         rtac (Thm.reflexive (cert ctxt (fst (rename bs u)))) i) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   130
       (* FIXME: rewrite_goal_tac does unwanted eta-contraction *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   131
       rewrite_goal_tac @{thms App_def Abs_def} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   132
       rewrite_goal_tac @{thms transfer_forall_eq [symmetric] transfer_implies_eq [symmetric]} i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   133
       rtac @{thm _} i]
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   134
  end)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   135
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   136
fun correspondence_tac ctxt i =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   137
  let
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   138
    val rules = Data.get ctxt
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   139
  in
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   140
    EVERY
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   141
      [CONVERSION (correspond_conv ctxt) i,
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   142
       REPEAT_ALL_NEW
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   143
         (resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) i]
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   144
  end
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   145
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   146
val transfer_method =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   147
  Scan.succeed (fn ctxt => SIMPLE_METHOD' (transfer_tac ctxt))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   148
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   149
val correspondence_method =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   150
  Scan.succeed (fn ctxt => SIMPLE_METHOD' (correspondence_tac ctxt))
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   151
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   152
(* Attribute for correspondence rules *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   153
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   154
val prep_rule = Conv.fconv_rule prep_conv
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   155
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   156
val transfer_add =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   157
  Thm.declaration_attribute (Data.add_thm o prep_rule)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   158
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   159
val transfer_del =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   160
  Thm.declaration_attribute (Data.del_thm o prep_rule)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   161
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   162
val transfer_attribute =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   163
  Attrib.add_del transfer_add transfer_del
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   164
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   165
(* Theory setup *)
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   166
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   167
val setup =
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   168
  Data.setup
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   169
  #> Attrib.setup @{binding transfer_rule} transfer_attribute
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   170
     "correspondence rule for transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   171
  #> Method.setup @{binding transfer} transfer_method
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   172
     "generic theorem transfer method"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   173
  #> Method.setup @{binding correspondence} correspondence_method
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   174
     "for proving correspondence rules"
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   175
ec6187036495 new transfer proof method
huffman
parents:
diff changeset
   176
end