这个问题是关于
我的问题的完整代码可以找到here。我将列出我的代码并最终得出问题。我的项目涉及到Data.AVL中的事物,所以我从一些样板开始:
open import Data.Product
open import Level
open import Relation.Binary
open import Relation.Binary.PropositionalEquality as P using (_≡_)
module Data.AVL.Properties-Refuse
{k v ℓ}
{Key : Set k} (Value : Key → Set v)
{_<_ : Rel Key ℓ}
(isStrictTotalOrder : IsStrictTotalOrder P._≡_ _<_) where
open import Data.AVL Value isStrictTotalOrder using (KV; module Extended-key; module Height-invariants; module Indexed)
import Data.AVL Value isStrictTotalOrder as AVL
open Extended-key
open Height-invariants
open Indexed
open IsStrictTotalOrder isStrictTotalOrder
然后我借用an idea from Vitus代表会员资格:
data _∈_ {lb ub} (K : Key) : ∀ {n} → Tree lb ub n → Set (k ⊔ v ⊔ ℓ) where
here : ∀ {hˡ hʳ} V
{l : Tree lb [ K ] hˡ}
{r : Tree [ K ] ub hʳ}
{b : ∃ λ h → hˡ ∼ hʳ ⊔ h} →
K ∈ node (K , V) l r (proj₂ b)
left : ∀ {hˡ hʳ K′} {V : Value K′}
{l : Tree lb [ K′ ] hˡ}
{r : Tree [ K′ ] ub hʳ}
{b : ∃ λ h → hˡ ∼ hʳ ⊔ h} →
K < K′ →
K ∈ l →
K ∈ node (K′ , V) l r (proj₂ b)
right : ∀ {hˡ hʳ K′} {V : Value K′}
{l : Tree lb [ K′ ] hˡ}
{r : Tree [ K′ ] ub hʳ}
{b : ∃ λ h → hˡ ∼ hʳ ⊔ h} →
K′ < K →
K ∈ r →
K ∈ node (K′ , V) l r (proj₂ b)
然后我声明一个函数(其含义无关紧要 - 这是一个更有意义的函数的人为和简单版本,未在此处显示):
refuse1 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse1 = {!!}
到目前为止,这么好。现在,我将案例拆分为默认变量:
refuse2 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse2 t k₁ k∈t = {!!}
现在我分成t
:
refuse3 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse3 (leaf l<u) k₁ k∈t = {!!}
refuse3 (node k₁ t t₁ bal) k₂ k∈t = {!!}
现在bal
:
refuse4 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse4 (leaf l<u) k₁ k∈t = {!!}
refuse4 (node k₁ t t₁ ∼+) k₂ k∈t = {!!}
refuse4 (node k₁ t t₁ ∼0) k₂ k∈t = {!!}
refuse4 (node k₁ t t₁ ∼-) k₂ k∈t = {!!}
第一个错误出现在我尝试对包括k∈t
的等式的(node ... ∼+)
进行分组时:
refuse5 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse5 (leaf l<u) k₁ k∈t = {!!}
refuse5 (node k₁ t t₁ ∼+) k₂ k∈t = {!k∈t!}
{- ERROR
I'm not sure if there should be a case for the constructor here,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
{_} ≟ {_}
node (k₅ , V) l r (proj₂ b) ≟ node k₄
t₂ t₃ ∼+
when checking that the expression ? has type Set
-}
refuse5 (node k₁ t t₁ ∼0) k₂ k∈t = {!!}
refuse5 (node k₁ t t₁ ∼-) k₂ k∈t = {!!}
Agda告诉我它在统一时遇到困难,但我不清楚为什么或如何提供帮助。在a response to a similar question中,Ulf建议在另一个变量上首先进行案例分割。所以,现在正在手工工作,我专注于从∼+
分割refuse5
行的案例,并包含许多隐含变量:
open import Data.Nat.Base as ℕ
refuse6 : ∀ {kₗ kᵤ h}
( t : Tree kₗ kᵤ h )
( k : Key )
( k∈t : k ∈ t ) →
Set
refuse6 {h = ℕ.suc .hˡ}
(node (k , V) lk ku (∼+ {n = hˡ}))
.k
(here {hˡ = .hˡ} {hʳ = ℕ.suc .hˡ} .V {l = .lk} {r = .ku} {b = (ℕ.suc .hˡ , ∼+ {n = .hˡ})}) = {!!}
{- ERROR
Refuse to solve heterogeneous constraint proj₂ b :
n ∼ hʳ ⊔ proj₁ b =?=
∼+ : n ∼ ℕ.suc n ⊔ ℕ.suc n
when checking that the pattern
here {hˡ = .hˡ} {hʳ = ℕ.suc .hˡ} .V {l = .lk} {r = .ku}
{b = ℕ.suc .hˡ , ∼+ {n = .hˡ}}
has type
k₂ ∈ node (k₁ , V) lk ku ∼+
-}
refuse6 _ _ _ = ?
糟糕。现在阿格达抱怨说它完全没法解决问题。这里发生了什么?是否可以指定方程的lhs,其中至少与refuse5 中的详细信息一样详细,并且k∈t
上的案例分割?如果是这样,怎么样?
答案 0 :(得分:4)
正如评论和Agda mailing list中所述,解决方案是将∃
替换为∀
:
data _∈_ {lb ub} (K : Key) : ∀ {n} → Tree lb ub n → Set (k ⊔ v ⊔ ℓ) where
here : ∀ {hˡ hʳ h} V
{l : Tree lb [ K ] hˡ}
{r : Tree [ K ] ub hʳ}
{b : hˡ ∼ hʳ ⊔ h} →
K ∈ node (K , V) l r b
...
但你也可以写
data _∈_ {lb ub} (K : Key) : ∀ {n} → Tree lb ub n → Set (k ⊔ v ⊔ ℓ) where
here : ∀ {hˡ hʳ} V
{l : Tree lb [ K ] hˡ}
{r : Tree [ K ] ub hʳ}
{b : ∃ λ h → hˡ ∼ hʳ ⊔ h} {h' b'} →
h' ≡ proj₁ b →
b' ≅ proj₂ b →
K ∈ node {h = h'} (K , V) l r b'
...
这是通常的技术,以击败绿色粘液,这是问题的原因,我想。我们需要b' ≅ proj₂ b
中的异构平等,因为否则Agda会推断,h
是proj₁ b
,而proj₁
会让Agda感到不快。
“绿色粘液”的存在 - 返回类型中定义的函数 建设者 - 是一个危险的信号。
至少有两种技术可以击败绿泥,但对于这种情况来说它们太复杂了。您可以找到一些讨论here。我不知道使用记录预测而不仅仅是函数应该有助于统一(可能是的,因为如果我们在您的情况下有proj₁ p == x
和proj₂ p == y
,那么p == x , y
就在那里没有歧义),但一般情况下,统一必须坚持,并且它不是缺陷。有关解释,请参阅this。