Context free grammar 用CFG实例调试Agda中的约束满足错误

Context free grammar 用CFG实例调试Agda中的约束满足错误,context-free-grammar,agda,Context Free Grammar,Agda,我试图实现Sipser计算理论中的第一个例子,得到一个无法辨认的黄色突出显示。在Agda中如何调试这些约束错误,在我的示例中如何调试?有没有什么成功的方法可以在第一时间避免它们SipserExample1会产生这种混乱: _r2_61 : rule Sipser1 [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,18-23 ] _r3_62 : rule

我试图实现Sipser计算理论中的第一个例子,得到一个无法辨认的黄色突出显示。在Agda中如何调试这些约束错误,在我的示例中如何调试?有没有什么成功的方法可以在第一时间避免它们<下面的代码>SipserExample1会产生这种混乱:

_r2_61 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,18-23 ]
_r3_62 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,18-23 ]
_r2_66 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,28-33 ]
_r3_67 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,28-33 ]

———— Errors ————————————————————————————————————————————————
Failed to solve the following constraints:
  _r2_66 ++ inj₁ A0 ∷ _r3_67 = inj₁ A0 ∷ []
    : List (CFG.V Sipser1 ⊎ CFG.Σ' Sipser1)
    (blocked on _r2_66)
  _r2_66 ++ (inj₁ B0 ∷ []) ++ _r3_67 = _r2_61 ++ inj₁ A0 ∷ _r3_62
    : List (CFG.V Sipser1 ⊎ CFG.Σ' Sipser1)
    (blocked on any(_r2_61, _r3_62, _r2_66, _r3_67))
  _r2_61 ++ (inj₁ B0 ∷ []) ++ _r3_62
    = inj₂ a0 ∷ map inj₂ (a0 ∷ a# ∷ a1 ∷ a1 ∷ [])
    : List (CFG.V Sipser1 ⊎ CFG.Σ' Sipser1)
    (blocked on _r2_61)
下面是生成黄色的代码。CFG是一个简单的记录,我定义了终端和非终端列表上的manystep缩减关系<代码>生成只允许用户证明给定CFG允许一个终端列表

module toy where

open import Data.List 
open import Data.Sum using (_⊎_ ; inj₁; inj₂)
open import Data.Product using (_×_; _,_)
open import Data.Unit
open import Data.Empty

binRel : Set → Set → Set₁
binRel A B = A → B → Set

record CFG : Set₁ where
  field
    V : Set -- non-terminal, or variable
    Σ' : Set -- terminals
    R : binRel V (List (V ⊎ Σ'))-- rules
    S : V -- start symbol

module ManyStep where
  open CFG

  rule : CFG → Set
  rule cfg = List (V cfg ⊎ Σ' cfg)

  data ↦* (cfg : CFG) : rule cfg → rule cfg → Set where
    refl : {r : (rule cfg)} → ↦* cfg r r --∀ {σ : Σ' cfg} → {!!}
    trans : {r1 r2 r3 : (rule cfg)} {v : V cfg} {X : (rule cfg)} → R cfg v X
            → ↦* cfg r1 (r2 ++ (inj₁ v) ∷ r3)
            → ↦* cfg r1 (r2 ++ X ++ r3)

  derives : (cfg : CFG) → rule cfg → Set
  derives cfg x = ↦* cfg (inj₁ (S cfg) ∷ []) x

  generates : (cfg : CFG) → List (Σ' cfg) → Set
  generates cfg xs = derives cfg (map inj₂ xs)

open ManyStep public

data V0 : Set where
  A0 : V0
  B0 : V0

data Σ0 : Set where
  a0 : Σ0
  a1 : Σ0
  a# : Σ0

data _⟶_ : V0 → List (V0 ⊎ Σ0) → Set where
  r0 : A0 ⟶ (inj₂ a0 ∷ inj₁ A0 ∷ inj₂ a1 ∷ [])
  r1 : A0 ⟶ (inj₁ B0 ∷ [])
  r2 : B0 ⟶ (inj₂ a# ∷ [])

Sipser1 : CFG
Sipser1 = record { V = V0 ; Σ' = Σ0 ; R = _⟶_ ; S = A0 }

SipserExample1 : generates Sipser1 (a0 ∷ a0 ∷ a# ∷ a1 ∷ a1 ∷ [])
SipserExample1 = trans r1 (trans r1 (refl {Sipser1} {inj₁ A0 ∷ []}))
-----编辑-----

根据@Jesper的一些见解,正确的解决方案实际上是:

SipserExample1 : generates Sipser1 (a0 ∷ a0 ∷ a# ∷ a1 ∷ a1 ∷ [])
SipserExample1 = trans {r2 = inj₂ a0 ∷ inj₂ a0 ∷ []} {r3 = inj₂ a1 ∷ inj₂ a1 ∷ []} r2
                 (trans {r2 = inj₂ a0 ∷ inj₂ a0 ∷ []} {r3 = inj₂ a1 ∷ inj₂ a1 ∷ []} r1
                 (trans {r2 = inj₂ a0 ∷ []} {r3 = inj₂ a1 ∷ []} r0

                 (trans {r2 = []} {r3 = []} r0 refl)))

我解决这类问题的策略是,首先忽略未解决的约束,而尝试帮助Agda填充未解决的元变量,在您的案例中,是以下部分:

_r2_61 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,18-23 ]
_r3_62 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,18-23 ]
_r2_66 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,28-33 ]
_r3_67 : rule Sipser1  [ at /home/wmacmil/agdaFall2019/constructiveTypeTheoriesNLSem/TT_course/agda_files/toy.agda:60,28-33 ]
这些元变量的名称及其位置为您提供了一个很好的线索:它们是对
SipserExample1
主体中的
trans
函数的第一次和第二次调用的第二个和第三个隐式参数。下一步是使这些隐式参数显式化:在调用trans后写入
{r2=?}{r3=?}
,重新加载文件,并尝试填充这些孔,直到约束消失或得到正确的错误消息


PS:通常人们更喜欢用等式推理的方式来写这类证明(参见例),这会迫使你在这种情况下解释出隐含的论点。

谢谢。在上面的正确解决方案中,我发现在编写解决方案时,所需的
{r2=?}{r3=?}
元变量可以通过
解决,除了空列表
(trans'{r2=[]}{r3=[]}r0 refl'))
需要人工实例化的情况。为什么打字员不能推断出这种情况?此外,为什么一旦提供了值,即使可以推断,仍然需要提供
r2
r3
值?有没有办法简化过程,使证明看起来更清晰,更容易编写一些等式推理语法糖的模块?Agda无法推断最后调用
trans
r2
r3
的原因是,它不是一个中性术语:它可以简化为
r0
。Agda typechecker(以及通常的双向typechecker)不能很好地推断没有注释的非中性术语的类型。我没有一个很好的方法来简化这个过程,我通常会添加很多隐式参数,直到所有问题都解决了,然后再看看哪些参数可以被删除,而不是破坏它。