| author | wenzelm | 
| Wed, 10 Oct 2007 17:32:00 +0200 | |
| changeset 24952 | f336c36f41a0 | 
| parent 24917 | 8b97a94ab187 | 
| child 25336 | 027a63deb61c | 
| permissions | -rw-r--r-- | 
| 24219 | 1 | (* Title: Pure/Isar/code_unit.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Florian Haftmann, TU Muenchen | |
| 4 | ||
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 5 | Basic notions of code generation. Auxiliary. | 
| 24219 | 6 | *) | 
| 7 | ||
| 8 | signature CODE_UNIT = | |
| 9 | sig | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 10 | (*generic non-sense*) | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 11 | val bad_thm: string -> 'a | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 12 | val error_thm: (thm -> thm) -> thm -> thm | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 13 | val warning_thm: (thm -> thm) -> thm -> thm option | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 14 | val try_thm: (thm -> thm) -> thm -> thm option | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 15 | |
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 16 | (*typ instantiations*) | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 17 | val typ_sort_inst: Sorts.algebra -> typ * sort | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 18 | -> sort Vartab.table -> sort Vartab.table | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 19 | val inst_thm: sort Vartab.table -> thm -> thm | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 20 | |
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 21 | (*constants*) | 
| 24219 | 22 | val string_of_typ: theory -> typ -> string | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 23 | val string_of_const: theory -> string -> string | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 24 | val no_args: theory -> string -> int | 
| 24219 | 25 | val read_bare_const: theory -> string -> string * typ | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 26 | val read_const: theory -> string -> string | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 27 | val read_const_exprs: theory -> (string list -> string list) | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 28 | -> string list -> bool * string list | 
| 24219 | 29 | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 30 | (*constructor sets*) | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 31 | val constrset_of_consts: theory -> (string * typ) list | 
| 24219 | 32 | -> string * ((string * sort) list * (string * typ list) list) | 
| 33 | ||
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 34 | (*defining equations*) | 
| 24219 | 35 | val assert_rew: thm -> thm | 
| 36 | val mk_rew: thm -> thm | |
| 37 | val mk_func: thm -> thm | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 38 | val head_func: thm -> string * typ | 
| 24219 | 39 | val expand_eta: int -> thm -> thm | 
| 40 | val rewrite_func: thm list -> thm -> thm | |
| 41 | val norm_args: thm list -> thm list | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 42 | val norm_varnames: (string -> string) -> (string -> string) -> thm list -> thm list | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 43 | |
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 44 | (*case certificates*) | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 45 | val case_cert: thm -> string * (int * string list) | 
| 24219 | 46 | end; | 
| 47 | ||
| 48 | structure CodeUnit: CODE_UNIT = | |
| 49 | struct | |
| 50 | ||
| 51 | ||
| 52 | (* auxiliary *) | |
| 53 | ||
| 54 | exception BAD_THM of string; | |
| 55 | fun bad_thm msg = raise BAD_THM msg; | |
| 56 | fun error_thm f thm = f thm handle BAD_THM msg => error msg; | |
| 57 | fun warning_thm f thm = SOME (f thm) handle BAD_THM msg | |
| 58 |   => (warning ("code generator: " ^ msg); NONE);
 | |
| 24624 
b8383b1bbae3
distinction between regular and default code theorems
 haftmann parents: 
24423diff
changeset | 59 | fun try_thm f thm = SOME (f thm) handle BAD_THM _ => NONE; | 
| 24219 | 60 | |
| 61 | fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy); | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 62 | fun string_of_const thy c = case Class.param_const thy c | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 63 | of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco) | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 64 | | NONE => Sign.extern_const thy c; | 
| 24219 | 65 | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 66 | fun no_args thy = length o fst o strip_type o Sign.the_const_type thy; | 
| 24219 | 67 | |
| 68 | (* reading constants as terms and wildcards pattern *) | |
| 69 | ||
| 70 | fun read_bare_const thy raw_t = | |
| 71 | let | |
| 24707 | 72 | val t = Syntax.read_term_global thy raw_t; | 
| 24219 | 73 | in case try dest_Const t | 
| 74 | of SOME c_ty => c_ty | |
| 75 |     | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t)
 | |
