(* Title: Pure/Syntax/syntax_trans.ML Author: Tobias Nipkow and Markus Wenzel, TU Muenchen
Syntax translation functions.
*)
signature BASIC_SYNTAX_TRANS = sig val eta_contract: bool Config.T end
signature SYNTAX_TRANS = sig
include BASIC_SYNTAX_TRANS val bracketsN: string val no_bracketsN: string val no_brackets: unit -> bool val type_bracketsN: string val no_type_bracketsN: string val no_type_brackets: unit -> bool val abs_tr: term list -> term val mk_binder_tr: string * string -> string * (Proof.context -> term list -> term) val antiquote_tr: string -> term -> term val quote_tr: string -> term -> term val quote_antiquote_tr: string -> string -> string -> string * (Proof.context -> term list -> term) val non_typed_tr': (Proof.context -> term list -> term) ->
Proof.context -> typ -> term list -> term val tappl_ast_tr': Ast.ast * Ast.ast list -> Ast.ast val appl_ast_tr': Ast.ast * Ast.ast list -> Ast.ast val applC_ast_tr': Ast.ast * Ast.ast list -> Ast.ast val declare_term_names: Proof.context -> term -> Name.context -> Name.context val variant_bounds: Proof.context -> term -> (string * 'a) list -> (string * 'a) list val mark_bound_abs: string * typ -> term val mark_bound_body: string * typ -> term val bound_vars: Proof.context -> (string * typ) list -> term -> term val abs_tr': Proof.context -> term -> term val atomic_abs_tr': Proof.context -> string * typ * term -> term * term val const_abs_tr': term -> term val mk_binder_tr': string * string -> string * (Proof.context -> term list -> term) val preserve_binder_abs_tr': string -> Proof.context -> typ -> term list -> term val preserve_binder_abs2_tr': string -> Proof.context -> typ -> term list -> term val print_abs: string * typ * term -> string * term val dependent_tr': string * string -> term list -> term val antiquote_tr': string -> term -> term val quote_tr': string -> term -> term val quote_antiquote_tr': string -> string -> string -> string * (Proof.context -> term list -> term) val update_name_tr': term -> term val get_idents: Proof.context -> {structs: stringlist, fixes: stringlist} val put_idents: {structs: stringlist, fixes: stringlist} -> Proof.context -> Proof.context val default_struct: Proof.context -> stringoption val pure_parse_ast_translation: (string * (Proof.context -> Ast.ast list -> Ast.ast)) list val pure_parse_translation: (string * (Proof.context -> term list -> term)) list val pure_print_ast_translation: (string * (Proof.context -> Ast.ast list -> Ast.ast)) list end;
structure Syntax_Trans: SYNTAX_TRANS = struct
structure Syntax = Lexicon.Syntax;
(* print mode *)
val bracketsN = "brackets"; val no_bracketsN = "no_brackets";
fun no_brackets () =
find_first (fn mode => mode = bracketsN orelse mode = no_bracketsN)
(print_mode_value ()) = SOME no_bracketsN;
val type_bracketsN = "type_brackets"; val no_type_bracketsN = "no_type_brackets";
fun no_type_brackets () =
find_first (fn mode => mode = type_bracketsN orelse mode = no_type_bracketsN)
(print_mode_value ()) <> SOME type_bracketsN;
fun absfree_proper (x, T) t = if Name.is_internal x then error ("Illegal internal variable in abstraction: " ^ quote x) else absfree (x, T) t;
fun abs_tr [Free x, t] = absfree_proper x t
| abs_tr [Const ("_idtdummy", T), t] = absdummy T t
| abs_tr [Const ("_constrain", _) $ x $ tT, t] = Syntax.const"_constrainAbs" $ abs_tr [x, t] $ tT
| abs_tr ts = raise TERM ("abs_tr", ts);
(* binder *)
fun mk_binder_tr (syn, name) = let fun err ts = raise TERM ("binder_tr: " ^ syn, ts) fun binder_tr [Const ("_idts", _) $ idt $ idts, t] = binder_tr [idt, binder_tr [idts, t]]
| binder_tr [x, t] = Syntax.const name $ (abs_tr [x, t] handle TERM _ => err [x, t])
| binder_tr ts = err ts; in (syn, fn _ => binder_tr) end;
(* type propositions *)
fun mk_type ty =
Syntax.const"_constrain" $
Syntax.const"\<^const>Pure.type" $ (Syntax.const"\<^type>itself" $ ty);
fun ofclass_tr [ty, cls] = cls $ mk_type ty
| ofclass_tr ts = raise TERM ("ofclass_tr", ts);
fun sort_constraint_tr [ty] = Syntax.const"\<^const>Pure.sort_constraint" $ mk_type ty
| sort_constraint_tr ts = raise TERM ("sort_constraint_tr", ts);
(* meta propositions *)
fun aprop_tr [t] = Syntax.const"_constrain" $ t $ Syntax.const"\<^type>prop"
| aprop_tr ts = raise TERM ("aprop_tr", ts);
(* meta implication *)
fun bigimpl_ast_tr (asts as [asms, concl]) = letval prems =
(case Ast.unfold_ast_p "_asms" asms of
(asms', Ast.Appl [Ast.Constant "_asm", asm']) => asms' @ [asm']
| _ => raise Ast.AST ("bigimpl_ast_tr", asts)) in Ast.fold_ast_p "\<^const>Pure.imp" (prems, concl) end
| bigimpl_ast_tr asts = raise Ast.AST ("bigimpl_ast_tr", asts);
(* type/term reflection *)
fun type_tr [ty] = mk_type ty
| type_tr ts = raise TERM ("type_tr", ts);
(* quote / antiquote *)
fun antiquote_tr name = let fun tr i ((t as Const (c, _)) $ u) = if c = name then tr i u $ Bound i else tr i t $ tr i u
| tr i (t $ u) = tr i t $ tr i u
| tr i (Abs (x, T, t)) = Abs (x, T, tr (i + 1) t)
| tr _ a = a; in tr 0 end;
fun quote_tr name t = Abs ("s", dummyT, antiquote_tr name (Term.incr_boundvars 1 t));
fun quote_antiquote_tr quoteN antiquoteN name = let fun tr [t] = Syntax.const name $ quote_tr antiquoteN t
| tr ts = raise TERM ("quote_tr", ts); in (quoteN, fn _ => tr) end;
fun eta_abs (Abs (a, T, t)) =
(case eta_abs t of
t' as Const ("_aprop", _) $ _ => Abs (a, T, t')
| t' as f $ u =>
(case eta_abs u of
Bound 0 => if Term.is_dependent f then Abs (a, T, t') else incr_boundvars ~1 f
| _ => Abs (a, T, t'))
| t' => Abs (a, T, t'))
| eta_abs t = t;
val eta_contract = Config.declare_option_bool ("eta_contract", \<^here>); fun eta_contr ctxt = Config.get ctxt eta_contract ? eta_abs;
(* renaming variables *)
fun declare_term_names ctxt = let val s = the_default "" (default_struct ctxt);
fun declare (Const ("_struct", _) $ Const ("_indexdefault", _)) = Name.declare s
| declare (Const (c, _)) = if Lexicon.is_fixed c then Name.declare (Lexicon.unmark_fixed c) else I
| declare (Free (x, _)) = Name.declare x
| declare (t $ u) = declare t #> declare u
| declare (Abs (_, _, t)) = declare t
| declare _ = I; in declare end;
fun variant_bounds ctxt =
Name.variant_names_build o declare_term_names ctxt;
(* abstraction *)
fun mark_bound_abs (x, T) = Const ("_bound", T --> T) $ Free (x, T); fun mark_bound_body (x, T) = Const ("_bound", dummyT) $ Free (x, T);
fun bound_vars ctxt vars body =
subst_bounds (map mark_bound_abs (rev (variant_bounds ctxt body vars)), body);
fun strip_abss ctxt vars_of body_of tm = let val vars = vars_of tm; val body = body_of tm; val new_vars = variant_bounds ctxt body vars; fun subst (x, T) b = if Name.is_internal x andalso not (Term.is_dependent b) then (Const ("_idtdummy", T), incr_boundvars ~1 b) else (mark_bound_abs (x, T), Term.subst_bound (mark_bound_body (x, T), b)); val (rev_vars', body') = fold_map subst (rev new_vars) body; in (rev rev_vars', body') end;
fun abs_tr' ctxt tm =
uncurry (fold_rev (fn x => fn t => Syntax.const"_abs" $ x $ t))
(strip_abss ctxt strip_abs_vars strip_abs_body (eta_contr ctxt tm));
fun const_abs_tr' t =
(case eta_abs t of
Abs (_, _, t') => if Term.is_dependent t' then raise Match else incr_boundvars ~1 t'
| _ => raiseMatch);
(* binders *)
fun mk_binder_tr' (name, syn) = let fun mk_idts [] = raiseMatch(*abort translation*)
| mk_idts [idt] = idt
| mk_idts (idt :: idts) = Syntax.const"_idts" $ idt $ mk_idts idts;
fun tr' ctxt t = let val (xs, bd) = strip_abss ctxt (strip_qnt_vars name) (strip_qnt_body name) t; in Syntax.const syn $ mk_idts xs $ bd end;
fun binder_tr' ctxt (t :: ts) = Term.list_comb (tr' ctxt (Syntax.const name $ t), ts)
| binder_tr' _ [] = raise Match; in (name, binder_tr') end;
fun preserve_binder_abs_tr' syn ctxt ty (Abs abs :: ts) = letval (x, t) = atomic_abs_tr' ctxt abs in list_comb (Const (syn, ty) $ x $ t, ts) end;
fun preserve_binder_abs2_tr' syn ctxt ty (A :: Abs abs :: ts) = letval (x, t) = atomic_abs_tr' ctxt abs in list_comb (Const (syn, ty) $ x $ A $ t, ts) end;
(* idtyp constraints *)
fun idtyp_ast_tr' a [Ast.Appl [Ast.Constant "_constrain", x, ty], xs] =
Ast.Appl [Ast.Constant a, Ast.Appl [Ast.Constant "_idtyp", x, ty], xs]
| idtyp_ast_tr' _ _ = raise Match;
(* meta implication *)
fun impl_ast_tr' asts = if no_brackets () thenraiseMatch else
(case Ast.unfold_ast_p "\<^const>Pure.imp"
(Ast.Appl (Ast.Constant "\<^const>Pure.imp" :: asts)) of
(prems as _ :: _ :: _, concl) => let val (asms, asm) = split_last prems; val asms' = Ast.fold_ast_p "_asms" (asms, Ast.Appl [Ast.Constant "_asm", asm]); in Ast.Appl [Ast.Constant "_bigimpl", asms', concl] end
| _ => raiseMatch);
(* dependent / nondependent quantifiers *)
fun print_abs (x, T, b) = letval x' = #1 (Name.variant x (Name.build_context (Term.declare_free_names b))) in (x', subst_bound (mark_bound_abs (x', T), b)) end;
fun dependent_tr' (q, r) (A :: Abs (x, T, B) :: ts) = if Term.is_dependent B then letval (x', B') = print_abs (x, dummyT, B); in Term.list_comb (Syntax.const q $ mark_bound_abs (x', T) $ A $ B', ts) end else Term.list_comb (Syntax.const r $ A $ incr_boundvars ~1 B, ts)
| dependent_tr' _ _ = raise Match;
(* quote / antiquote *)
fun antiquote_tr' name = let fun tr' i (t $ u) = if u aconv Bound i then Syntax.const name $ tr' i t else tr' i t $ tr' i u
| tr' i (Abs (x, T, t)) = Abs (x, T, tr' (i + 1) t)
| tr' i a = if a aconv Bound i then raise Match else a; in tr' 0 end;
fun quote_tr' name (Abs (_, _, t)) = Term.incr_boundvars ~1 (antiquote_tr' name t)
| quote_tr' _ _ = raise Match;
fun quote_antiquote_tr' quoteN antiquoteN name = let fun tr' (t :: ts) = Term.list_comb (Syntax.const quoteN $ quote_tr' antiquoteN t, ts)
| tr' _ = raise Match; in (name, fn _ => tr') end;
(* corresponding updates *)
local
fun upd_type (Type ("fun", [Type ("fun", [_, T]), _])) = T
| upd_type _ = dummyT;
fun upd_tr' (x_upd, T) =
(casetry (unsuffix "_update") x_upd of
SOME x => (x, upd_type T)
| NONE => raiseMatch);
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.