Theory Defer_Slot
theory Defer_Slot
imports Basic_Imports
begin
definition "DEFER_SLOT (x::prop) ≡ x"
lemma DEFER_SLOT_cong[cong]: "PROP DEFER_SLOT x ≡ PROP DEFER_SLOT x" .
abbreviation "EMPTY_DEFER_SLOT ≡ PROP (DEFER_SLOT (Trueprop True))"
lemma insert_slot_rl1:
assumes "PROP P ⟹ PROP EMPTY_DEFER_SLOT ⟹ PROP Q"
shows "PROP (DEFER_SLOT (PROP P)) ⟹ PROP Q"
using assms unfolding DEFER_SLOT_def by simp
lemma insert_slot_rl2:
assumes "PROP P ⟹ PROP (DEFER_SLOT S) ⟹ PROP Q"
shows "PROP (DEFER_SLOT (PROP S &&& PROP P)) ⟹ PROP Q"
using assms unfolding DEFER_SLOT_def conjunction_def .
lemma remove_slot: "PROP (EMPTY_DEFER_SLOT)"
unfolding DEFER_SLOT_def by (rule TrueI)
lemmas split_constraint_rls
= atomize_conj[symmetric] imp_conjunction all_conjunction conjunction_imp
ML ‹
signature DEFER_SLOT = sig
val WITH_SLOT: tactic' -> tactic
val ON_SLOT: tactic -> tactic
val create_slot_tac: tactic
val ensure_slot_tac: tactic
val remove_slot_tac: tactic
val prefer_slot_tac: tactic
val dest_slot_tac: tactic'
val has_slot: thm -> bool
val to_slot_tac: tactic'
val print_slot_tac: Proof.context -> tactic
val focus: tactic
val unfocus: tactic
val unfocus_ins:tactic
val cond_focus: (term -> bool) -> tactic
val some_to_slot_tac: (term -> bool) -> tactic
end
structure Defer_Slot: DEFER_SLOT = struct
fun is_slot_goal @{mpat "DEFER_SLOT _"} = true | is_slot_goal _ = false
fun slot_goal_num st = let
val i = find_index is_slot_goal (Thm.prems_of st) + 1
in
i
end
fun has_slot st = slot_goal_num st > 0
fun WITH_SLOT tac st = let
val si = slot_goal_num st
in
if si>0 then tac si st else (
if Thm.nprems_of st > 0 then warning "No defer slot" else ();
Seq.empty)
end
val to_slot_tac = IF_EXGOAL (fn i => WITH_SLOT (fn si =>
if i<si then
prefer_tac si THEN prefer_tac (i+1)
THEN (
PRIMITIVE (fn st => Drule.comp_no_flatten (st, 0) 1 @{thm insert_slot_rl1})
ORELSE PRIMITIVE (fn st => Drule.comp_no_flatten (st, 0) 1 @{thm insert_slot_rl2})
)
THEN defer_tac 1
else no_tac))
val create_slot_tac =
COND (has_slot) no_tac
(PRIMITIVE (Thm.implies_intr @{cterm "EMPTY_DEFER_SLOT"})
THEN defer_tac 1)
val ensure_slot_tac = TRY create_slot_tac
val prefer_slot_tac = WITH_SLOT prefer_tac
val dest_slot_tac = SELECT_GOAL (
ALLGOALS (
CONVERSION (Conv.rewr_conv @{thm DEFER_SLOT_def})
THEN' Goal.conjunction_tac
THEN' TRY o resolve0_tac @{thms TrueI})
THEN distinct_subgoals_tac
)
val remove_slot_tac = WITH_SLOT (resolve0_tac @{thms remove_slot})
val focus = WITH_SLOT (fn i =>
PRIMITIVE (Goal.restrict i 1)
THEN ALLGOALS dest_slot_tac
THEN create_slot_tac)
val unfocus_ins =
PRIMITIVE (Goal.unrestrict 1)
THEN WITH_SLOT defer_tac
fun some_to_slot_tac cond = (ALLGOALS (COND' (fn t => is_slot_goal t orelse not (cond t)) ORELSE' to_slot_tac))
val unfocus =
some_to_slot_tac (K true)
THEN unfocus_ins
fun cond_focus cond =
focus
THEN some_to_slot_tac (not o cond)
fun ON_SLOT tac = focus THEN tac THEN unfocus
fun print_slot_tac ctxt = ON_SLOT (print_tac ctxt "SLOT:")
end
›
method_setup defer_slot_print = ‹Scan.succeed (fn ctxt => SIMPLE_METHOD (Defer_Slot.print_slot_tac ctxt))›
method_setup defer_slot_ensure = ‹Scan.succeed (fn _ => SIMPLE_METHOD (Defer_Slot.ensure_slot_tac))›
method_setup defer_slot_defer = ‹Scan.succeed (fn _ => SIMPLE_METHOD' (Defer_Slot.to_slot_tac))›
method_setup defer_slot_dest = ‹Scan.succeed (fn _ => SIMPLE_METHOD' Defer_Slot.dest_slot_tac)›
method_setup defer_slot_dest' = ‹Scan.succeed (fn _ => SIMPLE_METHOD (Defer_Slot.prefer_slot_tac THEN FIRSTGOAL (Defer_Slot.dest_slot_tac)))›
end