13 signature GOALS = |
13 signature GOALS = |
14 sig |
14 sig |
15 structure Tactical: TACTICAL |
15 structure Tactical: TACTICAL |
16 local open Tactical Tactical.Thm in |
16 local open Tactical Tactical.Thm in |
17 type proof |
17 type proof |
18 val ba : int -> unit |
18 val ba : int -> unit |
19 val back : unit -> unit |
19 val back : unit -> unit |
20 val bd : thm -> int -> unit |
20 val bd : thm -> int -> unit |
21 val bds : thm list -> int -> unit |
21 val bds : thm list -> int -> unit |
22 val be : thm -> int -> unit |
22 val be : thm -> int -> unit |
23 val bes : thm list -> int -> unit |
23 val bes : thm list -> int -> unit |
24 val br : thm -> int -> unit |
24 val br : thm -> int -> unit |
25 val brs : thm list -> int -> unit |
25 val brs : thm list -> int -> unit |
26 val bw : thm -> unit |
26 val bw : thm -> unit |
27 val bws : thm list -> unit |
27 val bws : thm list -> unit |
28 val by : tactic -> unit |
28 val by : tactic -> unit |
29 val byev : tactic list -> unit |
29 val byev : tactic list -> unit |
30 val chop : unit -> unit |
30 val chop : unit -> unit |
31 val choplev : int -> unit |
31 val choplev : int -> unit |
32 val fa : unit -> unit |
32 val fa : unit -> unit |
33 val fd : thm -> unit |
33 val fd : thm -> unit |
34 val fds : thm list -> unit |
34 val fds : thm list -> unit |
35 val fe : thm -> unit |
35 val fe : thm -> unit |
36 val fes : thm list -> unit |
36 val fes : thm list -> unit |
37 val filter_goal : (term*term->bool) -> thm list -> int -> thm list |
37 val filter_goal : (term*term->bool) -> thm list -> int -> thm list |
38 val fr : thm -> unit |
38 val fr : thm -> unit |
39 val frs : thm list -> unit |
39 val frs : thm list -> unit |
40 val getgoal : int -> term |
40 val getgoal : int -> term |
41 val gethyps : int -> thm list |
41 val gethyps : int -> thm list |
42 val goal : theory -> string -> thm list |
42 val goal : theory -> string -> thm list |
43 val goalw : theory -> thm list -> string -> thm list |
43 val goalw : theory -> thm list -> string -> thm list |
44 val goalw_cterm : thm list -> cterm -> thm list |
44 val goalw_cterm : thm list -> cterm -> thm list |
45 val pop_proof : unit -> thm list |
45 val pop_proof : unit -> thm list |
46 val pr : unit -> unit |
46 val pr : unit -> unit |
47 val premises : unit -> thm list |
47 val premises : unit -> thm list |
48 val prin : term -> unit |
48 val prin : term -> unit |
49 val printyp : typ -> unit |
49 val printyp : typ -> unit |
50 val pprint_term : term -> pprint_args -> unit |
50 val pprint_term : term -> pprint_args -> unit |
51 val pprint_typ : typ -> pprint_args -> unit |
51 val pprint_typ : typ -> pprint_args -> unit |
52 val print_exn : exn -> 'a |
52 val print_exn : exn -> 'a |
53 val print_sign_exn : Sign.sg -> exn -> 'a |
53 val print_sign_exn : Sign.sg -> exn -> 'a |
54 val prlev : int -> unit |
54 val prlev : int -> unit |
55 val proof_timing : bool ref |
55 val proof_timing : bool ref |
56 val prove_goal : theory -> string -> (thm list -> tactic list) -> thm |
56 val prove_goal : theory -> string -> (thm list -> tactic list) -> thm |
57 val prove_goalw : theory->thm list->string->(thm list->tactic list)->thm |
57 val prove_goalw : theory->thm list->string->(thm list->tactic list)->thm |
58 val prove_goalw_cterm : thm list->cterm->(thm list->tactic list)->thm |
58 val prove_goalw_cterm : thm list->cterm->(thm list->tactic list)->thm |
59 val push_proof : unit -> unit |
59 val push_proof : unit -> unit |
60 val read : string -> term |
60 val read : string -> term |
61 val ren : string -> int -> unit |
61 val ren : string -> int -> unit |
62 val restore_proof : proof -> thm list |
62 val restore_proof : proof -> thm list |
63 val result : unit -> thm |
63 val result : unit -> thm |
64 val rotate_proof : unit -> thm list |
64 val rotate_proof : unit -> thm list |
65 val uresult : unit -> thm |
65 val uresult : unit -> thm |
66 val save_proof : unit -> proof |
66 val save_proof : unit -> proof |
67 val topthm : unit -> thm |
67 val topthm : unit -> thm |
68 val undo : unit -> unit |
68 val undo : unit -> unit |
69 end |
69 end |
70 end; |
70 end; |
71 |
71 |
72 functor GoalsFun (structure Logic: LOGIC and Drule: DRULE and Tactic: TACTIC |
72 functor GoalsFun (structure Logic: LOGIC and Drule: DRULE and Tactic: TACTIC |
73 and Pattern:PATTERN |
73 and Pattern:PATTERN |
74 sharing type Pattern.type_sig = Drule.Thm.Sign.Type.type_sig |
74 sharing type Pattern.type_sig = Drule.Thm.Sign.Type.type_sig |
75 and Drule.Thm = Tactic.Tactical.Thm) : GOALS = |
75 and Drule.Thm = Tactic.Tactical.Thm) : GOALS = |
76 struct |
76 struct |
77 structure Tactical = Tactic.Tactical |
77 structure Tactical = Tactic.Tactical |
78 local open Tactic Tactic.Tactical Tactic.Tactical.Thm Drule |
78 local open Tactic Tactic.Tactical Tactic.Tactical.Thm Drule |
79 in |
79 in |
130 val cAs = map (cterm_of sign) As; |
130 val cAs = map (cterm_of sign) As; |
131 val prems = map (rewrite_rule rths o forall_elim_vars(0) o assume) cAs |
131 val prems = map (rewrite_rule rths o forall_elim_vars(0) o assume) cAs |
132 and st0 = (rewrite_goals_rule rths o trivial) (cterm_of sign B) |
132 and st0 = (rewrite_goals_rule rths o trivial) (cterm_of sign B) |
133 fun result_error state msg = |
133 fun result_error state msg = |
134 (writeln ("Bad final proof state:"); |
134 (writeln ("Bad final proof state:"); |
135 !print_goals_ref (!goals_limit) state; |
135 !print_goals_ref (!goals_limit) state; |
136 error msg) |
136 error msg) |
137 (*discharges assumptions from state in the order they appear in goal; |
137 (*discharges assumptions from state in the order they appear in goal; |
138 checks (if requested) that resulting theorem is equivalent to goal. *) |
138 checks (if requested) that resulting theorem is equivalent to goal. *) |
139 fun mkresult (check,state) = |
139 fun mkresult (check,state) = |
140 let val state = Sequence.hd (flexflex_rule state) |
140 let val state = Sequence.hd (flexflex_rule state) |
141 handle _ => state (*smash flexflex pairs*) |
141 handle _ => state (*smash flexflex pairs*) |
142 val ngoals = nprems_of state |
142 val ngoals = nprems_of state |
143 val th = strip_shyps (implies_intr_list cAs state) |
143 val th = strip_shyps (implies_intr_list cAs state) |
144 val {hyps,prop,sign=sign',...} = rep_thm th |
144 val {hyps,prop,sign=sign',...} = rep_thm th |
145 val xshyps = extra_shyps th; |
145 val xshyps = extra_shyps th; |
146 in if not check then standard th |
146 in if not check then standard th |
147 else if not (Sign.eq_sg(sign,sign')) then result_error state |
147 else if not (Sign.eq_sg(sign,sign')) then result_error state |
148 ("Signature of proof state has changed!" ^ |
148 ("Signature of proof state has changed!" ^ |
149 sign_error (sign,sign')) |
149 sign_error (sign,sign')) |
150 else if ngoals>0 then result_error state |
150 else if ngoals>0 then result_error state |
151 (string_of_int ngoals ^ " unsolved goals!") |
151 (string_of_int ngoals ^ " unsolved goals!") |
152 else if not (null hyps) then result_error state |
152 else if not (null hyps) then result_error state |
153 ("Additional hypotheses:\n" ^ |
153 ("Additional hypotheses:\n" ^ |
154 cat_lines (map (Sign.string_of_term sign) hyps)) |
154 cat_lines (map (Sign.string_of_term sign) hyps)) |
155 else if not (null xshyps) then result_error state |
155 else if not (null xshyps) then result_error state |
156 ("Extra sort hypotheses: " ^ |
156 ("Extra sort hypotheses: " ^ |
157 commas (map Sign.Type.str_of_sort xshyps)) |
157 commas (map Sign.Type.str_of_sort xshyps)) |
158 else if Pattern.matches (#tsig(Sign.rep_sg sign)) |
158 else if Pattern.matches (#tsig(Sign.rep_sg sign)) |
159 (term_of chorn, prop) |
159 (term_of chorn, prop) |
160 then standard th |
160 then standard th |
161 else result_error state "proved a different theorem" |
161 else result_error state "proved a different theorem" |
162 end |
162 end |
163 in |
163 in |
164 if Sign.eq_sg(sign, #sign(rep_thm st0)) |
164 if Sign.eq_sg(sign, #sign(rep_thm st0)) |
165 then (prems, st0, mkresult) |
165 then (prems, st0, mkresult) |
166 else error ("Definitions would change the proof state's signature" ^ |
166 else error ("Definitions would change the proof state's signature" ^ |
167 sign_error (sign, #sign(rep_thm st0))) |
167 sign_error (sign, #sign(rep_thm st0))) |
168 end |
168 end |
169 handle THM(s,_,_) => error("prepare_proof: exception THM was raised!\n" ^ s); |
169 handle THM(s,_,_) => error("prepare_proof: exception THM was raised!\n" ^ s); |
170 |
170 |
171 (*Prints exceptions readably to users*) |
171 (*Prints exceptions readably to users*) |
172 fun print_sign_exn_unit sign e = |
172 fun print_sign_exn_unit sign e = |
173 case e of |
173 case e of |
174 THM (msg,i,thms) => |
174 THM (msg,i,thms) => |
175 (writeln ("Exception THM " ^ string_of_int i ^ " raised:\n" ^ msg); |
175 (writeln ("Exception THM " ^ string_of_int i ^ " raised:\n" ^ msg); |
176 seq print_thm thms) |
176 seq print_thm thms) |
177 | THEORY (msg,thys) => |
177 | THEORY (msg,thys) => |
178 (writeln ("Exception THEORY raised:\n" ^ msg); |
178 (writeln ("Exception THEORY raised:\n" ^ msg); |
179 seq print_theory thys) |
179 seq print_theory thys) |
180 | TERM (msg,ts) => |
180 | TERM (msg,ts) => |
181 (writeln ("Exception TERM raised:\n" ^ msg); |
181 (writeln ("Exception TERM raised:\n" ^ msg); |
182 seq (writeln o Sign.string_of_term sign) ts) |
182 seq (writeln o Sign.string_of_term sign) ts) |
183 | TYPE (msg,Ts,ts) => |
183 | TYPE (msg,Ts,ts) => |
184 (writeln ("Exception TYPE raised:\n" ^ msg); |
184 (writeln ("Exception TYPE raised:\n" ^ msg); |
185 seq (writeln o Sign.string_of_typ sign) Ts; |
185 seq (writeln o Sign.string_of_typ sign) Ts; |
186 seq (writeln o Sign.string_of_term sign) ts) |
186 seq (writeln o Sign.string_of_term sign) ts) |
187 | e => raise e; |
187 | e => raise e; |
188 |
188 |
189 (*Prints an exception, then fails*) |
189 (*Prints an exception, then fails*) |
190 fun print_sign_exn sign e = (print_sign_exn_unit sign e; raise ERROR); |
190 fun print_sign_exn sign e = (print_sign_exn_unit sign e; raise ERROR); |
191 |
191 |
197 (*Version taking the goal as a cterm*) |
197 (*Version taking the goal as a cterm*) |
198 fun prove_goalw_cterm rths chorn tacsf = |
198 fun prove_goalw_cterm rths chorn tacsf = |
199 let val (prems, st0, mkresult) = prepare_proof rths chorn |
199 let val (prems, st0, mkresult) = prepare_proof rths chorn |
200 val tac = EVERY (tacsf prems) |
200 val tac = EVERY (tacsf prems) |
201 fun statef() = |
201 fun statef() = |
202 (case Sequence.pull (tapply(tac,st0)) of |
202 (case Sequence.pull (tapply(tac,st0)) of |
203 Some(st,_) => st |
203 Some(st,_) => st |
204 | _ => error ("prove_goal: tactic failed")) |
204 | _ => error ("prove_goal: tactic failed")) |
205 in mkresult (true, cond_timeit (!proof_timing) statef) end |
205 in mkresult (true, cond_timeit (!proof_timing) statef) end |
206 handle e => (print_sign_exn_unit (#sign (rep_cterm chorn)) e; |
206 handle e => (print_sign_exn_unit (#sign (rep_cterm chorn)) e; |
207 error ("The exception above was raised for\n" ^ |
207 error ("The exception above was raised for\n" ^ |
208 string_of_cterm chorn)); |
208 string_of_cterm chorn)); |
209 |
209 |
210 |
210 |
211 (*Version taking the goal as a string*) |
211 (*Version taking the goal as a string*) |
212 fun prove_goalw thy rths agoal tacsf = |
212 fun prove_goalw thy rths agoal tacsf = |
213 let val sign = sign_of thy |
213 let val sign = sign_of thy |
214 val chorn = read_cterm sign (agoal,propT) |
214 val chorn = read_cterm sign (agoal,propT) |
215 in prove_goalw_cterm rths chorn tacsf end |
215 in prove_goalw_cterm rths chorn tacsf end |
216 handle ERROR => error (*from read_cterm?*) |
216 handle ERROR => error (*from read_cterm?*) |
217 ("The error above occurred for " ^ quote agoal); |
217 ("The error above occurred for " ^ quote agoal); |
218 |
218 |
219 (*String version with no meta-rewrite-rules*) |
219 (*String version with no meta-rewrite-rules*) |
220 fun prove_goal thy = prove_goalw thy []; |
220 fun prove_goal thy = prove_goalw thy []; |
221 |
221 |
222 |
222 |
307 |
307 |
308 (*Version taking the goal as a string*) |
308 (*Version taking the goal as a string*) |
309 fun goalw thy rths agoal = |
309 fun goalw thy rths agoal = |
310 goalw_cterm rths (read_cterm(sign_of thy)(agoal,propT)) |
310 goalw_cterm rths (read_cterm(sign_of thy)(agoal,propT)) |
311 handle ERROR => error (*from type_assign, etc via prepare_proof*) |
311 handle ERROR => error (*from type_assign, etc via prepare_proof*) |
312 ("The error above occurred for " ^ quote agoal); |
312 ("The error above occurred for " ^ quote agoal); |
313 |
313 |
314 (*String version with no meta-rewrite-rules*) |
314 (*String version with no meta-rewrite-rules*) |
315 fun goal thy = goalw thy []; |
315 fun goal thy = goalw thy []; |
316 |
316 |
317 (*Proof step "by" the given tactic -- apply tactic to the proof state*) |
317 (*Proof step "by" the given tactic -- apply tactic to the proof state*) |
318 fun by_com tac ((th,ths), pairs) : gstack = |
318 fun by_com tac ((th,ths), pairs) : gstack = |
319 (case Sequence.pull(tapply(tac, th)) of |
319 (case Sequence.pull(tapply(tac, th)) of |
320 None => error"by: tactic failed" |
320 None => error"by: tactic failed" |
321 | Some(th2,ths2) => |
321 | Some(th2,ths2) => |
322 (if eq_thm(th,th2) |
322 (if eq_thm(th,th2) |
323 then writeln"Warning: same as previous level" |
323 then writeln"Warning: same as previous level" |
324 else if eq_thm_sg(th,th2) then () |
324 else if eq_thm_sg(th,th2) then () |
325 else writeln("Warning: signature of proof state has changed" ^ |
325 else writeln("Warning: signature of proof state has changed" ^ |
326 sign_error (#sign(rep_thm th), #sign(rep_thm th2))); |
326 sign_error (#sign(rep_thm th), #sign(rep_thm th2))); |
327 ((th2,ths2)::(th,ths)::pairs))); |
327 ((th2,ths2)::(th,ths)::pairs))); |
328 |
328 |
329 fun by tac = cond_timeit (!proof_timing) |
329 fun by tac = cond_timeit (!proof_timing) |
330 (fn() => make_command (by_com tac)); |
330 (fn() => make_command (by_com tac)); |
331 |
331 |
337 (*Backtracking means find an alternative result from a tactic. |
337 (*Backtracking means find an alternative result from a tactic. |
338 If none at this level, try earlier levels*) |
338 If none at this level, try earlier levels*) |
339 fun backtrack [] = error"back: no alternatives" |
339 fun backtrack [] = error"back: no alternatives" |
340 | backtrack ((th,thstr) :: pairs) = |
340 | backtrack ((th,thstr) :: pairs) = |
341 (case Sequence.pull thstr of |
341 (case Sequence.pull thstr of |
342 None => (writeln"Going back a level..."; backtrack pairs) |
342 None => (writeln"Going back a level..."; backtrack pairs) |
343 | Some(th2,thstr2) => |
343 | Some(th2,thstr2) => |
344 (if eq_thm(th,th2) |
344 (if eq_thm(th,th2) |
345 then writeln"Warning: same as previous choice at this level" |
345 then writeln"Warning: same as previous choice at this level" |
346 else if eq_thm_sg(th,th2) then () |
346 else if eq_thm_sg(th,th2) then () |
347 else writeln"Warning: signature of proof state has changed"; |
347 else writeln"Warning: signature of proof state has changed"; |
348 (th2,thstr2)::pairs)); |
348 (th2,thstr2)::pairs)); |
349 |
349 |
350 fun back() = setstate (backtrack (getstate())); |
350 fun back() = setstate (backtrack (getstate())); |
351 |
351 |
352 (*Chop back to previous level of the proof*) |
352 (*Chop back to previous level of the proof*) |
353 fun choplev n = make_command (chop_level n); |
353 fun choplev n = make_command (chop_level n); |