以下是我对Relation.Binary.PropositionalEquality.TrustMe.trustMe
的理解:它似乎采取了任意x
和y
,并且:
x
和y
真正相等,则变为refl
postulate lie : x ≡ y
。现在,在后一种情况下,它很容易使Agda不一致,但这本身并不是一个问题:它只是意味着使用trustMe
的任何证据都是对权威的诉求。此外,虽然您可以使用这些内容来编写coerce : {A B : Set} -> A -> B
,但事实证明coerce {ℕ} {Bool} 0
没有减少(至少不是根据Cc Cn),所以它&#39 ; s,真的不像Haskell的语义踩踏unsafeCoerce
。
那么我需要担心trustMe
?另一方面,是否有理由在实现原语之外使用它?
答案 0 :(得分:5)
实际上,尝试在trustMe
上进行模式匹配(不评估为refl
)会导致术语卡住。看到(部分)用于定义trustMe
,primTrustMe
背后的原始操作的代码(或部分),也许是有启发性的:
(u', v') <- normalise (u, v)
if (u' == v') then redReturn (refl $ unArg u) else
return (NoReduction $ map notReduced [a, t, u, v])
此处,u
和v
分别代表术语x
和y
。其余代码可以在模块Agda.TypeChecking.Primitive
中找到。
是的,如果x
和y
在定义上不相等,那么primTrustMe
(以及trustMe
}的行为就像一个假设,即评估只是获得卡住。但是,将Agda编译为Haskell时有一个至关重要的区别。看一下模块Agda.Compiler.MAlonzo.Primitives
,我们找到了这段代码:
("primTrustMe" , Right <$> do
refl <- primRefl
flip runReaderT 0 $
term $ lam "a" (lam "A" (lam "x" (lam "y" refl))))
这看起来很可疑:无论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 C-x C-c
)并运行生成的可执行文件,我们得到......你猜错了 - 一个段错误。
如果我们改为使用假设,我们最终得到:
DontTrustMe.exe: MAlonzo Runtime Error:
postulate evaluated: DontTrustMe.trustMe′
如果您不打算编译您的程序(至少使用MAlonzo),那么不一致应该是您唯一的担心(另一方面,如果您只是检查您的程序,那么不一致通常是一件大事)。
目前我可以想到两个用例,首先是(如你所说)用于实现原语。标准库在三个位置使用trustMe
:实现Name
s(Reflection
模块),String
s(Data.String
模块)的可判定等式和{ {1}} s(Char
模块)。
第二个与第一个非常相似,除了你自己提供数据类型和相等函数,然后使用Data.Char
跳过证明,并使用相等函数来定义可判定的相等性。类似的东西:
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 : _
,编译器就无法保存你。