2016-09-03 6 views
0

Я пытаюсь реализовать некоторые матричные операции и доказательства вокруг них в Агда. код включать что-то около следующих определений:Закреплено простым доказательством равенства

open import Algebra  
open import Data.Nat hiding (_+_ ; _*_) 
open import Data.Vec 
open import Relation.Binary.PropositionalEquality 

module Teste {l l'}(cr : CommutativeSemiring l l') where 

    open CommutativeSemiring cr hiding (refl) 

    _×_ : ℕ → ℕ → Set l 
    n × m = Vec (Vec Carrier m) n 

    null : {n m : ℕ} → n × m 
    null = replicate (replicate 0#) 

    infixl 7 _∔_ 

    _∔_ : {n m : ℕ} → n × m → n × m → n × m 
    [] ∔ [] = [] 
    (xs ∷ xss) ∔ (ys ∷ yss) = zipWith _+_ xs ys ∷ xss ∔ yss 

я определил тип данных для матриц с использованием векторов и определит null матрицы и матрицу сложения. Мое желание, чтобы доказать, что null является левая идентичность сложения матриц:

null-left-id-∔ : ∀ {n m : ℕ} → (xss : n × m) → (null {n} {m}) ∔ xss ≡ xss 

Я попытался определить его индукцией по индексам матрицы следующим образом:

null-left-id-∔ : ∀ {n m : ℕ} → (xss : n × m) → (null {n} {m}) ∔ xss ≡ xss 
null-left-id-∔ {zero} {zero} [] = refl 
null-left-id-∔ {zero} {suc m} xss = {!!} 
null-left-id-∔ {suc n} {zero} xss = {!!} 
null-left-id-∔ {suc n} {suc m} xss = {!!} 

но, во всех отверстий, функция null не расширяется. Поскольку null определен с использованием replicate, и он использует рекурсию на натуральные числа, я ожидал, что соответствие по матричным индексам приведет к уменьшению на null.

Как раз упомянуть, я также попытался определить такое доказательство индукцией по матричной структуре (путем рекурсии на xss). Опять же, определение null не расширяется в отверстиях.

Я делаю что-то глупое?

EDIT: Я использую Agda 2.5.1.1 и стандартную версию библиотеки 0.12.

ответ

2

Думаю, вы проверяете отверстия с C-c C-, и C-c C-., которые не выполняют полную нормализацию. Вместо этого попробуйте C-u C-u C-c C-, и C-u C-u C-c C-..

Индукция по xss почти работает:

zipWith-+-replicate-0# : ∀ {n} → (xs : Vec Carrier n) → zipWith _+_ (replicate 0#) xs ≡ xs 
zipWith-+-replicate-0# []  = refl 
zipWith-+-replicate-0# (x ∷ xs) = cong₂ _∷_ {!!} (zipWith-+-replicate-0# xs) 

null-left-id-∔ : ∀ {n m} → (xss : n × m) → null ∔ xss ≡ xss 
null-left-id-∔ []  = refl 
null-left-id-∔ (xs ∷ xss) = cong₂ _∷_ (zipWith-+-replicate-0# xs) (null-left-id-∔ xss) 

Но ваше равенство _≈_ - не _≡_, так что вы не можете доказать 0# + x ≡ x. Вы должны использовать равенство из Data.Vec.Equality модуля, но это путь более многословен:

open Equality 
    (record { Carrier = Carrier 
      ; _≈_ = _≈_ 
      ; isEquivalence = isEquivalence 
      }) 
    renaming (_≈_ to _≈ᵥ_) 

zipWith-+-replicate-0# : ∀ {n} → (xs : Vec Carrier n) → zipWith _+_ (replicate 0#) xs ≈ᵥ xs 
zipWith-+-replicate-0# []  = []-cong 
zipWith-+-replicate-0# (x ∷ xs) = IsCommutativeMonoid.identityˡ +-isCommutativeMonoid _ 
          ∷-cong zipWith-+-replicate-0# xs 

private open module Dummy {m} = Equality 
      (record { Carrier = Vec Carrier m 
        ; _≈_ = λ xs ys -> xs ≈ᵥ ys 
        ; isEquivalence = record 
         { refl = refl _ 
         ; sym = Equality.sym _ 
         ; trans = Equality.trans _ 
         } 
        }) 
      renaming (_≈_ to _≈ᵥᵥ_) 

null-left-id-∔ : ∀ {n m} → (xss : n × m) → null ∔ xss ≈ᵥᵥ xss 
null-left-id-∔ []  = Equality.[]-cong 
null-left-id-∔ (xs ∷ xss) = zipWith-+-replicate-0# xs Equality.∷-cong null-left-id-∔ xss 

A full snippet.

+0

Спасибо за ваш ответ! Я всегда был озадачен системой записи/модуля Agda. –