tensures.nim 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. discard """
  2. nimout: '''tensures.nim(18, 10) Warning: BEGIN [User]
  3. tensures.nim(27, 5) Warning: cannot prove:
  4. 0 < n [IndexCheck]
  5. tensures.nim(47, 17) Warning: cannot prove: a < 4; counter example: y -> 2
  6. a`2 -> 4
  7. a`1 -> 3
  8. a -> 2 [IndexCheck]
  9. tensures.nim(69, 17) Warning: cannot prove: a < 4; counter example: y -> 2
  10. a`1 -> 4
  11. a -> 2 [IndexCheck]
  12. tensures.nim(73, 10) Warning: END [User]'''
  13. cmd: "drnim $file"
  14. action: "compile"
  15. """
  16. import std/logic
  17. {.push staticBoundChecks: defined(nimDrNim).}
  18. {.warning: "BEGIN".}
  19. proc fac(n: int) {.requires: n > 0.} =
  20. discard
  21. proc g(): int {.ensures: result > 0.} =
  22. result = 10
  23. fac 7 # fine
  24. fac -45 # wrong
  25. fac g() # fine
  26. proc main =
  27. var x = g()
  28. fac x
  29. main()
  30. proc myinc(x: var int) {.ensures: x == old(x)+1.} =
  31. inc x
  32. {.assume: old(x)+1 == x.}
  33. proc mainB(y: int) =
  34. var a = y
  35. if a < 3:
  36. myinc a
  37. {.assert: a < 4.}
  38. myinc a
  39. {.assert: a < 4.} # now this is wrong!
  40. mainB(3)
  41. proc a(yy, z: int) {.requires: (yy - z) > 6.} = discard
  42. # 'requires' must be weaker (or equal)
  43. # 'ensures' must be stronger (or equal)
  44. # a 'is weaker than' b iff b -> a
  45. # a 'is stronger than' b iff a -> b
  46. # --> We can use Z3 to compute whether 'var x: T = q' is valid
  47. type
  48. F = proc (yy, z3: int) {.requires: z3 < 5 and z3 > -5 and yy > 10.}
  49. var
  50. x: F = a # valid?
  51. proc testAsgn(y: int) =
  52. var a = y
  53. if a < 3:
  54. a = a + 2
  55. {.assert: a < 4.}
  56. testAsgn(3)
  57. {.warning: "END".}
  58. {.pop.}