我是Agda的新手,我认为在这个范例中我仍然有一个问题需要考虑。这是我的问题.. 我有一个类型monoid和一个类型组实现如下:
record Monoid : Set₁ where
constructor monoid
field Carrier : Set
_⊙_ : Carrier → Carrier → Carrier
e : Carrier
leftId : ∀ {x : Carrier} → (e ⊙ x) ≡ x
rightId : ∀ {x : Carrier} → (x ⊙ e) ≡ x
assoc : ∀ {x y z : Carrier} → (x ⊙ (y ⊙ z)) ≡ ((x ⊙ y) ⊙ z)
record Group : Set₁ where
constructor group
field m : Monoid
inv : Carrier → Carrier
inverse1 : {x y : Carrier} → x ⊙ (inv x) ≡ e
inverse2 : {x y : Carrier} → (inv x) ⊙ x ≡ e
现在,我想证明以下问题:
lemma1 : (x y : Carrier) → (inv x) ⊙ (x ⊙ y) ≡ y
lemma1 x y = ?
如果我在纸上做,我将应用关联性然后留下身份..但我不知道如何告诉agda应用这些规则..我有将我的想法转化为Agda范例的问题。
非常感谢任何帮助。
答案 0 :(得分:4)
当您在纸上进行证明时,应用关联性和然后左侧身份使用身份关系的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
,并且证明应该仍然有效,即{ {1}}。同样,实现已经在标准库中了,但无论如何它仍然存在:
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