一个粘滞的拒绝

时间:2015-08-15 03:08:14

标签: agda

这个问题是关于

  • 如何在解决统一问题时帮助Agda解决问题,
  • 如何说服Agda解决“异构约束”(无论这意味着什么)

我的问题的完整代码可以找到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上的案例分割?如果是这样,怎么样?

1 个答案:

答案 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会推断,hproj₁ b,而proj₁会让Agda感到不快。

  

“绿色粘液”的存在 - 返回类型中定义的函数   建设者 - 是一个危险的信号。

至少有两种技术可以击败绿泥,但对于这种情况来说它们太复杂了。您可以找到一些讨论here。我不知道使用记录预测而不仅仅是函数应该有助于统一(可能是的,因为如果我们在您的情况下有proj₁ p == xproj₂ p == y,那么p == x , y就在那里没有歧义),但一般情况下,统一必须坚持,并且它不是缺陷。有关解释,请参阅this