src/Pure/Isar/subgoal.ML
changeset 60695 757549b4bbe6
parent 60642 48dd1cefb4ae
child 60707 e96b7be56d44
equal deleted inserted replaced
60694:b3fa4a8cdb5f 60695:757549b4bbe6
    13 signature SUBGOAL =
    13 signature SUBGOAL =
    14 sig
    14 sig
    15   type focus =
    15   type focus =
    16    {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list,
    16    {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list,
    17     concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list}
    17     concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list}
    18   val focus_params: Proof.context -> int -> thm -> focus * thm
    18   val focus_params: Proof.context -> int -> binding list option -> thm -> focus * thm
    19   val focus_params_fixed: Proof.context -> int -> thm -> focus * thm
    19   val focus_params_fixed: Proof.context -> int -> binding list option -> thm -> focus * thm
    20   val focus_prems: Proof.context -> int -> thm -> focus * thm
    20   val focus_prems: Proof.context -> int -> binding list option -> thm -> focus * thm
    21   val focus: Proof.context -> int -> thm -> focus * thm
    21   val focus: Proof.context -> int -> binding list option -> thm -> focus * thm
    22   val retrofit: Proof.context -> Proof.context -> (string * cterm) list -> cterm list ->
    22   val retrofit: Proof.context -> Proof.context -> (string * cterm) list -> cterm list ->
    23     int -> thm -> thm -> thm Seq.seq
    23     int -> thm -> thm -> thm Seq.seq
    24   val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic
    24   val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic
    25   val FOCUS_PARAMS_FIXED: (focus -> tactic) -> Proof.context -> int -> tactic
    25   val FOCUS_PARAMS_FIXED: (focus -> tactic) -> Proof.context -> int -> tactic
    26   val FOCUS_PREMS: (focus -> tactic) -> Proof.context -> int -> tactic
    26   val FOCUS_PREMS: (focus -> tactic) -> Proof.context -> int -> tactic
    39 
    39 
    40 type focus =
    40 type focus =
    41  {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list,
    41  {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list,
    42   concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list};
    42   concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list};
    43 
    43 
    44 fun gen_focus (do_prems, do_concl) ctxt i raw_st =
    44 fun gen_focus (do_prems, do_concl) ctxt i bindings raw_st =
    45   let
    45   let
    46     val st = raw_st
    46     val st = raw_st
    47       |> Thm.transfer (Proof_Context.theory_of ctxt)
    47       |> Thm.transfer (Proof_Context.theory_of ctxt)
    48       |> Raw_Simplifier.norm_hhf_protect ctxt;
    48       |> Raw_Simplifier.norm_hhf_protect ctxt;
    49     val ((schematic_types, [st']), ctxt1) = Variable.importT [st] ctxt;
    49     val ((schematic_types, [st']), ctxt1) = Variable.importT [st] ctxt;
    50     val ((params, goal), ctxt2) = Variable.focus_cterm (Thm.cprem_of st' i) ctxt1;
    50     val ((params, goal), ctxt2) = Variable.focus_cterm bindings (Thm.cprem_of st' i) ctxt1;
    51 
    51 
    52     val (asms, concl) =
    52     val (asms, concl) =
    53       if do_prems then (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal)
    53       if do_prems then (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal)
    54       else ([], goal);
    54       else ([], goal);
    55     val text = asms @ (if do_concl then [concl] else []);
    55     val text = asms @ (if do_concl then [concl] else []);
   148 (* tacticals *)
   148 (* tacticals *)
   149 
   149 
   150 fun GEN_FOCUS flags tac ctxt i st =
   150 fun GEN_FOCUS flags tac ctxt i st =
   151   if Thm.nprems_of st < i then Seq.empty
   151   if Thm.nprems_of st < i then Seq.empty
   152   else
   152   else
   153     let val (args as {context = ctxt', params, asms, ...}, st') = gen_focus flags ctxt i st;
   153     let val (args as {context = ctxt', params, asms, ...}, st') = gen_focus flags ctxt i NONE st;
   154     in Seq.lifts (retrofit ctxt' ctxt params asms i) (tac args st') st end;
   154     in Seq.lifts (retrofit ctxt' ctxt params asms i) (tac args st') st end;
   155 
   155 
   156 val FOCUS_PARAMS = GEN_FOCUS (false, false);
   156 val FOCUS_PARAMS = GEN_FOCUS (false, false);
   157 val FOCUS_PARAMS_FIXED = GEN_FOCUS (false, true);
   157 val FOCUS_PARAMS_FIXED = GEN_FOCUS (false, true);
   158 val FOCUS_PREMS = GEN_FOCUS (true, false);
   158 val FOCUS_PREMS = GEN_FOCUS (true, false);
   163 
   163 
   164 (* Isar subgoal command *)
   164 (* Isar subgoal command *)
   165 
   165 
   166 local
   166 local
   167 
   167 
   168 fun rename_params ctxt (param_suffix, raw_param_specs) st =
   168 fun param_bindings ctxt (param_suffix, raw_param_specs) st =
   169   let
   169   let
   170     val _ = if Thm.no_prems st then error "No subgoals!" else ();
   170     val _ = if Thm.no_prems st then error "No subgoals!" else ();
   171     val (subgoal, goal') = Logic.dest_implies (Thm.prop_of st);
   171     val subgoal = #1 (Logic.dest_implies (Thm.prop_of st));
   172     val subgoal_params =
   172     val subgoal_params =
   173       map (apfst (Name.internal o Name.clean)) (Term.strip_all_vars subgoal)
   173       map (apfst (Name.internal o Name.clean)) (Term.strip_all_vars subgoal)
   174       |> Term.variant_frees subgoal |> map #1;
   174       |> Term.variant_frees subgoal |> map #1;
   175 
   175 
   176     val n = length subgoal_params;
   176     val n = length subgoal_params;
   182 
   182 
   183     val param_specs =
   183     val param_specs =
   184       raw_param_specs |> map
   184       raw_param_specs |> map
   185         (fn (NONE, _) => NONE
   185         (fn (NONE, _) => NONE
   186           | (SOME x, pos) =>
   186           | (SOME x, pos) =>
   187               let val b = #1 (#1 (Proof_Context.cert_var (Binding.make (x, pos), NONE, NoSyn) ctxt))
   187               let
   188               in SOME (Variable.check_name b) end)
   188                 val b = #1 (#1 (Proof_Context.cert_var (Binding.make (x, pos), NONE, NoSyn) ctxt));
       
   189                 val _ = Variable.check_name b;
       
   190               in SOME b end)
   189       |> param_suffix ? append (replicate (n - m) NONE);
   191       |> param_suffix ? append (replicate (n - m) NONE);
   190 
   192 
   191     fun rename_list (opt_x :: xs) (y :: ys) = (the_default y opt_x :: rename_list xs ys)
   193     fun bindings (SOME x :: xs) (_ :: ys) = x :: bindings xs ys
   192       | rename_list _ ys = ys;
   194       | bindings (NONE :: xs) (y :: ys) = Binding.name y :: bindings xs ys
   193 
   195       | bindings _ ys = map Binding.name ys;
   194     fun rename_prop (x :: xs) ((c as Const ("Pure.all", _)) $ Abs (_, T, t)) =
   196   in bindings param_specs subgoal_params end;
   195           (c $ Abs (x, T, rename_prop xs t))
       
   196       | rename_prop [] t = t;
       
   197 
       
   198     val subgoal' = rename_prop (rename_list param_specs subgoal_params) subgoal;
       
   199   in Thm.renamed_prop (Logic.mk_implies (subgoal', goal')) st end;
       
   200 
   197 
   201 fun gen_subgoal prep_atts raw_result_binding raw_prems_binding param_specs state =
   198 fun gen_subgoal prep_atts raw_result_binding raw_prems_binding param_specs state =
   202   let
   199   let
   203     val _ = Proof.assert_backward state;
   200     val _ = Proof.assert_backward state;
   204 
   201 
   210       (case raw_prems_binding of
   207       (case raw_prems_binding of
   211         SOME (b, raw_atts) => ((b, map (prep_atts ctxt) raw_atts), true)
   208         SOME (b, raw_atts) => ((b, map (prep_atts ctxt) raw_atts), true)
   212       | NONE => ((Binding.empty, []), false));
   209       | NONE => ((Binding.empty, []), false));
   213 
   210 
   214     val (subgoal_focus, _) =
   211     val (subgoal_focus, _) =
   215       rename_params ctxt param_specs st
   212       (if do_prems then focus else focus_params_fixed) ctxt
   216       |> (if do_prems then focus else focus_params_fixed) ctxt 1;
   213         1 (SOME (param_bindings ctxt param_specs st)) st;
   217 
   214 
   218     fun after_qed (ctxt'', [[result]]) =
   215     fun after_qed (ctxt'', [[result]]) =
   219       Proof.end_block #> (fn state' =>
   216       Proof.end_block #> (fn state' =>
   220         let
   217         let
   221           val ctxt' = Proof.context_of state';
   218           val ctxt' = Proof.context_of state';