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
现在,在后一种情况下,它很容易使Agda不一致,但这本身并不是一个问题:它只是意味着任何使用
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 : _