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 |