src/HOL/Library/cconv.ML
author wenzelm
Tue, 31 Mar 2015 19:39:05 +0200
changeset 59882 ada832308efe
parent 59739 4ed50ebf5d36
child 59975 da10875adf8e
permissions -rw-r--r--
tuned -- avoid exotic Name_Space.defined_entry;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
59739
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     1
infix 1 then_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     2
infix 0 else_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     3
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     4
type cconv = conv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     5
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     6
signature BASIC_CCONV =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     7
sig
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     8
  val then_cconv: cconv * cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
     9
  val else_cconv: cconv * cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    10
  val CCONVERSION: cconv -> int -> tactic
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    11
end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    12
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    13
signature CCONV =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    14
sig
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    15
  include BASIC_CCONV
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    16
  val no_cconv: cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    17
  val all_cconv: cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    18
  val first_cconv: cconv list -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    19
  val abs_cconv: (cterm * Proof.context -> cconv) -> Proof.context -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    20
  val combination_cconv: cconv -> cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    21
  val comb_cconv: cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    22
  val arg_cconv: cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    23
  val fun_cconv: cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    24
  val arg1_cconv: cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    25
  val fun2_cconv: cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    26
  val rewr_cconv: thm -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    27
  val rewrs_cconv: thm list -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    28
  val params_cconv: int -> (Proof.context -> cconv) -> Proof.context -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    29
  val prems_cconv: int -> cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    30
  val concl_cconv: int -> cconv -> cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    31
  val fconv_rule: cconv -> thm -> thm
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    32
  val gconv_rule: cconv -> int -> thm -> thm
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    33
end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    34
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    35
structure CConv : CCONV =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    36
struct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    37
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    38
val concl_lhs_of = Thm.cprop_of #> Drule.strip_imp_concl #> Thm.dest_equals_lhs
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    39
val concl_rhs_of = Thm.cprop_of #> Drule.strip_imp_concl #> Thm.dest_equals_rhs
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    40
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    41
fun transitive th1 th2 = Drule.transitive_thm OF [th1, th2]
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    42
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    43
val combination_thm =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    44
  let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    45
    val fg = @{cprop "f :: 'a :: {} \<Rightarrow> 'b :: {} \<equiv> g"}
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    46
    val st = @{cprop "s :: 'a :: {} \<equiv> t"}
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    47
    val thm = Thm.combination (Thm.assume fg) (Thm.assume st)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    48
      |> Thm.implies_intr st
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    49
      |> Thm.implies_intr fg
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    50
  in Drule.export_without_context thm end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    51
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    52
fun abstract_rule_thm n =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    53
  let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    54
    val eq = @{cprop "\<And>x :: 'a :: {}. (s :: 'a \<Rightarrow> 'b :: {}) x \<equiv> t x"}
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    55
    val x = @{cterm "x :: 'a :: {}"}
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    56
    val thm = eq
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    57
      |> Thm.assume
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    58
      |> Thm.forall_elim x
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    59
      |> Thm.abstract_rule n x
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    60
      |> Thm.implies_intr eq
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    61
  in Drule.export_without_context thm end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    62
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    63
val no_cconv = Conv.no_conv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    64
val all_cconv = Conv.all_conv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    65
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    66
fun (cv1 else_cconv cv2) ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    67
  (cv1 ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    68
    handle THM _ => cv2 ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    69
      | CTERM _ => cv2 ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    70
      | TERM _ => cv2 ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    71
      | TYPE _ => cv2 ct)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    72
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    73
fun (cv1 then_cconv cv2) ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    74
  let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    75
    val eq1 = cv1 ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    76
    val eq2 = cv2 (concl_rhs_of eq1)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    77
  in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    78
    if Thm.is_reflexive eq1 then eq2
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    79
    else if Thm.is_reflexive eq2 then eq1
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    80
    else transitive eq1 eq2
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    81
  end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    82
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    83
fun first_cconv cvs = fold_rev (curry op else_cconv) cvs no_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    84
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    85
fun rewr_cconv rule ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    86
  let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    87
    val rule1 = Thm.incr_indexes (Thm.maxidx_of_cterm ct + 1) rule
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    88
    val lhs = concl_lhs_of rule1
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    89
    val rule2 = Thm.rename_boundvars (Thm.term_of lhs) (Thm.term_of ct) rule1
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    90
    val rule3 = Thm.instantiate (Thm.match (lhs, ct)) rule2
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    91
                handle Pattern.MATCH => raise CTERM ("rewr_cconv", [lhs, ct])
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    92
    val rule4 =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    93
      if concl_lhs_of rule3 aconvc ct then rule3
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    94
      else let val ceq = Thm.dest_fun2 (Thm.cprop_of rule3)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    95
           in rule3 COMP Thm.trivial (Thm.mk_binop ceq ct (concl_rhs_of rule3)) end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    96
  in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    97
    transitive rule4 (Thm.beta_conversion true (concl_rhs_of rule4))
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    98
  end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
    99
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   100
fun rewrs_cconv rules = first_cconv (map rewr_cconv rules)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   101
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   102
fun combination_cconv cv1 cv2 cterm =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   103
  let val (l, r) = Thm.dest_comb cterm
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   104
  in combination_thm OF [cv1 l, cv2 r] end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   105
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   106
fun comb_cconv cv = combination_cconv cv cv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   107
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   108
fun fun_cconv conversion =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   109
  combination_cconv conversion all_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   110
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   111
fun arg_cconv conversion =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   112
  combination_cconv all_cconv conversion
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   113
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   114
fun abs_cconv cv ctxt ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   115
  (case Thm.term_of ct of
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   116
     Abs (x, _, _) =>
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   117
       let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   118
         (* Instantiate the rule properly and apply it to the eq theorem. *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   119
         fun abstract_rule u v eq =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   120
           let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   121
             (* Take a variable v and an equality theorem of form:
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   122
                  P1 Pure.imp ... Pure.imp Pn Pure.imp L v == R v
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   123
                And build a term of form:
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   124
                  !!v. (%x. L x) v == (%x. R x) v *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   125
             fun mk_concl var eq =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   126
               let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   127
                 val certify = Thm.cterm_of ctxt
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   128
                 fun abs term = (Term.lambda var term) $ var
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   129
                 fun equals_cong f t =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   130
                   Logic.dest_equals t
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   131
                   |> (fn (a, b) => (f a, f b))
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   132
                   |> Logic.mk_equals
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   133
               in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   134
                 Thm.concl_of eq
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   135
                 |> equals_cong abs
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   136
                 |> Logic.all var |> certify
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   137
               end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   138
             val rule = abstract_rule_thm x
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   139
             val inst = Thm.match (Drule.cprems_of rule |> hd, mk_concl (Thm.term_of v) eq)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   140
           in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   141
             (Drule.instantiate_normalize inst rule OF [Drule.generalize ([], [u]) eq])
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   142
             |> Drule.zero_var_indexes
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   143
           end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   144
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   145
         (* Destruct the abstraction and apply the conversion. *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   146
         val (u, ctxt') = yield_singleton Variable.variant_fixes Name.uu ctxt
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   147
         val (v, ct') = Thm.dest_abs (SOME u) ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   148
         val eq = cv (v, ctxt') ct'
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   149
       in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   150
         if Thm.is_reflexive eq
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   151
         then all_cconv ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   152
         else abstract_rule u v eq
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   153
       end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   154
   | _ => raise CTERM ("abs_cconv", [ct]))
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   155
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   156
val arg1_cconv = fun_cconv o arg_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   157
val fun2_cconv = fun_cconv o fun_cconv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   158
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   159
(* conversions on HHF rules *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   160
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   161
(*rewrite B in !!x1 ... xn. B*)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   162
fun params_cconv n cv ctxt ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   163
  if n <> 0 andalso Logic.is_all (Thm.term_of ct)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   164
  then arg_cconv (abs_cconv (params_cconv (n - 1) cv o #2) ctxt) ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   165
  else cv ctxt ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   166
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   167
(* TODO: This code behaves not exactly like Conv.prems_cconv does.
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   168
         Fix this! *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   169
(*rewrite the A's in A1 Pure.imp ... Pure.imp An Pure.imp B*)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   170
fun prems_cconv 0 cv ct = cv ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   171
  | prems_cconv n cv ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   172
      (case ct |> Thm.term_of of
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   173
        (Const (@{const_name "Pure.imp"}, _) $ _) $ _ => ((if n = 1 then fun_cconv else I) o arg_cconv) (prems_cconv (n-1) cv) ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   174
      | _ =>  cv ct)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   175
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   176
(*rewrite B in A1 Pure.imp ... Pure.imp An Pure.imp B*)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   177
fun concl_cconv 0 cv ct = cv ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   178
  | concl_cconv n cv ct =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   179
      (case ct |> Thm.term_of of
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   180
        (Const (@{const_name "Pure.imp"}, _) $ _) $ _ => arg_cconv (concl_cconv (n-1) cv) ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   181
      | _ =>  cv ct)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   182
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   183
(*forward conversion, cf. FCONV_RULE in LCF*)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   184
fun fconv_rule cv th =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   185
  let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   186
    val eq = cv (Thm.cprop_of th)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   187
  in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   188
    if Thm.is_reflexive eq then th
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   189
    else th COMP (Thm.permute_prems 0 (Thm.nprems_of eq) (eq RS Drule.equal_elim_rule1))
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   190
  end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   191
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   192
(*goal conversion*)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   193
fun gconv_rule cv i th =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   194
  (case try (Thm.cprem_of th) i of
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   195
    SOME ct =>
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   196
      let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   197
        val eq = cv ct
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   198
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   199
        (* Drule.with_subgoal assumes that there are no new premises generated
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   200
           and thus rotates the premises wrongly. *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   201
        fun with_subgoal i f thm =
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   202
          let
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   203
            val num_prems = Thm.nprems_of thm
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   204
            val rotate_to_front = rotate_prems (i - 1)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   205
            fun rotate_back thm = rotate_prems (1 - i + num_prems - Thm.nprems_of thm) thm
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   206
          in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   207
            thm |> rotate_to_front |> f |> rotate_back
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   208
          end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   209
      in
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   210
        if Thm.is_reflexive eq then th
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   211
        else with_subgoal i (fconv_rule (arg1_cconv (K eq))) th
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   212
      end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   213
  | NONE => raise THM ("gconv_rule", i, [th]))
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   214
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   215
  (* Conditional conversions as tactics. *)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   216
fun CCONVERSION cv i st = Seq.single (gconv_rule cv i st)
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   217
  handle THM _ => Seq.empty
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   218
       | CTERM _ => Seq.empty
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   219
       | TERM _ => Seq.empty
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   220
       | TYPE _ => Seq.empty
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   221
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   222
end
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   223
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   224
structure Basic_CConv: BASIC_CCONV = CConv
4ed50ebf5d36 added proof method rewrite
noschinl
parents:
diff changeset
   225
open Basic_CConv