简体   繁体   中英

Agda: Product of even numbers is even

I am pretty new to 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. 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. So the actual theorems are (I made n and m implicit, because this is convenient)

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. 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:

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.

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:

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. For instance the proof of plusEven becomes:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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