当你在纸上做证明时,应用关联性和,然后左边的身份使用ony关键性质的关系 - 传递性。也就是说,当您有一个p : x ≡ y
和q : y ≡ z
的证明时,您可以将它们合并为一个trans p q : x ≡ z
的单个证明。该trans
功能已经是标准库(Relation.Binary.PropositionalEquality
模块)的一部分,但它的实现是相当简单的,反正:
trans : {A : Set} {i j k : A} → i ≡ j → j ≡ k → i ≡ k
trans refl eq = eq
我正在使用幺和团体的有点不同表现,但你可以轻松适应证明到你的场景。
open import Function
open import Relation.Binary.PropositionalEquality
Op₁ : Set → Set
Op₁ A = A → A
Op₂ : Set → Set
Op₂ A = A → A → A
record IsMonoid {A : Set}
(_∙_ : Op₂ A) (ε : A) : Set where
field
right-id : ∀ x → x ∙ ε ≡ x
left-id : ∀ x → ε ∙ x ≡ x
assoc : ∀ x y z → x ∙ (y ∙ z) ≡ (x ∙ y) ∙ z
record IsGroup {A : Set}
(_∙_ : Op₂ A) (ε : A) (_⁻¹ : Op₁ A) : Set where
field
monoid : IsMonoid _∙_ ε
right-inv : ∀ x → x ∙ x ⁻¹ ≡ ε
left-inv : ∀ x → x ⁻¹ ∙ x ≡ ε
open IsMonoid monoid public
(为简便起见,缩进代码写为IsGroup
记录的一部分)。我们想证明:
lemma : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma x y = ?
的第一步是使用相关性,即assoc (x ⁻¹) x y
,这给我们留下了一个目标(x ⁻¹ ∙ x) ∙ y ≡ y
- 一旦我们证明,我们可以合并这两个部分共同使用trans
:
lemma x y =
trans (assoc (x ⁻¹) x y) ?
现在,我们需要应用正确的反转属性,但类型似乎不适合。我们有left-inv x : x ⁻¹ ∙ x ≡ ε
,我们需要以某种方式处理额外的y
。这是身份的另一个属性起作用的时候。
普通函数保存身份;如果我们有功能f
和证明p : x ≡ y
我们可以将f
应用于x
和y
并且证明应该仍然有效,即cong f p : f x ≡ f y
。再次,实施已经在标准库中,但在这里它是反正:
cong : {A : Set} {B : Set}
(f : A → B) {x y} → x ≡ y → f x ≡ f y
cong f refl = refl
我们应该使用什么函数?好的候选人似乎是λ z → z ∙ y
,它增加了缺失的y
部分。因此,我们有:
cong (λ z → z ∙ y) (left-inv x) : (x ⁻¹ ∙ x) ∙ y ≡ ε ∙ y
再次,我们只需要证明ε ∙ y ≡ y
,然后我们可以使用trans
拼凑那些在一起。但是这最后一个属性很简单,只是left-id y
。全部放在一起,我们得到:
lemma : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma x y =
trans (assoc (x ⁻¹) x y) $
trans (cong (λ z → z ∙ y) (left-inv x)) $
(left-id y)
标准库还为我们提供了一些不错的语法糖这样的:
open ≡-Reasoning
lemma′ : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma′ x y = begin
x ⁻¹ ∙ (x ∙ y) ≡⟨ assoc (x ⁻¹) x y ⟩
(x ⁻¹ ∙ x) ∙ y ≡⟨ cong (λ z → z ∙ y) (left-inv x) ⟩
ε ∙ y ≡⟨ left-id y ⟩
y ∎
在幕后,≡⟨ ⟩
使用精确trans
合并这些证据。这些类型是可选的(证明本身带有足够的关于它们的信息),但它们在这里是为了可读性。
为了让您的原始Group
记录,我们可以这样做:
record Group : Set₁ where
field
Carrier : Set
_∙_ : Op₂ Carrier
ε : Carrier
_⁻¹ : Op₁ Carrier
isGroup : IsGroup _∙_ ε _⁻¹
open IsGroup isGroup public
谢谢你这么多的详细解答..我很欣赏你的努力 – ymmagdi
还有一点,什么是$是你已经添加到'引理'功能? – ymmagdi
@ymmagdi:只是一个有助于减少参数数量的运算符,'f $ x'只是'f x',所以你可以写'f $ g x'而不是'f(g x)'。 – Vitus