src/Pure/codegen.ML
changeset 17521 0f1c48de39f5
parent 17412 e26cb20ef0cc
child 17549 ee4408eac12c
equal deleted inserted replaced
17520:8581c151adea 17521:0f1c48de39f5
   265 (**** add new code generators to theory ****)
   265 (**** add new code generators to theory ****)
   266 
   266 
   267 fun add_codegen name f thy =
   267 fun add_codegen name f thy =
   268   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   268   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   269     CodegenData.get thy
   269     CodegenData.get thy
   270   in (case assoc (codegens, name) of
   270   in (case AList.lookup (op =) codegens name of
   271       NONE => CodegenData.put {codegens = (name, f) :: codegens,
   271       NONE => CodegenData.put {codegens = (name, f) :: codegens,
   272         tycodegens = tycodegens, consts = consts, types = types,
   272         tycodegens = tycodegens, consts = consts, types = types,
   273         attrs = attrs, preprocs = preprocs, modules = modules,
   273         attrs = attrs, preprocs = preprocs, modules = modules,
   274         test_params = test_params} thy
   274         test_params = test_params} thy
   275     | SOME _ => error ("Code generator " ^ name ^ " already declared"))
   275     | SOME _ => error ("Code generator " ^ name ^ " already declared"))
   276   end;
   276   end;
   277 
   277 
   278 fun add_tycodegen name f thy =
   278 fun add_tycodegen name f thy =
   279   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   279   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   280     CodegenData.get thy
   280     CodegenData.get thy
   281   in (case assoc (tycodegens, name) of
   281   in (case AList.lookup (op =) tycodegens name of
   282       NONE => CodegenData.put {tycodegens = (name, f) :: tycodegens,
   282       NONE => CodegenData.put {tycodegens = (name, f) :: tycodegens,
   283         codegens = codegens, consts = consts, types = types,
   283         codegens = codegens, consts = consts, types = types,
   284         attrs = attrs, preprocs = preprocs, modules = modules,
   284         attrs = attrs, preprocs = preprocs, modules = modules,
   285         test_params = test_params} thy
   285         test_params = test_params} thy
   286     | SOME _ => error ("Code generator " ^ name ^ " already declared"))
   286     | SOME _ => error ("Code generator " ^ name ^ " already declared"))
   290 (**** code attribute ****)
   290 (**** code attribute ****)
   291 
   291 
   292 fun add_attribute name att thy =
   292 fun add_attribute name att thy =
   293   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   293   let val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   294     CodegenData.get thy
   294     CodegenData.get thy
   295   in (case assoc (attrs, name) of
   295   in (case AList.lookup (op =) attrs name of
   296       NONE => CodegenData.put {tycodegens = tycodegens,
   296       NONE => CodegenData.put {tycodegens = tycodegens,
   297         codegens = codegens, consts = consts, types = types,
   297         codegens = codegens, consts = consts, types = types,
   298         attrs = if name = "" then attrs @ [(name, att)] else (name, att) :: attrs,
   298         attrs = if name = "" then attrs @ [(name, att)] else (name, att) :: attrs,
   299         preprocs = preprocs, modules = modules,
   299         preprocs = preprocs, modules = modules,
   300         test_params = test_params} thy
   300         test_params = test_params} thy
   356               | SOME ty =>
   356               | SOME ty =>
   357                   let val U = prep_type thy ty
   357                   let val U = prep_type thy ty
   358                   in if Sign.typ_instance thy (U, T) then U
   358                   in if Sign.typ_instance thy (U, T) then U
   359                     else error ("Illegal type constraint for constant " ^ cname)
   359                     else error ("Illegal type constraint for constant " ^ cname)
   360                   end)
   360                   end)
   361          in (case assoc (consts, (cname, T')) of
   361          in (case AList.lookup (op =) consts (cname, T') of
   362              NONE => CodegenData.put {codegens = codegens,
   362              NONE => CodegenData.put {codegens = codegens,
   363                tycodegens = tycodegens,
   363                tycodegens = tycodegens,
   364                consts = ((cname, T'), syn) :: consts,
   364                consts = ((cname, T'), syn) :: consts,
   365                types = types, attrs = attrs, preprocs = preprocs,
   365                types = types, attrs = attrs, preprocs = preprocs,
   366                modules = modules, test_params = test_params} thy
   366                modules = modules, test_params = test_params} thy
   379   let
   379   let
   380     val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   380     val {codegens, tycodegens, consts, types, attrs, preprocs, modules, test_params} =
   381       CodegenData.get thy;
   381       CodegenData.get thy;
   382     val tc = Sign.intern_type thy s
   382     val tc = Sign.intern_type thy s
   383   in
   383   in
   384     (case assoc (types, tc) of
   384     (case AList.lookup (op =) types tc of
   385        NONE => CodegenData.put {codegens = codegens,
   385        NONE => CodegenData.put {codegens = codegens,
   386          tycodegens = tycodegens, consts = consts,
   386          tycodegens = tycodegens, consts = consts,
   387          types = (tc, syn) :: types, attrs = attrs,
   387          types = (tc, syn) :: types, attrs = attrs,
   388          preprocs = preprocs, modules = modules, test_params = test_params} thy
   388          preprocs = preprocs, modules = modules, test_params = test_params} thy
   389      | SOME _ => error ("Type " ^ tc ^ " already associated with code"))
   389      | SOME _ => error ("Type " ^ tc ^ " already associated with code"))
   390   end) (thy, xs);
   390   end) (thy, xs);
   391 
   391 
   392 fun get_assoc_type thy s = assoc (#types (CodegenData.get thy), s);
   392 fun get_assoc_type thy s = AList.lookup (op =) ((#types o CodegenData.get) thy) s;
   393 
   393 
   394 
   394 
   395 (**** make valid ML identifiers ****)
   395 (**** make valid ML identifiers ****)
   396 
   396 
   397 fun is_ascii_letdig x = Symbol.is_ascii_letter x orelse
   397 fun is_ascii_letdig x = Symbol.is_ascii_letter x orelse
   512     val (illegal, alt_names) = split_list (List.mapPartial (fn s =>
   512     val (illegal, alt_names) = split_list (List.mapPartial (fn s =>
   513       let val s' = mk_id s in if s = s' then NONE else SOME (s, s') end) names)
   513       let val s' = mk_id s in if s = s' then NONE else SOME (s, s') end) names)
   514     val ps = (reserved @ illegal) ~~
   514     val ps = (reserved @ illegal) ~~
   515       variantlist (map (suffix "'") reserved @ alt_names, names);
   515       variantlist (map (suffix "'") reserved @ alt_names, names);
   516 
   516 
   517     fun rename_id s = getOpt (assoc (ps, s), s);
   517     fun rename_id s = AList.lookup (op =) ps s |> the_default s;
   518 
   518 
   519     fun rename (Var ((a, i), T)) = Var ((rename_id a, i), T)
   519     fun rename (Var ((a, i), T)) = Var ((rename_id a, i), T)
   520       | rename (Free (a, T)) = Free (rename_id a, T)
   520       | rename (Free (a, T)) = Free (rename_id a, T)
   521       | rename (Abs (s, T, t)) = Abs (s, T, rename t)
   521       | rename (Abs (s, T, t)) = Abs (s, T, rename t)
   522       | rename (t $ u) = rename t $ rename u
   522       | rename (t $ u) = rename t $ rename u
   746 fun default_tycodegen thy defs gr dep module brack (TVar ((s, i), _)) =
   746 fun default_tycodegen thy defs gr dep module brack (TVar ((s, i), _)) =
   747       SOME (gr, Pretty.str (s ^ (if i = 0 then "" else string_of_int i)))
   747       SOME (gr, Pretty.str (s ^ (if i = 0 then "" else string_of_int i)))
   748   | default_tycodegen thy defs gr dep module brack (TFree (s, _)) =
   748   | default_tycodegen thy defs gr dep module brack (TFree (s, _)) =
   749       SOME (gr, Pretty.str s)
   749       SOME (gr, Pretty.str s)
   750   | default_tycodegen thy defs gr dep module brack (Type (s, Ts)) =
   750   | default_tycodegen thy defs gr dep module brack (Type (s, Ts)) =
   751       (case assoc (#types (CodegenData.get thy), s) of
   751       (case AList.lookup (op =) ((#types o CodegenData.get) thy) s of
   752          NONE => NONE
   752          NONE => NONE
   753        | SOME (ms, aux) =>
   753        | SOME (ms, aux) =>
   754            let
   754            let
   755              val (gr', ps) = foldl_map
   755              val (gr', ps) = foldl_map
   756                (invoke_tycodegen thy defs dep module false)
   756                (invoke_tycodegen thy defs dep module false)
   777   add_tycodegen "default" default_tycodegen];
   777   add_tycodegen "default" default_tycodegen];
   778 
   778 
   779 
   779 
   780 fun mk_struct name s = "structure " ^ name ^ " =\nstruct\n\n" ^ s ^ "end;\n";
   780 fun mk_struct name s = "structure " ^ name ^ " =\nstruct\n\n" ^ s ^ "end;\n";
   781 
   781 
   782 fun add_to_module name s ms =
   782 fun add_to_module name s = AList.map_entry (op =) name (suffix s);
   783   overwrite (ms, (name, the (assoc (ms, name)) ^ s));
       
   784 
   783 
   785 fun output_code gr module xs =
   784 fun output_code gr module xs =
   786   let
   785   let
   787     val code = List.mapPartial (fn s =>
   786     val code = List.mapPartial (fn s =>
   788       let val c as (_, module', _) = Graph.get_node gr s
   787       let val c as (_, module', _) = Graph.get_node gr s
   952     fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t
   951     fun strip (Const ("all", _) $ Abs (_, _, t)) = strip t
   953       | strip t = t;
   952       | strip t = t;
   954     val (gi, frees) = Logic.goal_params
   953     val (gi, frees) = Logic.goal_params
   955       (prop_of (snd (snd (Proof.get_goal (Toplevel.proof_of st))))) i;
   954       (prop_of (snd (snd (Proof.get_goal (Toplevel.proof_of st))))) i;
   956     val gi' = ObjectLogic.atomize_term thy (map_term_types
   955     val gi' = ObjectLogic.atomize_term thy (map_term_types
   957       (map_type_tfree (fn p as (s, _) => getOpt (assoc (tvinsts, s),
   956       (map_type_tfree (fn p as (s, _) => getOpt (AList.lookup (op =) tvinsts s,
   958         getOpt (default_type,TFree p)))) (subst_bounds (frees, strip gi)));
   957         getOpt (default_type, TFree p)))) (subst_bounds (frees, strip gi)));
   959   in case test_term (Toplevel.theory_of st) size iterations gi' of
   958   in case test_term (Toplevel.theory_of st) size iterations gi' of
   960       NONE => writeln "No counterexamples found."
   959       NONE => writeln "No counterexamples found."
   961     | SOME cex => writeln ("Counterexample found:\n" ^
   960     | SOME cex => writeln ("Counterexample found:\n" ^
   962         Pretty.string_of (Pretty.chunks (map (fn (s, t) =>
   961         Pretty.string_of (Pretty.chunks (map (fn (s, t) =>
   963           Pretty.block [Pretty.str (s ^ " ="), Pretty.brk 1,
   962           Pretty.block [Pretty.str (s ^ " ="), Pretty.brk 1,
  1073   [("size", P.nat >> (K o set_size)),
  1072   [("size", P.nat >> (K o set_size)),
  1074    ("iterations", P.nat >> (K o set_iterations)),
  1073    ("iterations", P.nat >> (K o set_iterations)),
  1075    ("default_type", P.typ >> set_default_type)];
  1074    ("default_type", P.typ >> set_default_type)];
  1076 
  1075 
  1077 val parse_test_params = P.short_ident :-- (fn s =>
  1076 val parse_test_params = P.short_ident :-- (fn s =>
  1078   P.$$$ "=" |-- getOpt (assoc (params, s), Scan.fail)) >> snd;
  1077   P.$$$ "=" |-- (AList.lookup (op =) params s |> the_default Scan.fail)) >> snd;
  1079 
  1078 
  1080 fun parse_tyinst xs =
  1079 fun parse_tyinst xs =
  1081   (P.type_ident --| P.$$$ "=" -- P.typ >> (fn (v, s) => fn thy =>
  1080   (P.type_ident --| P.$$$ "=" -- P.typ >> (fn (v, s) => fn thy =>
  1082     fn (x, ys) => (x, (v, typ_of (read_ctyp thy s)) :: ys))) xs;
  1081     fn (x, ys) => (x, (v, typ_of (read_ctyp thy s)) :: ys))) xs;
  1083 
  1082