嵌套的依赖模式匹配会产生错误

时间:2014-06-18 21:21:17

标签: pattern-matching agda

首先是一些导入和定义:

open import Relation.Binary.HeterogeneousEquality
open import Relation.Binary.PropositionalEquality
open import Data.Nat
open import Algebra
open import Data.Nat.Properties
module ℕCS = CommutativeSemiring commutativeSemiring

data Bin : ℕ → Set where
  zero  : Bin zero
  2*n   : ∀ {n} → Bin n → Bin (n + n)
  2*n+1 : ∀ {n} → Bin n → Bin (suc (n + n))

inc : ∀ {n} → Bin n → Bin (suc n)
inc zero = 2*n+1 zero
inc (2*n b) = 2*n+1 b
inc (2*n+1 {n} b) with n + suc n | ℕCS.+-comm n (suc n) | 2*n (inc b)
... | ._ | refl | b' = b'

nat2bin : (n : ℕ) → Bin n
nat2bin zero = zero
nat2bin (suc n) = inc (nat2bin n)

现在我想证明这个问题:

lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem zero = refl
lem (suc n) = {!!}

以下代码会产生错误:

lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem zero = refl
lem (suc n)
    with suc (n + suc (suc n)) | ℕCS.+-comm (suc n) (suc (suc n))
... | ._ | refl = ?

这是:

suc (n + suc (suc n)) != w of type ℕ
when checking that the type
(n w : ℕ) (w₁ : w ≡ suc (suc (n + suc n))) →
2*n+1 (inc (inc (nat2bin n))) ≅
inc
(inc (2*n+1 (inc (nat2bin n))) | w | w₁
 | 2*n (inc (inc (nat2bin n))))
of the generated with function is well-formed

虽然这段代码完美地检查了:

postulate Foo : ℕ -> Set

foo : (m n : ℕ) -> Foo (m + n) -> Foo (n + m)
foo m n x with n + m | ℕCS.+-comm n m
... | ._ | refl = x

bar : (m n : ℕ) (x : Foo (m + n)) -> foo m n x ≅ x
bar m n x with n + m | ℕCS.+-comm n m
... | ._ | refl = refl

这也没有进行类型检查:

qux : (n m : ℕ) -> (x : Foo (n + m)) -> foo m n (foo n m x) ≅ x
qux n m x with n + m | ℕCS.+-comm n m
... | ._ | refl = ?

错误:

n + m != w of type ℕ
when checking that the type
(n m w : ℕ) (w₁ : w ≡ m + n) (x : Foo w) →
(foo m n (foo n m x | w | w₁) | m + n
 | .Data.Nat.Properties.Simple.+-comm m n)
≅ x
of the generated with function is well-formed

出了什么问题?

1 个答案:

答案 0 :(得分:1)

这不是你特定问题的答案,但是:你的定义看起来很复杂。他们并非真的需要参与其中。

inc : ∀ {n} → Bin n → Bin (suc n)
inc zero = 2*n+1 zero
inc (2*n b) = 2*n+1 b
inc (2*n+1 {n} b) rewrite ℕCS.+-comm (suc n) n = 2*n (inc b)

lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem n rewrite ℕCS.+-comm (suc n) n = refl