src/HOL/Tools/Function/function_common.ML
author krauss
Mon, 02 Nov 2009 22:24:03 +0100
changeset 33395 62571cb54811
parent 33373 674df68d4df0
child 33519 e31a85f92ce9
permissions -rw-r--r--
conceal partial rules depending on config flag (i.e. when called via "fun")
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Function/fundef_common.ML
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     2
    Author:     Alexander Krauss, TU Muenchen
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     3
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     4
A package for general recursive function definitions. 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     5
Common definitions and other infrastructure.
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     6
*)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     7
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     8
structure Function_Common =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     9
struct
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    10
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    11
local open Function_Lib in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    12
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    13
(* Profiling *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    14
val profile = Unsynchronized.ref false;
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    15
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    16
fun PROFILE msg = if !profile then timeap_msg msg else I
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    17
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    18
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    19
val acc_const_name = @{const_name accp}
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    20
fun mk_acc domT R =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    21
    Const (acc_const_name, (domT --> domT --> HOLogic.boolT) --> domT --> HOLogic.boolT) $ R 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    22
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    23
val function_name = suffix "C"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    24
val graph_name = suffix "_graph"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    25
val rel_name = suffix "_rel"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    26
val dom_name = suffix "_dom"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    27
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    28
(* Termination rules *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    29
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    30
structure TerminationRule = GenericDataFun
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    31
(
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    32
  type T = thm list
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    33
  val empty = []
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    34
  val extend = I
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    35
  fun merge _ = Thm.merge_thms
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    36
);
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    37
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    38
val get_termination_rules = TerminationRule.get
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    39
val store_termination_rule = TerminationRule.map o cons
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    40
val apply_termination_rule = resolve_tac o get_termination_rules o Context.Proof
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    41
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    42
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    43
(* Function definition result data *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    44
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    45
datatype function_result =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    46
  FunctionResult of
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    47
     {
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    48
      fs: term list,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    49
      G: term,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    50
      R: term,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    51
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    52
      psimps : thm list, 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    53
      trsimps : thm list option, 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    54
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    55
      simple_pinducts : thm list, 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    56
      cases : thm,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    57
      termination : thm,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    58
      domintros : thm list option
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    59
     }
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    60
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    61
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    62
datatype function_context_data =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    63
  FunctionCtxData of
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    64
     {
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    65
      defname : string,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    66
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    67
      (* contains no logical entities: invariant under morphisms *)
33395
62571cb54811 conceal partial rules depending on config flag (i.e. when called via "fun")
krauss
parents: 33373
diff changeset
    68
      add_simps : (binding -> binding) -> string -> (binding -> binding) ->
62571cb54811 conceal partial rules depending on config flag (i.e. when called via "fun")
krauss
parents: 33373
diff changeset
    69
        Attrib.src list -> thm list -> local_theory -> thm list * local_theory,
62571cb54811 conceal partial rules depending on config flag (i.e. when called via "fun")
krauss
parents: 33373
diff changeset
    70
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    71
      case_names : string list,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    72
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    73
      fs : term list,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    74
      R : term,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    75
      
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    76
      psimps: thm list,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    77
      pinducts: thm list,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    78
      termination: thm
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    79
     }
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    80
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    81
fun morph_function_data (FunctionCtxData {add_simps, case_names, fs, R, 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    82
                                      psimps, pinducts, termination, defname}) phi =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    83
    let
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    84
      val term = Morphism.term phi val thm = Morphism.thm phi val fact = Morphism.fact phi
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    85
      val name = Binding.name_of o Morphism.binding phi o Binding.name
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    86
    in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    87
      FunctionCtxData { add_simps = add_simps, case_names = case_names,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    88
                      fs = map term fs, R = term R, psimps = fact psimps, 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    89
                      pinducts = fact pinducts, termination = thm termination,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    90
                      defname = name defname }
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    91
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    92
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    93
structure FunctionData = GenericDataFun
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    94
(
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    95
  type T = (term * function_context_data) Item_Net.T;
33373
674df68d4df0 adapted Item_Net;
wenzelm
parents: 33101
diff changeset
    96
  val empty : T = Item_Net.init (op aconv o pairself fst) (single o fst);
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    97
  val copy = I;
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    98
  val extend = I;
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    99
  fun merge _ (tab1, tab2) = Item_Net.merge (tab1, tab2)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   100
);
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   101
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   102
val get_function = FunctionData.get o Context.Proof;
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   103
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   104
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   105
(* Generally useful?? *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   106
fun lift_morphism thy f = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   107
    let 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   108
      val term = Drule.term_rule thy f
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   109
    in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   110
      Morphism.thm_morphism f $> Morphism.term_morphism term 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   111
       $> Morphism.typ_morphism (Logic.type_map term)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   112
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   113
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   114
fun import_function_data t ctxt =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   115
    let
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   116
      val thy = ProofContext.theory_of ctxt
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   117
      val ct = cterm_of thy t
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   118
      val inst_morph = lift_morphism thy o Thm.instantiate 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   119
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   120
      fun match (trm, data) = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   121
          SOME (morph_function_data data (inst_morph (Thm.match (cterm_of thy trm, ct))))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   122
          handle Pattern.MATCH => NONE
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   123
    in 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   124
      get_first match (Item_Net.retrieve (get_function ctxt) t)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   125
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   126
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   127
fun import_last_function ctxt =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   128
    case Item_Net.content (get_function ctxt) of
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   129
      [] => NONE
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   130
    | (t, data) :: _ =>
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   131
      let 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   132
        val ([t'], ctxt') = Variable.import_terms true [t] ctxt
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   133
      in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   134
        import_function_data t' ctxt'
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   135
      end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   136
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   137
val all_function_data = Item_Net.content o get_function
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   138
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   139
fun add_function_data (data as FunctionCtxData {fs, termination, ...}) =
33373
674df68d4df0 adapted Item_Net;
wenzelm
parents: 33101
diff changeset
   140
    FunctionData.map (fold (fn f => Item_Net.update (f, data)) fs)
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   141
    #> store_termination_rule termination
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   142
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   143
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   144
(* Simp rules for termination proofs *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   145
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   146
structure Termination_Simps = Named_Thms
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   147
(
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   148
  val name = "termination_simp" 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   149
  val description = "Simplification rule for termination proofs"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   150
);
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   151
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   152
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   153
(* Default Termination Prover *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   154
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   155
structure TerminationProver = GenericDataFun
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   156
(
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   157
  type T = Proof.context -> Proof.method
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   158
  val empty = (fn _ => error "Termination prover not configured")
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   159
  val extend = I
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   160
  fun merge _ (a,b) = b (* FIXME *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   161
);
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   162
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   163
val set_termination_prover = TerminationProver.put
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   164
val get_termination_prover = TerminationProver.get o Context.Proof
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   165
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   166
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   167
(* Configuration management *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   168
datatype function_opt 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   169
  = Sequential
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   170
  | Default of string
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   171
  | DomIntros
33101
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   172
  | No_Partials
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   173
  | Tailrec
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   174
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   175
datatype function_config
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   176
  = FunctionConfig of
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   177
   {
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   178
    sequential: bool,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   179
    default: string,
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   180
    domintros: bool,
33101
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   181
    partials: bool,
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   182
    tailrec: bool
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   183
   }
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   184
33101
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   185
fun apply_opt Sequential (FunctionConfig {sequential, default, domintros, partials, tailrec}) =
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   186
    FunctionConfig {sequential=true, default=default, domintros=domintros, partials=partials, tailrec=tailrec}
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   187
  | apply_opt (Default d) (FunctionConfig {sequential, default, domintros, partials, tailrec}) =
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   188
    FunctionConfig {sequential=sequential, default=d, domintros=domintros, partials=partials, tailrec=tailrec}
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   189
  | apply_opt DomIntros (FunctionConfig {sequential, default, domintros, partials, tailrec}) =
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   190
    FunctionConfig {sequential=sequential, default=default, domintros=true, partials=partials, tailrec=tailrec}
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   191
  | apply_opt Tailrec (FunctionConfig {sequential, default, domintros, partials, tailrec}) =
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   192
    FunctionConfig {sequential=sequential, default=default, domintros=domintros, partials=partials, tailrec=true}
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   193
  | apply_opt No_Partials (FunctionConfig {sequential, default, domintros, partials, tailrec}) =
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   194
    FunctionConfig {sequential=sequential, default=default, domintros=domintros, partials=false, tailrec=true}
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   195
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   196
val default_config =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   197
  FunctionConfig { sequential=false, default="%x. undefined" (*FIXME dynamic scoping*), 
33101
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   198
    domintros=false, partials=true, tailrec=false }
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   199
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   200
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   201
(* Analyzing function equations *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   202
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   203
fun split_def ctxt geq =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   204
    let
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   205
      fun input_error msg = cat_lines [msg, Syntax.string_of_term ctxt geq]
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   206
      val qs = Term.strip_qnt_vars "all" geq
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   207
      val imp = Term.strip_qnt_body "all" geq
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   208
      val (gs, eq) = Logic.strip_horn imp
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   209
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   210
      val (f_args, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop eq)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   211
          handle TERM _ => error (input_error "Not an equation")
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   212
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   213
      val (head, args) = strip_comb f_args
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   214
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   215
      val fname = fst (dest_Free head)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   216
          handle TERM _ => error (input_error "Head symbol must not be a bound variable")
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   217
    in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   218
      (fname, qs, gs, args, rhs)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   219
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   220
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   221
(* Check for all sorts of errors in the input *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   222
fun check_defs ctxt fixes eqs =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   223
    let
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   224
      val fnames = map (fst o fst) fixes
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   225
                                
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   226
      fun check geq = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   227
          let
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   228
            fun input_error msg = error (cat_lines [msg, Syntax.string_of_term ctxt geq])
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   229
                                  
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   230
            val fqgar as (fname, qs, gs, args, rhs) = split_def ctxt geq
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   231
                                 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   232
            val _ = fname mem fnames 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   233
                    orelse input_error 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   234
                             ("Head symbol of left hand side must be " 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   235
                              ^ plural "" "one out of " fnames ^ commas_quote fnames)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   236
                                            
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   237
            val _ = length args > 0 orelse input_error "Function has no arguments:"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   238
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   239
            fun add_bvs t is = add_loose_bnos (t, 0, is)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   240
            val rvs = (subtract (op =) (fold add_bvs args []) (add_bvs rhs []))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   241
                        |> map (fst o nth (rev qs))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   242
                      
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   243
            val _ = null rvs orelse input_error 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   244
                        ("Variable" ^ plural " " "s " rvs ^ commas_quote rvs
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   245
                         ^ " occur" ^ plural "s" "" rvs ^ " on right hand side only:")
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   246
                                    
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   247
            val _ = forall (not o Term.exists_subterm 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   248
                             (fn Free (n, _) => n mem fnames | _ => false)) (gs @ args)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   249
                    orelse input_error "Defined function may not occur in premises or arguments"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   250
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   251
            val freeargs = map (fn t => subst_bounds (rev (map Free qs), t)) args
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   252
            val funvars = filter (fn q => exists (exists_subterm (fn (Free q') $ _ => q = q' | _ => false)) freeargs) qs
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   253
            val _ = null funvars
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   254
                    orelse (warning (cat_lines 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   255
                    ["Bound variable" ^ plural " " "s " funvars 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   256
                     ^ commas_quote (map fst funvars) ^  
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   257
                     " occur" ^ plural "s" "" funvars ^ " in function position.",  
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   258
                     "Misspelled constructor???"]); true)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   259
          in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   260
            (fname, length args)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   261
          end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   262
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   263
      val _ = AList.group (op =) (map check eqs)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   264
        |> map (fn (fname, ars) =>
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   265
             length (distinct (op =) ars) = 1
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   266
             orelse error ("Function " ^ quote fname ^
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   267
                           " has different numbers of arguments in different equations"))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   268
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   269
      fun check_sorts ((fname, fT), _) =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   270
          Sorts.of_sort (Sign.classes_of (ProofContext.theory_of ctxt)) (fT, HOLogic.typeS)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   271
          orelse error (cat_lines 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   272
          ["Type of " ^ quote fname ^ " is not of sort " ^ quote "type" ^ ":",
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   273
           setmp_CRITICAL show_sorts true (Syntax.string_of_typ ctxt) fT])
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   274
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   275
      val _ = map check_sorts fixes
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   276
    in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   277
      ()
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   278
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   279
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   280
(* Preprocessors *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   281
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   282
type fixes = ((string * typ) * mixfix) list
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   283
type 'a spec = (Attrib.binding * 'a list) list
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   284
type preproc = function_config -> Proof.context -> fixes -> term spec 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   285
               -> (term list * (thm list -> thm spec) * (thm list -> thm list list) * string list)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   286
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   287
val fname_of = fst o dest_Free o fst o strip_comb o fst 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   288
 o HOLogic.dest_eq o HOLogic.dest_Trueprop o Logic.strip_imp_concl o snd o dest_all_all
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   289
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   290
fun mk_case_names i "" k = mk_case_names i (string_of_int (i + 1)) k
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   291
  | mk_case_names _ n 0 = []
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   292
  | mk_case_names _ n 1 = [n]
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   293
  | mk_case_names _ n k = map (fn i => n ^ "_" ^ string_of_int i) (1 upto k)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   294
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   295
fun empty_preproc check _ ctxt fixes spec =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   296
    let 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   297
      val (bnds, tss) = split_list spec
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   298
      val ts = flat tss
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   299
      val _ = check ctxt fixes ts
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   300
      val fnames = map (fst o fst) fixes
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   301
      val indices = map (fn eq => find_index (curry op = (fname_of eq)) fnames) ts
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   302
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   303
      fun sort xs = partition_list (fn i => fn (j,_) => i = j) 0 (length fnames - 1) 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   304
                                   (indices ~~ xs)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   305
                        |> map (map snd)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   306
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   307
      (* using theorem names for case name currently disabled *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   308
      val cnames = map_index (fn (i, _) => mk_case_names i "" 1) bnds |> flat
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   309
    in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   310
      (ts, curry op ~~ bnds o Library.unflat tss, sort, cnames)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   311
    end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   312
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   313
structure Preprocessor = GenericDataFun
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   314
(
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   315
  type T = preproc
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   316
  val empty : T = empty_preproc check_defs
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   317
  val extend = I
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   318
  fun merge _ (a, _) = a
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   319
);
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   320
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   321
val get_preproc = Preprocessor.get o Context.Proof
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   322
val set_preproc = Preprocessor.map o K
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   323
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   324
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   325
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   326
local 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   327
  structure P = OuterParse and K = OuterKeyword
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   328
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   329
  val option_parser = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   330
      P.group "option" ((P.reserved "sequential" >> K Sequential)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   331
                    || ((P.reserved "default" |-- P.term) >> Default)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   332
                    || (P.reserved "domintros" >> K DomIntros)
33101
8846318b52d0 configuration flag "partials"
krauss
parents: 33099
diff changeset
   333
                    || (P.reserved "no_partials" >> K No_Partials)
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   334
                    || (P.reserved "tailrec" >> K Tailrec))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   335
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   336
  fun config_parser default = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   337
      (Scan.optional (P.$$$ "(" |-- P.!!! (P.list1 option_parser) --| P.$$$ ")") [])
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   338
        >> (fn opts => fold apply_opt opts default)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   339
in
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   340
  fun function_parser default_cfg = 
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   341
      config_parser default_cfg -- P.fixes -- SpecParse.where_alt_specs
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   342
end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   343
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   344
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   345
end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   346
end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   347