Isabelle 伊莎贝尔:使用;导入“;或;导入“tac”;方法

Isabelle 伊莎贝尔:使用;导入“;或;导入“tac”;方法,isabelle,apply-script,Isabelle,Apply Script,假设我有一个关于简单归纳定义集的引理: inductive_set foo :: "'a ⇒ 'a list set" for x :: 'a where "[] ∈ foo x" | "[x] ∈ foo x" lemma "⋀x y. y ∈ foo x ⟹ qux x y ⟹ baz x y" (对我来说,重要的是⋀XY“位保持,因为引理实际上陈述了我的证据的状态在长的应用链的中间。”< /P> 我很难开始证明这个引理。我想按规则进行归纳 第一次尝试 我试着写作 apply (in

假设我有一个关于简单归纳定义集的引理:

inductive_set foo :: "'a ⇒ 'a list set" for x :: 'a where
  "[] ∈ foo x" | "[x] ∈ foo x"

lemma "⋀x y. y ∈ foo x ⟹ qux x y ⟹ baz x y"
(对我来说,重要的是⋀XY“位保持,因为引理实际上陈述了我的证据的状态在长的应用链的中间。”< /P> 我很难开始证明这个引理。我想按规则进行归纳

第一次尝试 我试着写作

apply (induct rule: foo.induct)
但这不起作用:
induct
方法失败。我发现我可以通过显式地修复
x
y
来解决这个问题,然后调用
induct
方法,如下所示:

proof -
  fix x :: 'a
  fix y :: "'a list"
  assume "y ∈ foo x" and "qux x y"
  thus "baz x y"
  apply (induct rule: foo.induct)
oops

但是,由于我实际上在一个应用程序链的中间,所以我宁可不输入一个结构化的证明块。 第二次尝试 我尝试使用

induct\u tac
方法,但不幸的是
induct\u tac
没有以我希望的方式应用
foo.induct
规则。如果我打字

apply (induct_tac rule: foo.induct, assumption)
那么第一个子目标是

⋀x y. y ∈ foo x ⟹ qux x y ⟹ baz x []

这不是我想要的:我想要的是
qux[]
而不是
qux x y
induct
方法正确地实现了这一点,但也存在其他问题,如上文所述。

如果您首先将目标转化为以下形式:

⋀x y. y ∈ foo x ⟹ qux x y ⟶ baz x []
然后
apply(导入规则:foo.induct)
将按照您想要的方式实例化导入规则。(它还将在结果目标中保留对象级别的含义,您需要对其应用
(rule impI)

induct
方法自动执行这些额外步骤来处理含义,这是其主要优势之一

另一方面,
induct\u tac rule:foo.induct
只做
apply(rule foo.induct)
。(通常,
induct\u tac
可以匹配您指定的变量,并根据它们的类型自动选择归纳规则,但您没有利用这些功能。)

我认为你最好的选择是在申请链的末端使用一个证明块。如果您担心所有的
修复
假设
显示
语句过于冗长,那么您可以使用小广告的
案例目标
功能:

apply ...
apply ...
proof -
  case goal1 thus ?case
    apply induct
    ...
qed

如果您首先将目标转化为如下所示:

⋀x y. y ∈ foo x ⟹ qux x y ⟶ baz x []
然后
apply(导入规则:foo.induct)
将按照您想要的方式实例化导入规则。(它还将在结果目标中保留对象级别的含义,您需要对其应用
(rule impI)

induct
方法自动执行这些额外步骤来处理含义,这是其主要优势之一

另一方面,
induct\u tac rule:foo.induct
只做
apply(rule foo.induct)
。(通常,
induct\u tac
可以匹配您指定的变量,并根据它们的类型自动选择归纳规则,但您没有利用这些功能。)

我认为你最好的选择是在申请链的末端使用一个证明块。如果您担心所有的
修复
假设
显示
语句过于冗长,那么您可以使用小广告的
案例目标
功能:

apply ...
apply ...
proof -
  case goal1 thus ?case
    apply induct
    ...
qed