簡體   English   中英

為 agda 證明獲得更好的推理

[英]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.

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