335 SELECT_GOAL (DEEPEN (2, the_default 20 opt_lim) (intprover_tac ctxt [] 0) 4 1); |
333 SELECT_GOAL (DEEPEN (2, the_default 20 opt_lim) (intprover_tac ctxt [] 0) 4 1); |
336 |
334 |
337 end; |
335 end; |
338 |
336 |
339 |
337 |
340 (* rule_tac etc. -- refer to dynamic goal state!! *) (* FIXME cleanup!! *) |
|
341 |
|
342 fun bires_inst_tac bires_flag ctxt insts thm = |
|
343 let |
|
344 val thy = ProofContext.theory_of ctxt; |
|
345 (* Separate type and term insts *) |
|
346 fun has_type_var ((x, _), _) = (case Symbol.explode x of |
|
347 "'"::cs => true | cs => false); |
|
348 val Tinsts = List.filter has_type_var insts; |
|
349 val tinsts = filter_out has_type_var insts; |
|
350 (* Tactic *) |
|
351 fun tac i st = |
|
352 let |
|
353 (* Preprocess state: extract environment information: |
|
354 - variables and their types |
|
355 - type variables and their sorts |
|
356 - parameters and their types *) |
|
357 val (types, sorts) = types_sorts st; |
|
358 (* Process type insts: Tinsts_env *) |
|
359 fun absent xi = error |
|
360 ("No such variable in theorem: " ^ Syntax.string_of_vname xi); |
|
361 val (rtypes, rsorts) = types_sorts thm; |
|
362 fun readT (xi, s) = |
|
363 let val S = case rsorts xi of SOME S => S | NONE => absent xi; |
|
364 val T = Sign.read_typ (thy, sorts) s; |
|
365 val U = TVar (xi, S); |
|
366 in if Sign.typ_instance thy (T, U) then (U, T) |
|
367 else error |
|
368 ("Instantiation of " ^ Syntax.string_of_vname xi ^ " fails") |
|
369 end; |
|
370 val Tinsts_env = map readT Tinsts; |
|
371 (* Preprocess rule: extract vars and their types, apply Tinsts *) |
|
372 fun get_typ xi = |
|
373 (case rtypes xi of |
|
374 SOME T => typ_subst_atomic Tinsts_env T |
|
375 | NONE => absent xi); |
|
376 val (xis, ss) = Library.split_list tinsts; |
|
377 val Ts = map get_typ xis; |
|
378 val (_, _, Bi, _) = dest_state(st,i) |
|
379 val params = Logic.strip_params Bi |
|
380 (* params of subgoal i as string typ pairs *) |
|
381 val params = rev(Term.rename_wrt_term Bi params) |
|
382 (* as they are printed: bound variables with *) |
|
383 (* the same name are renamed during printing *) |
|
384 fun types' (a, ~1) = (case AList.lookup (op =) params a of |
|
385 NONE => types (a, ~1) |
|
386 | some => some) |
|
387 | types' xi = types xi; |
|
388 fun internal x = is_some (types' (x, ~1)); |
|
389 val used = Drule.add_used thm (Drule.add_used st []); |
|
390 val (ts, envT) = |
|
391 ProofContext.read_termTs_schematic ctxt internal types' sorts used (ss ~~ Ts); |
|
392 val envT' = map (fn (ixn, T) => |
|
393 (TVar (ixn, the (rsorts ixn)), T)) envT @ Tinsts_env; |
|
394 val cenv = |
|
395 map |
|
396 (fn (xi, t) => |
|
397 pairself (Thm.cterm_of thy) (Var (xi, fastype_of t), t)) |
|
398 (distinct |
|
399 (fn ((x1, t1), (x2, t2)) => x1 = x2 andalso t1 aconv t2) |
|
400 (xis ~~ ts)); |
|
401 (* Lift and instantiate rule *) |
|
402 val {maxidx, ...} = rep_thm st; |
|
403 val paramTs = map #2 params |
|
404 and inc = maxidx+1 |
|
405 fun liftvar (Var ((a,j), T)) = |
|
406 Var((a, j+inc), paramTs ---> Logic.incr_tvar inc T) |
|
407 | liftvar t = raise TERM("Variable expected", [t]); |
|
408 fun liftterm t = list_abs_free |
|
409 (params, Logic.incr_indexes(paramTs,inc) t) |
|
410 fun liftpair (cv,ct) = |
|
411 (cterm_fun liftvar cv, cterm_fun liftterm ct) |
|
412 val lifttvar = pairself (ctyp_of thy o Logic.incr_tvar inc); |
|
413 val rule = Drule.instantiate |
|
414 (map lifttvar envT', map liftpair cenv) |
|
415 (Thm.lift_rule (Thm.cprem_of st i) thm) |
|
416 in |
|
417 if i > nprems_of st then no_tac st |
|
418 else st |> |
|
419 compose_tac (bires_flag, rule, nprems_of thm) i |
|
420 end |
|
421 handle TERM (msg,_) => (warning msg; no_tac st) |
|
422 | THM (msg,_,_) => (warning msg; no_tac st); |
|
423 in tac end; |
|
424 |
|
425 local |
|
426 |
|
427 fun gen_inst _ tac _ (quant, ([], thms)) = |
|
428 METHOD (fn facts => quant (insert_tac facts THEN' tac thms)) |
|
429 | gen_inst inst_tac _ ctxt (quant, (insts, [thm])) = |
|
430 METHOD (fn facts => |
|
431 quant (insert_tac facts THEN' inst_tac ctxt insts thm)) |
|
432 | gen_inst _ _ _ _ = error "Cannot have instantiations with multiple rules"; |
|
433 |
|
434 in |
|
435 |
|
436 val res_inst_meth = gen_inst (bires_inst_tac false) Tactic.resolve_tac; |
|
437 |
|
438 val eres_inst_meth = gen_inst (bires_inst_tac true) Tactic.eresolve_tac; |
|
439 |
|
440 val cut_inst_meth = |
|
441 gen_inst |
|
442 (fn ctxt => fn insts => bires_inst_tac false ctxt insts o Tactic.make_elim_preserve) |
|
443 Tactic.cut_rules_tac; |
|
444 |
|
445 val dres_inst_meth = |
|
446 gen_inst |
|
447 (fn ctxt => fn insts => bires_inst_tac true ctxt insts o Tactic.make_elim_preserve) |
|
448 Tactic.dresolve_tac; |
|
449 |
|
450 val forw_inst_meth = |
|
451 gen_inst |
|
452 (fn ctxt => fn insts => fn rule => |
|
453 bires_inst_tac false ctxt insts (Tactic.make_elim_preserve rule) THEN' |
|
454 assume_tac) |
|
455 Tactic.forward_tac; |
|
456 |
|
457 fun subgoal_tac ctxt sprop = |
|
458 DETERM o bires_inst_tac false ctxt [(("psi", 0), sprop)] cut_rl; |
|
459 |
|
460 fun subgoals_tac ctxt sprops = EVERY' (map (subgoal_tac ctxt) sprops); |
|
461 |
|
462 fun thin_tac ctxt s = |
|
463 bires_inst_tac true ctxt [(("V", 0), s)] thin_rl; |
|
464 |
|
465 end; |
|
466 |
|
467 |
|
468 (* ML tactics *) |
338 (* ML tactics *) |
469 |
339 |
470 val tactic_ref = ref ((fn _ => raise Match): Proof.context -> thm list -> tactic); |
340 val tactic_ref = ref ((fn _ => raise Match): Proof.context -> thm list -> tactic); |
471 fun set_tactic f = tactic_ref := f; |
341 fun set_tactic f = tactic_ref := f; |
472 |
342 |
668 (* tactic syntax *) |
538 (* tactic syntax *) |
669 |
539 |
670 fun nat_thms_args f = uncurry f oo |
540 fun nat_thms_args f = uncurry f oo |
671 (#2 oo syntax (Scan.lift (Scan.optional (Args.parens Args.nat) 0) -- Attrib.thms)); |
541 (#2 oo syntax (Scan.lift (Scan.optional (Args.parens Args.nat) 0) -- Attrib.thms)); |
672 |
542 |
673 val insts = |
|
674 Scan.optional |
|
675 (Args.enum1 "and" (Scan.lift (Args.name -- (Args.$$$ "=" |-- Args.!!! Args.name))) --| |
|
676 Scan.lift (Args.$$$ "in")) [] -- Attrib.thms; |
|
677 |
|
678 fun inst_args f src ctxt = f ctxt (#2 (syntax (Args.goal_spec HEADGOAL -- insts) src ctxt)); |
|
679 |
|
680 val insts_var = |
|
681 Scan.optional |
|
682 (Args.enum1 "and" (Scan.lift (Args.var -- (Args.$$$ "=" |-- Args.!!! Args.name))) --| |
|
683 Scan.lift (Args.$$$ "in")) [] -- Attrib.thms; |
|
684 |
|
685 fun inst_args_var f src ctxt = |
|
686 f ctxt (#2 (syntax (Args.goal_spec HEADGOAL -- insts_var) src ctxt)); |
|
687 |
|
688 fun goal_args' args tac src ctxt = #2 (syntax (Args.goal_spec HEADGOAL -- args >> |
543 fun goal_args' args tac src ctxt = #2 (syntax (Args.goal_spec HEADGOAL -- args >> |
689 (fn (quant, s) => SIMPLE_METHOD' quant (tac s))) src ctxt); |
544 (fn (quant, s) => SIMPLE_METHOD' quant (tac s))) src ctxt); |
690 |
545 |
691 fun goal_args args tac = goal_args' (Scan.lift args) tac; |
546 fun goal_args args tac = goal_args' (Scan.lift args) tac; |
692 |
547 |
693 fun goal_args_ctxt' args tac src ctxt = |
548 fun goal_args_ctxt' args tac src ctxt = |
694 #2 (syntax (Args.goal_spec HEADGOAL -- args >> |
549 #2 (syntax (Args.goal_spec HEADGOAL -- args >> |
695 (fn (quant, s) => SIMPLE_METHOD' quant (tac ctxt s))) src ctxt); |
550 (fn (quant, s) => SIMPLE_METHOD' quant (tac ctxt s))) src ctxt); |
696 |
551 |
697 fun goal_args_ctxt args tac = goal_args_ctxt' (Scan.lift args) tac; |
552 fun goal_args_ctxt args tac = goal_args_ctxt' (Scan.lift args) tac; |
698 |
|
699 |
|
700 (* misc tactic emulations *) |
|
701 |
|
702 val subgoal_meth = goal_args_ctxt (Scan.repeat1 Args.name) subgoals_tac; |
|
703 val thin_meth = goal_args_ctxt Args.name thin_tac; |
|
704 val rename_meth = goal_args (Scan.repeat1 Args.name) Tactic.rename_params_tac; |
|
705 val rotate_meth = goal_args (Scan.optional Args.int 1) Tactic.rotate_tac; |
|
706 |
553 |
707 |
554 |
708 (* theory setup *) |
555 (* theory setup *) |
709 |
556 |
710 val _ = Context.add_setup (add_methods |
557 val _ = Context.add_setup (add_methods |
724 ("drule", nat_thms_args drule, "apply rule in destruct manner (improper)"), |
571 ("drule", nat_thms_args drule, "apply rule in destruct manner (improper)"), |
725 ("frule", nat_thms_args frule, "apply rule in forward manner (improper)"), |
572 ("frule", nat_thms_args frule, "apply rule in forward manner (improper)"), |
726 ("this", no_args this, "apply current facts as rules"), |
573 ("this", no_args this, "apply current facts as rules"), |
727 ("fact", thms_ctxt_args fact, "composition by facts from context"), |
574 ("fact", thms_ctxt_args fact, "composition by facts from context"), |
728 ("assumption", ctxt_args assumption, "proof by assumption, preferring facts"), |
575 ("assumption", ctxt_args assumption, "proof by assumption, preferring facts"), |
729 ("rule_tac", inst_args_var res_inst_meth, "apply rule (dynamic instantiation)"), |
576 ("rename_tac", goal_args (Scan.repeat1 Args.name) Tactic.rename_params_tac, |
730 ("erule_tac", inst_args_var eres_inst_meth, "apply rule in elimination manner (dynamic instantiation)"), |
577 "rename parameters of goal (dynamic instantiation)"), |
731 ("drule_tac", inst_args_var dres_inst_meth, "apply rule in destruct manner (dynamic instantiation)"), |
578 ("rotate_tac", goal_args (Scan.optional Args.int 1) Tactic.rotate_tac, |
732 ("frule_tac", inst_args_var forw_inst_meth, "apply rule in forward manner (dynamic instantiation)"), |
579 "rotate assumptions of goal"), |
733 ("cut_tac", inst_args_var cut_inst_meth, "cut rule (dynamic instantiation)"), |
|
734 ("subgoal_tac", subgoal_meth, "insert subgoal (dynamic instantiation)"), |
|
735 ("thin_tac", thin_meth, "remove premise (dynamic instantiation)"), |
|
736 ("rename_tac", rename_meth, "rename parameters of goal (dynamic instantiation)"), |
|
737 ("rotate_tac", rotate_meth, "rotate assumptions of goal"), |
|
738 ("tactic", simple_args Args.name tactic, "ML tactic as proof method")]); |
580 ("tactic", simple_args Args.name tactic, "ML tactic as proof method")]); |
739 |
581 |
740 |
582 |
741 (*final declarations of this structure!*) |
583 (*final declarations of this structure!*) |
742 val unfold = unfold_meth; |
584 val unfold = unfold_meth; |