src/Pure/Isar/rule_cases.ML
changeset 34916 f625d8d6fcf3
parent 34058 97fd820dd402
child 34986 7f7939c9370f
equal deleted inserted replaced
34915:7894c7dab132 34916:f625d8d6fcf3
    23    {fixes: (string * typ) list,
    23    {fixes: (string * typ) list,
    24     assumes: (string * term list) list,
    24     assumes: (string * term list) list,
    25     binds: (indexname * term option) list,
    25     binds: (indexname * term option) list,
    26     cases: (string * T) list}
    26     cases: (string * T) list}
    27   val strip_params: term -> (string * typ) list
    27   val strip_params: term -> (string * typ) list
    28   val make_common: bool -> theory * term -> (string * string list) list -> cases
    28   val make_common: theory * term -> (string * string list) list -> cases
    29   val make_nested: bool -> term -> theory * term -> (string * string list) list -> cases
    29   val make_nested: term -> theory * term -> (string * string list) list -> cases
    30   val apply: term list -> T -> T
    30   val apply: term list -> T -> T
    31   val consume: thm list -> thm list -> ('a * int) * thm ->
    31   val consume: thm list -> thm list -> ('a * int) * thm ->
    32     (('a * (int * thm list)) * thm) Seq.seq
    32     (('a * (int * thm list)) * thm) Seq.seq
    33   val add_consumes: int -> thm -> thm
    33   val add_consumes: int -> thm -> thm
    34   val get_consumes: thm -> int
    34   val get_consumes: thm -> int
    41   val inner_rule: attribute
    41   val inner_rule: attribute
    42   val save: thm -> thm -> thm
    42   val save: thm -> thm -> thm
    43   val get: thm -> (string * string list) list * int
    43   val get: thm -> (string * string list) list * int
    44   val rename_params: string list list -> thm -> thm
    44   val rename_params: string list list -> thm -> thm
    45   val params: string list list -> attribute
    45   val params: string list list -> attribute
       
    46   val internalize_params: thm -> thm
    46   val mutual_rule: Proof.context -> thm list -> (int list * thm) option
    47   val mutual_rule: Proof.context -> thm list -> (int list * thm) option
    47   val strict_mutual_rule: Proof.context -> thm list -> int list * thm
    48   val strict_mutual_rule: Proof.context -> thm list -> int list * thm
    48 end;
    49 end;
    49 
    50 
    50 structure Rule_Cases: RULE_CASES =
    51 structure Rule_Cases: RULE_CASES =
    88   | extract_assumes qual (SOME outline) prop =
    89   | extract_assumes qual (SOME outline) prop =
    89       let val (hyps, prems) =
    90       let val (hyps, prems) =
    90         chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop)
    91         chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop)
    91       in ([(qual case_hypsN, hyps)], [(qual case_premsN, prems)]) end;
    92       in ([(qual case_hypsN, hyps)], [(qual case_premsN, prems)]) end;
    92 
    93 
    93 fun extract_case is_open thy (case_outline, raw_prop) name concls =
    94 fun extract_case thy (case_outline, raw_prop) name concls =
    94   let
    95   let
    95     val rename = if is_open then I else apfst (Name.internal o Name.clean);
       
    96 
       
    97     val props = Logic.dest_conjunctions (Drule.norm_hhf thy raw_prop);
    96     val props = Logic.dest_conjunctions (Drule.norm_hhf thy raw_prop);
    98     val len = length props;
    97     val len = length props;
    99     val nested = is_some case_outline andalso len > 1;
    98     val nested = is_some case_outline andalso len > 1;
   100 
    99 
   101     fun extract prop =
   100     fun extract prop =
   102       let
   101       let
   103         val (fixes1, fixes2) = extract_fixes case_outline prop
   102         val (fixes1, fixes2) = extract_fixes case_outline prop;
   104           |> apfst (map rename);
       
   105         val abs_fixes = abs (fixes1 @ fixes2);
   103         val abs_fixes = abs (fixes1 @ fixes2);
   106         fun abs_fixes1 t =
   104         fun abs_fixes1 t =
   107           if not nested then abs_fixes t
   105           if not nested then abs_fixes t
   108           else abs fixes1 (app (map (Term.dummy_pattern o #2) fixes2) (abs fixes2 t));
   106           else abs fixes1 (app (map (Term.dummy_pattern o #2) fixes2) (abs fixes2 t));
   109 
   107 
   133     else if len = 1 then SOME (common_case (hd cases))
   131     else if len = 1 then SOME (common_case (hd cases))
   134     else if is_none case_outline orelse length (distinct (op =) (map fst cases)) > 1 then NONE
   132     else if is_none case_outline orelse length (distinct (op =) (map fst cases)) > 1 then NONE
   135     else SOME (nested_case (hd cases))
   133     else SOME (nested_case (hd cases))
   136   end;
   134   end;
   137 
   135 
   138 fun make is_open rule_struct (thy, prop) cases =
   136 fun make rule_struct (thy, prop) cases =
   139   let
   137   let
   140     val n = length cases;
   138     val n = length cases;
   141     val nprems = Logic.count_prems prop;
   139     val nprems = Logic.count_prems prop;
   142     fun add_case (name, concls) (cs, i) =
   140     fun add_case (name, concls) (cs, i) =
   143       ((case try (fn () =>
   141       ((case try (fn () =>
   144           (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of
   142           (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of
   145         NONE => (name, NONE)
   143         NONE => (name, NONE)
   146       | SOME p => (name, extract_case is_open thy p name concls)) :: cs, i - 1);
   144       | SOME p => (name, extract_case thy p name concls)) :: cs, i - 1);
   147   in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end;
   145   in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end;
   148 
   146 
   149 in
   147 in
   150 
   148 
   151 fun make_common is_open = make is_open NONE;
   149 val make_common = make NONE;
   152 fun make_nested is_open rule_struct = make is_open (SOME rule_struct);
   150 fun make_nested rule_struct = make (SOME rule_struct);
   153 
   151 
   154 fun apply args =
   152 fun apply args =
   155   let
   153   let
   156     fun appl (Case {fixes, assumes, binds, cases}) =
   154     fun appl (Case {fixes, assumes, binds, cases}) =
   157       let
   155       let
   330   th
   328   th
   331   |> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss
   329   |> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss
   332   |> save th;
   330   |> save th;
   333 
   331 
   334 fun params xss = Thm.rule_attribute (K (rename_params xss));
   332 fun params xss = Thm.rule_attribute (K (rename_params xss));
       
   333 
       
   334 
       
   335 (* internalize parameter names *)
       
   336 
       
   337 fun internalize_params rule =
       
   338   let
       
   339     fun rename prem =
       
   340       let val xs =
       
   341         map (Name.internal o Name.clean o fst) (Logic.strip_params prem)
       
   342       in Logic.list_rename_params (xs, prem) end;
       
   343     fun rename_prems prop =
       
   344       let val (As, C) = Logic.strip_horn (Thm.prop_of rule)
       
   345       in Logic.list_implies (map rename As, C) end;
       
   346   in Thm.equal_elim (Thm.reflexive (Drule.cterm_fun rename_prems (Thm.cprop_of rule))) rule end;
   335 
   347 
   336 
   348 
   337 
   349 
   338 (** mutual_rule **)
   350 (** mutual_rule **)
   339 
   351