Nominal/nominal_termination.ML
author Christian Urban <urbanc@in.tum.de>
Tue, 19 Jul 2011 19:09:06 +0100
changeset 2981 c8acaded1777
parent 2976 d5ecc2f7f299
child 2982 4a00077c008f
permissions -rw-r--r--
temporary fix
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)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    45
      val goal = HOLogic.mk_Trueprop
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    46
                   (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
    47
      fun afterqed [[totality]] lthy =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    48
        let
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    49
          val totality = Thm.close_derivation totality
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    50
          val remove_domain_condition =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    51
            full_simplify (HOL_basic_ss addsimps [totality, @{thm True_implies_equals}])
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    52
          val tsimps = map remove_domain_condition psimps
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    53
          val tinduct = map remove_domain_condition pinducts
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    54
          val teqvts = map remove_domain_condition eqvts
2981
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    55
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    56
          val _ = tracing ("tot psimps1:\n" ^ cat_lines (map @{make_string} psimps))
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    57
          val _ = tracing ("tot psimps2:\n" ^ cat_lines (map @{make_string} tsimps))
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    58
          val _ = tracing ("tot induct1:\n" ^ cat_lines (map @{make_string} pinducts))
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    59
          val _ = tracing ("tot induct2:\n" ^ cat_lines (map @{make_string} tinduct))
c8acaded1777 temporary fix
Christian Urban <urbanc@in.tum.de>
parents: 2976
diff changeset
    60
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    61
          fun qualify n = Binding.name n
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    62
            |> Binding.qualify true defname
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    63
        in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    64
          lthy
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    65
          |> add_simps I "simps" I simp_attribs tsimps
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    66
          ||>> Local_Theory.note ((qualify "eqvt", [eqvt_attrib]), teqvts)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    67
          ||>> Local_Theory.note
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    68
             ((qualify "induct",
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    69
               [Attrib.internal (K (Rule_Cases.case_names case_names))]),
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    70
              tinduct)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    71
          |-> (fn ((simps, (_, eqvts)), (_, inducts)) => fn lthy =>
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    72
            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
    73
              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
    74
              simps=SOME simps, inducts=SOME inducts, termination=termination, eqvts=teqvts }
2976
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    75
            in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    76
              (info',
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    77
               lthy 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    78
               |> 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
    79
               |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps))
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
        end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    82
  in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    83
    (goal, afterqed, termination)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    84
  end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    85
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    86
fun gen_termination prep_term raw_term_opt lthy =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    87
  let
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    88
    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
    89
  in
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    90
    lthy
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.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    93
    |> Proof_Context.note_thmss ""
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    94
       [((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    95
    |> Proof_Context.note_thmss ""
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    96
       [((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]),
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    97
         [([Goal.norm_result termination], [])])] |> snd
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    98
    |> Proof.theorem NONE (snd oo afterqed) [[(goal, [])]]
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    99
  end
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   100
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   101
val termination = gen_termination Syntax.check_term
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   102
val termination_cmd = gen_termination Syntax.read_term
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   103
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   104
(* outer syntax *)
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 option_parser =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   107
  (Scan.optional (Parse.$$$ "(" |-- Parse.!!! 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   108
    (Parse.reserved "eqvt" >> K true) --| Parse.$$$ ")") false)
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   109
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   110
val _ =
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   111
  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
   112
  Keyword.thy_goal
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   113
  (option_parser -- Scan.option Parse.term >> 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   114
     (fn (is_eqvt, trm) => 
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   115
        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
   116
d5ecc2f7f299 added termination file
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   117
end