这个问题是以下问题isabelle proving commutativity for add的后续问题,我的后续工作时间太长,无法发表评论。所述问题是显示add函数的可交换性,定义如下:
fun add :: "nat ⇒ nat ⇒ nat" where
"add 0 n = n" |
"add (Suc m) n = Suc(add m n)"
尝试
theorem "add m n = add n m"
apply(induct_tac m)
apply(auto)
由于缺少引理而陷入困境(在归纳案例上)。我对这个问题感到好奇,并正在探索替代(尽管效率较低)的方法来证明这一点。假设我们定义了引理
lemma Lemma1 [simp]: "add n (Suc 0) = Suc n
伊莎贝尔可以通过归纳自动证明 然后归纳步骤是证明
Suc (add k m) = add m (Suc k)
我们可以手动完成如下
Suc (add k m)
= Suc (add m k) by the IH
= add (add m k) (Suc 0) by Lemma1 <--
= add m (add k (Suc 0)) by associativity (already proved)
= add m (Suc k) by the Lemma1 -->
然而,Isabelle无法证明这一点,并且似乎简化器停留在第二行。但是,使用更明显的
lemma Lemma2 [simp]: "add m (Suc n) = Suc (add m n)"
代替Lemma1,证明成功。它似乎能够在两个方向上使用Lemma2,但不能使用上面定义的Lemma1。 有谁知道为什么?我觉得我忽略了一些显而易见的事情。
备注:我意识到简化器实际上只在一个方向上应用定义等,但使用启发式方法尝试将等式的两边减少到相同的项
答案 0 :(得分:1)
Lemma2未在两个方向上使用,您可以在尝试使用subst
步骤手动执行校样时看到:
theorem commutativity2:
"add n m = add m n"
apply (induct n)
apply (subst Lemma0)
apply (subst add.simps(1))
apply (rule refl)
(* ⋀n. add n m = add m n ⟹ add (Suc n) m = add m (Suc n) *)
apply (subst add.simps(2))
(* ⋀n. add n m = add m n ⟹ Suc (add n m) = add m (Suc n) *)
apply (erule ssubst)
(* ⋀n. Suc (add m n) = add m (Suc n) *)
apply (subst Lemma2)
(* ⋀n. Suc (add m n) = Suc (add m n) *)
apply (rule refl)
done
它只是在目标方程的右侧工作,但仍然从左到右使用Lemma1。
如果您想在手动证明中进行证明,您也可以在Isabelle中轻松完成:
theorem commutativity:
"add m n = add n m"
proof (induct m)
show "add 0 n = add n 0" using Lemma0 by simp
next case (Suc k)
have "add (Suc k) n
= Suc (add k n)" by simp
also have "... = Suc (add n k)" using Suc.hyps by simp
also have "... = add (add n k) (Suc 0)" using Lemma1 by simp
also have "... = add n (add k (Suc 0))" using associativity by simp
also have "... = add n (Suc k)" using Lemma1 by simp
finally show ?case .
qed
编辑:
手动证明,说明为什么这不适用于Lemma1:在第一次重写时,必须从右到左使用引理1(使用[symmetric]
)。
theorem commutativity3:
"add n m = add m n"
apply (induct n)
apply (subst Lemma0)
apply (subst add.simps(1))
apply (rule refl)
(* ⋀n. add n m = add m n ⟹ add (Suc n) m = add m (Suc n) *)
apply (subst Lemma1[symmetric]) back
(* ⋀n. add n m = add m n ⟹ add (Suc n) m = add m (add n (Suc 0)) *)
apply (subst associativity)
(* ⋀n. add n m = add m n ⟹ add (Suc n) m = add (add m n) (Suc 0) *)
apply (subst Lemma1)
(* ⋀n. add n m = add m n ⟹ add (Suc n) m = Suc (add m n) *)
apply (erule subst)
(* ⋀n. add (Suc n) m = Suc (add n m) *)
apply (subst add.simps(2))
(* ⋀n. Suc (add n m) = Suc (add n m) *)
apply (rule refl)
done