1 (* Title: HOL/Tools/function_package/fundef_common.ML
3 Author: Alexander Krauss, TU Muenchen
5 A package for general recursive function definitions.
6 Common type definitions and other infrastructure.
9 structure FundefCommon =
13 val profile = ref false;
15 fun PROFILE msg = if !profile then timeap_msg msg else I
18 val acc_const_name = "Accessible_Part.acc"
20 Const (acc_const_name, (domT --> domT --> HOLogic.boolT) --> domT --> HOLogic.boolT) $ R
22 val function_name = suffix "C"
23 val graph_name = suffix "_graph"
24 val rel_name = suffix "_rel"
25 val dom_name = suffix "_dom"
27 type depgraph = int IntGraph.T
31 | Cong of (term * thm * depgraph * ((string * typ) list * thm list * ctx_tree) list)
32 | RCall of (term * ctx_tree)
36 datatype fundef_result =
44 trsimps : thm list option,
46 subset_pinducts : thm list,
47 simple_pinducts : thm list,
50 domintros : thm list option
54 datatype fundef_context_data =
59 add_simps : string -> Attrib.src list -> thm list -> local_theory -> thm list * local_theory,
69 fun morph_fundef_data phi (FundefCtxData {add_simps, fs, R, psimps, pinducts, termination, defname}) =
71 val term = Morphism.term phi val thm = Morphism.thm phi val fact = Morphism.fact phi
72 val name = Morphism.name phi
74 FundefCtxData { add_simps = add_simps (* contains no logical entities *),
75 fs = map term fs, R = term R, psimps = fact psimps,
76 pinducts = fact pinducts, termination = thm termination,
77 defname = name defname }
80 structure FundefData = GenericDataFun
82 type T = (term * fundef_context_data) NetRules.T;
83 val empty = NetRules.init
84 (op aconv o pairself fst : (term * fundef_context_data) * (term * fundef_context_data) -> bool)
88 fun merge _ (tab1, tab2) = NetRules.merge (tab1, tab2)
92 structure FundefCongs = GenericDataFun
97 fun merge _ = Drule.merge_rules
101 (* Generally useful?? *)
102 fun lift_morphism thy f =
104 val term = Drule.term_rule thy f
106 Morphism.thm_morphism f $> Morphism.term_morphism term $> Morphism.typ_morphism (Logic.type_map term)
109 fun import_fundef_data t ctxt =
111 val thy = Context.theory_of ctxt
112 val ct = cterm_of thy t
113 val inst_morph = lift_morphism thy o Thm.instantiate
116 SOME (morph_fundef_data (inst_morph (Thm.cterm_match (cterm_of thy (fst data), ct))) (snd data))
117 handle Pattern.MATCH => NONE
119 get_first match (NetRules.retrieve (FundefData.get ctxt) t)
122 fun import_last_fundef ctxt =
123 case NetRules.rules (FundefData.get ctxt) of
127 val ([t'], ctxt') = Variable.import_terms true [t] (Context.proof_of ctxt)
129 import_fundef_data t' (Context.Proof ctxt')
132 val all_fundef_data = NetRules.rules o FundefData.get
134 val map_fundef_congs = FundefCongs.map
135 val get_fundef_congs = FundefCongs.get
139 structure TerminationRule = GenericDataFun
144 fun merge _ = Drule.merge_rules
147 val get_termination_rules = TerminationRule.get
148 val store_termination_rule = TerminationRule.map o cons
149 val apply_termination_rule = resolve_tac o get_termination_rules o Context.Proof
151 fun add_fundef_data (data as FundefCtxData {fs, termination, ...}) =
152 FundefData.map (fold (fn f => NetRules.insert (f, data)) fs)
153 #> store_termination_rule termination
157 (* Configuration management *)
161 | Preprocessor of string
166 datatype fundef_config
171 preprocessor: string option,
172 target: xstring option,
178 val default_config = FundefConfig { sequential=false, default="%x. arbitrary", preprocessor=NONE,
179 target=NONE, domintros=false, tailrec=false }
181 val fun_config = FundefConfig { sequential=true, default="%x. arbitrary", preprocessor=NONE,
182 target=NONE, domintros=false, tailrec=false }
184 fun apply_opt Sequential (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec}) =
185 FundefConfig {sequential=true, default=default, preprocessor=preprocessor, target=target, domintros=domintros, tailrec=tailrec }
186 | apply_opt (Default d) (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec}) =
187 FundefConfig {sequential=sequential, default=d, preprocessor=preprocessor, target=target, domintros=domintros, tailrec=tailrec }
188 | apply_opt (Preprocessor p) (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec}) =
189 FundefConfig {sequential=sequential, default=default, preprocessor=SOME p, target=target, domintros=domintros, tailrec=tailrec }
190 | apply_opt (Target t) (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec }) =
191 FundefConfig {sequential=sequential, default=default, preprocessor=preprocessor, target=SOME t, domintros=domintros, tailrec=tailrec }
192 | apply_opt DomIntros (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec }) =
193 FundefConfig {sequential=sequential, default=default, preprocessor=preprocessor, target=target, domintros=true,tailrec=tailrec }
194 | apply_opt Tailrec (FundefConfig {sequential, default, preprocessor, target, domintros,tailrec }) =
195 FundefConfig {sequential=sequential, default=default, preprocessor=preprocessor, target=target, domintros=domintros,tailrec=true }
197 fun target_of (FundefConfig {target, ...}) = target
200 structure P = OuterParse and K = OuterKeyword
202 val opt_sequential = Scan.optional ((P.$$$ "(" |-- P.$$$ "sequential" --| P.$$$ ")") >> K true) false
204 val option_parser = (P.$$$ "sequential" >> K Sequential)
205 || ((P.reserved "default" |-- P.term) >> Default)
206 || (P.reserved "domintros" >> K DomIntros)
207 || (P.reserved "tailrec" >> K Tailrec)
208 || ((P.$$$ "in" |-- P.xname) >> Target)
210 fun config_parser def = (Scan.optional (P.$$$ "(" |-- P.!!! (P.list1 (P.group "option" option_parser)) --| P.$$$ ")") [])
211 >> (fn opts => fold apply_opt opts def)
213 fun pipe_list1 s = P.enum1 "|" s
215 val otherwise = P.$$$ "(" |-- P.$$$ "otherwise" --| P.$$$ ")"
217 fun pipe_error t = P.!!! (Scan.fail_with (K (cat_lines ["Equations must be separated by " ^ quote "|", quote t])))
219 val statement_ow = SpecParse.opt_thm_name ":" -- (P.prop -- Scan.optional (otherwise >> K true) false)
220 --| Scan.ahead ((P.term :-- pipe_error) || Scan.succeed ("",""))
222 val statements_ow = pipe_list1 statement_ow
224 fun fundef_parser default_cfg = config_parser default_cfg -- P.fixes --| P.$$$ "where" -- statements_ow
229 (* Common Abbreviations *)
231 structure FundefAbbrev =
234 fun implies_elim_swp x y = implies_elim y x
236 (* HOL abbreviations *)
237 val boolT = HOLogic.boolT
238 val mk_prod = HOLogic.mk_prod
239 val mk_eq = HOLogic.mk_eq
240 val eq_const = HOLogic.eq_const
241 val Trueprop = HOLogic.mk_Trueprop
242 val mk_relT = HOLogic.mk_setT o HOLogic.mk_prodT
244 fun free_to_var (Free (v,T)) = Var ((v,0),T)
245 | free_to_var _ = raise Match
247 fun var_to_free (Var ((v,_),T)) = Free (v,T)
248 | var_to_free _ = raise Match