src/Pure/Isar/rule_cases.ML
author wenzelm
Tue, 22 Nov 2005 19:34:50 +0100
changeset 18229 e5a624483a23
parent 18188 cb53a778455e
child 18237 2edb6a1f9c14
permissions -rw-r--r--
added type cases/cases_tactic, and CASES, SUBGOAL_CASES; added consume rule; support named case conclusions; tuned interfaces;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/Isar/rule_cases.ML
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     3
    Author:     Markus Wenzel, TU Muenchen
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     4
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
     5
Annotations and local contexts of rules.
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     6
*)
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
     7
18188
cb53a778455e added THEN_ALL_NEW_CASES;
wenzelm
parents: 18050
diff changeset
     8
infix 1 THEN_ALL_NEW_CASES;
cb53a778455e added THEN_ALL_NEW_CASES;
wenzelm
parents: 18050
diff changeset
     9
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    10
signature BASIC_RULE_CASES =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    11
sig
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    12
  type cases
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    13
  type cases_tactic
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    14
  val CASES: cases -> tactic -> cases_tactic
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    15
  val NO_CASES: tactic -> cases_tactic
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    16
  val SUBGOAL_CASES: ((term * int) -> cases_tactic) -> int -> cases_tactic
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    17
  val THEN_ALL_NEW_CASES: (int -> cases_tactic) * (int -> tactic) -> int -> cases_tactic
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    18
end
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    19
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    20
signature RULE_CASES =
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    21
sig
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    22
  include BASIC_RULE_CASES
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    23
  type T
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    24
  val consume: thm list -> ('a * int) * thm -> (('a * (int * thm list)) * thm) Seq.seq
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    25
  val consumes: int -> 'a attribute
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    26
  val consumes_default: int -> 'a attribute
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    27
  val name: string list -> thm -> thm
8427
wenzelm
parents: 8400
diff changeset
    28
  val case_names: string list -> 'a attribute
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    29
  val case_conclusion: string -> (string * string) list -> 'a attribute
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    30
  val case_conclusion_binops: string -> string list -> 'a attribute
12761
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
    31
  val save: thm -> thm -> thm
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    32
  val get: thm -> (string * (string * string) list) list * int
17861
28d3483afbbc export strip_params;
wenzelm
parents: 17361
diff changeset
    33
  val strip_params: term -> (string * typ) list
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    34
  val make: bool -> term option -> theory * term ->
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    35
    (string * (string * string) list) list -> cases
17361
008b14a7afc4 added simple;
wenzelm
parents: 17184
diff changeset
    36
  val simple: bool -> theory * term -> string -> string * T option