| 76 | end; | |
| 77 | ||
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 78 | fun read_const thy = Class.unoverload_const thy o read_bare_const thy; | 
| 24219 | 79 | |
| 80 | local | |
| 81 | ||
| 82 | fun consts_of thy some_thyname = | |
| 83 | let | |
| 84 | val this_thy = Option.map theory some_thyname |> the_default thy; | |
| 85 | val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I) | |
| 86 | ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) []; | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 87 | fun belongs_here thyname c = | 
| 24219 | 88 | not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy)) | 
| 89 | in case some_thyname | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 90 | of NONE => cs | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 91 | | SOME thyname => filter (belongs_here thyname) cs | 
| 24219 | 92 | end; | 
| 93 | ||
| 94 | fun read_const_expr thy "*" = ([], consts_of thy NONE) | |
| 95 | | read_const_expr thy s = if String.isSuffix ".*" s | |
| 96 | then ([], consts_of thy (SOME (unsuffix ".*" s))) | |
| 97 | else ([read_const thy s], []); | |
| 98 | ||
| 99 | in | |
| 100 | ||
| 101 | fun read_const_exprs thy select exprs = | |
| 102 | case (pairself flat o split_list o map (read_const_expr thy)) exprs | |
| 103 | of (consts, []) => (false, consts) | |
| 104 | | (consts, consts') => (true, consts @ select consts'); | |
| 105 | ||
| 106 | end; (*local*) | |
| 107 | ||
| 108 | ||
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 109 | (* constructor sets *) | 
| 24219 | 110 | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 111 | fun constrset_of_consts thy cs = | 
| 24219 | 112 | let | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 113 |     fun no_constr (c, ty) = error ("Not a datatype constructor: " ^ string_of_const thy c
 | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 114 | ^ " :: " ^ string_of_typ thy ty); | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 115 | fun last_typ c_ty ty = | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 116 | let | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 117 | val frees = typ_tfrees ty; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 118 | val (tyco, vs) = ((apsnd o map) (dest_TFree) o dest_Type o snd o strip_type) ty | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 119 | handle TYPE _ => no_constr c_ty | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 120 | val _ = if has_duplicates (eq_fst (op =)) vs then no_constr c_ty else (); | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 121 | val _ = if length frees <> length vs then no_constr c_ty else (); | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 122 | in (tyco, vs) end; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 123 | fun ty_sorts (c, ty) = | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 124 | let | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 125 | val ty_decl = (Logic.unvarifyT o Sign.the_const_type thy) c; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 126 | val (tyco, vs_decl) = last_typ (c, ty) ty_decl; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 127 | val (_, vs) = last_typ (c, ty) ty; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 128 | in ((tyco, map snd vs), (c, (map fst vs, ty_decl))) end; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 129 | fun add ((tyco', sorts'), c) ((tyco, sorts), cs) = | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 130 | let | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 131 | val _ = if tyco' <> tyco | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 132 | then error "Different type constructors in constructor set" | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 133 | else (); | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 134 | val sorts'' = map2 (curry (Sorts.inter_sort (Sign.classes_of thy))) sorts' sorts | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 135 | in ((tyco, sorts), c :: cs) end; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 136 | fun inst vs' (c, (vs, ty)) = | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 137 | let | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 138 | val the_v = the o AList.lookup (op =) (vs ~~ vs'); | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 139 | val ty' = map_atyps (fn TFree (v, _) => TFree (the_v v)) ty; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 140 | in (c, (fst o strip_type) ty') end; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 141 | val c' :: cs' = map ty_sorts cs; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 142 | val ((tyco, sorts), cs'') = fold add cs' (apsnd single c'); | 
