测试Idris中是否有证据

时间:2019-03-09 06:57:00

标签: testing idris theorem-proving

我正在尝试编写一个测试代码来检查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))

1 个答案:

答案 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_totalbelieve_me并未使用此方法捕获。