8427
wenzelm
parents: 8400
diff changeset
    37
  val rename_params: string list list -> thm -> thm
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    38
  val params: string list list -> 'a attribute
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    39
end;
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    40
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    41
structure RuleCases: RULE_CASES =
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    42
struct
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    43
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    44
(** tactics with cases **)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    45
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    46
type T =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    47
 {fixes: (string * typ) list,
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    48
  assumes: (string * term list) list,
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    49
  binds: (indexname * term option) list};
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    50
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    51
type cases = (string * T option) list;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    52
type cases_tactic = thm -> (cases * thm) Seq.seq;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    53
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    54
fun CASES cases tac st = Seq.map (pair cases) (tac st);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    55
fun NO_CASES tac = CASES [] tac;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    56
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    57
fun SUBGOAL_CASES tac i st =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    58
  (case try Logic.nth_prem (i, Thm.prop_of st) of
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    59
    SOME goal => tac (goal, i) st
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    60
  | NONE => Seq.empty);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    61
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    62
fun (tac1 THEN_ALL_NEW_CASES tac2) i st =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    63
  st |> tac1 i |> Seq.maps (fn (cases, st') =>
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    64
    Seq.map (pair cases) (Seq.INTERVAL tac2 i (i + nprems_of st' - nprems_of st) st'));
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    65
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    66
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    67
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    68
(** consume facts **)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    69
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    70
fun consume facts ((x, n), th) =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    71
  Drule.multi_resolves (Library.take (n, facts)) [th]
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    72
  |> Seq.map (pair (x, (n - length facts, Library.drop (n, facts))));
10811
98f52cb93d93 support ?case binding;
wenzelm
parents: 10530
diff changeset
    73
98f52cb93d93 support ?case binding;
wenzelm
parents: 10530
diff changeset
    74
val consumes_tagN = "consumes";
98f52cb93d93 support ?case binding;
wenzelm
parents: 10530
diff changeset
    75
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    76
fun lookup_consumes th =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    77
  let fun err () = raise THM ("Malformed 'consumes' tag of theorem", 0, [th]) in
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    78
    (case AList.lookup (op =) (Thm.tags_of_thm th) (consumes_tagN) of
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
    79
      NONE => NONE
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
    80
    | SOME [s] => (case Syntax.read_nat s of SOME n => SOME n | _ => err ())
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    81
    | _ => err ())
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    82
  end;
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    83
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
    84
fun put_consumes NONE th = th
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
    85
  | put_consumes (SOME n) th = th
12761
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
    86
      |> Drule.untag_rule consumes_tagN
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
    87
      |> Drule.tag_rule (consumes_tagN, [Library.string_of_int n]);
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
    88
12761
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
    89
val save_consumes = put_consumes o lookup_consumes;
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
    90
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
    91
fun consumes n x = Drule.rule_attribute (K (put_consumes (SOME n))) x;
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
    92
fun consumes_default n x =
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
    93
  if Library.is_some (lookup_consumes (#2 x)) then x else consumes n x;
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    94
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
    95
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    96
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    97
(** case names **)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    98
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
    99
val cases_tagN = "cases";
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   100
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   101
fun add_case_names NONE = I
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   102
  | add_case_names (SOME names) =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   103
      Drule.untag_rule cases_tagN
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   104
      #> Drule.tag_rule (cases_tagN, names);
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   105
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   106
fun lookup_case_names th = AList.lookup (op =) (Thm.tags_of_thm th) cases_tagN;
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
   107
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   108
val save_case_names = add_case_names o lookup_case_names;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   109
val name = add_case_names o SOME;
8427
wenzelm
parents: 8400
diff changeset
   110
fun case_names ss = Drule.rule_attribute (K (name ss));
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   111
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
   112
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   113
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   114
(** case conclusions **)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   115
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   116
(* term positions *)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   117
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   118
fun term_at pos tm =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   119
  let
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   120
    fun at [] t = t
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   121
      | at ("0" :: ps) (t $ _) = at ps t
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   122
      | at ("1" :: ps) (_ $ u) = at ps u
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   123
      | at _ _ = raise TERM ("Bad term position: " ^ pos, [tm]);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   124
  in at (explode pos) tm end;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   125
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   126
fun binop_positions [] = []
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   127
  | binop_positions [x] = [(x, "")]
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   128
  | binop_positions xs =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   129
      let
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   130
        fun pos i = replicate_string i "1";
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   131
        val k = length xs - 1;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   132
      in xs ~~ (map (suffix "01" o pos) (0 upto k - 1) @ [pos k]) end;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   133
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   134
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   135
(* conclusion tags *)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   136
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   137
val case_concl_tagN = "case_conclusion";
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   138
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   139
fun is_case_concl name ((a, b :: _): tag) = (a = case_concl_tagN andalso b = name)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   140
  | is_case_concl _ _ = false;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   141
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   142
fun add_case_concl (name, cs) = Drule.map_tags (fn tags =>
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   143
  filter_out (is_case_concl name) tags @ [(case_concl_tagN, name :: cs)]);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   144
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   145
fun lookup_case_concl th name =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   146
  find_first (is_case_concl name) (Thm.tags_of_thm th) |> Option.map (tl o snd);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   147
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   148
fun get_case_concls th name =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   149
  let
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   150
    fun concls (x :: pos :: cs) = (x, pos) :: concls cs
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   151
      | concls [] = []
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   152
      | concls [x] = error ("No position for conclusion " ^ quote x ^ " of case " ^ quote name);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   153
  in concls (these (lookup_case_concl th name)) end;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   154
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   155
fun save_case_concls th =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   156
  let val concls = Thm.tags_of_thm th |> List.mapPartial
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   157
    (fn (a, b :: bs) =>
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   158
      if a = case_concl_tagN then SOME (b, bs) else NONE
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   159
    | _ => NONE)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   160
  in fold add_case_concl concls end;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   161
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   162
fun case_conclusion name concls = Drule.rule_attribute (fn _ =>
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   163
  add_case_concl (name, List.concat (map (fn (a, b) => [a, b]) concls)));
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   164
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   165
fun case_conclusion_binops name xs = case_conclusion name (binop_positions xs);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   166
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   167
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   168
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   169
(** case declarations **)
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   170
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
   171
(* access hints *)
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
   172
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   173
fun save th = save_consumes th #> save_case_names th #> save_case_concls th;
12761
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
   174
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   175
fun get th =
12761
b0c39f9837af save: be slightly more about absent tags;
wenzelm
parents: 12166
diff changeset
   176
  let
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   177
    val n = the_default 0 (lookup_consumes th);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   178
    val cases =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   179
      (case lookup_case_names th of
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   180
        NONE => map (rpair [] o Library.string_of_int) (1 upto (Thm.nprems_of th - n))
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   181
      | SOME names => map (fn name => (name, get_case_concls th name)) names);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   182
  in (cases, n) end;
10530
df079a585e6d added consumes, consumes_default;
wenzelm
parents: 10407
diff changeset
   183
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   184
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   185
(* extract cases *)
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   186
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   187
val case_conclN = "case";
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   188
val case_hypsN = "hyps";
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   189
val case_premsN = "prems";
13425
119ae829ad9b support for split assumptions in cases (hyps vs. prems);
wenzelm
parents: 12809
diff changeset
   190
18188
cb53a778455e added THEN_ALL_NEW_CASES;
wenzelm
parents: 18050
diff changeset
   191
val strip_params = map (apfst Syntax.deskolem) o Logic.strip_params;
17167
7667a85b53f1 unskolem local vars;
wenzelm
parents: 17113
diff changeset
   192
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   193
fun extract_case is_open thy (split, raw_prop) name concls =
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   194
  let
17361
008b14a7afc4 added simple;
wenzelm
parents: 17184
diff changeset
   195
    val prop = Drule.norm_hhf thy raw_prop;
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   196
17861
28d3483afbbc export strip_params;
wenzelm
parents: 17361
diff changeset
   197
    val xs = strip_params prop;
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   198
    val rename = if is_open then I else map (apfst Syntax.internal);
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   199
    val fixes =
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   200
      (case split of
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   201
        NONE => rename xs
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   202
      | SOME t =>
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   203
          let val (us, vs) = splitAt (length (Logic.strip_params t), xs)
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   204
          in rename us @ vs end);
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   205
    fun abs_fixes t = Term.list_abs (fixes, t);
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   206
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   207
    val asms = map abs_fixes (Logic.strip_assums_hyp prop);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   208
    val assumes =
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   209
      (case split of
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   210
        NONE => [("", asms)]
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 14981
diff changeset
   211
      | SOME t =>
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   212
          let val (hyps, prems) = splitAt (length (Logic.strip_assums_hyp t), asms)
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   213
          in [(case_hypsN, hyps), (case_premsN, prems)] end);
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   214
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   215
    val concl = ObjectLogic.drop_judgment thy (Logic.strip_assums_concl prop);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   216
    fun bind (x, pos) = ((x, 0), SOME (abs_fixes (term_at pos concl)));
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   217
    val binds = bind (case_conclN, "") :: map bind concls;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   218
  in {fixes = fixes, assumes = assumes, binds = binds} end;
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   219
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   220
fun make is_open split (thy, prop) cases =
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   221
  let
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   222
    val n = length cases;
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   223
    val nprems = Logic.count_prems (prop, 0);
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   224
    fun add_case (name, concls) (cs, i) =
16148
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   225
      ((case try (fn () =>
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   226
          (Option.map (curry Logic.nth_prem i) split, Logic.nth_prem (i, prop))) () of
5f15a14122dc make: T option -- actually remove undefined cases;
wenzelm
parents: 15973
diff changeset
   227
        NONE => (name, NONE)
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   228
      | SOME sp => (name, SOME (extract_case is_open thy sp name concls))) :: cs, i - 1);
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   229
  in fold_rev add_case (Library.drop (n - nprems, cases)) ([], n) |> #1 end;
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   230
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   231
fun simple is_open (thy, prop) name =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   232
  (name, SOME (extract_case is_open thy (NONE, prop) name []));
17361
008b14a7afc4 added simple;
wenzelm
parents: 17184
diff changeset
   233
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   234
8427
wenzelm
parents: 8400
diff changeset
   235
(* params *)
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   236
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   237
fun rename_params xss th =
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   238
  th
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   239
  |> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   240
  |> save th;
8364
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   241
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   242
fun params xss = Drule.rule_attribute (K (rename_params xss));
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   243
0eb9ee70c8f8 added Isar/rule_cases.ML;
wenzelm
parents:
diff changeset
   244
end;
17113
3b67c1809e1c added NO_CASES;
wenzelm
parents: 16390
diff changeset
   245
18229
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   246
structure BasicRuleCases: BASIC_RULE_CASES = RuleCases;
e5a624483a23 added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents: 18188
diff changeset
   247
open BasicRuleCases;