| 24848 | 143 | val vs = Name.names Name.context Name.aT sorts; | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 144 | val cs''' = map (inst vs) cs''; | 
| 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 145 | in (tyco, (vs, cs''')) end; | 
| 24219 | 146 | |
| 147 | ||
| 148 | (* dictionary values *) | |
| 149 | ||
| 150 | fun typ_sort_inst algebra = | |
| 151 | let | |
| 152 | val inters = Sorts.inter_sort algebra; | |
| 153 | fun match _ [] = I | |
| 154 | | match (TVar (v, S)) S' = Vartab.map_default (v, []) (fn S'' => inters (S, inters (S', S''))) | |
| 155 | | match (Type (a, Ts)) S = | |
| 156 | fold2 match Ts (Sorts.mg_domain algebra a S) | |
| 157 | in uncurry match end; | |
| 158 | ||
| 159 | ||
| 160 | (* making rewrite theorems *) | |
| 161 | ||
| 162 | fun assert_rew thm = | |
| 163 | let | |
| 164 | val (lhs, rhs) = (Logic.dest_equals o Thm.plain_prop_of) thm | |
| 165 |       handle TERM _ => bad_thm ("Not an equation: " ^ Display.string_of_thm thm)
 | |
| 166 |           | THM _ => bad_thm ("Not an equation: " ^ Display.string_of_thm thm);
 | |
| 167 | fun vars_of t = fold_aterms | |
| 168 | (fn Var (v, _) => insert (op =) v | |
| 169 |        | Free _ => bad_thm ("Illegal free variable in rewrite theorem\n"
 | |
| 170 | ^ Display.string_of_thm thm) | |
| 171 | | _ => I) t []; | |
| 172 | fun tvars_of t = fold_term_types | |
| 173 | (fn _ => fold_atyps (fn TVar (v, _) => insert (op =) v | |
| 174 | | TFree _ => bad_thm | |
| 175 |       ("Illegal free type variable in rewrite theorem\n" ^ Display.string_of_thm thm))) t [];
 | |
| 176 | val lhs_vs = vars_of lhs; | |
| 177 | val rhs_vs = vars_of rhs; | |
| 178 | val lhs_tvs = tvars_of lhs; | |
| 179 | val rhs_tvs = tvars_of lhs; | |
| 180 | val _ = if null (subtract (op =) lhs_vs rhs_vs) | |
| 181 | then () | |
| 182 |       else bad_thm ("Free variables on right hand side of rewrite theorem\n"
 | |
| 183 | ^ Display.string_of_thm thm); | |
| 184 | val _ = if null (subtract (op =) lhs_tvs rhs_tvs) | |
| 185 | then () | |
| 186 |       else bad_thm ("Free type variables on right hand side of rewrite theorem\n"
 | |
| 187 | ^ Display.string_of_thm thm) | |
| 188 | in thm end; | |
| 189 | ||
| 190 | fun mk_rew thm = | |
| 191 | let | |
| 192 | val thy = Thm.theory_of_thm thm; | |
| 193 | val ctxt = ProofContext.init thy; | |
| 194 | in | |
| 195 | thm | |
| 196 | |> LocalDefs.meta_rewrite_rule ctxt | |
| 197 | |> assert_rew | |
| 198 | end; | |
| 199 | ||
| 200 | ||
| 201 | (* making defining equations *) | |
| 202 | ||
| 203 | fun assert_func thm = | |
| 204 | let | |
| 205 | val thy = Thm.theory_of_thm thm; | |
| 206 | val (head, args) = (strip_comb o fst o Logic.dest_equals | |
| 207 | o ObjectLogic.drop_judgment thy o Thm.plain_prop_of) thm; | |
| 208 | val _ = case head of Const _ => () | _ => | |
| 209 |       bad_thm ("Equation not headed by constant\n" ^ Display.string_of_thm thm);
 | |
