在Isabelle,我正在尝试对相互递归的归纳定义进行规则归纳。这是我能够创建的最简单的例子:
theory complex_exprs
imports Main
begin
datatype A = NumA int
| AB B
and B = NumB int
| BA A
inductive eval_a :: "A ⇒ int ⇒ bool" and eval_b :: "B ⇒ int ⇒ bool" where
eval_num_a: "eval_a (NumA i) i" |
eval_a_b: "eval_b b i ⟹ eval_a (AB b) i" |
eval_num_b: "eval_b (NumB i) i" |
eval_b_a: "eval_a a i ⟹ eval_b (BA a) i"
lemma foo:
assumes "eval_a a result"
shows "True"
using assms
proof (induction a)
case (NumA x)
show ?case by auto
case (AB x)
此时,Isabelle以“非法原理图变量”停止,以防“AB”。实际上,目前的目标是⋀x. ?P2.2 x ⟹ eval_a (AB x) result ⟹ True
,其中包含假设?P2.2 x
。这是Isabelle所说的'原理图变量'吗?它来自哪里,我怎么能摆脱它?
如果我尝试对规则进行归纳,我会遇到同样的问题:
proof (induction)
case (eval_num_a i)
show ?case by auto
case (eval_a_b b i)
同样,目标是⋀b i. eval_b b i ⟹ ?P2.0 b i ⟹ True
,其中包含未知?P2.0 b i
,我无法继续。
作为相关问题:我尝试使用
进行归纳proof (induction rule: eval_a_eval_b.induct)
但是Isabelle不接受这一点,说“未能应用初始证明方法”。
如何让这种感应通过? (在我的实际应用中,我确实需要归纳,因为目标比True
更复杂。)
答案 0 :(得分:3)
关于相互递归定义的证明,无论是数据类型,函数还是归纳谓词,都必须相互递归。但是,在您的引理中,您只说出eval_a
的归纳属性,而不是eval_b
的归纳属性。在AB
的情况下,你显然想要使用eval_b
的归纳假设,但由于引理没有说明eval_b
的归纳属性,因此Isabelle不知道它是什么。因此它将其作为原理图变量?P2.0
。
所以,你必须陈述两个目标,比如说
lemma
shows "eval_a a result ==> True"
and "eval_b b result ==> True"
然后,方法induction a b
将确定第一个语句对应A
,第二个语句对应B
。
归纳谓词的归纳规则失败,因为此规则消除了归纳谓词(仅对数据类型的归纳"消除"类型信息,但这不是HOL公式)并且它无法找到第二个归纳谓词。
有关相互递归对象的归纳的更多示例可以在src/HOL/Induct/Common_Patterns.thy
中找到。