lh-l4v/lib/Repeat_Attribute.thy

79 lines
2.0 KiB
Plaintext

(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*)
theory Repeat_Attribute
imports Main
begin
ML \<open>
local
val attribute_generic = Context.cases Attrib.attribute_global Attrib.attribute
fun apply_attributes attrs thm ctxt =
let
val (thm', ctxt') = fold (uncurry o Thm.apply_attribute) attrs (thm, ctxt)
in if Thm.eq_thm (thm, thm')
then (SOME ctxt', SOME thm)
else
apply_attributes attrs thm' ctxt'
handle e =>
(if Exn.is_interrupt e then Exn.reraise e else ();
(SOME ctxt', SOME thm'))
end
fun repeat_attribute_cmd attr_srcs (ctxt, thm) =
let val attrs = map (attribute_generic ctxt) attr_srcs
in apply_attributes attrs thm ctxt end
in
val _ = Theory.setup
(Attrib.setup @{binding REPEAT}
(Attrib.attribs >> repeat_attribute_cmd)
"higher order attribute combinator to repeatedly apply other attributes one or more times")
end
\<close>
text \<open>
The @{attribute REPEAT} attribute is an attribute combinator that repeatedly applies
other attributes one or more times. It will stop applying the attributes once they can
either no longer be applied, or if applying them would not change the theorem being
modified.
Usage:
thm foo[REPEAT [<attributes>]]
\<close>
section \<open>Examples\<close>
experiment begin
lemma test1: "True \<Longrightarrow> True" .
lemma test2: "True \<Longrightarrow> True \<Longrightarrow> True" .
lemmas tests = test1 test2
text \<open>
`tests[OF TrueI]` would only discharge one of the assumptions of @{thm test2}, but
@{attribute REPEAT} handles both cases.
\<close>
thm tests[REPEAT [OF TrueI]]
text \<open>
@{attribute REPEAT} succesfully terminates when applying an attribute that could loop,
such as @{attribute simplified} and @{attribute simp}. Importantly, it still updates
the context if necessary, in this case by adding P to the simp set.
\<close>
lemma
assumes P[REPEAT [simplified], REPEAT [simp]]: "P \<or> False"
shows P
by simp
end
end