fun class syn = Args.context -- Scan.lift Parse.embedded_inner_syntax >> (fn (ctxt, s) =>
Proof_Context.read_class ctxt s
|> syn ? Lexicon.mark_class
|> ML_Syntax.print_string);
ML_Antiquotation.inline_embedded \<^binding>\<open>const\<close>
(Args.context -- Scan.lift (Parse.position Parse.embedded_inner_syntax) -- Scan.optional
(Scan.lift (Args.$$$ "(") |-- Parse.enum1' "," Args.typ --| Scan.lift (Args.$$$ ")")) []
>> (fn ((ctxt, (raw_c, pos)), Ts) => let valConst (c, _) =
Proof_Context.read_const {proper = true, strict = true} ctxt raw_c; val consts = Proof_Context.consts_of ctxt; val n = length (Consts.typargs consts (c, Consts.type_scheme consts c)); val _ = length Ts <> n andalso
error ("Constant requires " ^ string_of_int n ^ " type argument(s): " ^
quote c ^ enclose "("")" (commas (replicate n "_")) ^ Position.here pos); valconst = Const (c, Consts.instance consts (c, Ts)); in ML_Syntax.atomic (ML_Syntax.print_term const) end)));
(* object-logic judgment *)
fun make_judgment ctxt = letvalconst = Object_Logic.judgment_const ctxt in fn t => Constconst $ t end;
fun dest_judgment ctxt = let val is_judgment = Object_Logic.is_judgment ctxt; val drop_judgment = Object_Logic.drop_judgment ctxt; in
fn t => if is_judgment t then drop_judgment t elseraise TERM ("dest_judgment", [t]) end;
fun parse_body b = if b then Parse.$$$ "=>" |-- Parse.!!! (Parse.embedded_ml >> single) else Scan.succeed [];
fun is_dummy [Antiquote.Text tok] = ML_Lex.content_of tok = "_"
| is_dummy _ = false;
val ml = ML_Lex.tokenize_no_range; val ml_range = ML_Lex.tokenize_range; val ml_dummy = ml "_"; fun ml_enclose range x = ml "(" @ x @ ml_range range ")"; fun ml_parens x = ml "(" @ x @ ml ")"; fun ml_bracks x = ml "[" @ x @ ml "]"; fun ml_commas xs = flat (separate (ml ", ") xs); val ml_list = ml_bracks o ml_commas; val ml_string = ml o ML_Syntax.print_string; fun ml_pair (x, y) = ml_parens (ml_commas [x, y]);
fun type_antiquotation binding {function} =
ML_Context.add_antiquotation_embedded binding
(fn range => fn input => fn ctxt => let val ((s, type_args), fn_body) = input
|> Parse.read_embedded ctxt keywords (parse_name_args -- parse_body function); val pos = Input.pos_of s;
valType (c, Ts) =
Proof_Context.read_type_name {proper = true, strict = true} ctxt
(Syntax.implode_input s); val n = length Ts; val _ =
length type_args = n orelse
error ("Type constructor " ^ quote (Proof_Context.markup_type ctxt c) ^ " takes " ^ string_of_int n ^ " argument(s)" ^ Position.here pos);
val (decls1, ctxt1) = ML_Context.expand_antiquotes_list type_args ctxt; val (decls2, ctxt2) = ML_Context.expand_antiquotes_list fn_body ctxt1; fun decl' ctxt' = let val (ml_args_env, ml_args_body) = split_list (decls1 ctxt'); val (ml_fn_env, ml_fn_body) = split_list (decls2 ctxt'); val ml1 =
ml_enclose range (ml "Term.Type " @ ml_pair (ml_string c, ml_list ml_args_body)); val ml2 = if function then
ml_enclose range
(ml_range range "fn " @ ml1 @ ml "=> " @ flat ml_fn_body @
ml "| T => " @ ml_range range "raise" @
ml " Term.TYPE (" @ ml_string ("Type_fn " ^ quote c) @ ml ", [T], [])") else ml1; in (flat (ml_args_env @ ml_fn_env), ml2) end; in (decl', ctxt2) end);
fun const_antiquotation binding {pattern, function} =
ML_Context.add_antiquotation_embedded binding
(fn range => fn input => fn ctxt => let val (((s, type_args), term_args), fn_body) = input
|> Parse.read_embedded ctxt keywords
(parse_name_args -- parse_for_args -- parse_body function);
val consts = Proof_Context.consts_of ctxt; val type_paths = Consts.type_arguments consts c; val type_params = map Term.dest_TVar (Consts.typargs consts (c, T));
val n = length type_params; val m = length (Term.binder_types T);
fun err msg =
error ("Constant " ^ quote (Proof_Context.markup_const ctxt c) ^ msg ^
Position.here (Input.pos_of s)); val _ =
length type_args <> n andalso err (" takes " ^ string_of_int n ^ " type argument(s)"); val _ =
length term_args > m andalso Term.is_Type (Term.body_type T) andalso
err (" cannot have more than " ^ string_of_int m ^ " argument(s)");
val (decls1, ctxt1) = ML_Context.expand_antiquotes_list type_args ctxt; val (decls2, ctxt2) = ML_Context.expand_antiquotes_list term_args ctxt1; val (decls3, ctxt3) = ML_Context.expand_antiquotes_list fn_body ctxt2; fun decl' ctxt' = let val (ml_args_env1, ml_args_body1) = split_list (decls1 ctxt'); val (ml_args_env2, ml_args_body2) = split_list (decls2 ctxt'); val (ml_fn_env, ml_fn_body) = split_list (decls3 ctxt');
val relevant = map is_dummy type_args ~~ type_paths; fun relevant_path is = not pattern orelse letval p = rev is in relevant |> exists (fn (u, q) => not u andalso is_prefix (op =) p q) end;
val ml_typarg = the o AList.lookup (op =) (type_params ~~ ml_args_body1); fun ml_typ is (Type (d, Us)) = if relevant_path is then
ml "Term.Type " @
ml_pair (ml_string d, ml_list (map_index (fn (i, U) => ml_typ (i :: is) U) Us)) else ml_dummy
| ml_typ is (TVar arg) = if relevant_path is then ml_typarg arg else ml_dummy
| ml_typ _ (TFree _) = raiseMatch;
fun ml_app [] = ml "Term.Const " @ ml_pair (ml_string c, ml_typ [] T)
| ml_app (u :: us) = ml "Term.$ " @ ml_pair (ml_app us, u);
val ml_env = flat (ml_args_env1 @ ml_args_env2 @ ml_fn_env); val ml1 = ml_enclose range (ml_app (rev ml_args_body2)); val ml2 = if function then
ml_enclose range
(ml_range range "fn " @ ml1 @ ml "=> " @ flat ml_fn_body @
ml "| t => " @ ml_range range "raise" @
ml " Term.TERM (" @ ml_string ("Const_fn " ^ quote c) @ ml ", [t])") else ml1; in (ml_env, ml2) end; in (decl', ctxt3) end);
val tokenize_text = map Antiquote.Text o ML_Lex.tokenize_no_range; val tokenize_range_text = map Antiquote.Text oo ML_Lex.tokenize_range;
val bg_expr = tokenize_text "(fn () =>"; val en_expr = tokenize_text ")"; fun make_expr a = bg_expr @ a @ en_expr;
fun make_handler range a =
tokenize_range_text range "(fn" @ a @
tokenize_range_text range "| exn => Exn.reraise exn)";
fun report_special tok = (ML_Lex.pos_of tok, Markup.keyword3);
fun print_special tok = letval (pos, markup) = report_special tok in Markup.markup markup (ML_Lex.content_of tok) ^ Position.here pos end;
val is_catch = ML_Lex.is_ident_with (fn x => x = "catch"); val is_finally = ML_Lex.is_ident_with (fn x => x = "finally"); fun is_special t = is_catch t orelse is_finally t; val is_special_text = fn Antiquote.Text t => is_special t | _ => false;
fun parse_try ctxt input = let val ants = ML_Lex.read_source input; val specials = ants
|> map_filter (fn Antiquote.Text t => if is_special t then SOME t else NONE | _ => NONE); val _ = Context_Position.reports ctxt (map report_special specials); in
(case specials of
[] => ("Isabelle_Thread.try", [make_expr ants])
| [s] => letval (a, b) = ants |> chop_prefix (not o is_special_text) ||> tl in if is_finally s then ("Isabelle_Thread.try_finally", [make_expr a, make_expr b]) else ("Isabelle_Thread.try_catch", [make_expr a, make_handler (ML_Lex.range_of s) b]) end
| _ => error ("Too many special keywords: " ^ commas (map print_special specials))) end;
fun parse_can (_: Proof.context) input =
("Isabelle_Thread.can", [make_expr (ML_Lex.read_source input)]);
val _ = Theory.setup
(ML_Context.add_antiquotation_embedded \<^binding>\<open>if_none\<close>
(fn _ => fn input => fn ctxt => let val tokenize = ML_Lex.tokenize_no_range;
val (decl, ctxt') = ML_Context.read_antiquotes input ctxt; fun decl' ctxt'' = let val (ml_env, ml_body) = decl ctxt''; val ml_body' = tokenize "(fn SOME x => x | NONE => " @ ml_body @ tokenize ")"; in (ml_env, ml_body') end; in (decl', ctxt') end));
(* basic combinators *)
local
val parameter = Parse.position Parse.nat >> (fn (n, pos) => if n > 1 then n else error ("Bad parameter: " ^ string_of_int n ^ Position.here pos));
fun indices n = map string_of_int (1 upto n);
fun empty n = replicate_string n " []"; fun dummy n = replicate_string n " _"; fun vars x n = implode (map (fn a => " " ^ x ^ a) (indices n)); fun cons n = implode (map (fn a => " (x" ^ a ^ " :: xs" ^ a ^ ")") (indices n));
val tuple = enclose "("")" o commas; fun tuple_empty n = tuple (replicate n "[]"); fun tuple_vars x n = tuple (map (fn a => x ^ a) (indices n)); fun tuple_cons n = "(" ^ tuple_vars "x" n ^ " :: xs)" fun cons_tuple n = tuple (map (fn a => "x" ^ a ^ " :: xs" ^ a) (indices n));
in
val _ = Theory.setup
(ML_Antiquotation.value \<^binding>\<open>map\<close>
(Scan.lift parameter >> (fn n => "fn f =>\n\
\ let\n\
\ funmap _" ^ empty n ^ " = []\n\
\ | map f" ^ cons n ^ " = f" ^ vars "x" n ^ " :: map f" ^ vars "xs" n ^ "\n\
\ | map _" ^ dummy n ^ " = raise ListPair.UnequalLengths\n" ^ " in map f end")) #>
ML_Antiquotation.value \<^binding>\<open>fold\<close>
(Scan.lift parameter >> (fn n => "fn f =>\n\
\ let\n\
\ fun fold _" ^ empty n ^ " a = a\n\
\ | fold f" ^ cons n ^ " a = fold f" ^ vars "xs" n ^ " (f" ^ vars "x" n ^ " a)\n\
\ | fold _" ^ dummy n ^ " _ = raise ListPair.UnequalLengths\n" ^ " in fold f end")) #>
ML_Antiquotation.value \<^binding>\<open>fold_map\<close>
(Scan.lift parameter >> (fn n => "fn f =>\n\
\ let\n\
\ fun fold_map _" ^ empty n ^ " a = ([], a)\n\
\ | fold_map f" ^ cons n ^ " a =\n\
\ let\n\
\ val (x, a') = f" ^ vars "x" n ^ " a\n\
\ val (xs, a'') = fold_map f" ^ vars "xs" n ^ " a'\n\
\ in (x :: xs, a'') end\n\
\ | fold_map _" ^ dummy n ^ " _ = raise ListPair.UnequalLengths\n" ^ " in fold_map f end")) #>
ML_Antiquotation.value \<^binding>\<open>split_list\<close>
(Scan.lift parameter >> (fn n => "fn list =>\n\
\ let\n\
\ fun split_list [] =" ^ tuple_empty n ^ "\n\
\ | split_list" ^ tuple_cons n ^ " =\n\
\ letval" ^ tuple_vars "xs" n ^ " = split_list xs\n\
\ in" ^ cons_tuple n ^ "end\n\
\ in split_list listend")) #>
ML_Antiquotation.value \<^binding>\<open>apply\<close>
(Scan.lift (parameter -- Scan.option (Args.parens (Parse.position Parse.nat))) >>
(fn (n, opt_index) => let val cond =
(case opt_index of
NONE => K true
| SOME (index, index_pos) => if 1 <= index andalso index <= n then equal (string_of_int index) else error ("Bad index: " ^ string_of_int index ^ Position.here index_pos)); in "fn f => fn " ^ tuple_vars "x" n ^ " => " ^
tuple (map (fn a => (if cond a then"f x"else"x") ^ a) (indices n)) end)));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.