| 210 | val _ = | |
| 211 | if has_duplicates (op =) | |
| 212 | ((fold o fold_aterms) (fn Var (v, _) => cons v | |
| 213 | | _ => I | |
| 214 | ) args []) | |
| 215 |       then bad_thm ("Duplicated variables on left hand side of equation\n"
 | |
| 216 | ^ Display.string_of_thm thm) | |
| 217 | else () | |
| 218 | fun check _ (Abs _) = bad_thm | |
| 219 |           ("Abstraction on left hand side of equation\n"
 | |
| 220 | ^ Display.string_of_thm thm) | |
| 221 | | check 0 (Var _) = () | |
| 222 | | check _ (Var _) = bad_thm | |
| 223 |           ("Variable with application on left hand side of defining equation\n"
 | |
| 224 | ^ Display.string_of_thm thm) | |
| 225 | | check n (t1 $ t2) = (check (n+1) t1; check 0 t2) | |
| 226 | | check n (Const (_, ty)) = if n <> (length o fst o strip_type) ty | |
| 227 | then bad_thm | |
| 228 |             ("Partially applied constant on left hand side of equation\n"
 | |
| 229 | ^ Display.string_of_thm thm) | |
| 230 | else (); | |
| 231 | val _ = map (check 0) args; | |
| 232 | in thm end; | |
| 233 | ||
| 234 | val mk_func = assert_func o mk_rew; | |
| 235 | ||
| 236 | fun head_func thm = | |
| 237 | let | |
| 238 | val thy = Thm.theory_of_thm thm; | |
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 239 | val Const (c, ty) = (fst o strip_comb o fst o Logic.dest_equals | 
| 24219 | 240 | o ObjectLogic.drop_judgment thy o Thm.plain_prop_of) thm; | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24219diff
changeset | 241 | in (c, ty) end; | 
| 24219 | 242 | |
| 243 | ||
| 244 | (* utilities *) | |
| 245 | ||
| 246 | fun inst_thm tvars' thm = | |
| 247 | let | |
| 248 | val thy = Thm.theory_of_thm thm; | |
| 249 | val tvars = (Term.add_tvars o Thm.prop_of) thm []; | |
| 250 | fun mk_inst (tvar as (v, _)) = case Vartab.lookup tvars' v | |
| 251 | of SOME sort => SOME (pairself (Thm.ctyp_of thy o TVar) (tvar, (v, sort))) | |
| 252 | | NONE => NONE; | |
| 253 | val insts = map_filter mk_inst tvars; | |
| 254 | in Thm.instantiate (insts, []) thm end; | |
| 255 | ||
| 256 | fun expand_eta k thm = | |
| 257 | let | |
| 258 | val thy = Thm.theory_of_thm thm; | |
| 259 | val (lhs, rhs) = (Logic.dest_equals o Thm.plain_prop_of) thm; | |
| 260 | val (head, args) = strip_comb lhs; | |
| 261 | val l = if k = ~1 | |
| 262 | then (length o fst o strip_abs) rhs | |
| 263 | else Int.max (0, k - length args); | |
| 264 | val used = Name.make_context (map (fst o fst) (Term.add_vars lhs [])); | |
| 265 | fun get_name _ 0 used = ([], used) | |
| 266 | | get_name (Abs (v, ty, t)) k used = | |
| 267 | used | |
| 268 | |> Name.variants [v] | |
| 269 | ||>> get_name t (k - 1) | |
| 270 | |>> (fn ([v'], vs') => (v', ty) :: vs') | |
| 271 | | get_name t k used = | |
| 272 | let | |
| 273 | val (tys, _) = (strip_type o fastype_of) t | |
| 274 | in case tys | |
| 275 |            of [] => raise TERM ("expand_eta", [t])
 | |
| 276 | | ty :: _ => | |
| 277 | used | |
| 278 | |> Name.variants [""] | |
| 279 | |-> (fn [v] => get_name (t $ Var ((v, 0), ty)) (k - 1) | |
| 280 | #>> (fn vs' => (v, ty) :: vs')) | |
| 281 | end; | |
| 282 | val (vs, _) = get_name rhs l used; | |
| 283 | val vs_refl = map (fn (v, ty) => Thm.reflexive (Thm.cterm_of thy (Var ((v, 0), ty)))) vs; | |
| 284 | in | |
| 285 | thm | |
| 286 | |> fold (fn refl => fn thm => Thm.combination thm refl) vs_refl | |
| 287 | |> Conv.fconv_rule Drule.beta_eta_conversion | |
| 288 | end; | |
| 289 | ||
| 290 | fun rewrite_func rewrites thm = | |
| 291 | let | |
| 292 | val rewrite = MetaSimplifier.rewrite false rewrites; | |
| 293 | val (ct_eq, [ct_lhs, ct_rhs]) = (Drule.strip_comb o Thm.cprop_of) thm; | |
| 294 |     val Const ("==", _) = Thm.term_of ct_eq;
 | |
| 295 | val (ct_f, ct_args) = Drule.strip_comb ct_lhs; | |
| 296 | val rhs' = rewrite ct_rhs; | |
| 297 | val args' = map rewrite ct_args; | |
| 298 | val lhs' = Thm.symmetric (fold (fn th1 => fn th2 => Thm.combination th2 th1) | |
| 299 | args' (Thm.reflexive ct_f)); | |
| 300 | in Thm.transitive (Thm.transitive lhs' thm) rhs' end; | |
| 301 | ||
| 302 | fun norm_args thms = | |
| 303 | let | |
| 304 | val num_args_of = length o snd o strip_comb o fst o Logic.dest_equals; | |
| 305 | val k = fold (curry Int.max o num_args_of o Thm.plain_prop_of) thms 0; | |
| 306 | in | |
| 307 | thms | |
| 308 | |> map (expand_eta k) | |
| 309 | |> map (Conv.fconv_rule Drule.beta_eta_conversion) | |
| 310 | end; | |
| 311 | ||
| 312 | fun canonical_tvars purify_tvar thm = | |
| 313 | let | |
| 314 | val ctyp = Thm.ctyp_of (Thm.theory_of_thm thm); | |
| 315 | fun tvars_subst_for thm = (fold_types o fold_atyps) | |
| 316 | (fn TVar (v_i as (v, _), sort) => let | |
| 317 | val v' = purify_tvar v | |
| 318 | in if v = v' then I | |
| 319 | else insert (op =) (v_i, (v', sort)) end | |
| 320 | | _ => I) (prop_of thm) []; | |
| 321 | fun mk_inst (v_i, (v', sort)) (maxidx, acc) = | |
| 322 | let | |
| 323 | val ty = TVar (v_i, sort) | |
| 324 | in | |
| 325 | (maxidx + 1, (ctyp ty, ctyp (TVar ((v', maxidx), sort))) :: acc) | |
| 326 | end; | |
| 327 | val maxidx = Thm.maxidx_of thm + 1; | |
| 328 | val (_, inst) = fold mk_inst (tvars_subst_for thm) (maxidx + 1, []); | |
| 329 | in Thm.instantiate (inst, []) thm end; | |
| 330 | ||
| 331 | fun canonical_vars purify_var thm = | |
| 332 | let | |
| 333 | val cterm = Thm.cterm_of (Thm.theory_of_thm thm); | |
| 334 | fun vars_subst_for thm = fold_aterms | |
| 335 | (fn Var (v_i as (v, _), ty) => let | |
| 336 | val v' = purify_var v | |
| 337 | in if v = v' then I | |
| 338 | else insert (op =) (v_i, (v', ty)) end | |
| 339 | | _ => I) (prop_of thm) []; | |
| 340 | fun mk_inst (v_i as (v, i), (v', ty)) (maxidx, acc) = | |
| 341 | let | |
| 342 | val t = Var (v_i, ty) | |
| 343 | in | |
| 344 | (maxidx + 1, (cterm t, cterm (Var ((v', maxidx), ty))) :: acc) | |
| 345 | end; | |
| 346 | val maxidx = Thm.maxidx_of thm + 1; | |
| 347 | val (_, inst) = fold mk_inst (vars_subst_for thm) (maxidx + 1, []); | |
| 348 | in Thm.instantiate ([], inst) thm end; | |
| 349 | ||
| 350 | fun canonical_absvars purify_var thm = | |
| 351 | let | |
| 352 | val t = Thm.plain_prop_of thm; | |
| 353 | val t' = Term.map_abs_vars purify_var t; | |
| 354 | in Thm.rename_boundvars t t' thm end; | |
| 355 | ||
| 356 | fun norm_varnames purify_tvar purify_var thms = | |
| 357 | let | |
| 358 | fun burrow_thms f [] = [] | |
| 359 | | burrow_thms f thms = | |
| 360 | thms | |
| 361 | |> Conjunction.intr_balanced | |
| 362 | |> f | |
| 363 | |> Conjunction.elim_balanced (length thms) | |
| 364 | in | |
| 365 | thms | |
| 366 | |> burrow_thms (canonical_tvars purify_tvar) | |
| 367 | |> map (canonical_vars purify_var) | |
| 368 | |> map (canonical_absvars purify_var) | |
| 369 | |> map Drule.zero_var_indexes | |
| 370 | end; | |
| 371 | ||
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 372 | |
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 373 | (* case cerificates *) | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 374 | |
| 24917 | 375 | fun case_certificate thm = | 
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 376 | let | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 377 | val thy = Thm.theory_of_thm thm; | 
| 24917 | 378 | val ((head, raw_case_expr), cases) = (apfst Logic.dest_equals | 
| 379 | o apsnd Logic.dest_conjunctions o Logic.dest_implies o Thm.prop_of) thm; | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 380 | val _ = case head of Free _ => true | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 381 | | Var _ => true | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 382 |       | _ => raise TERM ("case_cert", []);
 | 
| 24917 | 383 | val ([(case_var, _)], case_expr) = Term.strip_abs_eta 1 raw_case_expr; | 
| 384 | val (Const (case_const, _), raw_params) = strip_comb case_expr; | |
| 385 | val n = find_index (fn Free (v, _) => v = case_var | _ => false) raw_params; | |
| 386 |     val _ = if n = ~1 then raise TERM ("case_cert", []) else ();
 | |
| 387 | val params = map (fst o dest_Var) (nth_drop n raw_params); | |
| 388 | fun dest_case t = | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 389 | let | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 390 | val (head' $ t_co, rhs) = Logic.dest_equals t; | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 391 |         val _ = if head' = head then () else raise TERM ("case_cert", []);
 | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 392 | val (Const (co, _), args) = strip_comb t_co; | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 393 | val (Var (param, _), args') = strip_comb rhs; | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 394 |         val _ = if args' = args then () else raise TERM ("case_cert", []);
 | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 395 | in (param, co) end; | 
| 24917 | 396 | fun analyze_cases cases = | 
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 397 | let | 
| 24917 | 398 | val co_list = fold (AList.update (op =) o dest_case) cases []; | 
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 399 | in map (the o AList.lookup (op =) co_list) params end; | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 400 | fun analyze_let t = | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 401 | let | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 402 | val (head' $ arg, Var (param', _) $ arg') = Logic.dest_equals t; | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 403 |         val _ = if head' = head then () else raise TERM ("case_cert", []);
 | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 404 |         val _ = if arg' = arg then () else raise TERM ("case_cert", []);
 | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 405 |         val _ = if [param'] = params then () else raise TERM ("case_cert", []);
 | 
| 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 406 | in [] end; | 
| 24917 | 407 | fun analyze (cases as [let_case]) = | 
| 408 | (analyze_cases cases handle Bind => analyze_let let_case) | |
| 409 | | analyze cases = analyze_cases cases; | |
| 410 | in (case_const, (n, analyze cases)) end; | |
| 411 | ||
| 412 | fun case_cert thm = case_certificate thm | |
| 413 | handle Bind => error "bad case certificate" | |
| 414 | | TERM _ => error "bad case certificate"; | |
| 24844 
98c006a30218
certificates for code generator case expressions
 haftmann parents: 
24707diff
changeset | 415 | |
| 24219 | 416 | end; |