my blog lives here now
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.9 KiB

6 years ago
  1. ---
  2. title: "Announcement: amc-prove"
  3. date: September 25, 2019
  4. maths: true
  5. ---
  6. `amc-prove` is a smallish tool to automatically prove (some) sentences
  7. of constructive quantifier-free[^1] first-order logic using the Amulet
  8. compiler's capability to suggest replacements for typed holes.
  9. In addition to printing whether or not it could determine the truthiness
  10. of the sentence, `amc-prove` will also report the smallest proof term it
  11. could compute of that type.
  12. ### What works right now
  13. * Function types `P -> Q`{.amcprove}, corresponding to $P \to Q$ in the logic.
  14. * Product types `P * Q`{.amcprove}, corresponding to $P \land Q$ in the logic.
  15. * Sum types `P + Q`{.amcprove}, corresponding to $P \lor Q$ in the logic
  16. * `tt`{.amcprove} and `ff`{.amcprove} correspond to $\top$ and $\bot$ respectively
  17. * The propositional bi-implication type `P <-> Q`{.amcprove} stands for $P \iff Q$
  18. and is interpreted as $P \to Q \land Q \to P$
  19. ### What is fiddly right now
  20. Amulet will not attempt to pattern match on a sum type nested inside a
  21. product type. Concretely, this means having to replace $(P \lor Q) \land
  22. R \to S$ by $(P \lor Q) \to R \to S$ (currying).
  23. `amc-prove`'s support for negation and quantifiers is incredibly fiddly.
  24. There is a canonical empty type, `ff`{.amcprove}, but the negation
  25. connective `not P`{.amcprove} expands to `P -> forall 'a.
  26. 'a`{.amcprove}, since empty types aren't properly supported. As a
  27. concrete example, take the double-negation of the law of excluded middle
  28. $\neg\neg(P \lor \neg{}P)$, which holds constructively.
  29. If you enter the direct translation of that sentence as a type,
  30. `amc-prove` will report that it couldn't find a solution. However, by
  31. using `P -> ff`{.amc-prove} instead of `not P`{.amc-prove}, a solution is
  32. found.
  33. ```amc-prove
  34. ? not (not (P + not P))
  35. probably not.
  36. ? ((P + (P -> forall 'a. 'a)) -> forall 'a. 'a) -> forall 'a. 'a
  37. probably not.
  38. ? ((P + (P -> ff)) -> ff) -> ff
  39. yes.
  40. fun f -> f (R (fun b -> f (L b)))
  41. ```
  42. ### How to get it
  43. `amc-prove` is bundled with the rest of the Amulet compiler [on Github].
  44. You'll need [Stack] to build. I recommend building with `stack build
  45. --fast` since the compiler is rather large and `amc-prove` does not
  46. benefit much from GHC's optimisations.
  47. ```
  48. % git clone https://github.com/tmpim/amc-prove.git
  49. % cd amc-prove
  50. % stack build --fast
  51. % stack run amc-prove
  52. Welcome to amc-prove.
  53. ?
  54. ```
  55. ### Usage sample
  56. Here's a small demonstration of everything that works.
  57. ```amc-prove
  58. ? P -> P
  59. yes.
  60. fun b -> b
  61. ? P -> Q -> P
  62. yes.
  63. fun a b -> a
  64. ? Q -> P -> P
  65. yes.
  66. fun a b -> b
  67. ? (P -> Q) * P -> Q
  68. yes.
  69. fun (h, x) -> h x
  70. ? P * Q -> P
  71. yes.
  72. fun (z, a) -> z
  73. ? P * Q -> Q
  74. yes.
  75. fun (z, a) -> a
  76. ? P -> Q -> P * Q
  77. yes.
  78. fun b c -> (b, c)
  79. ? P -> P + Q
  80. yes.
  81. fun y -> L y
  82. ? Q -> P + Q
  83. yes.
  84. fun y -> R y
  85. ? (P -> R) -> (Q -> R) -> P + Q -> R
  86. yes.
  87. fun g f -> function
  88. | (L y) -> g y
  89. | (R c) -> f c
  90. ? not (P * not P)
  91. yes.
  92. Not (fun (a, (Not h)) -> h a)
  93. (* Note: Only one implication of DeMorgan's second law holds
  94. constructively *)
  95. ? not (P + Q) <-> (not P) * (not Q)
  96. yes.
  97. (* Note: I have a marvellous term to prove this proposition,
  98. but unfortunately it is too large to fit in this margin. *)
  99. ? (not P) + (not Q) -> not (P * Q)
  100. yes.
  101. function
  102. | (L (Not f)) ->
  103. Not (fun (a, b) -> f a)
  104. | (R (Not g)) ->
  105. Not (fun (y, z) -> g z)
  106. ```
  107. [^1]: Technically, amc-prove "supports" the entire Amulet type system,
  108. which includes things like type-classes and rank-N types (it's equal in
  109. expressive power to System F). However, the hole-filling logic is meant
  110. to aid the programmer while she codes, not exhaustively search for a
  111. solution, so it was written to fail early and fail fast instead of
  112. spending unbounded time searching for a solution that might not be
  113. there.
  114. You can find the proof term I redacted from DeMorgan's first law [here].
  115. [on Github]: https://github.com/tmpim/amulet
  116. [Stack]: https://haskellstack.org
  117. [here]: /static/demorgan-1.ml.html