簡體   English   中英

阿格達:偶數乘積是偶數

[英]Agda: Product of even numbers is even

我對Agda很陌生。 我正在處理作業中的一個問題。 我已經掌握了其中的大部分,但是我堅持了一個目標。

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₁))

我要證明的目標是

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

我覺得我必須使用plusEven,甚至有些方法。 但是目標看起來並不那么簡單。 我讓這個問題變得困難了嗎? 還是我在正確的軌道上? 有沒有更簡單的方法可以做到這一點? 我不想解決這個問題。 但是朝正確方向的推動將不勝感激。 我已經堅持了一段時間了。

如果n為偶數,則n * m為偶數,因此m是否為偶數無關緊要,因此您應該放棄此約束。 所以實際定理是(我把nm隱含了,因為這很方便)

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

您可以證明n * m ≡ m * n並從前者導出后者定理。 因此,僅需證明第一個。 在遞歸的情況下,您需要證明在范圍上具有Even (n * m) (歸納假設)的Even (suc (suc n) * m) (減少為Even (m + (m + n * m) ))。這將需要另一個引理:

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

我真的很喜歡這里發布的答案,它們對我有很大幫助。 但我無法更改作業中給出的問題。 我使用發布的答案來解決該問題。 我花了一段時間,看起來有些混亂,但是可以用。 以為我也將其張貼在這里。

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₁)))

@ user3237465暗示,一種無需做過多工作即可處理這些引理的干凈方法,就是重用自然數的眾所周知的屬性,這可能不是您對本作業的期望。

從這些眾所周知的屬性中獲取更多收益的一種方法是引入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
(...)

然后,您可以通過使用方程式推理,重用標准庫中的引理來證明plusEventimesEven(Right/Left) 例如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))

這是一個具有所有正確輸入和所有證明的要點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM