证明n次偶数会在Agda中产生偶数

时间:2017-10-10 18:27:49

标签: proof agda

我试图在Agda中将1..n∈ℕ的和定义为n *(n + 1)/ 2 并需要证明n *(n + 1)是偶然的。 证明非常简单,但似乎有一个我不理解的概念,因为我是Agda的新手(虽然既不是数学也不是haskell)并且是从http://www.cse.chalmers.se/~ulfn/papers/afp08/tutorial.pdf学到的。 (更多高级教程的指示超过欢迎!)。

open import Data.Nat
open import Relation.Binary.PropositionalEquality
open import Data.Sum

-- A natural number is even, if there is a k ∈ ℕ with k * 2 = n.
data IsEven : ℕ → Set where
  even : (k : ℕ) → IsEven (k * 2)

-- A product is even, if one of the factors is even.
even-product : {n m : ℕ} → IsEven n ⊎ IsEven m → IsEven (m * n)
even-product {n} {m} (inj₁ (even k)) = even (m * k)
even-product {n} {m} (inj₂ (even k)) = even (n * k)

代码返回

m != 2 of type ℕ
when checking that the expression even (k * m) has type
IsEven (k * 2 * m)

我已经尝试使用模式来说服编译器k * 2实际上是n,但无济于事。将m * k切换为k * m给出

k * m != m of type ℕ
when checking that the expression even (k * m) has type
IsEven (m * (k * 2))

2 个答案:

答案 0 :(得分:3)

你可以通过{!找出问题所在。您尝试的解决方案周围的标记,并使用C-c C-.快捷方式。

even-product : {n m : ℕ} → IsEven n ⊎ IsEven m → IsEven (m * n)
even-product {n} {m} (inj₁ (even k)) = {!even (m * k)!}
even-product {n} {m} (inj₂ (even k)) = {!even (n * k)!}

重新加载文件,然后用光标在第一个孔中按C-c C-.,会得到以下响应:

Goal: IsEven (m * (k * 2))
Have: IsEven (m * k * 2)
————————————————————————————————————————————————————————————
n : ℕ
m : ℕ
k : ℕ

现在问题很明显:目标是证明(m * (k * 2))是偶数,但你有(m * k * 2)是偶数的证明。

要解决此问题,您必须使用*关联的事实。我将通过示例在这里假设它,但显然你想在以后给它一个实际的证明。

postulate
  *-assoc : (k l m : ℕ) → k * (l * m) ≡ (k * l) * m

现在我们可以使用rewrite关键字和*-assoc来修复第一种情况:

even-product : {n m : ℕ} → IsEven n ⊎ IsEven m → IsEven (m * n)
even-product {n} {m} (inj₁ (even k)) rewrite *-assoc m k 2 = even (m * k)
even-product {n} {m} (inj₂ (even k)) = {!even (n * k)!}

在第二种情况下,C-c C-.给出以下回复:

Goal: IsEven (k * 2 * n)
Have: IsEven (n * k * 2)
————————————————————————————————————————————————————————————
m : ℕ
n : ℕ
k : ℕ

所以现在你需要使用*的交换性以及关联性。我会将完整的解决方案作为练习留给读者。

答案 1 :(得分:2)

证明2 *和(1..n)= n *(n + 1)是不是更容易?这表明n *(n + 1)是偶数?