src/HOL/Tools/Function/function.ML
author blanchet
Wed, 08 Jun 2011 16:20:18 +0200
changeset 43293 a80cdc4b27a3
parent 42361 23f352990944
child 43277 1fd31f859fc7
permissions -rw-r--r--
made "query" type systes a bit more sound -- local facts, e.g. the negated conjecture, may make invalid the infinity check, e.g. if we are proving that there exists two values of an infinite type, we can use the negated conjecture that there is only one value to derive unsound proofs unless the type is properly encoded
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37744
3daaf23b9ab4 tuned titles
haftmann
parents: 37145
diff changeset
     1
(*  Title:      HOL/Tools/Function/function.ML
33099
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
41114
f9ae7c2abf7e tuned headers
krauss
parents: 40076
diff changeset
     4
Main entry points to the function package.
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     5
*)
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
signature FUNCTION =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
     8
sig
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
     9
  include FUNCTION_DATA
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    10
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    11
  val add_function: (binding * typ option * mixfix) list ->
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    12
    (Attrib.binding * term) list -> Function_Common.function_config ->
36522
e80a95279ef6 return info record (relative to auxiliary context!)
krauss
parents: 36520
diff changeset
    13
    (Proof.context -> tactic) -> local_theory -> info * local_theory
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    14
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    15
  val add_function_cmd: (binding * string option * mixfix) list ->
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    16
    (Attrib.binding * string) list -> Function_Common.function_config ->
36522
e80a95279ef6 return info record (relative to auxiliary context!)
krauss
parents: 36520
diff changeset
    17
    (Proof.context -> tactic) -> local_theory -> info * local_theory
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    18
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
    19
  val function: (binding * typ option * mixfix) list ->
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    20
    (Attrib.binding * term) list -> Function_Common.function_config ->
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    21
    local_theory -> Proof.state
34230
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
    22
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
    23
  val function_cmd: (binding * string option * mixfix) list ->
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    24
    (Attrib.binding * string) list -> Function_Common.function_config ->
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    25
    local_theory -> Proof.state
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    26
36547
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
    27
  val prove_termination: term option -> tactic -> local_theory -> 
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
    28
    info * local_theory
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
    29
  val prove_termination_cmd: string option -> tactic -> local_theory ->
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
    30
    info * local_theory
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
    31
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
    32
  val termination : term option -> local_theory -> Proof.state
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
    33
  val termination_cmd : string option -> local_theory -> Proof.state
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    34
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    35
  val setup : theory -> theory
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    36
  val get_congs : Proof.context -> thm list
34230
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
    37
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    38
  val get_info : Proof.context -> term -> info
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    39
end
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    40
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
structure Function : FUNCTION =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    43
struct
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
open Function_Lib
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    46
open Function_Common
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
val simp_attribs = map (Attrib.internal o K)
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    49
  [Simplifier.simp_add,
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    50
   Code.add_default_eqn_attribute,
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    51
   Nitpick_Simps.add]
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    52
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    53
val psimp_attribs = map (Attrib.internal o K)
39754
150f831ce4a3 no longer declare .psimps rules as [simp].
krauss
parents: 37744
diff changeset
    54
  [Nitpick_Psimps.add]
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    55
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    56
fun mk_defname fixes = fixes |> map (fst o fst) |> space_implode "_"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    57
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    58
fun add_simps fnames post sort extra_qualify label mod_binding moreatts
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    59
  simps lthy =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    60
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    61
    val spec = post simps
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    62
      |> map (apfst (apsnd (fn ats => moreatts @ ats)))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    63
      |> map (apfst (apfst extra_qualify))
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    64
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    65
    val (saved_spec_simps, lthy) =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    66
      fold_map Local_Theory.note spec lthy
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    67
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    68
    val saved_simps = maps snd saved_spec_simps
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    69
    val simps_by_f = sort saved_simps
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    70
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    71
    fun add_for_f fname simps =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    72
      Local_Theory.note
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    73
        ((mod_binding (Binding.qualify true fname (Binding.name label)), []), simps)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    74
      #> snd
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    75
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    76
    (saved_simps, fold2 add_for_f fnames simps_by_f lthy)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    77
  end
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    78
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
    79
