我正在尝试编写一个测试代码来检查plusComm : (a : Nat) -> (b : Nat) -> a + b = b + a
是否确实证明了自然数上的a + b = b + a
,即该代码不会使用postulate
,{{ 1}},believe_me
等
特别是,如果证明以某种方式被伪造,我希望程序以以下三种方式之一失败:
如果这些选项不可行,那么我将接受源代码分析作为最后的手段(出于我的目的,也应该使用Idris编写)。我听说过assert_total
,但不确定这里是否合适。
下面的代码是一次失败的尝试,因为Language.Reflection
甚至没有查看传递的实际值:
proofEval
上面的代码在编译和运行时会产生以下输出,并且没有错误地退出。
plusComm : (a : Nat) -> (b : Nat) -> a + b = b + a
plusComm a b = ?plusComm
proofEval : {a : ty} -> (a = b) -> ty
proofEval {a=a} _ = a
main : IO ()
main = do
putStrLn "Compiled Successfully!"
print (proofEval (plusComm 1 2))
答案 0 :(得分:1)
我发现了a way to catch postulate
and holes using dependent tuples:
plusComm : (a : Nat) -> (b : Nat) -> a + b = b + a
plusComm = plusCommutative
proofEval : (a : Nat) -> (b : Nat) -> (a : Nat ** (b : Nat ** (a + b = b + a)))
proofEval a b = (a ** (b ** plusComm a b))
main : IO ()
main = do
putStrLn "Compiled Successfully!"
print $ fst $ snd $ proofEval 1 2
-- `print $ fst $ proofEval 1 2` doesn't work for the purpose
输出:
Compiled Successfully!
2
一些可能的虚假证明和结果:
-- typed hole
plusComm : (a : Nat) -> (b : Nat) -> a + b = b + a
plusComm = ?plusComm
-- result: runtime error (abort)
ABORT: Attempt to evaluate hole Main.plusComm1
-- postulate
postulate plusComm : (a : Nat) -> (b : Nat) -> a + b = b + a
-- result: compilation error
reachable postulates:
Main.plusComm
请注意,链接段中标记的 assert_total
或believe_me
并未使用此方法捕获。