src/HOL/Tools/function_package/fundef_common.ML
author wenzelm
Mon, 07 May 2007 00:49:59 +0200
changeset 22846 fb79144af9a3
parent 22760 6eafeffe801c
child 22903 95ad1a91ecef
permissions -rw-r--r--
simplified DataFun interfaces;
     1 (*  Title:      HOL/Tools/function_package/fundef_common.ML
     2     ID:         $Id$
     3     Author:     Alexander Krauss, TU Muenchen
     4 
     5 A package for general recursive function definitions. 
     6 Common type definitions and other infrastructure.
     7 *)
     8 
     9 structure FundefCommon =
    10 struct
    11 
    12 (* Profiling *)
    13 val profile = ref false;
    14 
    15 fun PROFILE msg = if !profile then timeap_msg msg else I
    16 
    17 
    18 val acc_const_name = "Accessible_Part.acc"
    19 fun mk_acc domT R =
    20     Const (acc_const_name, (domT --> domT --> HOLogic.boolT) --> domT --> HOLogic.boolT) $ R 
    21 
    22 val function_name = suffix "C"
    23 val graph_name = suffix "_graph"
    24 val rel_name = suffix "_rel"
    25 val dom_name = suffix "_dom"
    26 
    27 type depgraph = int IntGraph.T
    28 
    29 datatype ctx_tree 
    30   = Leaf of term
    31   | Cong of (term * thm * depgraph * ((string * typ) list * thm list * ctx_tree) list)
    32   | RCall of (term * ctx_tree)
    33 
    34 
    35 
    36 datatype fundef_result =
    37   FundefResult of
    38      {
    39       fs: term list,
    40       G: term,
    41       R: term,
    42 
    43       psimps : thm list, 
    44       trsimps : thm list option, 
    45 
    46       subset_pinducts : thm list, 
    47       simple_pinducts : thm list, 
    48       cases : thm,
    49       termination : thm,
    50       domintros : thm list option
    51      }
    52 
    53 
    54 datatype fundef_context_data =
    55   FundefCtxData of
    56      {
    57       defname : string,
    58 
    59       add_simps : string -> Attrib.src list -> thm list -> local_theory -> thm list * local_theory,
    60 
    61       fs : term list,
    62       R : term,
    63       
    64       psimps: thm list,
    65       pinducts: thm list,
    66       termination: thm
    67      }
    68 
    69 fun morph_fundef_data phi (FundefCtxData {add_simps, fs, R, psimps, pinducts, termination, defname}) =
    70     let
    71       val term = Morphism.term phi val thm = Morphism.thm phi val fact = Morphism.fact phi
    72       val name = Morphism.name phi
    73     in
    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 }
    78     end
    79 
    80 structure FundefData = GenericDataFun
    81 (
    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)
    85     fst;
    86   val copy = I;
    87   val extend = I;
    88   fun merge _ (tab1, tab2) = NetRules.merge (tab1, tab2)
    89 );
    90 
    91 
    92 structure FundefCongs = GenericDataFun
    93 (
    94   type T = thm list
    95   val empty = []
    96   val extend = I
    97   fun merge _ = Drule.merge_rules
    98 );
    99 
   100 
   101 (* Generally useful?? *)
   102 fun lift_morphism thy f = 
   103     let 
   104       val term = Drule.term_rule thy f
   105     in
   106       Morphism.thm_morphism f $> Morphism.term_morphism term $> Morphism.typ_morphism (Logic.type_map term)
   107     end
   108 
   109 fun import_fundef_data t ctxt =
   110     let
   111       val thy = Context.theory_of ctxt
   112       val ct = cterm_of thy t
   113       val inst_morph = lift_morphism thy o Thm.instantiate 
   114 
   115       fun match data = 
   116           SOME (morph_fundef_data (inst_morph (Thm.cterm_match (cterm_of thy (fst data), ct))) (snd data))
   117           handle Pattern.MATCH => NONE
   118     in 
   119       get_first match (NetRules.retrieve (FundefData.get ctxt) t)
   120     end
   121 
   122 fun import_last_fundef ctxt =
   123     case NetRules.rules (FundefData.get ctxt) of
   124       [] => NONE
   125     | (t, data) :: _ =>
   126       let 
   127         val ([t'], ctxt') = Variable.import_terms true [t] (Context.proof_of ctxt)
   128       in
   129         import_fundef_data t' (Context.Proof ctxt')
   130       end
   131 
   132 val all_fundef_data = NetRules.rules o FundefData.get
   133 
   134 val map_fundef_congs = FundefCongs.map 
   135 val get_fundef_congs = FundefCongs.get
   136 
   137 
   138 
   139 structure TerminationRule = GenericDataFun
   140 (
   141   type T = thm list
   142   val empty = []
   143   val extend = I
   144   fun merge _ = Drule.merge_rules
   145 );
   146 
   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
   150 
   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
   154 
   155 
   156 
   157 (* Configuration management *)
   158 datatype fundef_opt 
   159   = Sequential
   160   | Default of string
   161   | Preprocessor of string
   162   | Target of xstring
   163   | DomIntros
   164   | Tailrec
   165 
   166 datatype fundef_config
   167   = FundefConfig of
   168    {
   169     sequential: bool,
   170     default: string,
   171     preprocessor: string option,
   172     target: xstring option,
   173     domintros: bool,
   174     tailrec: bool
   175    }
   176 
   177 
   178 val default_config = FundefConfig { sequential=false, default="%x. arbitrary", preprocessor=NONE,
   179                                     target=NONE, domintros=false, tailrec=false }
   180 
   181 val fun_config = FundefConfig { sequential=true, default="%x. arbitrary", preprocessor=NONE, 
   182                                 target=NONE, domintros=false, tailrec=false }
   183 
   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 } 
   196 
   197 fun target_of (FundefConfig {target, ...}) = target
   198 
   199 local 
   200   structure P = OuterParse and K = OuterKeyword 
   201 
   202   val opt_sequential = Scan.optional ((P.$$$ "(" |-- P.$$$ "sequential" --| P.$$$ ")") >> K true) false
   203                        
   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)
   209 
   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)
   212 
   213   fun pipe_list1 s = P.enum1 "|" s
   214 
   215   val otherwise = P.$$$ "(" |-- P.$$$ "otherwise" --| P.$$$ ")"
   216 
   217   fun pipe_error t = P.!!! (Scan.fail_with (K (cat_lines ["Equations must be separated by " ^ quote "|", quote t])))
   218 
   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 ("",""))
   221 
   222   val statements_ow = pipe_list1 statement_ow
   223 in
   224   fun fundef_parser default_cfg = config_parser default_cfg -- P.fixes --| P.$$$ "where" -- statements_ow
   225 end
   226 
   227 end
   228 
   229 (* Common Abbreviations *)
   230 
   231 structure FundefAbbrev =
   232 struct
   233 
   234 fun implies_elim_swp x y = implies_elim y x
   235 
   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
   243 
   244 fun free_to_var (Free (v,T)) = Var ((v,0),T)
   245   | free_to_var _ = raise Match
   246 
   247 fun var_to_free (Var ((v,_),T)) = Free (v,T)
   248   | var_to_free _ = raise Match
   249 
   250 
   251 end