我试图在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))
答案 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)是偶数?