src/Pure/Isar/rule_cases.ML
changeset 60565 b7ee41f72add
parent 60456 323b15b5af73
child 60574 380d5a433719
equal deleted inserted replaced
60564:6a363e56ffff 60565:b7ee41f72add
    20 signature RULE_CASES =
    20 signature RULE_CASES =
    21 sig
    21 sig
    22   include BASIC_RULE_CASES
    22   include BASIC_RULE_CASES
    23   datatype T = Case of
    23   datatype T = Case of
    24    {fixes: (binding * typ) list,
    24    {fixes: (binding * typ) list,
    25     assumes: (binding * term list) list,
    25     assumes: (string * term list) list,
    26     binds: (indexname * term option) list,
    26     binds: (indexname * term option) list,
    27     cases: (string * T) list}
    27     cases: (string * T) list}
    28   val case_hypsN: string
    28   val case_hypsN: string
    29   val strip_params: term -> (string * typ) list
    29   val strip_params: term -> (string * typ) list
    30   val make_common: Proof.context -> term ->
    30   val make_common: Proof.context -> term ->
    63 
    63 
    64 (** cases **)
    64 (** cases **)
    65 
    65 
    66 datatype T = Case of
    66 datatype T = Case of
    67  {fixes: (binding * typ) list,
    67  {fixes: (binding * typ) list,
    68   assumes: (binding * term list) list,
    68   assumes: (string * term list) list,
    69   binds: (indexname * term option) list,
    69   binds: (indexname * term option) list,
    70   cases: (string * T) list};
    70   cases: (string * T) list};
    71 
    71 
    72 type cases = (string * T option) list;
    72 type cases = (string * T option) list;
    73 
    73 
    92 
    92 
    93 fun extract_fixes NONE prop = (strip_params prop, [])
    93 fun extract_fixes NONE prop = (strip_params prop, [])
    94   | extract_fixes (SOME outline) prop =
    94   | extract_fixes (SOME outline) prop =
    95       chop (length (Logic.strip_params outline)) (strip_params prop);
    95       chop (length (Logic.strip_params outline)) (strip_params prop);
    96 
    96 
    97 fun extract_assumes _ _ NONE prop = ([(Binding.empty, Logic.strip_assums_hyp prop)], [])
    97 fun extract_assumes _ NONE prop = ([("", Logic.strip_assums_hyp prop)], [])
    98   | extract_assumes qualifier hyp_names (SOME outline) prop =
    98   | extract_assumes hyp_names (SOME outline) prop =
    99       let
    99       let
   100         val qual = Binding.qualify true qualifier o Binding.name;
       
   101         val (hyps, prems) =
   100         val (hyps, prems) =
   102           chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop)
   101           chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop)
   103         fun extract ((hyp_name, hyp) :: rest) = (qual hyp_name, hyp :: map snd rest);
   102         fun extract ((hyp_name, hyp) :: rest) = (hyp_name, hyp :: map snd rest);
   104         val (hyps1, hyps2) = chop (length hyp_names) hyps;
   103         val (hyps1, hyps2) = chop (length hyp_names) hyps;
   105         val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1;
   104         val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1;
   106         val pairs = pairs1 @ map (pair case_hypsN) hyps2;
   105         val pairs = pairs1 @ map (pair case_hypsN) hyps2;
   107         val named_hyps = map extract (partition_eq (eq_fst op =) pairs);
   106         val named_hyps = map extract (partition_eq (eq_fst op =) pairs);
   108       in (named_hyps, [(qual case_premsN, prems)]) end;
   107       in (named_hyps, [(case_premsN, prems)]) end;
   109 
   108 
   110 fun bindings args = map (apfst Binding.name) args;
   109 fun bindings args = map (apfst Binding.name) args;
   111 
   110 
   112 fun extract_case ctxt (case_outline, raw_prop) name hyp_names concls =
   111 fun extract_case ctxt (case_outline, raw_prop) hyp_names concls =
   113   let
   112   let
   114     val props = Logic.dest_conjunctions (Drule.norm_hhf (Proof_Context.theory_of ctxt) raw_prop);
   113     val props = Logic.dest_conjunctions (Drule.norm_hhf (Proof_Context.theory_of ctxt) raw_prop);
   115     val len = length props;
   114     val len = length props;
   116     val nested = is_some case_outline andalso len > 1;
   115     val nested = is_some case_outline andalso len > 1;
   117 
   116 
   123           if not nested then abs_fixes t
   122           if not nested then abs_fixes t
   124           else
   123           else
   125             fold_rev Term.abs fixes1
   124             fold_rev Term.abs fixes1
   126               (app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t));
   125               (app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t));
   127         val (assumes1, assumes2) =
   126         val (assumes1, assumes2) =
   128           extract_assumes name hyp_names case_outline prop
   127           extract_assumes hyp_names case_outline prop
   129           |> apply2 (map (apsnd (maps Logic.dest_conjunctions)));
   128           |> apply2 (map (apsnd (maps Logic.dest_conjunctions)));
   130 
   129 
   131         val concl = Object_Logic.drop_judgment ctxt (Logic.strip_assums_concl prop);
   130         val concl = Object_Logic.drop_judgment ctxt (Logic.strip_assums_concl prop);
   132         val binds =
   131         val binds =
   133           (case_conclN, concl) :: dest_binops concls concl
   132           (case_conclN, concl) :: dest_binops concls concl
   160     val nprems = Logic.count_prems prop;
   159     val nprems = Logic.count_prems prop;
   161     fun add_case ((name, hyp_names), concls) (cs, i) =
   160     fun add_case ((name, hyp_names), concls) (cs, i) =
   162       ((case try (fn () =>
   161       ((case try (fn () =>
   163           (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of
   162           (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of
   164         NONE => (name, NONE)
   163         NONE => (name, NONE)
   165       | SOME p => (name, extract_case ctxt p name hyp_names concls)) :: cs, i - 1);
   164       | SOME p => (name, extract_case ctxt p hyp_names concls)) :: cs, i - 1);
   166   in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end;
   165   in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end;
   167 
   166 
   168 in
   167 in
   169 
   168 
   170 fun make_common ctxt = make ctxt NONE;
   169 fun make_common ctxt = make ctxt NONE;