Agda 信任我有多危险?
以下是我对Agda 信任我有多危险?,agda,Agda,以下是我对Relation.Binary.propositionalquality.TrustMe.TrustMe的理解:它似乎采用任意的x和y,并且: 如果x和y是真正相等的,它就变成refl 如果不是,则其行为类似于假定谎言:x≡ y 现在,在后一种情况下,它很容易使Agda不一致,但这本身并不是一个问题:它只是意味着任何使用trustMe的证据都是通过向权威机构上诉而得到的证据。此外,尽管您可以使用这些东西编写强制:{ab:Set}->A->B,但实际情况是强制{ℕ} {Bool}0不
Relation.Binary.propositionalquality.TrustMe.TrustMe
的理解:它似乎采用任意的x
和y
,并且:
- 如果
和x
是真正相等的,它就变成y
refl
- 如果不是,则其行为类似于假定谎言:x≡ y
trustMe
的证据都是通过向权威机构上诉而得到的证据。此外,尽管您可以使用这些东西编写强制:{ab:Set}->A->B
,但实际情况是强制{ℕ} {Bool}0
不会减少(至少,不是根据C-C-n),所以它实际上与Haskell的语义跺脚不安全
不相似
那么,我对
trustMe
有什么恐惧呢?另一方面,有没有理由在实现原语之外使用它呢?事实上,试图在trustMe
上进行模式匹配,而该模式不计算为refl
会导致一个卡住的术语。也许这是一个启发性的发现(部分)定义trustMe
,primrustme
后面的基本操作的代码:
(u', v') <- normalise (u, v)
if (u' == v') then redReturn (refl $ unArg u) else
return (NoReduction $ map notReduced [a, t, u, v])
这看起来可疑:它总是返回refl
,无论x
和y
是什么。让我们来测试一下模块:
module DontTrustMe where
open import Data.Nat
open import Data.String
open import Function
open import IO
open import Relation.Binary.PropositionalEquality
open import Relation.Binary.PropositionalEquality.TrustMe
postulate
trustMe′ : ∀ {a} {A : Set a} {x y : A} → x ≡ y
transport : ℕ → String
transport = subst id (trustMe {x = ℕ} {y = String})
main = run ∘ putStrLn $ transport 42
使用trustMe
内部transport
,编译模块(C-C-x C-C
)并运行生成的可执行文件,我们得到了…您猜对了-一个错误
如果我们改用这个假设,我们最终会得到:
DontTrustMe.exe: MAlonzo Runtime Error:
postulate evaluated: DontTrustMe.trustMe′
如果您不打算编译程序(至少使用MAlonzo),那么不一致性应该是您唯一担心的问题(另一方面,如果您只对程序进行打字检查,那么不一致性通常是一件大事) 目前我可以想到两个用例,第一个是(正如您所说)实现原语。标准库在三个地方使用
trustMe
:在实现Name
s(Reflection
module)的可判定等式时,String
s(Data.String
module)和Char
s(Data.Char
module)
第二个与第一个非常相似,只是您自己提供了数据类型和相等函数,然后使用trustMe
跳过验证,只使用相等函数定义可判定相等。类似于:
open import Data.Bool
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
data X : Set where
a b : X
eq : X → X → Bool
eq a a = true
eq b b = true
eq _ _ = false
dec-eq : Decidable {A = X} _≡_
dec-eq x y with eq x y
... | true = yes trustMe
... | false = no whatever
where postulate whatever : _
但是,如果你把eq
搞砸了,编译器就无法保存你
open import Data.Bool
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
data X : Set where
a b : X
eq : X → X → Bool
eq a a = true
eq b b = true
eq _ _ = false
dec-eq : Decidable {A = X} _≡_
dec-eq x y with eq x y
... | true = yes trustMe
... | false = no whatever
where postulate whatever : _