fun prepare_function is_external prep default_constraint fixspec eqns config lthy =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    80
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    81
    val constrn_fxs = map (fn (b, T, mx) => (b, SOME (the_default default_constraint T), mx))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    82
    val ((fixes0, spec0), ctxt') = prep (constrn_fxs fixspec) eqns lthy
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    83
    val fixes = map (apfst (apfst Binding.name_of)) fixes0;
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    84
    val spec = map (fn (bnd, prop) => (bnd, [prop])) spec0;
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    85
    val (eqs, post, sort_cont, cnames) = get_preproc lthy config ctxt' fixes spec
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    86
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    87
    val defname = mk_defname fixes
41846
b368a7aee46a removed support for tail-recursion from function package (now implemented by partial_function)
krauss
parents: 41417
diff changeset
    88
    val FunctionConfig {partials, default, ...} = config
41417
211dbd42f95d function (default) is legacy feature
krauss
parents: 41405
diff changeset
    89
    val _ =
211dbd42f95d function (default) is legacy feature
krauss
parents: 41405
diff changeset
    90
      if is_some default then Output.legacy_feature
211dbd42f95d function (default) is legacy feature
krauss
parents: 41405
diff changeset
    91
        "'function (default)'. Use 'partial_function'."
211dbd42f95d function (default) is legacy feature
krauss
parents: 41405
diff changeset
    92
      else ()
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    93
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
    94
    val ((goal_state, cont), lthy') =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    95
      Function_Mutual.prepare_function_mutual config defname fixes eqs lthy
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
    96
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    97
    fun afterqed [[proof]] lthy =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
    98
      let
41846
b368a7aee46a removed support for tail-recursion from function package (now implemented by partial_function)
krauss
parents: 41417
diff changeset
    99
        val FunctionResult {fs, R, psimps, simple_pinducts,
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   100
          termination, domintros, cases, ...} =
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   101
          cont (Thm.close_derivation proof)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   102
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   103
        val fnames = map (fst o fst) fixes
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   104
        fun qualify n = Binding.name n
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   105
          |> Binding.qualify true defname
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   106
        val conceal_partial = if partials then I else Binding.conceal
33394
9c6980f2eb39 conceal "termination" rule, used only by special tools
krauss
parents: 33369
diff changeset
   107
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   108
        val addsmps = add_simps fnames post sort_cont
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   109
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   110
        val (((psimps', pinducts'), (_, [termination'])), lthy) =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   111
          lthy
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   112
          |> addsmps (conceal_partial o Binding.qualify false "partial")
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   113
               "psimps" conceal_partial psimp_attribs psimps
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   114
          ||>> Local_Theory.note ((conceal_partial (qualify "pinduct"),
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   115
                 [Attrib.internal (K (Rule_Cases.case_names cnames)),
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   116
                  Attrib.internal (K (Rule_Cases.consumes 1)),
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   117
                  Attrib.internal (K (Induct.induct_pred ""))]), simple_pinducts)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   118
          ||>> Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination])
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   119
          ||> (snd o Local_Theory.note ((qualify "cases",
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   120
                 [Attrib.internal (K (Rule_Cases.case_names cnames))]), [cases]))
40076
6f012a209dac some cleanup in Function_Lib
krauss
parents: 39754
diff changeset
   121
          ||> (case domintros of NONE => I | SOME thms => 
6f012a209dac some cleanup in Function_Lib
krauss
parents: 39754
diff changeset
   122
                   Local_Theory.note ((qualify "domintros", []), thms) #> snd)
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   123
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   124
        val info = { add_simps=addsmps, case_names=cnames, psimps=psimps',
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   125
          pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination',
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   126
          fs=fs, R=R, defname=defname, is_partial=true }
34230
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
   127
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   128
        val _ =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   129
          if not is_external then ()
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   130
          else Specification.print_consts lthy (K false) (map fst fixes)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   131
      in
36522
e80a95279ef6 return info record (relative to auxiliary context!)
krauss
parents: 36520
diff changeset
   132
        (info, 
e80a95279ef6 return info record (relative to auxiliary context!)
krauss
parents: 36520
diff changeset
   133
         lthy |> Local_Theory.declaration false (add_function_data o morph_function_data info))
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   134
      end
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   135
  in
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   136
    ((goal_state, afterqed), lthy')
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   137
  end
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   138
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   139
fun gen_add_function is_external prep default_constraint fixspec eqns config tac lthy =
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   140
  let
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   141
    val ((goal_state, afterqed), lthy') =
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   142
      prepare_function is_external prep default_constraint fixspec eqns config lthy
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   143
    val pattern_thm =
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   144
      case SINGLE (tac lthy') goal_state of
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   145
        NONE => error "pattern completeness and compatibility proof failed"
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   146
      | SOME st => Goal.finish lthy' st
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   147
  in
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   148
    lthy'
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   149
    |> afterqed [[pattern_thm]]
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   150
  end
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   151
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   152
val add_function =
37145
01aa36932739 renamed structure TypeInfer to Type_Infer, keeping the old name as legacy alias for some time;
wenzelm
parents: 36960
diff changeset
   153
  gen_add_function false Specification.check_spec (Type_Infer.anyT HOLogic.typeS)
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   154
val add_function_cmd = gen_add_function true Specification.read_spec "_::type"
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   155
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   156
fun gen_function is_external prep default_constraint fixspec eqns config lthy =
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   157
  let
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   158
    val ((goal_state, afterqed), lthy') =
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   159
      prepare_function is_external prep default_constraint fixspec eqns config lthy
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   160
  in
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   161
    lthy'
36522
e80a95279ef6 return info record (relative to auxiliary context!)
krauss
parents: 36520
diff changeset
   162
    |> Proof.theorem NONE (snd oo afterqed) [[(Logic.unprotect (concl_of goal_state), [])]]
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   163
    |> Proof.refine (Method.primitive_text (K goal_state)) |> Seq.hd
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   164
  end
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   165
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   166
val function =
37145
01aa36932739 renamed structure TypeInfer to Type_Infer, keeping the old name as legacy alias for some time;
wenzelm
parents: 36960
diff changeset
   167
  gen_function false Specification.check_spec (Type_Infer.anyT HOLogic.typeS)
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   168
val function_cmd = gen_function true Specification.read_spec "_::type"
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   169
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   170
fun prepare_termination_proof prep_term raw_term_opt lthy =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   171
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   172
    val term_opt = Option.map (prep_term lthy) raw_term_opt
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   173
    val info = the (case term_opt of
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   174
                      SOME t => (import_function_data t lthy
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   175
                        handle Option.Option =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   176
                          error ("Not a function: " ^ quote (Syntax.string_of_term lthy t)))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   177
                    | NONE => (import_last_function lthy handle Option.Option => error "Not a function"))
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   178
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   179
      val { termination, fs, R, add_simps, case_names, psimps,
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   180
        pinducts, defname, ...} = info
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   181
      val domT = domain_type (fastype_of R)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   182
      val goal = HOLogic.mk_Trueprop
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   183
                   (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT)))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   184
      fun afterqed [[totality]] lthy =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   185
        let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   186
          val totality = Thm.close_derivation totality
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   187
          val remove_domain_condition =
35410
1ea89d2a1bd4 more antiquotations;
wenzelm
parents: 35324
diff changeset
   188
            full_simplify (HOL_basic_ss addsimps [totality, @{thm True_implies_equals}])
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   189
          val tsimps = map remove_domain_condition psimps
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   190
          val tinduct = map remove_domain_condition pinducts
34230
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
   191
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   192
          fun qualify n = Binding.name n
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   193
            |> Binding.qualify true defname
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   194
        in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   195
          lthy
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   196
          |> add_simps I "simps" I simp_attribs tsimps
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   197
          ||>> Local_Theory.note
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   198
             ((qualify "induct",
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   199
               [Attrib.internal (K (Rule_Cases.case_names case_names))]),
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   200
              tinduct)
36547
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   201
          |-> (fn (simps, (_, inducts)) => fn lthy =>
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   202
            let val info' = { is_partial=false, defname=defname, add_simps=add_simps,
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   203
              case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts,
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   204
              simps=SOME simps, inducts=SOME inducts, termination=termination }
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   205
            in
36547
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   206
              (info',
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   207
               lthy 
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   208
               |> Local_Theory.declaration false (add_function_data o morph_function_data info')
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   209
               |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps))
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   210
            end)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   211
        end
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   212
  in
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   213
    (goal, afterqed, termination)
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   214
  end
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   215
36520
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   216
fun gen_prove_termination prep_term raw_term_opt tac lthy =
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   217
  let
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   218
    val (goal, afterqed, termination) =
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   219
      prepare_termination_proof prep_term raw_term_opt lthy
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   220
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   221
    val totality = Goal.prove lthy [] [] goal (K tac)
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   222
  in
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   223
    afterqed [[totality]] lthy
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   224
end
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   225
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   226
val prove_termination = gen_prove_termination Syntax.check_term
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   227
val prove_termination_cmd = gen_prove_termination Syntax.read_term
772ed73e1d61 function: sane interface for programmatic use
krauss
parents: 36519
diff changeset
   228
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   229
fun gen_termination prep_term raw_term_opt lthy =
36518
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   230
  let
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   231
    val (goal, afterqed, termination) = prepare_termination_proof prep_term raw_term_opt lthy
a33b986f2e22 function: better separate Isar integration from actual functionality
krauss
parents: 36323
diff changeset
   232
  in
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   233
    lthy
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41846
diff changeset
   234
    |> Proof_Context.note_thmss ""
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   235
       [((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41846
diff changeset
   236
    |> Proof_Context.note_thmss ""
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   237
       [((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 41846
diff changeset
   238
    |> Proof_Context.note_thmss ""
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   239
       [((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]),
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   240
         [([Goal.norm_result termination], [])])] |> snd
36547
2a9d0ec8c10d return updated info record after termination proof
krauss
parents: 36522
diff changeset
   241
    |> Proof.theorem NONE (snd oo afterqed) [[(goal, [])]]
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   242
  end
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   243
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   244
val termination = gen_termination Syntax.check_term
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   245
val termination_cmd = gen_termination Syntax.read_term
33099
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
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   248
(* Datatype hook to declare datatype congs as "function_congs" *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   249
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
fun add_case_cong n thy =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   252
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   253
    val cong = #case_cong (Datatype.the_info thy n)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   254
      |> safe_mk_meta_eq
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   255
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   256
    Context.theory_map
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   257
      (Function_Ctx_Tree.map_function_congs (Thm.add_thm cong)) thy
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 34231
diff changeset
   258
  end
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   259
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   260
val setup_case_cong = Datatype.interpretation (K (fold add_case_cong))
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   261
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
(* setup *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   264
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   265
val setup =
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   266
  Attrib.setup @{binding fundef_cong}
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   267
    (Attrib.add_del Function_Ctx_Tree.cong_add Function_Ctx_Tree.cong_del)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   268
    "declaration of congruence rule for function definitions"
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   269
  #> setup_case_cong
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   270
  #> Function_Relation.setup
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   271
  #> Function_Common.Termination_Simps.setup
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   272
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   273
val get_congs = Function_Ctx_Tree.get_function_congs
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   274
34230
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
   275
fun get_info ctxt t = Item_Net.retrieve (get_function ctxt) t
b0d21ae2528e more official data record Function.info
krauss
parents: 33726
diff changeset
   276
  |> the_single |> snd
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   277
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   278
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   279
(* outer syntax *)
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   280
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   281
val _ =
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   282
  Outer_Syntax.local_theory_to_proof "function" "define general recursive functions"
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   283
  Keyword.thy_goal
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   284
  (function_parser default_config
36519
46bf776a81e0 ML interface uses plain command names, following conventions from typedef
krauss
parents: 36518
diff changeset
   285
     >> (fn ((config, fixes), statements) => function_cmd fixes statements config))
33099
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 _ =
36960
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   288
  Outer_Syntax.local_theory_to_proof "termination" "prove termination of a recursive function"
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   289
  Keyword.thy_goal
01594f816e3a prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
wenzelm
parents: 36547
diff changeset
   290
  (Scan.option Parse.term >> termination_cmd)
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   291
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   292
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents:
diff changeset
   293
end