在 Agda 中,如何证明 with-abstractions 中匹配模式的属性?

In Agda, how to prove properties about matched patterns in with-abstractions?

进口:

open import Data.Nat using (ℕ; zero; suc)
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_)
open import Data.List using (List; _∷_; [])

示例 1:

postulate
    a : ℕ
    p : a ≡ zero

b : ℕ
b with a
... | zero = zero
... | _ = suc zero

q : b ≡ zero
q = ?

这是一个最小的工作示例。如果要证明q,我应该怎么填坑呢?

我不知道的部分是如何在 q 的证明中推理 b 中发生的模式匹配。我不知道有什么语法允许我这样做(我对 Agda 不是很熟悉)。

示例 2(稍微复杂一点):

postulate
    a : List ℕ
    p : a ≡ zero ∷ []

b : List ℕ
b with a
... | zero ∷ ns = ns
... | _ = []

q : b ≡ []
q = ?

再说一次,如果我要证明q,我应该怎么填坑呢?

示例1和示例2的区别:在示例1中我们只关心“进入with-abstraction中的哪个分支”,而在示例2中我们还关心“结果ns的值是多少”来自模式匹配”。不过,我不确定这是否是相关差异。

如果你定义这样的隐式函数,你会让你的生活变得一团糟。为什么不让 b 成为 a 的实际函数呢?另外,不完整案例的推理也更难。但这是您第一个难题的解决方案:

b : ℕ
b with a
... | zero = zero
... | suc _ = suc zero  -- first change

q : b ≡ zero
q = Eq.trans (Eq.sym (f≡b a Eq.refl)) (r a p)
  where
    f : ℕ → ℕ
    f zero = zero
    f (suc _) = suc zero
    r : (x : ℕ) → x ≡ zero → f x ≡ zero
    r .zero Eq.refl = Eq.refl
    f≡b : ∀ x → x ≡ a → f x ≡ b
    f≡b .a Eq.refl with a
    ... | zero = Eq.refl
    ... | suc x = Eq.refl

请注意,我的回答本质上是如何强制生成一个等同于 b 的函数 fwithinspect 也可能有一些复杂的方法来做到这一点,但我不太明白。

要在同一个文件中工作,您的问题是:

postulate
    a′ : List ℕ
    p′ : a′ ≡ zero ∷ []

c : List ℕ
c with a′
... | zero ∷ ns = ns
... | suc _ ∷ _ = []
... | [] = []

qq : c ≡ []
qq = {!!}

这根本不值得。相反,比较一下这有多容易:

cc : List ℕ → List ℕ
cc [] = []
cc (zero ∷ ns) = ns
cc ((suc _) ∷ _) = []

qqq : (x : List ℕ) → x ≡ zero ∷ [] → cc x ≡ []
qqq .(zero ∷ []) Eq.refl = Eq.refl