src/Pure/Syntax/syntax.ML
changeset 39135 6f5f64542405
parent 39126 ee117c5b3b75
child 39136 b0b3b6318e3b
equal deleted inserted replaced
39134:917b4b6ba3d2 39135:6f5f64542405
    20   include SYN_EXT0
    20   include SYN_EXT0
    21   include TYPE_EXT0
    21   include TYPE_EXT0
    22   include SYN_TRANS1
    22   include SYN_TRANS1
    23   include MIXFIX1
    23   include MIXFIX1
    24   include PRINTER0
    24   include PRINTER0
    25   type syntax
       
    26   val eq_syntax: syntax * syntax -> bool
       
    27   val is_keyword: syntax -> string -> bool
       
    28   type mode
       
    29   val mode_default: mode
       
    30   val mode_input: mode
       
    31   val merge_syntaxes: syntax -> syntax -> syntax
       
    32   val basic_syntax: syntax
       
    33   val basic_nonterms: string list
       
    34   val print_gram: syntax -> unit
       
    35   val print_trans: syntax -> unit
       
    36   val print_syntax: syntax -> unit
       
    37   val guess_infix: syntax -> string -> mixfix option
       
    38   val read_token: string -> Symbol_Pos.T list * Position.T
    25   val read_token: string -> Symbol_Pos.T list * Position.T
    39   val ambiguity_enabled: bool Config.T
       
    40   val ambiguity_level_value: Config.value Config.T
       
    41   val ambiguity_level: int Config.T
       
    42   val ambiguity_limit: int Config.T
       
    43   val standard_parse_term: Pretty.pp -> (term -> string option) ->
       
    44     (((string * int) * sort) list -> string * int -> Term.sort) ->
       
    45     (string -> bool * string) -> (string -> string option) -> Proof.context ->
       
    46     (string -> bool) -> syntax -> typ -> Symbol_Pos.T list * Position.T -> term
       
    47   val standard_parse_typ: Proof.context -> syntax ->
       
    48     ((indexname * sort) list -> indexname -> sort) -> Symbol_Pos.T list * Position.T -> typ
       
    49   val standard_parse_sort: Proof.context -> syntax -> Symbol_Pos.T list * Position.T -> sort
       
    50   datatype 'a trrule =
       
    51     ParseRule of 'a * 'a |
       
    52     PrintRule of 'a * 'a |
       
    53     ParsePrintRule of 'a * 'a
       
    54   val map_trrule: ('a -> 'b) -> 'a trrule -> 'b trrule
       
    55   val is_const: syntax -> string -> bool
       
    56   val standard_unparse_term: {structs: string list, fixes: string list} ->
       
    57     {extern_class: string -> xstring, extern_type: string -> xstring,
       
    58       extern_const: string -> xstring} -> Proof.context -> syntax -> bool -> term -> Pretty.T
       
    59   val standard_unparse_typ: {extern_class: string -> xstring, extern_type: string -> xstring} ->
       
    60     Proof.context -> syntax -> typ -> Pretty.T
       
    61   val standard_unparse_sort: {extern_class: string -> xstring} ->
       
    62     Proof.context -> syntax -> sort -> Pretty.T
       
    63   val update_trfuns:
       
    64     (string * ((ast list -> ast) * stamp)) list *
       
    65     (string * ((term list -> term) * stamp)) list *
       
    66     (string * ((bool -> typ -> term list -> term) * stamp)) list *
       
    67     (string * ((ast list -> ast) * stamp)) list -> syntax -> syntax
       
    68   val update_advanced_trfuns:
       
    69     (string * ((Proof.context -> ast list -> ast) * stamp)) list *
       
    70     (string * ((Proof.context -> term list -> term) * stamp)) list *
       
    71     (string * ((Proof.context -> bool -> typ -> term list -> term) * stamp)) list *
       
    72     (string * ((Proof.context -> ast list -> ast) * stamp)) list -> syntax -> syntax
       
    73   val extend_tokentrfuns: (string * string * (Proof.context -> string -> Pretty.T)) list ->
       
    74     syntax -> syntax
       
    75   val update_type_gram: bool -> mode -> (string * typ * mixfix) list -> syntax -> syntax
       
    76   val update_const_gram: bool -> (string -> bool) ->
       
    77     mode -> (string * typ * mixfix) list -> syntax -> syntax
       
    78   val update_trrules: Proof.context -> (string -> bool) -> syntax ->
       
    79     (string * string) trrule list -> syntax -> syntax
       
    80   val remove_trrules: Proof.context -> (string -> bool) -> syntax ->
       
    81     (string * string) trrule list -> syntax -> syntax
       
    82   val update_trrules_i: ast trrule list -> syntax -> syntax
       
    83   val remove_trrules_i: ast trrule list -> syntax -> syntax
       
    84   val parse_token: Proof.context -> Markup.T -> string -> Symbol_Pos.T list * Position.T
    26   val parse_token: Proof.context -> Markup.T -> string -> Symbol_Pos.T list * Position.T
    85   val parse_sort: Proof.context -> string -> sort
    27   val parse_sort: Proof.context -> string -> sort
    86   val parse_typ: Proof.context -> string -> typ
    28   val parse_typ: Proof.context -> string -> typ
    87   val parse_term: Proof.context -> string -> term
    29   val parse_term: Proof.context -> string -> term
    88   val parse_prop: Proof.context -> string -> term
    30   val parse_prop: Proof.context -> string -> term
   153   val string_of_term_global: theory -> term -> string
    95   val string_of_term_global: theory -> term -> string
   154   val string_of_typ_global: theory -> typ -> string
    96   val string_of_typ_global: theory -> typ -> string
   155   val string_of_sort_global: theory -> sort -> string
    97   val string_of_sort_global: theory -> sort -> string
   156   val pp: Proof.context -> Pretty.pp
    98   val pp: Proof.context -> Pretty.pp
   157   val pp_global: theory -> Pretty.pp
    99   val pp_global: theory -> Pretty.pp
       
   100   type syntax
       
   101   val eq_syntax: syntax * syntax -> bool
       
   102   val is_keyword: syntax -> string -> bool
       
   103   type mode
       
   104   val mode_default: mode
       
   105   val mode_input: mode
       
   106   val merge_syntaxes: syntax -> syntax -> syntax
       
   107   val basic_syntax: syntax
       
   108   val basic_nonterms: string list
       
   109   val print_gram: syntax -> unit
       
   110   val print_trans: syntax -> unit
       
   111   val print_syntax: syntax -> unit
       
   112   val guess_infix: syntax -> string -> mixfix option
       
   113   val ambiguity_enabled: bool Config.T
       
   114   val ambiguity_level_value: Config.value Config.T
       
   115   val ambiguity_level: int Config.T
       
   116   val ambiguity_limit: int Config.T
       
   117   val standard_parse_term: Pretty.pp -> (term -> string option) ->
       
   118     (((string * int) * sort) list -> string * int -> Term.sort) ->
       
   119     (string -> bool * string) -> (string -> string option) -> Proof.context ->
       
   120     (string -> bool) -> syntax -> typ -> Symbol_Pos.T list * Position.T -> term
       
   121   val standard_parse_typ: Proof.context -> syntax ->
       
   122     ((indexname * sort) list -> indexname -> sort) -> Symbol_Pos.T list * Position.T -> typ
       
   123   val standard_parse_sort: Proof.context -> syntax -> Symbol_Pos.T list * Position.T -> sort
       
   124   datatype 'a trrule =
       
   125     ParseRule of 'a * 'a |
       
   126     PrintRule of 'a * 'a |
       
   127     ParsePrintRule of 'a * 'a
       
   128   val map_trrule: ('a -> 'b) -> 'a trrule -> 'b trrule
       
   129   val is_const: syntax -> string -> bool
       
   130   val standard_unparse_term: {structs: string list, fixes: string list} ->
       
   131     {extern_class: string -> xstring, extern_type: string -> xstring,
       
   132       extern_const: string -> xstring} -> Proof.context -> syntax -> bool -> term -> Pretty.T
       
   133   val standard_unparse_typ: {extern_class: string -> xstring, extern_type: string -> xstring} ->
       
   134     Proof.context -> syntax -> typ -> Pretty.T
       
   135   val standard_unparse_sort: {extern_class: string -> xstring} ->
       
   136     Proof.context -> syntax -> sort -> Pretty.T
       
   137   val update_trfuns:
       
   138     (string * ((ast list -> ast) * stamp)) list *
       
   139     (string * ((term list -> term) * stamp)) list *
       
   140     (string * ((bool -> typ -> term list -> term) * stamp)) list *
       
   141     (string * ((ast list -> ast) * stamp)) list -> syntax -> syntax
       
   142   val update_advanced_trfuns:
       
   143     (string * ((Proof.context -> ast list -> ast) * stamp)) list *
       
   144     (string * ((Proof.context -> term list -> term) * stamp)) list *
       
   145     (string * ((Proof.context -> bool -> typ -> term list -> term) * stamp)) list *
       
   146     (string * ((Proof.context -> ast list -> ast) * stamp)) list -> syntax -> syntax
       
   147   val extend_tokentrfuns: (string * string * (Proof.context -> string -> Pretty.T)) list ->
       
   148     syntax -> syntax
       
   149   val update_type_gram: bool -> mode -> (string * typ * mixfix) list -> syntax -> syntax
       
   150   val update_const_gram: bool -> (string -> bool) ->
       
   151     mode -> (string * typ * mixfix) list -> syntax -> syntax
       
   152   val update_trrules: Proof.context -> (string -> bool) -> syntax ->
       
   153     (string * string) trrule list -> syntax -> syntax
       
   154   val remove_trrules: Proof.context -> (string -> bool) -> syntax ->
       
   155     (string * string) trrule list -> syntax -> syntax
       
   156   val update_trrules_i: ast trrule list -> syntax -> syntax
       
   157   val remove_trrules_i: ast trrule list -> syntax -> syntax
   158 end;
   158 end;
   159 
   159 
   160 structure Syntax: SYNTAX =
   160 structure Syntax: SYNTAX =
   161 struct
   161 struct
       
   162 
       
   163 (** inner syntax operations **)
       
   164 
       
   165 (* read token -- with optional YXML encoding of position *)
       
   166 
       
   167 fun read_token str =
       
   168   let
       
   169     val tree = YXML.parse str handle Fail msg => error msg;
       
   170     val text = Buffer.empty |> XML.add_content tree |> Buffer.content;
       
   171     val pos =
       
   172       (case tree of
       
   173         XML.Elem ((name, props), _) =>
       
   174           if name = Markup.tokenN then Position.of_properties props
       
   175           else Position.none
       
   176       | XML.Text _ => Position.none);
       
   177   in (Symbol_Pos.explode (text, pos), pos) end;
       
   178 
       
   179 
       
   180 (* (un)parsing *)
       
   181 
       
   182 fun parse_token ctxt markup str =
       
   183   let
       
   184     val (syms, pos) = read_token str;
       
   185     val _ = Context_Position.report ctxt markup pos;
       
   186   in (syms, pos) end;
       
   187 
       
   188 local
       
   189 
       
   190 type operations =
       
   191  {parse_sort: Proof.context -> string -> sort,
       
   192   parse_typ: Proof.context -> string -> typ,
       
   193   parse_term: Proof.context -> string -> term,
       
   194   parse_prop: Proof.context -> string -> term,
       
   195   unparse_sort: Proof.context -> sort -> Pretty.T,
       
   196   unparse_typ: Proof.context -> typ -> Pretty.T,
       
   197   unparse_term: Proof.context -> term -> Pretty.T};
       
   198 
       
   199 val operations: operations Single_Assignment.var = Single_Assignment.var "Syntax.operations";
       
   200 
       
   201 fun operation which ctxt x =
       
   202   (case Single_Assignment.peek operations of
       
   203     NONE => raise Fail "Inner syntax operations not installed"
       
   204   | SOME ops => which ops ctxt x);
       
   205 
       
   206 in
       
   207 
       
   208 val parse_sort = operation #parse_sort;
       
   209 val parse_typ = operation #parse_typ;
       
   210 val parse_term = operation #parse_term;
       
   211 val parse_prop = operation #parse_prop;
       
   212 val unparse_sort = operation #unparse_sort;
       
   213 val unparse_typ = operation #unparse_typ;
       
   214 val unparse_term = operation #unparse_term;
       
   215 
       
   216 fun install_operations ops = Single_Assignment.assign operations ops;
       
   217 
       
   218 end;
       
   219 
       
   220 
       
   221 (* context-sensitive (un)checking *)
       
   222 
       
   223 local
       
   224 
       
   225 type key = int * bool;
       
   226 type 'a check = 'a list -> Proof.context -> ('a list * Proof.context) option;
       
   227 
       
   228 structure Checks = Generic_Data
       
   229 (
       
   230   type T =
       
   231     ((key * ((string * typ check) * stamp) list) list *
       
   232      (key * ((string * term check) * stamp) list) list);
       
   233   val empty = ([], []);
       
   234   val extend = I;
       
   235   fun merge ((typ_checks1, term_checks1), (typ_checks2, term_checks2)) : T =
       
   236     (AList.join (op =) (K (Library.merge (eq_snd (op =)))) (typ_checks1, typ_checks2),
       
   237      AList.join (op =) (K (Library.merge (eq_snd (op =)))) (term_checks1, term_checks2));
       
   238 );
       
   239 
       
   240 fun gen_add which (key: key) name f =
       
   241   Checks.map (which (AList.map_default op = (key, []) (cons ((name, f), stamp ()))));
       
   242 
       
   243 fun check_stage fs = perhaps_loop (perhaps_apply (map uncurry fs));
       
   244 
       
   245 fun gen_check which uncheck ctxt0 xs0 =
       
   246   let
       
   247     val funs = which (Checks.get (Context.Proof ctxt0))
       
   248       |> map_filter (fn ((i, u), fs) => if uncheck = u then SOME (i, map (snd o fst) fs) else NONE)
       
   249       |> Library.sort (int_ord o pairself fst) |> map snd
       
   250       |> not uncheck ? map rev;
       
   251     val check_all = perhaps_apply (map check_stage funs);
       
   252   in #1 (perhaps check_all (xs0, ctxt0)) end;
       
   253 
       
   254 fun map_sort f S =
       
   255   (case f (TFree ("", S)) of
       
   256     TFree ("", S') => S'
       
   257   | _ => raise TYPE ("map_sort", [TFree ("", S)], []));
       
   258 
       
   259 in
       
   260 
       
   261 fun print_checks ctxt =
       
   262   let
       
   263     fun split_checks checks =
       
   264       List.partition (fn ((_, un), _) => not un) checks
       
   265       |> pairself (map (fn ((i, _), fs) => (i, map (fst o fst) fs))
       
   266           #> sort (int_ord o pairself fst));
       
   267     fun pretty_checks kind checks =
       
   268       checks |> map (fn (i, names) => Pretty.block
       
   269         [Pretty.str (kind ^ " (stage " ^ signed_string_of_int i ^ "):"),
       
   270           Pretty.brk 1, Pretty.strs names]);
       
   271 
       
   272     val (typs, terms) = Checks.get (Context.Proof ctxt);
       
   273     val (typ_checks, typ_unchecks) = split_checks typs;
       
   274     val (term_checks, term_unchecks) = split_checks terms;
       
   275   in
       
   276     pretty_checks "typ_checks" typ_checks @
       
   277     pretty_checks "term_checks" term_checks @
       
   278     pretty_checks "typ_unchecks" typ_unchecks @
       
   279     pretty_checks "term_unchecks" term_unchecks
       
   280   end |> Pretty.chunks |> Pretty.writeln;
       
   281 
       
   282 fun add_typ_check stage = gen_add apfst (stage, false);
       
   283 fun add_term_check stage = gen_add apsnd (stage, false);
       
   284 fun add_typ_uncheck stage = gen_add apfst (stage, true);
       
   285 fun add_term_uncheck stage = gen_add apsnd (stage, true);
       
   286 
       
   287 val check_typs = gen_check fst false;
       
   288 val check_terms = gen_check snd false;
       
   289 fun check_props ctxt = map (Type_Ext.type_constraint propT) #> check_terms ctxt;
       
   290 
       
   291 val check_typ = singleton o check_typs;
       
   292 val check_term = singleton o check_terms;
       
   293 val check_prop = singleton o check_props;
       
   294 val check_sort = map_sort o check_typ;
       
   295 
       
   296 val uncheck_typs = gen_check fst true;
       
   297 val uncheck_terms = gen_check snd true;
       
   298 val uncheck_sort = map_sort o singleton o uncheck_typs;
       
   299 
       
   300 end;
       
   301 
       
   302 
       
   303 (* derived operations for classrel and arity *)
       
   304 
       
   305 val uncheck_classrel = map o singleton o uncheck_sort;
       
   306 
       
   307 fun unparse_classrel ctxt cs = Pretty.block (flat
       
   308   (separate [Pretty.str " <", Pretty.brk 1] (map (single o unparse_sort ctxt o single) cs)));
       
   309 
       
   310 fun uncheck_arity ctxt (a, Ss, S) =
       
   311   let
       
   312     val T = Type (a, replicate (length Ss) dummyT);
       
   313     val a' =
       
   314       (case singleton (uncheck_typs ctxt) T of
       
   315         Type (a', _) => a'
       
   316       | T => raise TYPE ("uncheck_arity", [T], []));
       
   317     val Ss' = map (uncheck_sort ctxt) Ss;
       
   318     val S' = uncheck_sort ctxt S;
       
   319   in (a', Ss', S') end;
       
   320 
       
   321 fun unparse_arity ctxt (a, Ss, S) =
       
   322   let
       
   323     val prtT = unparse_typ ctxt (Type (a, []));
       
   324     val dom =
       
   325       if null Ss then []
       
   326       else [Pretty.list "(" ")" (map (unparse_sort ctxt) Ss), Pretty.brk 1];
       
   327   in Pretty.block ([prtT, Pretty.str " ::", Pretty.brk 1] @ dom @ [unparse_sort ctxt S]) end;
       
   328 
       
   329 
       
   330 (* read = parse + check *)
       
   331 
       
   332 fun read_sort ctxt = parse_sort ctxt #> check_sort ctxt;
       
   333 fun read_typ ctxt = parse_typ ctxt #> singleton (check_typs ctxt);
       
   334 
       
   335 fun read_terms ctxt = map (parse_term ctxt) #> check_terms ctxt;
       
   336 fun read_props ctxt = map (parse_prop ctxt) #> check_props ctxt;
       
   337 
       
   338 val read_term = singleton o read_terms;
       
   339 val read_prop = singleton o read_props;
       
   340 
       
   341 val read_sort_global = read_sort o ProofContext.init_global;
       
   342 val read_typ_global = read_typ o ProofContext.init_global;
       
   343 val read_term_global = read_term o ProofContext.init_global;
       
   344 val read_prop_global = read_prop o ProofContext.init_global;
       
   345 
       
   346 
       
   347 (* pretty = uncheck + unparse *)
       
   348 
       
   349 fun pretty_term ctxt = singleton (uncheck_terms ctxt) #> unparse_term ctxt;
       
   350 fun pretty_typ ctxt = singleton (uncheck_typs ctxt) #> unparse_typ ctxt;
       
   351 fun pretty_sort ctxt = uncheck_sort ctxt #> unparse_sort ctxt;
       
   352 fun pretty_classrel ctxt = uncheck_classrel ctxt #> unparse_classrel ctxt;
       
   353 fun pretty_arity ctxt = uncheck_arity ctxt #> unparse_arity ctxt;
       
   354 
       
   355 val string_of_term = Pretty.string_of oo pretty_term;
       
   356 val string_of_typ = Pretty.string_of oo pretty_typ;
       
   357 val string_of_sort = Pretty.string_of oo pretty_sort;
       
   358 val string_of_classrel = Pretty.string_of oo pretty_classrel;
       
   359 val string_of_arity = Pretty.string_of oo pretty_arity;
       
   360 
       
   361 
       
   362 (* global pretty printing *)
       
   363 
       
   364 structure PrettyGlobal = Proof_Data(type T = bool fun init _ = false);
       
   365 val is_pretty_global = PrettyGlobal.get;
       
   366 val set_pretty_global = PrettyGlobal.put;
       
   367 val init_pretty_global = set_pretty_global true o ProofContext.init_global;
       
   368 
       
   369 val pretty_term_global = pretty_term o init_pretty_global;
       
   370 val pretty_typ_global = pretty_typ o init_pretty_global;
       
   371 val pretty_sort_global = pretty_sort o init_pretty_global;
       
   372 
       
   373 val string_of_term_global = string_of_term o init_pretty_global;
       
   374 val string_of_typ_global = string_of_typ o init_pretty_global;
       
   375 val string_of_sort_global = string_of_sort o init_pretty_global;
       
   376 
       
   377 
       
   378 (* pp operations -- deferred evaluation *)
       
   379 
       
   380 fun pp ctxt = Pretty.pp
       
   381  (fn x => pretty_term ctxt x,
       
   382   fn x => pretty_typ ctxt x,
       
   383   fn x => pretty_sort ctxt x,
       
   384   fn x => pretty_classrel ctxt x,
       
   385   fn x => pretty_arity ctxt x);
       
   386 
       
   387 fun pp_global thy = Pretty.pp
       
   388  (fn x => pretty_term_global thy x,
       
   389   fn x => pretty_typ_global thy x,
       
   390   fn x => pretty_sort_global thy x,
       
   391   fn x => pretty_classrel (init_pretty_global thy) x,
       
   392   fn x => pretty_arity (init_pretty_global thy) x);
       
   393 
       
   394 
   162 
   395 
   163 (** tables of translation functions **)
   396 (** tables of translation functions **)
   164 
   397 
   165 (* parse (ast) translations *)
   398 (* parse (ast) translations *)
   166 
   399 
   454 
   687 
   455 
   688 
   456 
   689 
   457 (** read **)
   690 (** read **)
   458 
   691 
   459 (* read token -- with optional YXML encoding of position *)
       
   460 
       
   461 fun read_token str =
       
   462   let
       
   463     val tree = YXML.parse str handle Fail msg => error msg;
       
   464     val text = Buffer.empty |> XML.add_content tree |> Buffer.content;
       
   465     val pos =
       
   466       (case tree of
       
   467         XML.Elem ((name, props), _) =>
       
   468           if name = Markup.tokenN then Position.of_properties props
       
   469           else Position.none
       
   470       | XML.Text _ => Position.none);
       
   471   in (Symbol_Pos.explode (text, pos), pos) end;
       
   472 
       
   473 
       
   474 (* read_ast *)
   692 (* read_ast *)
   475 
   693 
   476 val ambiguity_enabled =
   694 val ambiguity_enabled =
   477   Config.bool (Config.declare "syntax_ambiguity_enabled" (fn _ => Config.Bool true));
   695   Config.bool (Config.declare "syntax_ambiguity_enabled" (fn _ => Config.Bool true));
   478 
   696 
   694 
   912 
   695 val update_trrules_i = ext_syntax Syn_Ext.syn_ext_rules o cert_rules;
   913 val update_trrules_i = ext_syntax Syn_Ext.syn_ext_rules o cert_rules;
   696 val remove_trrules_i = remove_syntax mode_default o Syn_Ext.syn_ext_rules o cert_rules;
   914 val remove_trrules_i = remove_syntax mode_default o Syn_Ext.syn_ext_rules o cert_rules;
   697 
   915 
   698 
   916 
   699 
       
   700 (** inner syntax operations **)
       
   701 
       
   702 (* (un)parsing *)
       
   703 
       
   704 fun parse_token ctxt markup str =
       
   705   let
       
   706     val (syms, pos) = read_token str;
       
   707     val _ = Context_Position.report ctxt markup pos;
       
   708   in (syms, pos) end;
       
   709 
       
   710 local
       
   711 
       
   712 type operations =
       
   713  {parse_sort: Proof.context -> string -> sort,
       
   714   parse_typ: Proof.context -> string -> typ,
       
   715   parse_term: Proof.context -> string -> term,
       
   716   parse_prop: Proof.context -> string -> term,
       
   717   unparse_sort: Proof.context -> sort -> Pretty.T,
       
   718   unparse_typ: Proof.context -> typ -> Pretty.T,
       
   719   unparse_term: Proof.context -> term -> Pretty.T};
       
   720 
       
   721 val operations: operations Single_Assignment.var = Single_Assignment.var "Syntax.operations";
       
   722 
       
   723 fun operation which ctxt x =
       
   724   (case Single_Assignment.peek operations of
       
   725     NONE => raise Fail "Inner syntax operations not installed"
       
   726   | SOME ops => which ops ctxt x);
       
   727 
       
   728 in
       
   729 
       
   730 val parse_sort = operation #parse_sort;
       
   731 val parse_typ = operation #parse_typ;
       
   732 val parse_term = operation #parse_term;
       
   733 val parse_prop = operation #parse_prop;
       
   734 val unparse_sort = operation #unparse_sort;
       
   735 val unparse_typ = operation #unparse_typ;
       
   736 val unparse_term = operation #unparse_term;
       
   737 
       
   738 fun install_operations ops = Single_Assignment.assign operations ops;
       
   739 
       
   740 end;
       
   741 
       
   742 
       
   743 (* context-sensitive (un)checking *)
       
   744 
       
   745 local
       
   746 
       
   747 type key = int * bool;
       
   748 type 'a check = 'a list -> Proof.context -> ('a list * Proof.context) option;
       
   749 
       
   750 structure Checks = Generic_Data
       
   751 (
       
   752   type T =
       
   753     ((key * ((string * typ check) * stamp) list) list *
       
   754      (key * ((string * term check) * stamp) list) list);
       
   755   val empty = ([], []);
       
   756   val extend = I;
       
   757   fun merge ((typ_checks1, term_checks1), (typ_checks2, term_checks2)) : T =
       
   758     (AList.join (op =) (K (Library.merge (eq_snd (op =)))) (typ_checks1, typ_checks2),
       
   759      AList.join (op =) (K (Library.merge (eq_snd (op =)))) (term_checks1, term_checks2));
       
   760 );
       
   761 
       
   762 fun gen_add which (key: key) name f =
       
   763   Checks.map (which (AList.map_default op = (key, []) (cons ((name, f), stamp ()))));
       
   764 
       
   765 fun check_stage fs = perhaps_loop (perhaps_apply (map uncurry fs));
       
   766 
       
   767 fun gen_check which uncheck ctxt0 xs0 =
       
   768   let
       
   769     val funs = which (Checks.get (Context.Proof ctxt0))
       
   770       |> map_filter (fn ((i, u), fs) => if uncheck = u then SOME (i, map (snd o fst) fs) else NONE)
       
   771       |> Library.sort (int_ord o pairself fst) |> map snd
       
   772       |> not uncheck ? map rev;
       
   773     val check_all = perhaps_apply (map check_stage funs);
       
   774   in #1 (perhaps check_all (xs0, ctxt0)) end;
       
   775 
       
   776 fun map_sort f S =
       
   777   (case f (TFree ("", S)) of
       
   778     TFree ("", S') => S'
       
   779   | _ => raise TYPE ("map_sort", [TFree ("", S)], []));
       
   780 
       
   781 in
       
   782 
       
   783 fun print_checks ctxt =
       
   784   let
       
   785     fun split_checks checks =
       
   786       List.partition (fn ((_, un), _) => not un) checks
       
   787       |> pairself (map (fn ((i, _), fs) => (i, map (fst o fst) fs))
       
   788           #> sort (int_ord o pairself fst));
       
   789     fun pretty_checks kind checks =
       
   790       checks |> map (fn (i, names) => Pretty.block
       
   791         [Pretty.str (kind ^ " (stage " ^ signed_string_of_int i ^ "):"),
       
   792           Pretty.brk 1, Pretty.strs names]);
       
   793 
       
   794     val (typs, terms) = Checks.get (Context.Proof ctxt);
       
   795     val (typ_checks, typ_unchecks) = split_checks typs;
       
   796     val (term_checks, term_unchecks) = split_checks terms;
       
   797   in
       
   798     pretty_checks "typ_checks" typ_checks @
       
   799     pretty_checks "term_checks" term_checks @
       
   800     pretty_checks "typ_unchecks" typ_unchecks @
       
   801     pretty_checks "term_unchecks" term_unchecks
       
   802   end |> Pretty.chunks |> Pretty.writeln;
       
   803 
       
   804 fun add_typ_check stage = gen_add apfst (stage, false);
       
   805 fun add_term_check stage = gen_add apsnd (stage, false);
       
   806 fun add_typ_uncheck stage = gen_add apfst (stage, true);
       
   807 fun add_term_uncheck stage = gen_add apsnd (stage, true);
       
   808 
       
   809 val check_typs = gen_check fst false;
       
   810 val check_terms = gen_check snd false;
       
   811 fun check_props ctxt = map (Type_Ext.type_constraint propT) #> check_terms ctxt;
       
   812 
       
   813 val check_typ = singleton o check_typs;
       
   814 val check_term = singleton o check_terms;
       
   815 val check_prop = singleton o check_props;
       
   816 val check_sort = map_sort o check_typ;
       
   817 
       
   818 val uncheck_typs = gen_check fst true;
       
   819 val uncheck_terms = gen_check snd true;
       
   820 val uncheck_sort = map_sort o singleton o uncheck_typs;
       
   821 
       
   822 end;
       
   823 
       
   824 
       
   825 (* derived operations for classrel and arity *)
       
   826 
       
   827 val uncheck_classrel = map o singleton o uncheck_sort;
       
   828 
       
   829 fun unparse_classrel ctxt cs = Pretty.block (flat
       
   830   (separate [Pretty.str " <", Pretty.brk 1] (map (single o unparse_sort ctxt o single) cs)));
       
   831 
       
   832 fun uncheck_arity ctxt (a, Ss, S) =
       
   833   let
       
   834     val T = Type (a, replicate (length Ss) dummyT);
       
   835     val a' =
       
   836       (case singleton (uncheck_typs ctxt) T of
       
   837         Type (a', _) => a'
       
   838       | T => raise TYPE ("uncheck_arity", [T], []));
       
   839     val Ss' = map (uncheck_sort ctxt) Ss;
       
   840     val S' = uncheck_sort ctxt S;
       
   841   in (a', Ss', S') end;
       
   842 
       
   843 fun unparse_arity ctxt (a, Ss, S) =
       
   844   let
       
   845     val prtT = unparse_typ ctxt (Type (a, []));
       
   846     val dom =
       
   847       if null Ss then []
       
   848       else [Pretty.list "(" ")" (map (unparse_sort ctxt) Ss), Pretty.brk 1];
       
   849   in Pretty.block ([prtT, Pretty.str " ::", Pretty.brk 1] @ dom @ [unparse_sort ctxt S]) end;
       
   850 
       
   851 
       
   852 (* read = parse + check *)
       
   853 
       
   854 fun read_sort ctxt = parse_sort ctxt #> check_sort ctxt;
       
   855 fun read_typ ctxt = parse_typ ctxt #> singleton (check_typs ctxt);
       
   856 
       
   857 fun read_terms ctxt = map (parse_term ctxt) #> check_terms ctxt;
       
   858 fun read_props ctxt = map (parse_prop ctxt) #> check_props ctxt;
       
   859 
       
   860 val read_term = singleton o read_terms;
       
   861 val read_prop = singleton o read_props;
       
   862 
       
   863 val read_sort_global = read_sort o ProofContext.init_global;
       
   864 val read_typ_global = read_typ o ProofContext.init_global;
       
   865 val read_term_global = read_term o ProofContext.init_global;
       
   866 val read_prop_global = read_prop o ProofContext.init_global;
       
   867 
       
   868 
       
   869 (* pretty = uncheck + unparse *)
       
   870 
       
   871 fun pretty_term ctxt = singleton (uncheck_terms ctxt) #> unparse_term ctxt;
       
   872 fun pretty_typ ctxt = singleton (uncheck_typs ctxt) #> unparse_typ ctxt;
       
   873 fun pretty_sort ctxt = uncheck_sort ctxt #> unparse_sort ctxt;
       
   874 fun pretty_classrel ctxt = uncheck_classrel ctxt #> unparse_classrel ctxt;
       
   875 fun pretty_arity ctxt = uncheck_arity ctxt #> unparse_arity ctxt;
       
   876 
       
   877 val string_of_term = Pretty.string_of oo pretty_term;
       
   878 val string_of_typ = Pretty.string_of oo pretty_typ;
       
   879 val string_of_sort = Pretty.string_of oo pretty_sort;
       
   880 val string_of_classrel = Pretty.string_of oo pretty_classrel;
       
   881 val string_of_arity = Pretty.string_of oo pretty_arity;
       
   882 
       
   883 
       
   884 (* global pretty printing *)
       
   885 
       
   886 structure PrettyGlobal = Proof_Data(type T = bool fun init _ = false);
       
   887 val is_pretty_global = PrettyGlobal.get;
       
   888 val set_pretty_global = PrettyGlobal.put;
       
   889 val init_pretty_global = set_pretty_global true o ProofContext.init_global;
       
   890 
       
   891 val pretty_term_global = pretty_term o init_pretty_global;
       
   892 val pretty_typ_global = pretty_typ o init_pretty_global;
       
   893 val pretty_sort_global = pretty_sort o init_pretty_global;
       
   894 
       
   895 val string_of_term_global = string_of_term o init_pretty_global;
       
   896 val string_of_typ_global = string_of_typ o init_pretty_global;
       
   897 val string_of_sort_global = string_of_sort o init_pretty_global;
       
   898 
       
   899 
       
   900 (* pp operations -- deferred evaluation *)
       
   901 
       
   902 fun pp ctxt = Pretty.pp
       
   903  (fn x => pretty_term ctxt x,
       
   904   fn x => pretty_typ ctxt x,
       
   905   fn x => pretty_sort ctxt x,
       
   906   fn x => pretty_classrel ctxt x,
       
   907   fn x => pretty_arity ctxt x);
       
   908 
       
   909 fun pp_global thy = Pretty.pp
       
   910  (fn x => pretty_term_global thy x,
       
   911   fn x => pretty_typ_global thy x,
       
   912   fn x => pretty_sort_global thy x,
       
   913   fn x => pretty_classrel (init_pretty_global thy) x,
       
   914   fn x => pretty_arity (init_pretty_global thy) x);
       
   915 
       
   916 
       
   917 (*export parts of internal Syntax structures*)
   917 (*export parts of internal Syntax structures*)
   918 open Lexicon Syn_Ext Ast Parser Type_Ext Syn_Trans Mixfix Printer;
   918 open Lexicon Syn_Ext Ast Parser Type_Ext Syn_Trans Mixfix Printer;
   919 
   919 
   920 end;
   920 end;
   921 
   921