wenzelm@5823: (* Title: Pure/Isar/attrib.ML wenzelm@5823: Author: Markus Wenzel, TU Muenchen wenzelm@5823: wenzelm@18734: Symbolic representation of attributes -- with name and syntax. wenzelm@5823: *) wenzelm@5823: wenzelm@5823: signature ATTRIB = wenzelm@5823: sig wenzelm@27729: type src = Args.src haftmann@29581: type binding = binding * src list haftmann@28965: val empty_binding: binding wenzelm@45584: val is_empty_binding: binding -> bool wenzelm@27729: val print_attributes: theory -> unit wenzelm@16458: val intern: theory -> xstring -> string wenzelm@16458: val intern_src: theory -> src -> src wenzelm@21031: val pretty_attribs: Proof.context -> src list -> Pretty.T list wenzelm@26891: val defined: theory -> string -> bool wenzelm@18734: val attribute: theory -> src -> attribute wenzelm@18734: val attribute_i: theory -> src -> attribute wenzelm@45390: val map_specs: ('a list -> 'att list) -> wenzelm@30759: (('c * 'a list) * 'b) list -> (('c * 'att list) * 'b) list wenzelm@45390: val map_facts: ('a list -> 'att list) -> wenzelm@17105: (('c * 'a list) * ('d * 'a list) list) list -> wenzelm@18905: (('c * 'att list) * ('d * 'att list) list) list wenzelm@45390: val map_facts_refs: ('a list -> 'att list) -> ('b -> 'fact) -> wenzelm@30759: (('c * 'a list) * ('b * 'a list) list) list -> wenzelm@30759: (('c * 'att list) * ('fact * 'att list) list) list wenzelm@38330: val eval_thms: Proof.context -> (Facts.ref * src list) list -> thm list wenzelm@30525: val setup: Binding.binding -> attribute context_parser -> string -> theory -> theory wenzelm@30575: val attribute_setup: bstring * Position.T -> Symbol_Pos.text * Position.T -> string -> wenzelm@30575: theory -> theory wenzelm@30525: val add_del: attribute -> attribute -> attribute context_parser wenzelm@30513: val thm_sel: Facts.interval list parser wenzelm@30513: val thm: thm context_parser wenzelm@30513: val thms: thm list context_parser wenzelm@30513: val multi_thm: thm list context_parser wenzelm@45493: val partial_evaluation: Proof.context -> wenzelm@45493: (binding * (thm list * Args.src list) list) list -> wenzelm@45493: (binding * (thm list * Args.src list) list) list wenzelm@45493: val internal: (morphism -> attribute) -> src wenzelm@24110: val print_configs: Proof.context -> unit wenzelm@42616: val config_bool: Binding.binding -> wenzelm@42616: (Context.generic -> bool) -> bool Config.T * (theory -> theory) wenzelm@42616: val config_int: Binding.binding -> wenzelm@42616: (Context.generic -> int) -> int Config.T * (theory -> theory) wenzelm@42616: val config_real: Binding.binding -> wenzelm@42616: (Context.generic -> real) -> real Config.T * (theory -> theory) wenzelm@42616: val config_string: Binding.binding -> wenzelm@42616: (Context.generic -> string) -> string Config.T * (theory -> theory) wenzelm@42616: val setup_config_bool: Binding.binding -> (Context.generic -> bool) -> bool Config.T wenzelm@42616: val setup_config_int: Binding.binding -> (Context.generic -> int) -> int Config.T wenzelm@42616: val setup_config_string: Binding.binding -> (Context.generic -> string) -> string Config.T wenzelm@42616: val setup_config_real: Binding.binding -> (Context.generic -> real) -> real Config.T wenzelm@5823: end; wenzelm@5823: wenzelm@5823: structure Attrib: ATTRIB = wenzelm@5823: struct wenzelm@5823: wenzelm@28084: (* source and bindings *) wenzelm@28084: wenzelm@15703: type src = Args.src; wenzelm@15703: haftmann@29581: type binding = binding * src list; wenzelm@45584: haftmann@28965: val empty_binding: binding = (Binding.empty, []); wenzelm@45584: fun is_empty_binding ((b, srcs): binding) = Binding.is_empty b andalso null srcs; wenzelm@28084: wenzelm@28084: wenzelm@27729: wenzelm@18734: (** named attributes **) wenzelm@18636: wenzelm@18734: (* theory data *) wenzelm@5823: wenzelm@33522: structure Attributes = Theory_Data wenzelm@22846: ( wenzelm@33095: type T = ((src -> attribute) * string) Name_Space.table; wenzelm@33159: val empty : T = Name_Space.empty_table "attribute"; wenzelm@16458: val extend = I; wenzelm@33522: fun merge data : T = Name_Space.merge_tables data; wenzelm@22846: ); wenzelm@5823: wenzelm@22846: fun print_attributes thy = wenzelm@22846: let wenzelm@42360: val ctxt = Proof_Context.init_global thy; wenzelm@24110: val attribs = Attributes.get thy; wenzelm@42813: fun prt_attr (name, (_, "")) = Pretty.str name wenzelm@42813: | prt_attr (name, (_, comment)) = wenzelm@42813: Pretty.block [Pretty.str (name ^ ":"), Pretty.brk 2, Pretty.str comment]; wenzelm@22846: in wenzelm@42358: [Pretty.big_list "attributes:" (map prt_attr (Name_Space.extern_table ctxt attribs))] wenzelm@22846: |> Pretty.chunks |> Pretty.writeln wenzelm@22846: end; wenzelm@7611: wenzelm@33092: fun add_attribute name att comment thy = thy wenzelm@42375: |> Attributes.map wenzelm@42375: (Name_Space.define (Proof_Context.init_global thy) true (Sign.naming_of thy) wenzelm@42375: (name, (att, comment)) #> snd); wenzelm@31306: wenzelm@5823: wenzelm@21031: (* name space *) wenzelm@15703: wenzelm@33095: val intern = Name_Space.intern o #1 o Attributes.get; wenzelm@15703: val intern_src = Args.map_name o intern; wenzelm@15703: wenzelm@42360: fun extern ctxt = Name_Space.extern ctxt (#1 (Attributes.get (Proof_Context.theory_of ctxt))); wenzelm@21031: wenzelm@21031: wenzelm@21031: (* pretty printing *) wenzelm@21031: wenzelm@21031: fun pretty_attribs _ [] = [] wenzelm@21031: | pretty_attribs ctxt srcs = wenzelm@38329: [Pretty.enum "," "[" "]" (map (Args.pretty_src ctxt o Args.map_name (extern ctxt)) srcs)]; wenzelm@21031: wenzelm@15703: wenzelm@18734: (* get attributes *) wenzelm@5823: wenzelm@26891: val defined = Symtab.defined o #2 o Attributes.get; wenzelm@26891: wenzelm@18734: fun attribute_i thy = wenzelm@5823: let wenzelm@42380: val (space, tab) = Attributes.get thy; wenzelm@5879: fun attr src = wenzelm@16344: let val ((name, _), pos) = Args.dest_src src in wenzelm@42380: (case Symtab.lookup tab name of skalberg@15531: NONE => error ("Unknown attribute: " ^ quote name ^ Position.str_of pos) wenzelm@42380: | SOME (att, _) => (Position.report pos (Name_Space.markup space name); att src)) wenzelm@5823: end; wenzelm@5823: in attr end; wenzelm@5823: wenzelm@18734: fun attribute thy = attribute_i thy o intern_src thy; wenzelm@18636: wenzelm@5823: wenzelm@17105: (* attributed declarations *) wenzelm@17105: wenzelm@45390: fun map_specs f = map (apfst (apsnd f)); wenzelm@30759: wenzelm@45390: fun map_facts f = map (apfst (apsnd f) o apsnd (map (apsnd f))); wenzelm@30759: fun map_facts_refs f g = map_facts f #> map (apsnd (map (apfst g))); wenzelm@17105: wenzelm@17105: wenzelm@38330: (* fact expressions *) wenzelm@38330: wenzelm@38330: fun eval_thms ctxt srcs = ctxt wenzelm@42360: |> Proof_Context.note_thmss "" wenzelm@45390: (map_facts_refs (map (attribute (Proof_Context.theory_of ctxt))) (Proof_Context.get_fact ctxt) wenzelm@38330: [((Binding.empty, []), srcs)]) wenzelm@38330: |> fst |> maps snd; wenzelm@38330: wenzelm@38330: wenzelm@30525: (* attribute setup *) wenzelm@30525: wenzelm@31306: fun syntax scan = Args.syntax "attribute" scan; wenzelm@30525: wenzelm@31306: fun setup name scan = wenzelm@31306: add_attribute name wenzelm@31306: (fn src => fn (ctxt, th) => let val (a, ctxt') = syntax scan src ctxt in a (ctxt', th) end); wenzelm@5879: wenzelm@30525: fun attribute_setup name (txt, pos) cmt = wenzelm@30525: Context.theory_map (ML_Context.expression pos wenzelm@30525: "val (name, scan, comment): binding * attribute context_parser * string" wenzelm@30525: "Context.map_theory (Attrib.setup name scan comment)" wenzelm@37198: (ML_Lex.read Position.none ("(" ^ ML_Syntax.make_binding name ^ ", ") @ wenzelm@37198: ML_Lex.read pos txt @ wenzelm@37198: ML_Lex.read Position.none (", " ^ ML_Syntax.print_string cmt ^ ")"))); wenzelm@30525: wenzelm@30525: wenzelm@31305: (* add/del syntax *) wenzelm@5823: wenzelm@31305: fun add_del add del = Scan.lift (Args.add >> K add || Args.del >> K del || Scan.succeed add); wenzelm@5879: wenzelm@5879: wenzelm@25983: wenzelm@25983: (** parsing attributed theorems **) wenzelm@5879: wenzelm@36950: val thm_sel = Parse.$$$ "(" |-- Parse.list1 wenzelm@36950: (Parse.nat --| Parse.minus -- Parse.nat >> Facts.FromTo || wenzelm@36950: Parse.nat --| Parse.minus >> Facts.From || wenzelm@36950: Parse.nat >> Facts.Single) --| Parse.$$$ ")"; wenzelm@27812: wenzelm@18636: local wenzelm@18636: wenzelm@21698: val fact_name = Args.internal_fact >> K "" || Args.name; wenzelm@21698: wenzelm@26336: fun gen_thm pick = Scan.depend (fn context => wenzelm@26336: let wenzelm@26336: val thy = Context.theory_of context; wenzelm@42360: val get = Context.cases (Global_Theory.get_fact context) Proof_Context.get_fact context; wenzelm@26361: val get_fact = get o Facts.Fact; wenzelm@27820: fun get_named pos name = get (Facts.Named ((name, pos), NONE)); wenzelm@26336: in wenzelm@36950: Parse.$$$ "[" |-- Args.attribs (intern thy) --| Parse.$$$ "]" >> (fn srcs => wenzelm@24008: let wenzelm@26336: val atts = map (attribute_i thy) srcs; wenzelm@45375: val (context', th') = wenzelm@45375: Library.apply (map Thm.apply_attribute atts) (context, Drule.dummy_thm); wenzelm@26336: in (context', pick "" [th']) end) wenzelm@26336: || wenzelm@26336: (Scan.ahead Args.alt_name -- Args.named_fact get_fact wenzelm@27820: >> (fn (s, fact) => ("", Facts.Fact s, fact)) || wenzelm@36950: Scan.ahead (Parse.position fact_name) :|-- (fn (name, pos) => wenzelm@27820: Args.named_fact (get_named pos) -- Scan.option thm_sel wenzelm@27820: >> (fn (fact, sel) => (name, Facts.Named ((name, pos), sel), fact)))) wenzelm@26336: -- Args.opt_attribs (intern thy) >> (fn ((name, thmref, fact), srcs) => wenzelm@26336: let wenzelm@26336: val ths = Facts.select thmref fact; wenzelm@26336: val atts = map (attribute_i thy) srcs; wenzelm@45375: val (context', ths') = wenzelm@45375: Library.foldl_map (Library.apply (map Thm.apply_attribute atts)) (context, ths); wenzelm@26336: in (context', pick name ths') end) wenzelm@26336: end); berghofe@15456: wenzelm@18636: in wenzelm@18636: wenzelm@26336: val thm = gen_thm Facts.the_single; wenzelm@18998: val multi_thm = gen_thm (K I); wenzelm@19482: val thms = Scan.repeat multi_thm >> flat; wenzelm@18636: wenzelm@18636: end; wenzelm@18636: wenzelm@5823: wenzelm@5879: wenzelm@45586: (** partial evaluation -- observing rule/declaration/mixed attributes **) wenzelm@45493: wenzelm@45493: local wenzelm@45526: wenzelm@45586: val strict_eq_thm = op = o pairself Thm.rep_thm; wenzelm@45493: wenzelm@45493: fun apply_att src (context, th) = wenzelm@45526: let wenzelm@45526: val src1 = Args.assignable src; wenzelm@45526: val result = attribute_i (Context.theory_of context) src1 (context, th); wenzelm@45526: val src2 = Args.closure src1; wenzelm@45526: in (src2, result) end; wenzelm@45493: wenzelm@45527: fun err msg src = wenzelm@45527: let val ((name, _), pos) = Args.dest_src src wenzelm@45527: in error (msg ^ " " ^ quote name ^ Position.str_of pos) end; wenzelm@45527: wenzelm@45527: fun eval src ((th, dyn), (decls, context)) = wenzelm@45527: (case (apply_att src (context, th), dyn) of wenzelm@45527: ((_, (NONE, SOME th')), NONE) => ((th', NONE), (decls, context)) wenzelm@45527: | ((_, (NONE, SOME _)), SOME _) => err "Mixed dynamic attribute followed by static rule" src wenzelm@45527: | ((src', (SOME context', NONE)), NONE) => wenzelm@45493: let wenzelm@45493: val decls' = wenzelm@45493: (case decls of wenzelm@45526: [] => [(th, [src'])] wenzelm@45493: | (th2, srcs2) :: rest => wenzelm@45586: if strict_eq_thm (th, th2) wenzelm@45526: then ((th2, src' :: srcs2) :: rest) wenzelm@45526: else (th, [src']) :: (th2, srcs2) :: rest); wenzelm@45527: in ((th, NONE), (decls', context')) end wenzelm@45527: | ((src', (opt_context', opt_th')), _) => wenzelm@45527: let wenzelm@45527: val context' = the_default context opt_context'; wenzelm@45527: val th' = the_default th opt_th'; wenzelm@45527: val dyn' = wenzelm@45527: (case dyn of wenzelm@45527: NONE => SOME (th, [src']) wenzelm@45527: | SOME (dyn_th, srcs) => SOME (dyn_th, src' :: srcs)); wenzelm@45527: in ((th', dyn'), (decls, context')) end); wenzelm@45493: wenzelm@45493: in wenzelm@45493: wenzelm@45493: fun partial_evaluation ctxt facts = wenzelm@45586: (facts, Context.Proof (Context_Position.set_visible false ctxt)) |-> wenzelm@45586: fold_map (fn ((b, more_atts), fact) => fn context => wenzelm@45586: let wenzelm@45586: val (fact', (decls, context')) = wenzelm@45586: (fact, ([], context)) |-> fold_map (fn (ths, atts) => fn res1 => wenzelm@45586: (ths, res1) |-> fold_map (fn th => fn res2 => wenzelm@45586: let wenzelm@45586: val ((th', dyn'), res3) = fold eval (atts @ more_atts) ((th, NONE), res2); wenzelm@45586: val th_atts' = wenzelm@45586: (case dyn' of wenzelm@45586: NONE => (th', []) wenzelm@45586: | SOME (dyn_th', atts') => (dyn_th', rev atts')); wenzelm@45586: in (th_atts', res3) end)) wenzelm@45586: |>> flat; wenzelm@45586: val decls' = rev (map (apsnd rev) decls); wenzelm@45586: val facts' = wenzelm@45586: if eq_list (eq_fst strict_eq_thm) (decls', fact') then wenzelm@45586: [((b, []), map2 (fn (th, atts1) => fn (_, atts2) => (th, atts1 @ atts2)) decls' fact')] wenzelm@45619: else if null decls' then [((b, []), fact')] wenzelm@45586: else [(empty_binding, decls'), ((b, []), fact')]; wenzelm@45586: in (facts', context') end) wenzelm@45586: |> fst |> flat |> map (apsnd (map (apfst single))); wenzelm@45493: wenzelm@45493: end; wenzelm@45493: wenzelm@45493: wenzelm@45493: wenzelm@25983: (** basic attributes **) wenzelm@25983: wenzelm@25983: (* internal *) wenzelm@25983: wenzelm@36959: fun internal att = Args.src (("Pure.attribute", [Token.mk_attribute att]), Position.none); wenzelm@25983: wenzelm@25983: wenzelm@25983: (* rule composition *) wenzelm@25983: wenzelm@25983: val COMP_att = wenzelm@36950: Scan.lift (Scan.optional (Args.bracks Parse.nat) 1) -- thm wenzelm@31305: >> (fn (i, B) => Thm.rule_attribute (fn _ => fn A => Drule.compose_single (A, i, B))); wenzelm@25983: wenzelm@25983: val THEN_att = wenzelm@36950: Scan.lift (Scan.optional (Args.bracks Parse.nat) 1) -- thm wenzelm@31305: >> (fn (i, B) => Thm.rule_attribute (fn _ => fn A => A RSN (i, B))); wenzelm@25983: wenzelm@25983: val OF_att = wenzelm@31305: thms >> (fn Bs => Thm.rule_attribute (fn _ => fn A => Bs MRS A)); wenzelm@25983: wenzelm@25983: wenzelm@25983: (* rename_abs *) wenzelm@25983: wenzelm@45375: val rename_abs = wenzelm@45375: Scan.repeat (Args.maybe Args.name) wenzelm@45375: >> (fn args => Thm.rule_attribute (K (Drule.rename_bvars' args))); wenzelm@25983: wenzelm@25983: wenzelm@25983: (* unfold / fold definitions *) wenzelm@25983: wenzelm@25983: fun unfolded_syntax rule = wenzelm@31305: thms >> (fn ths => Thm.rule_attribute (fn context => rule (Context.proof_of context) ths)); wenzelm@25983: wenzelm@35624: val unfolded = unfolded_syntax Local_Defs.unfold; wenzelm@35624: val folded = unfolded_syntax Local_Defs.fold; wenzelm@25983: wenzelm@25983: wenzelm@25983: (* rule format *) wenzelm@25983: wenzelm@31305: val rule_format = Args.mode "no_asm" wenzelm@35625: >> (fn true => Object_Logic.rule_format_no_asm | false => Object_Logic.rule_format); wenzelm@25983: wenzelm@31305: val elim_format = Thm.rule_attribute (K Tactic.make_elim); wenzelm@25983: wenzelm@25983: nipkow@44046: (* case names *) nipkow@44046: wenzelm@45375: val case_names = wenzelm@45375: Scan.repeat1 (Args.name -- wenzelm@45375: Scan.optional (Parse.$$$ "[" |-- Scan.repeat1 (Args.maybe Args.name) --| Parse.$$$ "]") []) >> wenzelm@45375: (fn cs => wenzelm@45375: Rule_Cases.cases_hyp_names (map fst cs) wenzelm@45375: (map (map (the_default Rule_Cases.case_hypsN) o snd) cs)); wenzelm@44053: nipkow@44046: wenzelm@25983: (* misc rules *) wenzelm@25983: wenzelm@31305: val no_vars = Thm.rule_attribute (fn context => fn th => wenzelm@26715: let wenzelm@26715: val ctxt = Variable.set_body false (Context.proof_of context); wenzelm@31794: val ((_, [th']), _) = Variable.import true [th] ctxt; wenzelm@31305: in th' end); wenzelm@25983: wenzelm@25983: val eta_long = wenzelm@31305: Thm.rule_attribute (K (Conv.fconv_rule Drule.eta_long_conversion)); wenzelm@25983: wenzelm@36950: val rotated = Scan.optional Parse.int 1 >> (fn n => Thm.rule_attribute (K (rotate_prems n))); berghofe@29690: wenzelm@25983: wenzelm@25983: (* theory setup *) wenzelm@5823: wenzelm@26463: val _ = Context.>> (Context.map_theory wenzelm@31305: (setup (Binding.name "attribute") (Scan.lift Args.internal_attribute >> Morphism.form) wenzelm@31305: "internal attribute" #> wenzelm@31305: setup (Binding.name "tagged") (Scan.lift (Args.name -- Args.name) >> Thm.tag) "tagged theorem" #> wenzelm@31305: setup (Binding.name "untagged") (Scan.lift Args.name >> Thm.untag) "untagged theorem" #> wenzelm@31305: setup (Binding.name "kind") (Scan.lift Args.name >> Thm.kind) "theorem kind" #> wenzelm@31305: setup (Binding.name "COMP") COMP_att "direct composition with rules (no lifting)" #> wenzelm@31305: setup (Binding.name "THEN") THEN_att "resolution with rule" #> wenzelm@31305: setup (Binding.name "OF") OF_att "rule applied to facts" #> wenzelm@31305: setup (Binding.name "rename_abs") (Scan.lift rename_abs) wenzelm@31305: "rename bound variables in abstractions" #> wenzelm@31305: setup (Binding.name "unfolded") unfolded "unfolded definitions" #> wenzelm@31305: setup (Binding.name "folded") folded "folded definitions" #> wenzelm@36950: setup (Binding.name "consumes") (Scan.lift (Scan.optional Parse.nat 1) >> Rule_Cases.consumes) wenzelm@31305: "number of consumed facts" #> wenzelm@36950: setup (Binding.name "constraints") (Scan.lift Parse.nat >> Rule_Cases.constraints) berghofe@34986: "number of equality constraints" #> wenzelm@45375: setup (Binding.name "case_names") (Scan.lift case_names) "named rule cases" #> wenzelm@31305: setup (Binding.name "case_conclusion") wenzelm@33368: (Scan.lift (Args.name -- Scan.repeat Args.name) >> Rule_Cases.case_conclusion) wenzelm@31305: "named conclusion of rule cases" #> wenzelm@31305: setup (Binding.name "params") wenzelm@36950: (Scan.lift (Parse.and_list1 (Scan.repeat Args.name)) >> Rule_Cases.params) wenzelm@31305: "named rule parameters" #> wenzelm@35021: setup (Binding.name "standard") (Scan.succeed (Thm.rule_attribute (K Drule.export_without_context))) wenzelm@31305: "result put into standard form (legacy)" #> wenzelm@31305: setup (Binding.name "rule_format") rule_format "result put into canonical rule format" #> wenzelm@31305: setup (Binding.name "elim_format") (Scan.succeed elim_format) wenzelm@31305: "destruct rule turned into elimination rule format" #> wenzelm@31305: setup (Binding.name "no_vars") (Scan.succeed no_vars) "frozen schematic vars" #> wenzelm@31305: setup (Binding.name "eta_long") (Scan.succeed eta_long) wenzelm@31305: "put theorem into eta long beta normal form" #> wenzelm@35625: setup (Binding.name "atomize") (Scan.succeed Object_Logic.declare_atomize) wenzelm@31305: "declaration of atomize rule" #> wenzelm@35625: setup (Binding.name "rulify") (Scan.succeed Object_Logic.declare_rulify) wenzelm@31305: "declaration of rulify rule" #> wenzelm@31305: setup (Binding.name "rotated") (Scan.lift rotated) "rotated theorem premises" #> wenzelm@35624: setup (Binding.name "defn") (add_del Local_Defs.defn_add Local_Defs.defn_del) wenzelm@31305: "declaration of definitional transformations" #> wenzelm@31305: setup (Binding.name "abs_def") (Scan.succeed (Thm.rule_attribute (K Drule.abs_def))) wenzelm@31305: "abstract over free variables of a definition")); wenzelm@8633: wenzelm@5823: wenzelm@5823: wenzelm@24110: (** configuration options **) wenzelm@24110: wenzelm@24110: (* naming *) wenzelm@24110: wenzelm@33522: structure Configs = Theory_Data wenzelm@24713: ( wenzelm@39163: type T = Config.raw Symtab.table; wenzelm@24110: val empty = Symtab.empty; wenzelm@24110: val extend = I; wenzelm@33522: fun merge data = Symtab.merge (K true) data; wenzelm@24713: ); wenzelm@5823: wenzelm@24110: fun print_configs ctxt = wenzelm@24110: let wenzelm@42360: val thy = Proof_Context.theory_of ctxt; wenzelm@24110: fun prt (name, config) = wenzelm@24110: let val value = Config.get ctxt config in wenzelm@24110: Pretty.block [Pretty.str (name ^ ": " ^ Config.print_type value ^ " ="), Pretty.brk 1, wenzelm@24110: Pretty.str (Config.print_value value)] wenzelm@24110: end; wenzelm@42358: val configs = Name_Space.extern_table ctxt (#1 (Attributes.get thy), Configs.get thy); wenzelm@24110: in Pretty.writeln (Pretty.big_list "configuration options" (map prt configs)) end; wenzelm@24110: wenzelm@24110: wenzelm@24110: (* concrete syntax *) wenzelm@23988: wenzelm@24003: local wenzelm@24003: wenzelm@36950: val equals = Parse.$$$ "="; wenzelm@24003: wenzelm@24110: fun scan_value (Config.Bool _) = wenzelm@24110: equals -- Args.$$$ "false" >> K (Config.Bool false) || wenzelm@24110: equals -- Args.$$$ "true" >> K (Config.Bool true) || wenzelm@24110: Scan.succeed (Config.Bool true) wenzelm@36950: | scan_value (Config.Int _) = equals |-- Parse.int >> Config.Int wenzelm@40291: | scan_value (Config.Real _) = equals |-- Parse.real >> Config.Real wenzelm@24110: | scan_value (Config.String _) = equals |-- Args.name >> Config.String; wenzelm@24003: wenzelm@24110: fun scan_config thy config = wenzelm@36787: let val config_type = Config.get_global thy config wenzelm@24110: in scan_value config_type >> (K o Thm.declaration_attribute o K o Config.put_generic config) end; wenzelm@24003: wenzelm@42616: fun register binding config thy = wenzelm@42616: let val name = Sign.full_name thy binding in wenzelm@24126: thy wenzelm@42616: |> setup binding (Scan.lift (scan_config thy config) >> Morphism.form) "configuration option" wenzelm@24126: |> Configs.map (Symtab.update (name, config)) wenzelm@24126: end; wenzelm@24110: wenzelm@42808: fun declare make coerce binding default = wenzelm@24110: let wenzelm@42616: val name = Binding.name_of binding; wenzelm@42808: val config_value = Config.declare_generic {global = false} name (make o default); wenzelm@24110: val config = coerce config_value; wenzelm@42616: in (config, register binding config_value) end; wenzelm@42616: wenzelm@42616: in wenzelm@42616: wenzelm@42808: val config_bool = declare Config.Bool Config.bool; wenzelm@42808: val config_int = declare Config.Int Config.int; wenzelm@42808: val config_real = declare Config.Real Config.real; wenzelm@42808: val config_string = declare Config.String Config.string; wenzelm@42616: wenzelm@42616: fun register_config config = register (Binding.name (Config.name_of config)) config; wenzelm@42616: wenzelm@42616: end; wenzelm@24110: wenzelm@42616: wenzelm@42616: (* implicit setup *) wenzelm@42616: wenzelm@42616: local wenzelm@24110: wenzelm@42616: fun setup_config declare_config binding default = wenzelm@42616: let wenzelm@42616: val (config, setup) = declare_config binding default; wenzelm@42616: val _ = Context.>> (Context.map_theory setup); wenzelm@42616: in config end; wenzelm@42616: wenzelm@42616: in wenzelm@42616: wenzelm@42616: val setup_config_bool = setup_config config_bool; wenzelm@42616: val setup_config_int = setup_config config_int; wenzelm@42616: val setup_config_string = setup_config config_string; wenzelm@42616: val setup_config_real = setup_config config_real; wenzelm@24003: wenzelm@24003: end; wenzelm@23988: wenzelm@23988: wenzelm@18636: (* theory setup *) wenzelm@5823: wenzelm@26463: val _ = Context.>> (Context.map_theory wenzelm@42277: (register_config Ast.trace_raw #> wenzelm@43347: register_config Ast.stats_raw #> wenzelm@42289: register_config Printer.show_brackets_raw #> wenzelm@42289: register_config Printer.show_sorts_raw #> wenzelm@42289: register_config Printer.show_types_raw #> wenzelm@42289: register_config Printer.show_structs_raw #> wenzelm@42289: register_config Printer.show_question_marks_raw #> wenzelm@46512: register_config Syntax.ambiguity_warning_raw #> wenzelm@46506: register_config Syntax.ambiguity_limit_raw #> wenzelm@42284: register_config Syntax_Trans.eta_contract_raw #> wenzelm@42669: register_config Name_Space.names_long_raw #> wenzelm@42669: register_config Name_Space.names_short_raw #> wenzelm@42669: register_config Name_Space.names_unique_raw #> wenzelm@41375: register_config ML_Context.trace_raw #> wenzelm@42360: register_config Proof_Context.show_abbrevs_raw #> wenzelm@39163: register_config Goal_Display.goals_limit_raw #> wenzelm@39163: register_config Goal_Display.show_main_goal_raw #> wenzelm@39163: register_config Goal_Display.show_consts_raw #> wenzelm@39166: register_config Display.show_hyps_raw #> wenzelm@39166: register_config Display.show_tags_raw #> wenzelm@39163: register_config Unify.trace_bound_raw #> wenzelm@39163: register_config Unify.search_bound_raw #> wenzelm@39163: register_config Unify.trace_simp_raw #> wenzelm@39163: register_config Unify.trace_types_raw #> wenzelm@41228: register_config Raw_Simplifier.simp_depth_limit_raw #> wenzelm@41228: register_config Raw_Simplifier.simp_trace_depth_limit_raw #> wenzelm@41228: register_config Raw_Simplifier.simp_debug_raw #> wenzelm@41228: register_config Raw_Simplifier.simp_trace_raw)); wenzelm@5823: wenzelm@5823: end;