如何告诉AGDA展开一个定义以证明等效性
我有这样的函数:
open import Data.Char
open import Data.Nat
open import Data.Bool
open import Relation.Binary.PropositionalEquality
open Relation.Binary.PropositionalEquality.≡-Reasoning
foo : Char → Char → ℕ
foo c1 c2 with c1 == c2
... | true = 123
... | false = 456
我想证明,当我以相同的参数调用它(foo c c
)时,它总是产生123
:
foo-eq⇒123 : ∀ (c : Char) → foo c c ≡ 123
foo-eq⇒123 c =
foo c c ≡⟨ {!!} ⟩
123 ∎
我可以使用refl
要证明一个微不足道的示例:
foo-example : foo 'a' 'a' ≡ 123
foo-example = refl
因此,我认为我可以将refl
放入孔中,因为所有AGDA都需要做的是beta-reduce foo c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c
。但是,用refl
替换孔会产生以下错误:
.../Unfold.agda:15,14-18
(foo c c
| Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c)))))
!= 123 of type ℕ
when checking that the expression refl has type foo c c ≡ 123
我怀疑问题是AGDA并不自动理解c == c
is true
true 代码>对于所有c
:
c==c : ∀ (c : Char) → (c == c) ≡ true
c==c c = refl
.../Unfold.agda:23,10-14
Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c))))
!= true of type Bool
when checking that the expression refl has type (c == c) ≡ true
那么,证明我的foo-eq⇒123
定理的正确方法是什么?
I have a function like this:
open import Data.Char
open import Data.Nat
open import Data.Bool
open import Relation.Binary.PropositionalEquality
open Relation.Binary.PropositionalEquality.≡-Reasoning
foo : Char → Char → ℕ
foo c1 c2 with c1 == c2
... | true = 123
... | false = 456
I would like to prove that when I call it with the same argument (foo c c
), it always yields 123
:
foo-eq⇒123 : ∀ (c : Char) → foo c c ≡ 123
foo-eq⇒123 c =
foo c c ≡⟨ {!!} ⟩
123 ∎
I am able to use refl
to prove a trivial example:
foo-example : foo 'a' 'a' ≡ 123
foo-example = refl
So, I would think that I could just put refl
in the hole since all Agda needs to do is beta-reduce foo c c
. However, replacing the hole with refl
yields the following error:
.../Unfold.agda:15,14-18
(foo c c
| Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c)))))
!= 123 of type ℕ
when checking that the expression refl has type foo c c ≡ 123
I suspect the issue is that Agda doesn't automatically understand that c == c
is true
for all c
:
c==c : ∀ (c : Char) → (c == c) ≡ true
c==c c = refl
.../Unfold.agda:23,10-14
Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c))))
!= true of type Bool
when checking that the expression refl has type (c == c) ≡ true
So, what is the right way to prove my foo-eq⇒123
theorem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
AGDA的内置
char
类型有点奇怪。让我们将其与非weird内置类型()对比。
的平等测试如下。
请注意,
n程n
也不简化为true
。毕竟,AGDA不知道n
是Zero
或suc> suc
,即,这两个条款中的哪个申请减少。因此,这与您的char
示例具有相同的问题。但是,对于,有一种简单的方法。
让我们再次查看您的示例,还要添加
基于
foo
,bar
的版本。那么,
的简便方法是什么?我们在
n
上进行模式匹配/做一个案例拆分,以减少n程N
足够的以完成我们的证明。即,要么基本情况零
或下一个递归步骤suc n
。ℕ
只有两个构造函数,我们知道²
是什么样子,因此模式匹配是直接的。对于
char
,事情变得更加复杂。长话短说,char
的平等测试是根据函数toℕ
来定义的,AGDA没有给我们定义。另外,char
数据类型是假定的,并且不带任何构造函数。因此,bar-eq⇒123
之类的证明不是char
的选项。我们没有条款,也没有构造函数。 (我不会打电话,说'a'
char> char
的构造函数与1234
的方式相似,不是的构造函数ℕ
。)那么,我们可以做什么?请注意,在错误消息中,您引用的
c == c
简化为涉及isyes
的相当复杂的事物。如果我们减少了c == c
只有一个小一点(而不是尽可能多),我们将获得isyes(c≟C)
(而不是复杂的来自错误消息的事情)。_≟_
是char
的可决定性平等(即,“相等或不相等?”布尔值和证明的组合)。isyes
剥离了证明,并给了我们布尔值。然后,我的证明想法是不要在
c
上进行案例(就像我们为>
>),而是在c≟C
上进行。 。这将产生两种情况,并将isyes
分别降低到分别为 false 。true
情况很明显。false
案例可以通过与可决定性平等的证据矛盾来划分。请注意,此证明不容易转化为
,因为
_ cod>_º_
不是基于可决定的等式和iSyes
> 。这是原始的。也许一个更好的想法是始终坚持可决定的平等,因为
char
以及,而不是使用
_ == _
或<代码> _防_ 。foo
然后看起来如下。foo-eq⇒123
证明将适用于其不变。Agda's built-in
Char
type is a little weird. Let's contrast it with a non-weird built-in type,ℕ
. The equality test forℕ
looks as follows.Note that
n ≡ᵇ n
doesn't reduce totrue
, either. After all, Agda doesn't know whethern
iszero
orsuc
, i.e., which of the two clauses to apply for the reduction. So, this has the same problem as yourChar
example. But forℕ
there is an easy way out.Let's look at your example again and let's also add a
ℕ
-based version offoo
,bar
.So, what's the easy way out for
ℕ
? We pattern match / do a case split onn
to reducen ≡ᵇ n
just enough to do our proof. I.e., either to the base casezero
or to the next recursive stepsuc n
.ℕ
just has two constructors and we know what≡ᵇ
looks like, so pattern matching is straight forward.For
Char
, things are way more complicated. Long story short, the equality test forChar
is defined in terms of a functiontoℕ
that Agda doesn't give us a definition for. Also, theChar
data type is postulated and doesn't come with any constructors. So a proof likebar-eq⇒123
is not an option forChar
. We don't have clauses and we don't have constructors. (I wouldn't call, say,'a'
a constructor forChar
. Similarly to how1234
is not a constructor forℕ
.)So, what could we do? Note that
c == c
in the error message that you quoted reduces to something pretty complicated that involvesisYes
. If we reducedc == c
only a tiny little bit (instead of as much as possible), we'd getisYes (c ≟ c)
(instead of the complicated thing from the error message)._≟_
is the decidable equality forChar
(i.e., a combination of an "Equal or not?" Boolean and a proof).isYes
strips away the proof and gives us the Boolean.My idea for a proof would then be to not do a case split on
c
(as we did forℕ
), but onc ≟ c
. This would yield two cases and reduce theisYes
totrue
orfalse
, respectively. Thetrue
case would be obvious. Thefalse
case could be dicharged by contradiction with the proof from the decidable equality.Note that, in turn, this proof doesn't easily translate to
ℕ
, as_≡ᵇ_
isn't based on decidable equality andisYes
. It's a primitive instead.Maybe an even better idea would be to consistently stick to decidable equality, for
Char
as well asℕ
instead of using_==_
or_≡ᵇ_
.foo
would then look as follows.And the
foo-eq⇒123
proof would apply to it unchanged.