证明添加的交换性,取2

时间:2016-04-21 05:41:51

标签: logic proof isabelle theorem

这个问题是以下问题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。 有谁知道为什么?我觉得我忽略了一些显而易见的事情。

备注:我意识到简化器实际上只在一个方向上应用定义等,但使用启发式方法尝试将等式的两边减少到相同的项

1 个答案:

答案 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