src/Pure/Tools/codegen_func.ML
author haftmann
Fri, 26 Jan 2007 13:59:04 +0100
changeset 22197 461130ccfef4
parent 22185 24bf0e403526
child 22211 e2b5f3d24a17
permissions -rw-r--r--
clarified code
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/Tools/codegen_func.ML
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     2
    ID:         $Id$
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     4
22185
haftmann
parents: 22049
diff changeset
     5
Basic handling of defining equations ("func"s) for code generator framework.
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     6
*)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     7
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     8
signature CODEGEN_FUNC =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     9
sig
22185
haftmann
parents: 22049
diff changeset
    10
  val assert_rew: thm -> thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    11
  val mk_rew: thm -> thm list
22185
haftmann
parents: 22049
diff changeset
    12
  val assert_func: thm -> thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    13
  val mk_func: thm -> (CodegenConsts.const * thm) list
22185
haftmann
parents: 22049
diff changeset
    14
  val mk_head: thm -> CodegenConsts.const * thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    15
  val dest_func: thm -> (string * typ) * term list
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    16
  val typ_func: thm -> typ
22185
haftmann
parents: 22049
diff changeset
    17
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
    18
  val inst_thm: sort Vartab.table -> thm -> thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    19
  val expand_eta: int -> thm -> thm
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    20
  val rewrite_func: thm list -> thm -> thm
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    21
end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    22
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    23
structure CodegenFunc : CODEGEN_FUNC =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    24
struct
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    25
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    26
fun lift_thm_thy f thm = f (Thm.theory_of_thm thm) thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    27
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    28
fun bad_thm msg thm =
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    29
  error (msg ^ ": " ^ string_of_thm thm);
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    30
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    31
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    32
(* making rewrite theorems *)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    33
22185
haftmann
parents: 22049
diff changeset
    34
