简体   繁体   English

阿格达:偶数乘积是偶数

[英]Agda: Product of even numbers is even

I am pretty new to Agda. 我对Agda很陌生。 I am working on a question from the assignment. 我正在处理作业中的一个问题。 I have got most of it but there is one goal on which i am stuck. 我已经掌握了其中的大部分,但是我坚持了一个目标。

data Arith : Set where
 Num : ℕ → Arith
 Plus : Arith → Arith → Arith
 Times : Arith → Arith → Arith

eval : Arith → ℕ
eval (Num x) = x
eval (Plus e1 e2) = eval e1 + eval e2 
eval (Times e1 e2) = eval e1 * eval e2

data Even : ℕ → Set where
 zEven : Even 0
 ssEven : {n : ℕ} → Even n → Even (suc (suc n))

-- [PROBLEM 1]

plusEven : ∀ n m → Even n → Even m → Even (n + m)
plusEven zero m x x₁ = x₁
plusEven (suc zero) m () x₁
plusEven (suc (suc .0)) m (ssEven zEven) x₁ = ssEven x₁
plusEven (suc (suc ._)) m (ssEven (ssEven x)) x₁ = ssEven (ssEven (plusEven _ m  x  x₁ ))

-- [PROBLEM 2]

timesEven : ∀ n m → Even n → Even m → Even (n * m)
timesEven zero m x x₁ = zEven
timesEven (suc ._) zero (ssEven x) x₁ =  (timesEven _ zero x x₁)
timesEven (suc ._) (suc ._) (ssEven x) (ssEven x₁) = ssEven ((λ h → {!!}) (timesEven _ _ x x₁))

The goal I have to prove is 我要证明的目标是

Goal: Even (.n₁ + suc (suc (.n₁ + .n * suc (suc .n₁))))

I feel that I have to use plusEven some how. 我觉得我必须使用plusEven,甚至有些方法。 But the goal does not look that straightforward. 但是目标看起来并不那么简单。 Have I made the problem difficult for me? 我让这个问题变得困难了吗? or am I on the right track? 还是我在正确的轨道上? Is there an easier way to do this? 有没有更简单的方法可以做到这一点? I don't want the solution to this. 我不想解决这个问题。 But a push in the right direction would be appreciated. 但是朝正确方向的推动将不胜感激。 I have been stuck on this for a while now. 我已经坚持了一段时间了。

If n is even, then n * m is even too, so it's irrelevant whether m is even or not and hence you should just throw away this constraint. 如果n为偶数,则n * m为偶数,因此m是否为偶数无关紧要,因此您应该放弃此约束。 So the actual theorems are (I made n and m implicit, because this is convenient) 所以实际定理是(我把nm隐含了,因为这很方便)

timesEvenLeft  : ∀ {n m} → Even n → Even (n * m)
timesEvenRight : ∀ {n m} → Even m → Even (n * m)

You can prove that n * m ≡ m * n and derive the latter theorem from the former. 您可以证明n * m ≡ m * n并从前者导出后者定理。 Hence it only remains to prove the first one. 因此,仅需证明第一个。 In the recursive case you need to prove Even (suc (suc n) * m) (which reduces to Even (m + (m + n * m) ) having Even (n * m) (the induction hypothesis) in scope. For this you'll need yet another lemma: 在递归的情况下,您需要证明在范围上具有Even (n * m) (归纳假设)的Even (suc (suc n) * m) (减少为Even (m + (m + n * m) ))。这将需要另一个引理:

plusDoubleEven : ∀ {n} m → Even n → Even (m + (m + n))

I really liked the answers posted here and they helped me a lot. 我真的很喜欢这里发布的答案,它们对我有很大帮助。 But I cannot change the question given in the assignment. 但我无法更改作业中给出的问题。 I used the answers posted to come up with a solution to the problem. 我使用发布的答案来解决该问题。 It took me a while and it looks a little messy but it works. 我花了一段时间,看起来有些混乱,但是可以用。 Thought i'd post it here too. 以为我也将其张贴在这里。

timesEven : ∀ n m → Even n → Even m → Even (n * m)
timesEven zero m x x₁ = zEven
timesEven (suc zero) m () x₁
timesEven (suc (suc n)) zero (ssEven x) x₁ = timesEven n zero x x₁
timesEven (suc (suc n)) (suc zero) x ()
timesEven (suc (suc n)) (suc (suc m)) (ssEven x) (ssEven x₁) = ssEven ((λ h → plusEven m (suc (suc (m + n * suc (suc m)))) x₁  (ssEven (plusEven m (n * suc (suc m)) x₁ h))) (timesEven n (suc (suc m)) x (ssEven x₁)))

It's probably not what is expected of you for this homework but a clean way to deal with these lemmas without doing too much work is, as hinted at by @user3237465, to reuse well-known properties of the natural numbers. @ user3237465暗示,一种无需做过多工作即可处理这些引理的干净方法,就是重用自然数的众所周知的属性,这可能不是您对本作业的期望。

One way to get more out of these well-known properties is to introduce an alternative definition of Even which you can prove equivalent to the inductive one: 从这些众所周知的属性中获取更多收益的一种方法是引入Even的替代定义,您可以证明它等同于归纳定义:

data Even : ℕ → Set where
 zEven  : Even 0
 ssEven : {n : ℕ} → Even n → Even (suc (suc n))

record Even′ (n : ℕ) : Set where
  constructor mkEven′
  field factor    : ℕ
        .equality : n ≡ factor * 2
open Even′

Even⇒Even′ : {n : ℕ} → Even n → Even′ n
(...)
Even′⇒Even : {n : ℕ} → Even′ n → Even n
(...)

You can then prove plusEven and timesEven(Right/Left) by using equational reasoning, reusing lemmas from the standard library. 然后,您可以通过使用方程式推理,重用标准库中的引理来证明plusEventimesEven(Right/Left) For instance the proof of plusEven becomes: 例如plusEven的证明变为:

plusEven′ : ∀ n m → Even′ n → Even′ m → Even′ (n + m)
plusEven′ n m (mkEven′ p Hp) (mkEven′ q Hq) = mkEven′ (p + q) eq where

  .eq : n + m ≡ (p + q) * 2
  eq = begin
         n + m          ≡⟨ cong₂ _+_ Hp Hq ⟩
         p * 2 + q * 2  ≡⟨ sym (distribʳ-*-+ 2 p q) ⟩
         (p + q) * 2
       ∎

plusEven : ∀ n m → Even n → Even m → Even (n + m)
plusEven n m en em = Even′⇒Even (plusEven′ n m (Even⇒Even′ en) (Even⇒Even′ em))

Here is a gist with all the right imports and all the proofs. 这是一个具有所有正确输入和所有证明的要点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM