[英]Getting better inference for agda proofs
假設我有以下編譯的 Agda 代碼(其中+-assoc
和+-comm
取自plf課程。在每個步驟中要求顯式子表達式以簡化代碼似乎很費力;但是刪除任何一個顯式表達式導致代碼無法編譯。
編寫證明時如何獲得更好的類型推斷?
+-swap : ∀ (m n p : ℕ) -> m + (n + p) ≡ n + (m + p)
+-swap zero n p = refl
+-swap (suc m) n p =
begin
suc m + (n + p)
≡⟨ +-comm (suc m) (n + p) ⟩
(n + p) + (suc m)
≡⟨ +-assoc n p (suc m) ⟩
n + (p + suc m)
≡⟨ cong (n +_) (+-comm p (suc m)) ⟩
n + (suc m + p)
∎
如果我對您的要求的理解是正確的,您希望能夠省略中間表達式,例如suc m + (n + p)
≡-Reasoning
模塊為用戶提供諸如_∎
, _≡⟨_⟩_
和begin_
等運算符的全部意義在於使這些數量明確化,以便證明更具可讀性,並且可以顯示每個推理步驟和清楚地理解。
這意味着如果您想省略這些數量,則不應使用此庫,而應使用以下方法之一來證明此類等式證明。
出於自我控制的目的,以下是所需的進口:
module EqProofs where
open import Data.Nat
open import Data.Nat.Properties
open import Relation.Binary.PropositionalEquality
open ≡-Reasoning
第一種可能性是使用相等推理模塊,就像您所做的那樣:
+-swap₁ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₁ zero n p = refl
+-swap₁ (suc m) n p = begin
suc m + (n + p) ≡⟨ +-comm (suc m) (n + p) ⟩
(n + p) + (suc m) ≡⟨ +-assoc n p (suc m) ⟩
n + (p + suc m) ≡⟨ cong (n +_) (+-comm p (suc m)) ⟩
n + (suc m + p) ∎
但是您也可以使用等式的傳遞性明確地給出該術語:
+-swap₂ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₂ zero _ _ = refl
+-swap₂ (suc m) n p =
trans
(+-comm (suc m) (n + p))
(trans
(+-assoc n p (suc m))
(cong (n +_) (+-comm p (suc m))))
或者您可以使用rewrite
來簡化使用相等證明的目標:
+-swap₃ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₃ zero _ _ = refl
+-swap₃ (suc m) n p
rewrite +-comm (suc m) (n + p)
| +-assoc n p (suc m)
| cong (n +_) (+-comm p (suc m)) = refl
在最后兩種可能性中,中間數量被隱藏了(並且很容易被 Agda 推斷出來),正如你所希望的那樣。
編輯:
您可以使用下划線省略一些(但不是全部,因為類型檢查器需要信息來解決約束)所需的參數。 這可以在所有情況下完成,除了使用重寫時,如下所示:
+-swap₁ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₁ zero n p = refl
+-swap₁ (suc m) n p = begin
suc m + (n + p) ≡⟨ +-comm _ (n + p) ⟩
(n + p) + (suc m) ≡⟨ +-assoc n p _ ⟩
n + (p + suc m) ≡⟨ cong (n +_) (+-comm p _) ⟩
n + (suc m + p) ∎
+-swap₂ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₂ zero _ _ = refl
+-swap₂ (suc m) n p =
trans
(+-comm _ (n + p))
(trans
(+-assoc n p _)
(cong (n +_) (+-comm p _)))
+-swap₃ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₃ zero _ _ = refl
+-swap₃ (suc m) n p
rewrite +-comm (suc m) (n + p)
| +-assoc n p (suc m)
| cong (n +_) (+-comm p (suc m)) = refl
編輯n°2:
附帶說明一下,您可以證明此屬性,而無需對其 arguments 中的任何一個進行模式匹配。 這是這個證明,使用鏈式相等。 您可以注意到,只有幾個參數必須顯式提供,而其他參數可以用下划線代替:
+-swap₄ : ∀ (m n p : ℕ) → m + (n + p) ≡ n + (m + p)
+-swap₄ m n p = begin
m + (n + p) ≡⟨ +-assoc m _ _ ⟩
(m + n) + p ≡⟨ cong (_+ p) (+-comm m _) ⟩
(n + m) + p ≡⟨ +-assoc n _ _ ⟩
n + (m + p) ∎
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.