95 in |
95 in |
96 |
96 |
97 (*Discover what goal is chosen: SOMEGOAL(trace_goalno_tac tac) *) |
97 (*Discover what goal is chosen: SOMEGOAL(trace_goalno_tac tac) *) |
98 fun trace_goalno_tac tf i = Tactic (fn state => |
98 fun trace_goalno_tac tf i = Tactic (fn state => |
99 case Sequence.pull(tapply(tf i, state)) of |
99 case Sequence.pull(tapply(tf i, state)) of |
100 None => Sequence.null |
100 None => Sequence.null |
101 | seqcell => (prs("Subgoal " ^ string_of_int i ^ " selected\n"); |
101 | seqcell => (prs("Subgoal " ^ string_of_int i ^ " selected\n"); |
102 Sequence.seqof(fn()=> seqcell))); |
102 Sequence.seqof(fn()=> seqcell))); |
103 |
103 |
104 fun string_of (a,0) = a |
104 fun string_of (a,0) = a |
105 | string_of (a,i) = a ^ "_" ^ string_of_int i; |
105 | string_of (a,i) = a ^ "_" ^ string_of_int i; |
106 |
106 |
107 (*convert all Vars in a theorem to Frees*) |
107 (*convert all Vars in a theorem to Frees*) |
108 fun freeze th = |
108 fun freeze th = |
109 let val fth = freezeT th |
109 let val fth = freezeT th |
110 val {prop,sign,...} = rep_thm fth |
110 val {prop,sign,...} = rep_thm fth |
111 fun mk_inst (Var(v,T)) = |
111 fun mk_inst (Var(v,T)) = |
112 (cterm_of sign (Var(v,T)), |
112 (cterm_of sign (Var(v,T)), |
113 cterm_of sign (Free(string_of v, T))) |
113 cterm_of sign (Free(string_of v, T))) |
114 val insts = map mk_inst (term_vars prop) |
114 val insts = map mk_inst (term_vars prop) |
115 in instantiate ([],insts) fth end; |
115 in instantiate ([],insts) fth end; |
116 |
116 |
117 (*Makes a rule by applying a tactic to an existing rule*) |
117 (*Makes a rule by applying a tactic to an existing rule*) |
118 fun rule_by_tactic (Tactic tf) rl = |
118 fun rule_by_tactic (Tactic tf) rl = |
119 case Sequence.pull(tf (freeze (standard rl))) of |
119 case Sequence.pull(tf (freeze (standard rl))) of |
120 None => raise THM("rule_by_tactic", 0, [rl]) |
120 None => raise THM("rule_by_tactic", 0, [rl]) |
121 | Some(rl',_) => standard rl'; |
121 | Some(rl',_) => standard rl'; |
122 |
122 |
123 (*** Basic tactics ***) |
123 (*** Basic tactics ***) |
124 |
124 |
125 (*Makes a tactic whose effect on a state is given by thmfun: thm->thm seq.*) |
125 (*Makes a tactic whose effect on a state is given by thmfun: thm->thm seq.*) |
126 fun PRIMSEQ thmfun = Tactic (fn state => thmfun state |
126 fun PRIMSEQ thmfun = Tactic (fn state => thmfun state |
127 handle THM _ => Sequence.null); |
127 handle THM _ => Sequence.null); |
128 |
128 |
129 (*Makes a tactic whose effect on a state is given by thmfun: thm->thm.*) |
129 (*Makes a tactic whose effect on a state is given by thmfun: thm->thm.*) |
130 fun PRIMITIVE thmfun = PRIMSEQ (Sequence.single o thmfun); |
130 fun PRIMITIVE thmfun = PRIMSEQ (Sequence.single o thmfun); |
131 |
131 |
132 (*** The following fail if the goal number is out of range: |
132 (*** The following fail if the goal number is out of range: |
162 |
162 |
163 (*Like forward_tac, but deletes the assumption after use.*) |
163 (*Like forward_tac, but deletes the assumption after use.*) |
164 fun dresolve_tac rls = eresolve_tac (map make_elim rls); |
164 fun dresolve_tac rls = eresolve_tac (map make_elim rls); |
165 |
165 |
166 (*Shorthand versions: for resolution with a single theorem*) |
166 (*Shorthand versions: for resolution with a single theorem*) |
167 fun rtac rl = resolve_tac [rl]; |
167 fun rtac rl = rtac rl ; |
168 fun etac rl = eresolve_tac [rl]; |
168 fun etac rl = etac rl ; |
169 fun dtac rl = dresolve_tac [rl]; |
169 fun dtac rl = dtac rl ; |
170 val atac = assume_tac; |
170 val atac = assume_tac; |
171 |
171 |
172 (*Use an assumption or some rules ... A popular combination!*) |
172 (*Use an assumption or some rules ... A popular combination!*) |
173 fun ares_tac rules = assume_tac ORELSE' resolve_tac rules; |
173 fun ares_tac rules = assume_tac ORELSE' resolve_tac rules; |
174 |
174 |
183 |
183 |
184 (*Lift and instantiate a rule wrt the given state and subgoal number *) |
184 (*Lift and instantiate a rule wrt the given state and subgoal number *) |
185 fun lift_inst_rule (state, i, sinsts, rule) = |
185 fun lift_inst_rule (state, i, sinsts, rule) = |
186 let val {maxidx,sign,...} = rep_thm state |
186 let val {maxidx,sign,...} = rep_thm state |
187 val (_, _, Bi, _) = dest_state(state,i) |
187 val (_, _, Bi, _) = dest_state(state,i) |
188 val params = Logic.strip_params Bi (*params of subgoal i*) |
188 val params = Logic.strip_params Bi (*params of subgoal i*) |
189 val params = rev(rename_wrt_term Bi params) (*as they are printed*) |
189 val params = rev(rename_wrt_term Bi params) (*as they are printed*) |
190 val paramTs = map #2 params |
190 val paramTs = map #2 params |
191 and inc = maxidx+1 |
191 and inc = maxidx+1 |
192 fun liftvar (Var ((a,j), T)) = Var((a, j+inc), paramTs---> incr_tvar inc T) |
192 fun liftvar (Var ((a,j), T)) = Var((a, j+inc), paramTs---> incr_tvar inc T) |
193 | liftvar t = raise TERM("Variable expected", [t]); |
193 | liftvar t = raise TERM("Variable expected", [t]); |
194 fun liftterm t = list_abs_free (params, |
194 fun liftterm t = list_abs_free (params, |
195 Logic.incr_indexes(paramTs,inc) t) |
195 Logic.incr_indexes(paramTs,inc) t) |
196 (*Lifts instantiation pair over params*) |
196 (*Lifts instantiation pair over params*) |
197 fun liftpair (cv,ct) = (cterm_fun liftvar cv, cterm_fun liftterm ct) |
197 fun liftpair (cv,ct) = (cterm_fun liftvar cv, cterm_fun liftterm ct) |
198 fun lifttvar((a,i),ctyp) = |
198 fun lifttvar((a,i),ctyp) = |
199 let val {T,sign} = rep_ctyp ctyp |
199 let val {T,sign} = rep_ctyp ctyp |
200 in ((a,i+inc), ctyp_of sign (incr_tvar inc T)) end |
200 in ((a,i+inc), ctyp_of sign (incr_tvar inc T)) end |
201 val rts = types_sorts rule and (types,sorts) = types_sorts state |
201 val rts = types_sorts rule and (types,sorts) = types_sorts state |
202 fun types'(a,~1) = (case assoc(params,a) of None => types(a,~1) | sm => sm) |
202 fun types'(a,~1) = (case assoc(params,a) of None => types(a,~1) | sm => sm) |
203 | types'(ixn) = types ixn; |
203 | types'(ixn) = types ixn; |
204 val used = add_term_tvarnames |
204 val used = add_term_tvarnames |
205 (#prop(rep_thm state) $ #prop(rep_thm rule),[]) |
205 (#prop(rep_thm state) $ #prop(rep_thm rule),[]) |
213 subgoal. Fails if "i" is out of range. ***) |
213 subgoal. Fails if "i" is out of range. ***) |
214 |
214 |
215 (*compose version: arguments are as for bicompose.*) |
215 (*compose version: arguments are as for bicompose.*) |
216 fun compose_inst_tac sinsts (bires_flg, rule, nsubgoal) i = |
216 fun compose_inst_tac sinsts (bires_flg, rule, nsubgoal) i = |
217 STATE ( fn state => |
217 STATE ( fn state => |
218 compose_tac (bires_flg, lift_inst_rule (state, i, sinsts, rule), |
218 compose_tac (bires_flg, lift_inst_rule (state, i, sinsts, rule), |
219 nsubgoal) i |
219 nsubgoal) i |
220 handle TERM (msg,_) => (writeln msg; no_tac) |
220 handle TERM (msg,_) => (writeln msg; no_tac) |
221 | THM (msg,_,_) => (writeln msg; no_tac) ); |
221 | THM (msg,_,_) => (writeln msg; no_tac) ); |
222 |
222 |
223 (*"Resolve" version. Note: res_inst_tac cannot behave sensibly if the |
223 (*"Resolve" version. Note: res_inst_tac cannot behave sensibly if the |
224 terms that are substituted contain (term or type) unknowns from the |
224 terms that are substituted contain (term or type) unknowns from the |
225 goal, because it is unable to instantiate goal unknowns at the same time. |
225 goal, because it is unable to instantiate goal unknowns at the same time. |
226 |
226 |
240 increment revcut_rl instead.*) |
240 increment revcut_rl instead.*) |
241 fun make_elim_preserve rl = |
241 fun make_elim_preserve rl = |
242 let val {maxidx,...} = rep_thm rl |
242 let val {maxidx,...} = rep_thm rl |
243 fun cvar ixn = cterm_of Sign.proto_pure (Var(ixn,propT)); |
243 fun cvar ixn = cterm_of Sign.proto_pure (Var(ixn,propT)); |
244 val revcut_rl' = |
244 val revcut_rl' = |
245 instantiate ([], [(cvar("V",0), cvar("V",maxidx+1)), |
245 instantiate ([], [(cvar("V",0), cvar("V",maxidx+1)), |
246 (cvar("W",0), cvar("W",maxidx+1))]) revcut_rl |
246 (cvar("W",0), cvar("W",maxidx+1))]) revcut_rl |
247 val arg = (false, rl, nprems_of rl) |
247 val arg = (false, rl, nprems_of rl) |
248 val [th] = Sequence.list_of_s (bicompose false arg 1 revcut_rl') |
248 val [th] = Sequence.list_of_s (bicompose false arg 1 revcut_rl') |
249 in th end |
249 in th end |
250 handle Bind => raise THM("make_elim_preserve", 1, [rl]); |
250 handle Bind => raise THM("make_elim_preserve", 1, [rl]); |
251 |
251 |
260 |
260 |
261 (*** Applications of cut_rl ***) |
261 (*** Applications of cut_rl ***) |
262 |
262 |
263 (*Used by metacut_tac*) |
263 (*Used by metacut_tac*) |
264 fun bires_cut_tac arg i = |
264 fun bires_cut_tac arg i = |
265 resolve_tac [cut_rl] i THEN biresolve_tac arg (i+1) ; |
265 rtac cut_rl i THEN biresolve_tac arg (i+1) ; |
266 |
266 |
267 (*The conclusion of the rule gets assumed in subgoal i, |
267 (*The conclusion of the rule gets assumed in subgoal i, |
268 while subgoal i+1,... are the premises of the rule.*) |
268 while subgoal i+1,... are the premises of the rule.*) |
269 fun metacut_tac rule = bires_cut_tac [(false,rule)]; |
269 fun metacut_tac rule = bires_cut_tac [(false,rule)]; |
270 |
270 |
271 (*Recognizes theorems that are not rules, but simple propositions*) |
271 (*Recognizes theorems that are not rules, but simple propositions*) |
272 fun is_fact rl = |
272 fun is_fact rl = |
273 case prems_of rl of |
273 case prems_of rl of |
274 [] => true | _::_ => false; |
274 [] => true | _::_ => false; |
275 |
275 |
276 (*"Cut" all facts from theorem list into the goal as assumptions. *) |
276 (*"Cut" all facts from theorem list into the goal as assumptions. *) |
277 fun cut_facts_tac ths i = |
277 fun cut_facts_tac ths i = |
278 EVERY (map (fn th => metacut_tac th i) (filter is_fact ths)); |
278 EVERY (map (fn th => metacut_tac th i) (filter is_fact ths)); |
279 |
279 |
285 |
285 |
286 |
286 |
287 (**** Indexing and filtering of theorems ****) |
287 (**** Indexing and filtering of theorems ****) |
288 |
288 |
289 (*Returns the list of potentially resolvable theorems for the goal "prem", |
289 (*Returns the list of potentially resolvable theorems for the goal "prem", |
290 using the predicate could(subgoal,concl). |
290 using the predicate could(subgoal,concl). |
291 Resulting list is no longer than "limit"*) |
291 Resulting list is no longer than "limit"*) |
292 fun filter_thms could (limit, prem, ths) = |
292 fun filter_thms could (limit, prem, ths) = |
293 let val pb = Logic.strip_assums_concl prem; (*delete assumptions*) |
293 let val pb = Logic.strip_assums_concl prem; (*delete assumptions*) |
294 fun filtr (limit, []) = [] |
294 fun filtr (limit, []) = [] |
295 | filtr (limit, th::ths) = |
295 | filtr (limit, th::ths) = |
296 if limit=0 then [] |
296 if limit=0 then [] |
297 else if could(pb, concl_of th) then th :: filtr(limit-1, ths) |
297 else if could(pb, concl_of th) then th :: filtr(limit-1, ths) |
298 else filtr(limit,ths) |
298 else filtr(limit,ths) |
299 in filtr(limit,ths) end; |
299 in filtr(limit,ths) end; |
300 |
300 |
301 |
301 |
302 (*** biresolution and resolution using nets ***) |
302 (*** biresolution and resolution using nets ***) |
303 |
303 |
318 val orderlist = untaglist o sort (fn(x,y)=> #1 x < #1 y); |
318 val orderlist = untaglist o sort (fn(x,y)=> #1 x < #1 y); |
319 |
319 |
320 (*insert one tagged brl into the pair of nets*) |
320 (*insert one tagged brl into the pair of nets*) |
321 fun insert_tagged_brl (kbrl as (k,(eres,th)), (inet,enet)) = |
321 fun insert_tagged_brl (kbrl as (k,(eres,th)), (inet,enet)) = |
322 if eres then |
322 if eres then |
323 case prems_of th of |
323 case prems_of th of |
324 prem::_ => (inet, Net.insert_term ((prem,kbrl), enet, K false)) |
324 prem::_ => (inet, Net.insert_term ((prem,kbrl), enet, K false)) |
325 | [] => error"insert_tagged_brl: elimination rule with no premises" |
325 | [] => error"insert_tagged_brl: elimination rule with no premises" |
326 else (Net.insert_term ((concl_of th, kbrl), inet, K false), enet); |
326 else (Net.insert_term ((concl_of th, kbrl), inet, K false), enet); |
327 |
327 |
328 (*build a pair of nets for biresolution*) |
328 (*build a pair of nets for biresolution*) |
329 fun build_netpair netpair brls = |
329 fun build_netpair netpair brls = |
330 foldr insert_tagged_brl (taglist 1 brls, netpair); |
330 foldr insert_tagged_brl (taglist 1 brls, netpair); |
412 fun rewrite_tac defs = PRIMITIVE(rewrite_rule defs); |
412 fun rewrite_tac defs = PRIMITIVE(rewrite_rule defs); |
413 |
413 |
414 (*Rewrite subgoals only, not main goal. *) |
414 (*Rewrite subgoals only, not main goal. *) |
415 fun rewrite_goals_tac defs = PRIMITIVE (rewrite_goals_rule defs); |
415 fun rewrite_goals_tac defs = PRIMITIVE (rewrite_goals_rule defs); |
416 |
416 |
417 fun rewtac def = rewrite_goals_tac [def]; |
417 fun rewtac def = rewtac def; |
418 |
418 |
419 |
419 |
420 (*** Tactic for folding definitions, handling critical pairs ***) |
420 (*** Tactic for folding definitions, handling critical pairs ***) |
421 |
421 |
422 (*The depth of nesting in a term*) |
422 (*The depth of nesting in a term*) |
449 fun rename_tac str i = |
449 fun rename_tac str i = |
450 let val cs = explode str |
450 let val cs = explode str |
451 in |
451 in |
452 if !Logic.auto_rename |
452 if !Logic.auto_rename |
453 then (writeln"Note: setting Logic.auto_rename := false"; |
453 then (writeln"Note: setting Logic.auto_rename := false"; |
454 Logic.auto_rename := false) |
454 Logic.auto_rename := false) |
455 else (); |
455 else (); |
456 case #2 (take_prefix (is_letdig orf is_blank) cs) of |
456 case #2 (take_prefix (is_letdig orf is_blank) cs) of |
457 [] => PRIMITIVE (rename_params_rule (scanwords is_letdig cs, i)) |
457 [] => PRIMITIVE (rename_params_rule (scanwords is_letdig cs, i)) |
458 | c::_ => error ("Illegal character: " ^ c) |
458 | c::_ => error ("Illegal character: " ^ c) |
459 end; |
459 end; |