src/HOL/Tools/Function/fun_cases.ML
author blanchet
Tue, 24 Sep 2013 00:10:59 +0200
changeset 53810 69e8ba502eda
parent 53670 5ccee1cb245a
child 53991 d8f7f3d998de
permissions -rw-r--r--
tuning
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Function/fun_cases.ML
53609
0f472e7063af tuned headers
krauss
parents: 53603
diff changeset
     2
    Author:     Manuel Eberl, TU Muenchen
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     3
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
     4
Provide the fun_cases command for generating specialised elimination
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     5
rules for function package functions.
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     6
*)
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     7
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     8
signature FUN_CASES =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
     9
sig
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    10
  val mk_fun_cases : Proof.context -> term -> thm
53670
5ccee1cb245a tuned signature;
wenzelm
parents: 53668
diff changeset
    11
  val fun_cases_cmd: ((binding * Args.src list) * string list) list -> local_theory ->
5ccee1cb245a tuned signature;
wenzelm
parents: 53668
diff changeset
    12
    (string * thm list) list * local_theory
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    13
  (* FIXME regular ML interface for fun_cases *)
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    14
end;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    15
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    16
structure Fun_Cases : FUN_CASES =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    17
struct
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    18
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    19
local
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    20
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    21
val refl_thin = Goal.prove_global @{theory HOL} [] [] @{prop "!!P. a = a ==> P ==> P"}
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    22
  (fn _ => assume_tac 1);
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    23
val elim_rls = [asm_rl, FalseE, refl_thin, conjE, exE];
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    24
val elim_tac = REPEAT o Tactic.eresolve_tac elim_rls;
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    25
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    26
fun simp_case_tac ctxt i =
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    27
  EVERY' [elim_tac, TRY o asm_full_simp_tac ctxt, elim_tac, REPEAT o bound_hyp_subst_tac ctxt] i;
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    28
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    29
in
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    30
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    31
fun mk_fun_cases ctxt prop =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    32
  let val thy = Proof_Context.theory_of ctxt;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    33
      fun err () =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    34
        error (Pretty.string_of (Pretty.block
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    35
          [Pretty.str "Proposition is not a function equation:",
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    36
           Pretty.fbrk, Syntax.pretty_term ctxt prop]));
53610
dde3cc2804cc dropped unnecessary 'open'
krauss
parents: 53609
diff changeset
    37
      val ((f,_),_) = Function_Elims.dest_funprop (HOLogic.dest_Trueprop prop)
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    38
              handle TERM _ => err ();
53668
2da931497d2c more explicit exception pattern (NB: unqualified exceptions without arguments are in danger of becoming catch-all patterns by accident);
wenzelm
parents: 53667
diff changeset
    39
      val info = Function.get_info ctxt f handle List.Empty => err ();
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    40
      val {elims, pelims, is_partial, ...} = info;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    41
      val elims = if is_partial then pelims else the elims
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    42
      val cprop = cterm_of thy prop;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    43
      val tac = ALLGOALS (simp_case_tac ctxt) THEN prune_params_tac;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    44
      fun mk_elim rl =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    45
        Thm.implies_intr cprop (Tactic.rule_by_tactic ctxt tac (Thm.assume cprop RS rl))
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    46
        |> singleton (Variable.export (Variable.auto_fixes prop ctxt) ctxt);
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    47
  in
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    48
    case get_first (try mk_elim) (flat elims) of
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    49
      SOME r => r
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    50
    | NONE => err ()
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    51
  end;
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    52
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    53
end;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    54
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    55
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    56
(* Setting up the fun_cases command *)
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    57
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    58
local
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    59
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    60
(* Convert the schematic variables and type variables in a term into free
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    61
   variables and takes care of schematic variables originating from dummy
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    62
   patterns by renaming them to something sensible. *)
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    63
fun pat_to_term ctxt t =
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    64
  let
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    65
     fun prep_var ((x,_),T) =
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    66
          if x = "_dummy_" then ("x",T) else (x,T);
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    67
     val schem_vars = Term.add_vars t [];
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    68
     val prepped_vars = map prep_var schem_vars;
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    69
     val fresh_vars = map Free (Variable.variant_frees ctxt [t] prepped_vars);
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    70
     val subst = ListPair.zip (map fst schem_vars, fresh_vars);
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    71
  in fst (yield_singleton (Variable.import_terms true)
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    72
         (subst_Vars subst t) ctxt)
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    73
  end;
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    74
53670
5ccee1cb245a tuned signature;
wenzelm
parents: 53668
diff changeset
    75
in
5ccee1cb245a tuned signature;
wenzelm
parents: 53668
diff changeset
    76
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    77
fun fun_cases_cmd args lthy =
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    78
  let
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    79
    val thy = Proof_Context.theory_of lthy
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    80
    val thmss = map snd args
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    81
                |> burrow (grouped 10 Par_List.map
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    82
                    (mk_fun_cases lthy
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    83
                     o pat_to_term lthy
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    84
                     o HOLogic.mk_Trueprop
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    85
                     o Proof_Context.read_term_pattern lthy));
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    86
    val facts = map2 (fn ((a,atts), _) => fn thms =>
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    87
      ((a, map (Attrib.intern_src thy) atts), [(thms, [])])) args thmss;
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    88
  in
53670
5ccee1cb245a tuned signature;
wenzelm
parents: 53668
diff changeset
    89
    lthy |> Local_Theory.notes facts
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    90
  end;
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    91
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    92
val _ =
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    93
  Outer_Syntax.local_theory @{command_spec "fun_cases"}
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    94
    "automatic derivation of simplified elimination rules for function equations"
53667
0aefb31e27e0 distinguish Proof.context vs. local_theory semantically, with corresponding naming conventions;
wenzelm
parents: 53666
diff changeset
    95
    (Parse.and_list1 Parse_Spec.specs >> (snd oo fun_cases_cmd));
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    96
53603
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    97
end;
59ef06cda7b9 generate elim rules for elimination of function equalities;
Manuel Eberl
parents:
diff changeset
    98
53666
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
    99
end;
52a0a526e677 tuned white space;
wenzelm
parents: 53610
diff changeset
   100