src/Pure/Isar/obtain.ML
changeset 60387 76359ff1090f
parent 60383 70b0362c784d
child 60388 0c9d2a4f589d
equal deleted inserted replaced
60386:16b5b1b9dd02 60387:76359ff1090f
    69     val _ = null bads orelse
    69     val _ = null bads orelse
    70       error ("Result contains obtained parameters: " ^
    70       error ("Result contains obtained parameters: " ^
    71         space_implode " " (map (Syntax.string_of_term ctxt) bads));
    71         space_implode " " (map (Syntax.string_of_term ctxt) bads));
    72   in tm end;
    72   in tm end;
    73 
    73 
    74 fun eliminate fix_ctxt rule xs As thm =
    74 fun eliminate ctxt rule xs As thm =
    75   let
    75   let
    76     val _ = eliminate_term fix_ctxt xs (Thm.full_prop_of thm);
    76     val _ = eliminate_term ctxt xs (Thm.full_prop_of thm);
    77     val _ = Object_Logic.is_judgment fix_ctxt (Thm.concl_of thm) orelse
    77     val _ = Object_Logic.is_judgment ctxt (Thm.concl_of thm) orelse
    78       error "Conclusion in obtained context must be object-logic judgment";
    78       error "Conclusion in obtained context must be object-logic judgment";
    79 
    79 
    80     val ((_, [thm']), ctxt') = Variable.import true [thm] fix_ctxt;
    80     val ((_, [thm']), ctxt') = Variable.import true [thm] ctxt;
    81     val prems = Drule.strip_imp_prems (#prop (Thm.crep_thm thm'));
    81     val prems = Drule.strip_imp_prems (#prop (Thm.crep_thm thm'));
    82   in
    82   in
    83     ((Drule.implies_elim_list thm' (map Thm.assume prems)
    83     ((Drule.implies_elim_list thm' (map Thm.assume prems)
    84         |> Drule.implies_intr_list (map (Drule.norm_hhf_cterm ctxt') As)
    84         |> Drule.implies_intr_list (map (Drule.norm_hhf_cterm ctxt') As)
    85         |> Drule.forall_intr_list xs)
    85         |> Drule.forall_intr_list xs)
    86       COMP rule)
    86       COMP rule)
    87     |> Drule.implies_intr_list prems
    87     |> Drule.implies_intr_list prems
    88     |> singleton (Variable.export ctxt' fix_ctxt)
    88     |> singleton (Variable.export ctxt' ctxt)
    89   end;
    89   end;
    90 
    90 
    91 fun obtain_export ctxt rule xs _ As =
    91 fun obtain_export ctxt rule xs _ As =
    92   (eliminate ctxt rule xs As, eliminate_term ctxt xs);
    92   (eliminate ctxt rule xs As, eliminate_term ctxt xs);
    93 
    93 
   116     val (vars, vars_ctxt) = fold_map prep_var raw_vars ctxt;
   116     val (vars, vars_ctxt) = fold_map prep_var raw_vars ctxt;
   117     val (xs', fix_ctxt) = vars_ctxt |> Proof_Context.add_fixes vars;
   117     val (xs', fix_ctxt) = vars_ctxt |> Proof_Context.add_fixes vars;
   118     val xs = map (Variable.check_name o #1) vars;
   118     val xs = map (Variable.check_name o #1) vars;
   119 
   119 
   120     (*obtain asms*)
   120     (*obtain asms*)
   121     val (proppss, asms_ctxt) = prep_propp (map snd raw_asms) fix_ctxt;
   121     val ((propss, binds), props_ctxt) = prep_propp (map snd raw_asms) fix_ctxt;
   122     val ((_, binds), binds_ctxt) = Proof_Context.bind_propp proppss asms_ctxt;
   122     val props = flat propss;
   123     val asm_props = maps (map fst) proppss;
   123     val asms =
   124     val asms = map fst (Attrib.map_specs (map (prep_att ctxt)) raw_asms) ~~ proppss;
   124       map (fn ((b, raw_atts), _) => (b, map (prep_att ctxt) raw_atts)) raw_asms ~~
   125 
   125       unflat propss (map (rpair []) props);
   126     (*obtain parms*)
   126 
   127     val (Ts, parms_ctxt) = fold_map Proof_Context.inferred_param xs' asms_ctxt;
   127     (*obtain params*)
   128     val parms = map Free (xs' ~~ Ts);
   128     val (Ts, params_ctxt) = fold_map Proof_Context.inferred_param xs' props_ctxt;
   129     val cparms = map (Thm.cterm_of ctxt) parms;
   129     val params = map Free (xs' ~~ Ts);
   130     val _ = Variable.warn_extra_tfrees fix_ctxt parms_ctxt;
   130     val cparams = map (Thm.cterm_of params_ctxt) params;
       
   131     val _ = Variable.warn_extra_tfrees fix_ctxt params_ctxt;
       
   132 
       
   133     (*abstracted term bindings*)
       
   134     fun abs_params t =
       
   135       let
       
   136         val ps =
       
   137           (xs ~~ params) |> map_filter (fn (x, p) =>
       
   138             if exists_subterm (fn u => u aconv p) t then SOME (x, p) else NONE);
       
   139       in fold_rev Term.lambda_name ps t end;
       
   140     val binds' = map (apsnd (Term.close_schematic_term o abs_params)) binds;
   131 
   141 
   132     (*obtain statements*)
   142     (*obtain statements*)
   133     val thesisN = singleton (Name.variant_list xs) Auto_Bind.thesisN;
   143     val thesisN = singleton (Name.variant_list xs) Auto_Bind.thesisN;
   134     val (thesis_var, thesis) = #1 (bind_judgment fix_ctxt thesisN);
   144     val (thesis_var, thesis) = #1 (bind_judgment fix_ctxt thesisN);
   135 
   145 
   136     val that_name = if name = "" then thatN else name;
   146     val that_name = if name = "" then thatN else name;
   137     val that_prop =
   147     val that_prop =
   138       Logic.list_rename_params xs
   148       Logic.list_rename_params xs
   139         (fold_rev Logic.all parms (Logic.list_implies (asm_props, thesis)));
   149         (fold_rev Logic.all params (Logic.list_implies (props, thesis)));
   140     val obtain_prop =
   150     val obtain_prop =
   141       Logic.list_rename_params [Auto_Bind.thesisN]
   151       Logic.list_rename_params [Auto_Bind.thesisN]
   142         (Logic.all (Free thesis_var) (Logic.mk_implies (that_prop, thesis)));
   152         (Logic.all (Free thesis_var) (Logic.mk_implies (that_prop, thesis)));
   143 
   153 
   144     fun after_qed _ =
   154     fun after_qed _ =
   145       Proof.local_qed (NONE, false)
   155       Proof.local_qed (NONE, false)
   146       #> `Proof.the_fact #-> (fn rule =>
   156       #> `Proof.the_fact #-> (fn rule =>
   147         Proof.fix vars
   157         Proof.fix vars
   148         #> Proof.assm (obtain_export fix_ctxt rule cparms) asms);
   158         #> Proof.map_context (Proof_Context.bind_terms binds)
       
   159         #> Proof.assm (obtain_export params_ctxt rule cparams) asms);
   149   in
   160   in
   150     state
   161     state
   151     |> Proof.enter_forward
   162     |> Proof.enter_forward
   152     |> Proof.have NONE (K I) [(Thm.empty_binding, [(obtain_prop, [])])] int
   163     |> Proof.have NONE (K I) [(Thm.empty_binding, [(obtain_prop, [])])] int
   153     |> Proof.map_context (Proof_Context.export_bind_terms binds binds_ctxt)
   164     |> Proof.map_context (Proof_Context.bind_terms binds')
   154     |> Proof.proof (SOME Method.succeed_text) |> Seq.hd
   165     |> Proof.proof (SOME Method.succeed_text) |> Seq.hd
   155     |> Proof.fix [(Binding.name thesisN, NONE, NoSyn)]
   166     |> Proof.fix [(Binding.name thesisN, NONE, NoSyn)]
   156     |> Proof.assume
   167     |> Proof.assume
   157       [((Binding.name that_name, [Context_Rules.intro_query NONE]), [(that_prop, [])])]
   168       [((Binding.name that_name, [Context_Rules.intro_query NONE]), [(that_prop, [])])]
   158     |> `Proof.the_facts
   169     |> `Proof.the_facts
   161     |-> Proof.refine_insert
   172     |-> Proof.refine_insert
   162   end;
   173   end;
   163 
   174 
   164 in
   175 in
   165 
   176 
   166 val obtain = gen_obtain (K I) Proof_Context.cert_var Proof_Context.cert_propp;
   177 val obtain = gen_obtain (K I) Proof_Context.cert_var Proof_Context.bind_propp;
   167 val obtain_cmd = gen_obtain Attrib.attribute_cmd Proof_Context.read_var Proof_Context.read_propp;
   178 val obtain_cmd = gen_obtain Attrib.attribute_cmd Proof_Context.read_var Proof_Context.bind_propp_cmd;
   168 
   179 
   169 end;
   180 end;
   170 
   181 
   171 
   182 
   172 
   183