table.lisp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. ;; table.lisp -- Generate tables from parsed propositions
  2. ;; Copyright (C) 2024 Alexander Rosenberg
  3. ;;
  4. ;; This program is free software: you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;;
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. (in-package :truth-table/base)
  17. (defun flatten-tree (tree)
  18. "Flatten TREE into a single list."
  19. (if (atom tree)
  20. (list tree)
  21. (apply 'append (mapcar 'flatten-tree tree))))
  22. (defun discover-variables (prop)
  23. "Return a list of all the variables in PROP, in left to right order."
  24. (let ((vars))
  25. (dolist (item (flatten-tree prop) (nreverse vars))
  26. (when (stringp item)
  27. (pushnew item vars :test 'equal)))))
  28. (defun permute-variables (vars)
  29. "Return a list of alists, each with a different permutation of VARS."
  30. (loop for var in vars
  31. for perms = (list (list (cons (car vars) t))
  32. (list (cons (car vars) nil)))
  33. then (loop for entry in perms
  34. collect (cons (cons var t) entry)
  35. collect (cons (cons var nil) entry))
  36. finally (return (mapcar 'reverse perms))))
  37. (defun create-truth-table (prop &key (vars (discover-variables prop))
  38. (include-intermediate t) (include-vars t))
  39. "Evaluate PROP with all possible combinations of truth values for its
  40. variables. If supplied VARS should be a list of all the know variables in PORP,
  41. if it is excluded, `discover-variables' will be used to generate it."
  42. (cond
  43. ((null prop)
  44. (list (list (cons nil nil))))
  45. ((null vars)
  46. (list (list (cons prop (eval-proposition prop '())))))
  47. (t
  48. (loop for perm in (permute-variables vars)
  49. for (value sub-map) = (multiple-value-list
  50. (eval-proposition prop perm))
  51. collect
  52. (append (when include-vars perm)
  53. (when include-intermediate
  54. (reverse (delete-if (lambda (item) (equal prop (car item)))
  55. sub-map)))
  56. (list (cons prop value)))))))
  57. (defun extract-truth-table-expressions (table)
  58. "Extract each expression from TABLE and return them as a list.
  59. NOTE: this just gets each expression from the first row, assuming each row has
  60. the same expressions."
  61. (mapcar 'car (car table)))
  62. (defun extract-truth-table-values (table)
  63. "Return a new table, where each row consists of just the value of the
  64. expression that was originally in that spot in TABLE."
  65. (mapcar (lambda (row)
  66. (mapcar 'cdr row))
  67. table))
  68. (defun combine-tables (table1 table2)
  69. "Join TABLE1 and TABLE2. Both tables must have the same number of rows.
  70. TABLE1 is modified during this process."
  71. (loop for row1 in table1
  72. for row2 in table2
  73. do
  74. (setf (cdr (last row1)) row2))
  75. (mapcar 'keep-unique-expressions table1))
  76. (defun create-combined-truth-table (props vars &key (include-intermediate nil)
  77. (include-vars t))
  78. "Create a large truth table from all the propositions in PROPS. The other
  79. arguments are as they are in `create-truth-table'."
  80. (loop with output-table = (create-truth-table
  81. (car props)
  82. :vars vars
  83. :include-intermediate include-intermediate
  84. :include-vars include-vars)
  85. for prop in (cdr props)
  86. for first-iter = t then nil do
  87. (setq output-table
  88. (combine-tables output-table
  89. (create-truth-table
  90. prop :vars vars
  91. :include-intermediate include-intermediate
  92. :include-vars nil)))
  93. finally (return output-table)))