さまざまな可能性があると思いますが、それはアプリケーションのコンテキストによって最適なものが少し異なります。一般に、自動化された証明のための個々の ML コードは、非常に古い時代には一般的でしたが、今日では比較的まれであることに注意してください。たとえば、かなり小規模なHOL-Bali (1997 年に開始) のカスタム戦術の量と、AFP の大規模なJinjaThreads (2007 年に開始し、最近まで継続) を比較してください。
ML 反引用符を入れ子@{tactic}
にすることは、原則として機能しますが、定理の引数が再び Isar または ML ソースである必要がある場合はどうなるかなど、さらなる疑問にすぐに遭遇します。
ML で戦術構築ブロックをアンチクォートする代わりに、より基本的なアプローチは、次のような通常のメソッド構文を与えることで、Isar で証明手順を引用することです。
ML {*
(*foo_tac -- the payload of what you want to do,
note the dependency on ctxt: Proof.context*)
fun foo_tac ctxt =
let
val my_ctxt =
ctxt |> Simplifier.map_simpset
(fold Splitter.add_split @{thms prod.splits} #>
Simplifier.add_simp @{thm split_def})
in ALLGOALS (clarsimp_tac my_ctxt) end
*}
method_setup foo = {*
(*concrete syntax like "clarsimp", "auto" etc.*)
Method.sections Clasimp.clasimp_modifiers >>
(*Isar method boilerplate*)
(fn _ => fn ctxt => SIMPLE_METHOD (CHANGED (foo_tac ctxt)))
*}
ここでは、最初foo_tac
に Isabelle/ML で従来の定義を作成し、それを証明方法として通常の Isar の方法でラップしました。後者はSIMPLE_METHOD
、「チェインされた事実」を目標状態にプッシュCHANGED
し、Isar メソッドが確実に進行するようにするようなラッパーがあることを意味します (simp
またはのようにauto
)。
このfoo_tac
例では、コンテキスト (またはその simpset) の変更が固定の分割ルールによって一定であると想定しています。そこにさらにパラメーターが必要な場合は、具体的なメソッド構文に含めることができます。Method.sections
この点に関しては、すでに非常に洗練されていることに注意してください。より基本的な引数パーサーは、 isar-refマニュアルの「証明方法の定義」セクションに記載されています。method_setup
また、 (Isabelle/IsarMethod.setup
で) または (Isabelle/ML で)のソースを検索して、既存の例を調べる必要があります。
具体的なメソッド構文の代わりに ML の反引用符を使用したい場合は、次の@{context}
ような修飾子を許可するバリアントを試すことができます。
@{context simp add: ...}
これは少し推測的で、その場で発明されたものであり、悪い習慣になる可能性があります。前述したように、ML は Isabelle フレームワークの不可欠な部分ですが、Isabelle でのきめ細かい戦術プログラミングは近年少し使われなくなりました。より多くのアプリケーション コンテキストを使用してより具体的な質問を提示する場合は、反引用のアプローチを再検討できます。