在 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
的函数 f
? with
和 inspect
也可能有一些复杂的方法来做到这一点,但我不太明白。
要在同一个文件中工作,您的问题是:
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
进口:
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
的函数 f
? with
和 inspect
也可能有一些复杂的方法来做到这一点,但我不太明白。
要在同一个文件中工作,您的问题是:
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