在Agda中应用规则

时间:2014-02-28 22:50:44

标签: agda

我是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范例的问题。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

当您在纸上进行证明时,应用关联性和然后左侧身份使用身份关系的ony密钥属性 - 传递性。也就是说,当您有p : x ≡ yq : 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应用于xy,并且证明应该仍然有效,即{ {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