在Agda中定义依赖对的可判定等式

时间:2018-02-20 23:28:36

标签: equality agda dependent-type existential-type

我正在尝试在sigma类型上定义可判定的相等性,但是尽管我的目标与我在洞中的目标相匹配,但仍然会卡住。

module SigmaEqual where

open import Function using (id)
open import Data.Nat using (ℕ) renaming (_≟_ to _≟ℕ_)
open import Data.Product using (Σ; _,_; proj₁; proj₂)
open import Relation.Nullary using (yes; no)
open import Relation.Binary using (Decidable)
open import Relation.Binary.PropositionalEquality using (_≡_; cong; refl)

data B : ℕ → Set where
  bcons : (n : ℕ) → B n

Tuple = Σ ℕ B

_≟B_ : ∀ {n} → Decidable {A = B n} _≡_
bcons n ≟B bcons .n = yes refl

_≟_ : Decidable {A = Tuple} _≡_
(n₁ , b₁) ≟ (n₂ , b₂) with n₁ ≟ℕ n₂
(n₁ , b₁) ≟ (n₂ , b₂) | no ¬p = no λ q → ¬p (cong proj₁ q)
(n₁ , b₁) ≟ (.n₁ , b₂) | yes refl with b₁ ≟B b₂
(n₁ , b₁) ≟ (.n₁ , .b₁) | yes refl | yes refl = yes refl
(n₁ , b₁) ≟ (.n₁ , b₂) | yes refl | no ¬p = no λ q → ¬p (lemm {n₁} {b₁} {b₂} q)
  where
  lemm : {a : ℕ}{b₁ b₂ : B n₁} → (a , b₁) ≡ (a , b₂) → b₁ ≡ b₂
  lemm refl = refl

当我检查洞中的上下文时,我有以下内容:

Goal: (n₁ , b₁) ≡ (n₁ , b₂)
Have: (n₁ , b₁) ≡ (n₁ , b₂)
————————————————————————————————————————————————————————————
q  : (n₁ , b₁) ≡ (n₁ , b₂)
¬p : b₁ ≡ b₂ → .Data.Empty.⊥
...

所以我想我应该能够优化它并将q置于其位置,但它不起作用,如果我放q,我会收到以下错误。

x != n₁ of type ℕ when checking that the expression q has type (n₁ , b₁) ≡ (n₁ , b₂)

由于我不知道问题所在的x来自何处,因此尤其令人费解。

2 个答案:

答案 0 :(得分:2)

您可以通过在文件顶部添加以下行来弄清楚发生了什么:

{-# OPTIONS --show-implicit #-}
open import Agda.Primitive

然后你可以看到出了什么问题:

Goal: _≡_ {lzero} {Σ {lzero} {lzero} ℕ (λ v → B n₁)} (n₁ , b₁)
      (n₁ , b₂)
Have: _≡_ {lzero} {Σ {lzero} {lzero} ℕ B} (n₁ , b₁) (n₁ , b₂)

你可以在目标中看到你有一个非依赖的西格玛类型,但你的引理有一个依赖的!所以你只需要在你的引理中将B对n 1的依赖关系改为a

lemm : {a : ℕ}{b₁ b₂ : B a} → _≡_ {A = Tuple} (a , b₁) (a , b₂) → b₁ ≡ b₂
lemm refl = refl

通过对lemma类型的这一小改动,您的证明被接受了!

答案 1 :(得分:1)

在这种情况下(通常情况下,当目标和已经明显匹配但Agda给予悲伤时)问题是由于隐式变量不匹配。如果您打开show-implicit(通过C-c C-x C-h{-# OPTIONS --show-implicit #-}),然后比较GoalHave,您就可以发现差异,从而让自己感到不安。 (弄清楚为什么存在这样的差异是一个单独的问题。)