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