src/Pure/Isar/obtain.ML
changeset 10464 b7b916a82dca
parent 10379 93630e0c5ae9
child 10582 49ebade930ea
equal deleted inserted replaced
10463:474263d29057 10464:b7b916a82dca
    19 *)
    19 *)
    20 
    20 
    21 signature OBTAIN =
    21 signature OBTAIN =
    22 sig
    22 sig
    23   val obtain: ((string list * string option) * Comment.text) list
    23   val obtain: ((string list * string option) * Comment.text) list
    24     * ((string * Args.src list * (string * (string list * string list)) list)
    24     * (((string * Args.src list) * (string * (string list * string list)) list)
    25       * Comment.text) list -> ProofHistory.T -> ProofHistory.T
    25       * Comment.text) list -> ProofHistory.T -> ProofHistory.T
    26   val obtain_i: ((string list * typ option) * Comment.text) list
    26   val obtain_i: ((string list * typ option) * Comment.text) list
    27     * ((string * Proof.context attribute list * (term * (term list * term list)) list)
    27     * (((string * Proof.context attribute list) * (term * (term list * term list)) list)
    28       * Comment.text) list -> ProofHistory.T -> ProofHistory.T
    28       * Comment.text) list -> ProofHistory.T -> ProofHistory.T
    29 end;
    29 end;
    30 
    30 
    31 structure Obtain: OBTAIN =
    31 structure Obtain: OBTAIN =
    32 struct
    32 struct
    64 
    64 
    65 fun gen_obtain prep_vars prep_propp prep_att (raw_vars, raw_asms) state =
    65 fun gen_obtain prep_vars prep_propp prep_att (raw_vars, raw_asms) state =
    66   let
    66   let
    67     val _ = Proof.assert_forward_or_chain state;
    67     val _ = Proof.assert_forward_or_chain state;
    68     val chain_facts = if Proof.is_chain state then Proof.the_facts state else [];
    68     val chain_facts = if Proof.is_chain state then Proof.the_facts state else [];
       
    69     val thy = Proof.theory_of state;
    69 
    70 
    70     (*obtain vars*)
    71     (*obtain vars*)
    71     val (vars_ctxt, vars) =
    72     val (vars_ctxt, vars) =
    72       foldl_map prep_vars (Proof.context_of state, map Comment.ignore raw_vars);
    73       foldl_map prep_vars (Proof.context_of state, map Comment.ignore raw_vars);
    73     val xs = flat (map fst vars);
    74     val xs = flat (map fst vars);
    76     val bind_skolem = ProofContext.bind_skolem vars_ctxt (xs @ [thesisN]);
    77     val bind_skolem = ProofContext.bind_skolem vars_ctxt (xs @ [thesisN]);
    77     fun bind_propp (prop, (pats1, pats2)) =
    78     fun bind_propp (prop, (pats1, pats2)) =
    78       (bind_skolem prop, (map bind_skolem pats1, map bind_skolem pats2));
    79       (bind_skolem prop, (map bind_skolem pats1, map bind_skolem pats2));
    79 
    80 
    80     (*obtain asms*)
    81     (*obtain asms*)
    81     fun prep_asm (ctxt, (name, src, raw_propps)) =
    82     val (asms_ctxt, proppss) = prep_propp (vars_ctxt, map (snd o Comment.ignore) raw_asms);
    82       let
    83     val asm_props = flat (map (map fst) proppss);
    83         val atts = map (prep_att (ProofContext.theory_of ctxt)) src;
       
    84         val (ctxt', propps) = foldl_map prep_propp (ctxt, raw_propps);
       
    85       in (ctxt', ((name, atts, map bind_propp propps), map #1 propps)) end;
       
    86 
    84 
    87     val (asms_ctxt, asms_result) = foldl_map prep_asm (vars_ctxt, map Comment.ignore raw_asms);
    85     fun prep_asm ((name, src), propps) = ((name, map (prep_att thy) src), map bind_propp propps);
    88     val (asms, asm_propss) = Library.split_list asms_result;
    86     val asms = map2 prep_asm (map (fst o Comment.ignore) raw_asms, proppss);
    89     val asm_props = flat asm_propss;
    87 
    90     val _ = ProofContext.warn_extra_tfrees vars_ctxt asms_ctxt;
    88     val _ = ProofContext.warn_extra_tfrees vars_ctxt asms_ctxt;
    91 
    89 
    92     (*that_prop*)
    90     (*that_prop*)
    93     fun find_free x t =
    91     fun find_free x t =
    94       (case ProofContext.find_free t x of Some (Free a) => Some a | _ => None);
    92       (case ProofContext.find_free t x of Some (Free a) => Some a | _ => None);
    95     fun occs_var x = Library.get_first (find_free x) asm_props;
    93     fun occs_var x = Library.get_first (find_free x) asm_props;
    96     val xs' = mapfilter occs_var xs;
    94     val xs' = mapfilter occs_var xs;
    97     val parms = map (bind_skolem o Free) xs';
    95     val parms = map (bind_skolem o Free) xs';
    98 
    96 
    99     val bound_thesis = bind_skolem (AutoBind.atomic_judgment (Proof.theory_of state) thesisN);
    97     val bound_thesis = bind_skolem (AutoBind.atomic_judgment thy thesisN);
   100     val that_prop = Term.list_all_free (xs', Logic.list_implies (asm_props, bound_thesis));
    98     val that_prop = Term.list_all_free (xs', Logic.list_implies (asm_props, bound_thesis));
   101 
    99 
   102     fun export_obtained rule =
   100     fun export_obtained rule =
   103       (disch_obtained state parms rule, fn _ => fn _ => []);
   101       (disch_obtained state parms rule, fn _ => fn _ => []);
   104 
   102 
   110   in
   108   in
   111     state
   109     state
   112     |> Proof.enter_forward
   110     |> Proof.enter_forward
   113     |> Proof.begin_block
   111     |> Proof.begin_block
   114     |> Proof.fix_i [([thesisN], None)]
   112     |> Proof.fix_i [([thesisN], None)]
   115     |> Proof.assume_i [(thatN, [Method.intro_local], [(that_prop, ([], []))])]
   113     |> Proof.assume_i [((thatN, [Method.intro_local]), [(that_prop, ([], []))])]
   116     |> (fn state' =>
   114     |> (fn state' =>
   117       state'
   115       state'
   118       |> Proof.from_facts chain_facts
   116       |> Proof.from_facts chain_facts
   119       |> Proof.have_i after_qed "" [] (bound_thesis, ([], []))
   117       |> Proof.have_i after_qed "" [] (bound_thesis, ([], []))
   120       |> Method.refine (Method.Basic (K (Method.insert (Proof.the_facts state')))))
   118       |> Method.refine (Method.Basic (K (Method.insert (Proof.the_facts state')))))
   137   OuterSyntax.command "obtain" "generalized existence"
   135   OuterSyntax.command "obtain" "generalized existence"
   138     K.prf_asm_goal
   136     K.prf_asm_goal
   139     (Scan.optional
   137     (Scan.optional
   140       (P.and_list1 (Scan.repeat1 P.name -- Scan.option (P.$$$ "::" |-- P.typ) -- P.marg_comment)
   138       (P.and_list1 (Scan.repeat1 P.name -- Scan.option (P.$$$ "::" |-- P.typ) -- P.marg_comment)
   141         --| P.$$$ "where") [] --
   139         --| P.$$$ "where") [] --
   142       P.and_list1 ((P.opt_thm_name ":" -- Scan.repeat1 P.propp >> P.triple1) -- P.marg_comment)
   140       P.and_list1 (P.opt_thm_name ":" -- Scan.repeat1 P.propp -- P.marg_comment)
   143     >> (Toplevel.print oo (Toplevel.proof o obtain)));
   141     >> (Toplevel.print oo (Toplevel.proof o obtain)));
   144 
   142 
   145 val _ = OuterSyntax.add_keywords ["where"];
   143 val _ = OuterSyntax.add_keywords ["where"];
   146 val _ = OuterSyntax.add_parsers [obtainP];
   144 val _ = OuterSyntax.add_parsers [obtainP];
   147 
   145