fun assert_rew thm =
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    35
  let
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    36
    val thy = Thm.theory_of_thm thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    37
    val (lhs, rhs) = (Logic.dest_equals o Thm.prop_of) thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    38
    fun vars_of t = fold_aterms
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    39
     (fn Var (v, _) => insert (op =) v
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    40
       | Free _ => bad_thm "Illegal free variable in rewrite theorem" thm
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    41
       | _ => I) t [];
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    42
    fun tvars_of t = fold_term_types
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    43
     (fn _ => fold_atyps (fn TVar (v, _) => insert (op =) v
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    44
                          | TFree _ => bad_thm "Illegal free type variable in rewrite theorem" thm)) t [];
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    45
    val lhs_vs = vars_of lhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    46
    val rhs_vs = vars_of rhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    47
    val lhs_tvs = tvars_of lhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    48
    val rhs_tvs = tvars_of lhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    49
    val _ = if null (subtract (op =) lhs_vs rhs_vs)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    50
      then ()
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    51
      else bad_thm "Free variables on right hand side of rewrite theorems" thm
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    52
    val _ = if null (subtract (op =) lhs_tvs rhs_tvs)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    53
      then ()
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    54
      else bad_thm "Free type variables on right hand side of rewrite theorems" thm
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    55
  in thm end;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    56
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    57
fun mk_rew thm =
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    58
  let
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    59
    val thy = Thm.theory_of_thm thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    60
    val thms = (#mk o #mk_rews o snd o MetaSimplifier.rep_ss o Simplifier.simpset_of) thy thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    61
  in
22185
haftmann
parents: 22049
diff changeset
    62
    map assert_rew thms
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    63
  end;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    64
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    65
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
    66
(* making defining equations *)
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    67
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    68
val typ_func = lift_thm_thy (fn thy => snd o dest_Const o fst o strip_comb
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    69
  o fst o Logic.dest_equals o ObjectLogic.drop_judgment thy o Drule.plain_prop_of);
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    70
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    71
val dest_func = lift_thm_thy (fn thy => apfst dest_Const o strip_comb
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    72
  o fst o Logic.dest_equals o ObjectLogic.drop_judgment thy o Drule.plain_prop_of
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    73
  o Drule.fconv_rule Drule.beta_eta_conversion);
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    74
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    75
val mk_head = lift_thm_thy (fn thy => fn thm =>
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    76
  ((CodegenConsts.norm_of_typ thy o fst o dest_func) thm, thm));
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    77
22185
haftmann
parents: 22049
diff changeset
    78
fun assert_func thm = case try dest_func thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    79
 of SOME (c_ty as (c, ty), args) =>
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    80
      let
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    81
        val thy = Thm.theory_of_thm thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    82
        val _ =
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    83
          if has_duplicates (op =)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    84
            ((fold o fold_aterms) (fn Var (v, _) => cons v
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    85
              | _ => I
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    86
            ) args [])
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
    87
          then bad_thm "Repeated variables on left hand side of defining equation" thm
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    88
          else ()
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
    89
        fun no_abs (Abs _) = bad_thm "Abstraction on left hand side of defining equation" thm 
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    90
          | no_abs (t1 $ t2) = (no_abs t1; no_abs t2)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    91
          | no_abs _ = ();
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    92
        val _ = map no_abs args;
22185
haftmann
parents: 22049
diff changeset
    93
      in thm end
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
    94
  | NONE => bad_thm "Not a defining equation" thm;
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    95
22185
haftmann
parents: 22049
diff changeset
    96
val mk_func = map (mk_head o assert_func) o mk_rew;
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    97
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    98
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
    99
(* utilities *)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   100
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   101
fun inst_thm tvars' thm =
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   102
  let
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   103
    val thy = Thm.theory_of_thm thm;
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   104
    val tvars = (Term.add_tvars o Thm.prop_of) thm [];
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   105
    fun mk_inst (tvar as (v, _)) = case Vartab.lookup tvars' v
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   106
     of SOME sort => SOME (pairself (Thm.ctyp_of thy o TVar) (tvar, (v, sort)))
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   107
      | NONE => NONE;
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   108
    val insts = map_filter mk_inst tvars;
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   109
  in Thm.instantiate (insts, []) thm end;
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   110
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   111
fun expand_eta k thm =
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   112
  let
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   113
    val thy = Thm.theory_of_thm thm;
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   114
    val (lhs, rhs) = (Logic.dest_equals o Drule.plain_prop_of) thm;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   115
    val (head, args) = strip_comb lhs;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   116
    val l = if k = ~1
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   117
      then (length o fst o strip_abs) rhs
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   118
      else Int.max (0, k - length args);
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   119
    val used = Name.make_context (map (fst o fst) (Term.add_vars lhs []));
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   120
    fun get_name _ 0 used = ([], used)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   121
      | get_name (Abs (v, ty, t)) k used =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   122
          used
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   123
          |> Name.variants [v]
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   124
          ||>> get_name t (k - 1)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   125
          |>> (fn ([v'], vs') => (v', ty) :: vs')
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   126
      | get_name t k used = 
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   127
          let
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   128
            val (tys, _) = (strip_type o fastype_of) t
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   129
          in case tys
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   130
           of [] => raise TERM ("expand_eta", [t])
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   131
            | ty :: _ =>
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   132
                used
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   133
                |> Name.variants [""]
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   134
                |-> (fn [v] => get_name (t $ Var ((v, 0), ty)) (k - 1)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   135
                #>> (fn vs' => (v, ty) :: vs'))
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   136
          end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   137
    val (vs, _) = get_name rhs l used;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   138
    val vs_refl = map (fn (v, ty) => Thm.reflexive (Thm.cterm_of thy (Var ((v, 0), ty)))) vs;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   139
  in
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   140
    fold (fn refl => fn thm => Thm.combination thm refl) vs_refl thm
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   141
  end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   142
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   143
fun rewrite_func rewrites thm =
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   144
  let
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   145
    val rewrite = MetaSimplifier.rewrite false rewrites;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   146
    val (ct_eq, [ct_lhs, ct_rhs]) = (Drule.strip_comb o Thm.cprop_of) thm;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   147
    val Const ("==", _) = Thm.term_of ct_eq;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   148
    val (ct_f, ct_args) = Drule.strip_comb ct_lhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   149
    val rhs' = rewrite ct_rhs;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   150
    val args' = map rewrite ct_args;
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   151
    val lhs' = Thm.symmetric (fold (fn th1 => fn th2 => Thm.combination th2 th1)
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   152
      args' (Thm.reflexive ct_f));
22197
461130ccfef4 clarified code
haftmann
parents: 22185
diff changeset
   153
  in Thm.transitive (Thm.transitive lhs' thm) rhs' end;
22033
8e19bad4125f moved a lot to codegen_func.ML
haftmann
parents: 22023
diff changeset
   154
22023
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
   155
end;