src/Pure/Tools/codegen_func.ML
author aspinall
Sun, 07 Jan 2007 14:05:44 +0100
changeset 22028 c13f6b5bf2b8
parent 22023 487b79b95a20
child 22033 8e19bad4125f
permissions -rw-r--r--
Be more chatty in PGIP file operations.
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
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     5
Handling defining equations ("func"s) for code generator framework
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
(* FIXME move various stuff here *)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
     9
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    10
signature CODEGEN_FUNC =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    11
sig
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    12
  val expand_eta: theory -> int -> thm -> thm
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    13
end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    14
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    15
structure CodegenFunc : CODEGEN_FUNC =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    16
struct
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    17
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    18
(* FIXME get rid of this code duplication *)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    19
val purify_name =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    20
  let
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    21
    fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    22
    val is_junk = not o is_valid andf Symbol.not_eof;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    23
    val junk = Scan.many is_junk;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    24
    val scan_valids = Symbol.scanner "Malformed input"
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    25
      ((junk |--
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    26
        (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    27
        --| junk))
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    28
      -- Scan.repeat ((Scan.many1 is_valid >> implode) --| junk) >> op ::);
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    29
  in explode #> scan_valids #> space_implode "_" end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    30
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    31
val purify_lower =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    32
  explode
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    33
  #> (fn cs => (if forall Symbol.is_ascii_upper cs
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    34
        then map else nth_map 0) Symbol.to_ascii_lower cs)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    35
  #> implode;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    36
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    37
fun purify_var "" = "x"
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    38
  | purify_var v = (purify_name #> purify_lower) v;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    39
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    40
fun expand_eta thy k thm =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    41
  let
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    42
    val (lhs, rhs) = (Logic.dest_equals o Drule.plain_prop_of) thm;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    43
    val (head, args) = strip_comb lhs;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    44
    val l = if k = ~1
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    45
      then (length o fst o strip_abs) rhs
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    46
      else Int.max (0, k - length args);
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    47
    val used = Name.make_context (map (fst o fst) (Term.add_vars lhs []));
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    48
    fun get_name _ 0 used = ([], used)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    49
      | get_name (Abs (v, ty, t)) k used =
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    50
          used
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    51
          |> Name.variants [purify_var v]
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    52
          ||>> get_name t (k - 1)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    53
          |>> (fn ([v'], vs') => (v', ty) :: vs')
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    54
      | get_name t k used = 
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    55
          let
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    56
            val (tys, _) = (strip_type o fastype_of) t
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    57
          in case tys
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    58
           of [] => raise TERM ("expand_eta", [t])
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    59
            | ty :: _ =>
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    60
                used
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    61
                |> Name.variants [""]
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    62
                |-> (fn [v] => get_name (t $ Var ((v, 0), ty)) (k - 1)
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    63
                #>> (fn vs' => (v, ty) :: vs'))
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    64
          end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    65
    val (vs, _) = get_name rhs l used;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    66
    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
    67
  in
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    68
    fold (fn refl => fn thm => Thm.combination thm refl) vs_refl thm
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    69
  end;
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    70
487b79b95a20 added codegen_func.ML
haftmann
parents:
diff changeset
    71
end;