Nominal/nominal_termination.ML
author Christian Urban <urbanc@in.tum.de>
Fri, 22 Jul 2011 11:37:16 +0100
changeset 2982 4a00077c008f
parent 2981 c8acaded1777
child 3045 d0ad264f8c4f
child 3068 f89ee40fbb08
permissions -rw-r--r--
completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     1
(*  Nominal Termination
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     2
    Author: Christian Urban
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     3
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     4
    heavily based on the code of Alexander Krauss
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     5
    (code forked on 18 July 2011)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     6
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     7
Redefinition of the termination command
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     8
*)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     9
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    10
signature NOMINAL_FUNCTION_TERMINATION =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    11
sig
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    12
  include NOMINAL_FUNCTION_DATA
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    13
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    14
  val termination : term option -> local_theory -> Proof.state
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    15
  val termination_cmd : string option -> local_theory -> Proof.state
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    16
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    17
end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    18
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    19
structure Nominal_Function_Termination : NOMINAL_FUNCTION_TERMINATION =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    20
struct
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    21
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    22
open Function_Lib
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    23
open Function_Common
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    24
open Nominal_Function_Common
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    25
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    26
val simp_attribs = map (Attrib.internal o K)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    27
  [Simplifier.simp_add,
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    28
   Code.add_default_eqn_attribute,
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    29
   Nitpick_Simps.add]
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    30
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    31
val eqvt_attrib =  Attrib.internal (K Nominal_ThmDecls.eqvt_add)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    32
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    33
fun prepare_termination_proof prep_term raw_term_opt lthy =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    34
  let
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    35
    val term_opt = Option.map (prep_term lthy) raw_term_opt
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    36
    val info = the (case term_opt of
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    37
                      SOME t => (import_function_data t lthy
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    38
                        handle Option.Option =>
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    39
                          error ("Not a function: " ^ quote (Syntax.string_of_term lthy t)))
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    40
                    | NONE => (import_last_function lthy handle Option.Option => error "Not a function"))
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    41
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    42
      val { termination, fs, R, add_simps, case_names, psimps,
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    43
        pinducts, defname, eqvts, ...} = info
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    44
      val domT = domain_type (fastype_of R)
2982
4a00077c008f completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents: 2981
diff changeset
    45
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    46
      val goal = HOLogic.mk_Trueprop
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    47
                   (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT)))
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    48
      fun afterqed [[totality]] lthy =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    49
        let
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    50
          val totality = Thm.close_derivation totality
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    51
          val remove_domain_condition =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    52
            full_simplify (HOL_basic_ss addsimps [totality, @{thm True_implies_equals}])
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    53
          val tsimps = map remove_domain_condition psimps
2982
4a00077c008f completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents: 2981
diff changeset
    54
          val tinducts = map remove_domain_condition pinducts
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    55
          val teqvts = map remove_domain_condition eqvts
2981
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    56
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    57
          fun qualify n = Binding.name n
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    58
            |> Binding.qualify true defname
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    59
        in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    60
          lthy
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    61
          |> add_simps I "simps" I simp_attribs tsimps
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    62
          ||>> Local_Theory.note ((qualify "eqvt", [eqvt_attrib]), teqvts)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    63
          ||>> Local_Theory.note
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    64
             ((qualify "induct",
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    65
               [Attrib.internal (K (Rule_Cases.case_names case_names))]),
2982
4a00077c008f completed the eqvt-proofs for functions; they are stored under the name function_name.eqvt and added to the eqvt-list
Christian Urban <urbanc@in.tum.de>
parents: 2981
diff changeset
    66
              tinducts)
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    67
          |-> (fn ((simps, (_, eqvts)), (_, inducts)) => fn lthy =>
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    68
            let val info' = { is_partial=false, defname=defname, add_simps=add_simps,
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    69
              case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts,
2981
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    70
              simps=SOME simps, inducts=SOME inducts, termination=termination, eqvts=teqvts }
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    71
            in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    72
              (info',
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    73
               lthy 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    74
               |> Local_Theory.declaration false (add_function_data o morph_function_data info')
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    75
               |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps))
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    76
            end)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    77
        end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    78
  in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    79
    (goal, afterqed, termination)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    80
  end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    81
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    82
fun gen_termination prep_term raw_term_opt lthy =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    83
  let
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    84
    val (goal, afterqed, termination) = prepare_termination_proof prep_term raw_term_opt lthy
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    85
  in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    86
    lthy
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    87
    |> Proof_Context.note_thmss ""
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    88
       [((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    89
    |> Proof_Context.note_thmss ""
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    90
       [((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    91
    |> Proof_Context.note_thmss ""
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    92
       [((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]),
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    93
         [([Goal.norm_result termination], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    94
    |> Proof.theorem NONE (snd oo afterqed) [[(goal, [])]]
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    95
  end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    96
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    97
val termination = gen_termination Syntax.check_term
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    98
val termination_cmd = gen_termination Syntax.read_term
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    99
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   100
(* outer syntax *)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   101
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   102
val option_parser =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   103
  (Scan.optional (Parse.$$$ "(" |-- Parse.!!! 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   104
    (Parse.reserved "eqvt" >> K true) --| Parse.$$$ ")") false)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   105
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   106
val _ =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   107
  Outer_Syntax.local_theory_to_proof "termination" "prove termination of a recursive function"
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   108
  Keyword.thy_goal
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   109
  (option_parser -- Scan.option Parse.term >> 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   110
     (fn (is_eqvt, trm) => 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   111
        if is_eqvt then termination_cmd trm else Function.termination_cmd trm))
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   112
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   113
end