実際に、trustMe
which で評価されないパターン マッチを試みると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 にコンパイルする場合、決定的な違いが 1 つあります。module を見ると、次の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
insideを使用してtransport
、モジュール ( C-c C-x C-c
) をコンパイルし、結果の実行可能ファイルを実行すると、... ご想像のとおり、segfault が発生します。
代わりに仮定を使用すると、次のようになります。
DontTrustMe.exe: MAlonzo Runtime Error:
postulate evaluated: DontTrustMe.trustMe′
(少なくとも MAlonzo を使用して) プログラムをコンパイルするつもりがない場合は、矛盾が唯一の懸念事項です (一方、プログラムのタイプチェックのみを行う場合、通常、矛盾は一種の大きな問題です)。
現時点で考えられるユースケースは 2 つあります。1 つ目は (おっしゃる通り) プリミティブを実装する場合です。標準ライブラリは3 つの場所で使用します: s (モジュール)、s (モジュール)、およびs (モジュール) のtrustMe
決定可能な等価性の実装。Name
Reflection
String
Data.String
Char
Data.Char
2 つ目は最初のものとよく似ていますが、データ型と等値関数を自分で指定し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
と、コンパイラはあなたを救うことができません。