Agda:类型为isn';t在'with'块中简化

Agda:类型为isn';t在'with'块中简化,agda,Agda,我试图解决教程第23页上的奖励练习,但我无法填补这个漏洞: lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool) -> All (satisfies p) (filter p xs) lem-all-filter [] p = all[] lem-all-filter (x :: xs) p with p x ... | true = {! !} :all: lem-all-filter xs p .

我试图解决教程第23页上的奖励练习,但我无法填补这个漏洞:

lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool)
              -> All (satisfies p) (filter p xs)
lem-all-filter [] p = all[]
lem-all-filter (x :: xs) p with p x
... | true = {! !} :all: lem-all-filter xs p
... | false = lem-all-filter xs p
如果我在孔中键入C-C-,则会得到以下消息:

Goal: isTrue (p x)
--------------------------------
xs : List .A
p  : .A -> Bool
x  : .A
.A : Set

但我希望目标类型为True,因为
px
True
isTrue-True=True
。我遗漏了什么吗?

当你在
px
上进行模式匹配时,
px
在上下文中的任何地方都会被重写到模式中,但重写时上下文中没有这个漏洞:它出现得晚,因此其类型中的
px
不会被重写。您可以记住,使用本文后面介绍的inspect惯用语(现在已弃用,赞成使用),p x等于
true
,但您也可以执行以下操作:

lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool)
              -> All (satisfies p) (filter p xs)
lem-all-filter [] p = all[]
lem-all-filter (x :: xs) p with p x | λ (y : isTrue (p x)) -> y :all: lem-all-filter xs p
... | true  | onTrue = onTrue _
... | false | onTrue = lem-all-filter xs p

在这里,您在上下文中将参数的类型显式地引入到
:all:
,因此当
px
被重写为
true
时,
onTrue
的类型将根据需要减少到
true->all(满足p)(x::filterpxs)

当您在
px
上进行模式匹配时,
px
被重写到上下文中任何地方的模式,但重写时上下文中没有该漏洞:它出现得晚,因此其类型中的
px
不会被重写。您可以记住,使用本文后面介绍的inspect惯用语(现在已弃用,赞成使用),p x等于
true
,但您也可以执行以下操作:

lem-all-filter : {A : Set}(xs : List A)(p : A -> Bool)
              -> All (satisfies p) (filter p xs)
lem-all-filter [] p = all[]
lem-all-filter (x :: xs) p with p x | λ (y : isTrue (p x)) -> y :all: lem-all-filter xs p
... | true  | onTrue = onTrue _
... | false | onTrue = lem-all-filter xs p

在这里,您在上下文中将参数的类型显式地引入到
:all:
,因此当
px
被重写为
true
时,
onTrue
的类型会根据需要减少为
true->all(满足p)(x::filter pxs)

太棒了!但是为什么不继续重写后来出现在上下文中的东西呢
px
仍然是真的,为什么要忘记它呢?@RhubarbAndC,我不知道确切的原因。这种平等性可以作为本地的
{-#REWRITE}
规则添加。但我想追踪所有这些等式的成本太高了:可能会有相当长的
s链。此外,您实际上很少需要像上面这样做。我认为沉默的隐性改写是令人困惑的,听起来很公平。在这一点上,我太新手了,不知道这会有多大的不同。接下来的问题是:当使用inspect习惯用法时,为什么我不能在等式证明上进行模式匹配,以发现它是
refl
?错误消息表明我需要知道两边是相等的,但这很愚蠢:当你在
p:x上进行模式匹配时,它应该告诉我这一点≡ y
,Agda试图统一
x
y
,但
px
true
无法统一。解决方案是将
px
推广到一个新变量,该变量可以与
true
统一。请参阅您正在阅读的教程2.6模块的最后一部分,了解如何做到这一点。或者你可以简单地使用。太好了!但是为什么不继续重写后来出现在上下文中的东西呢
px
仍然是真的,为什么要忘记它呢?@RhubarbAndC,我不知道确切的原因。这种平等性可以作为本地的
{-#REWRITE}
规则添加。但我想追踪所有这些等式的成本太高了:可能会有相当长的
s链。此外,您实际上很少需要像上面这样做。我认为沉默的隐性改写是令人困惑的,听起来很公平。在这一点上,我太新手了,不知道这会有多大的不同。接下来的问题是:当使用inspect习惯用法时,为什么我不能在等式证明上进行模式匹配,以发现它是
refl
?错误消息表明我需要知道两边是相等的,但这很愚蠢:当你在
p:x上进行模式匹配时,它应该告诉我这一点≡ y
,Agda试图统一
x
y
,但
px
true
无法统一。解决方案是将
px
推广到一个新变量,该变量可以与
true
统一。请参阅您正在阅读的教程2.6模块的最后一部分,了解如何做到这一点。或者你可以简单地使用。