I just have a small problem on the loop catching the condition on the generated truth table.. so you input a logical expression then it turns it into a truth table where it also interprets if it is valid or invalid or inconsistent. So far this is part of the program that interprets it, but it only catches invalid or valid... can you please guide me thru this? Thanks
*edit// So this is how the program runs:
*******Welcome!********
Type (LogicStart) to begin or (exit) to quit anytime.
;; Loaded file MyLogic.lisp
T [2]> (LogicStart) Enter Logical Expression or Formula: "(p^(~p))"
p (~p) (p^(~p))
T NIL NIL
NIL T NIL
The formula is Invalid
So the input is only a logical expression, then the output is a truth table for that expression.... and can also interpret it, But my code only has two intepretations: invalid or valid(tautology), since the example above should be inconsistent/unsatisfiable(since all interpretations of the formula/expression is false)
end edit
(defun interpret() ; interpret if valid or not or inconsistent
(setq lastcolumn (- (column) 1))
(setq lastcolumnROW 1)
(loop
(unless (aref (aref tbl lastcolumn) lastcolumnROW) (progn (princ "The formula is Invalid")(return)))
(setq lastcolumnROW (+ lastcolumnROW 1))
(when (= lastcolumnROW (+ 1 (row))) (progn (princ "The formula is a Tautology ") (return)))
)
)
edit two:///
This is LogicStart Function:
(defun LogicStart()
;Function to run program
(princ "Enter Logical Expression or Formula: " )
(setq input (read))
;Get input
(format t "-----------------------------------------------~C" #\linefeed)
;Create two dimension array(table)
(setq tbl (make-array (column)))
(setq index 0)
(loop
(setf (aref tbl index) (make-array (+ (row) 1)))
(setq index (+ 1 index))
(when (= index (column))(return))
)
(setAtoms)
(setFirstValue)
(tblReplaceValue)
(watchTable)
(format t "-----------------------------------------------~C" #\linefeed)
(interpret)
)
setAtoms Function:
(defun setAtoms()
;Get ALL possible formula
(setq indexOFTBL (make-array (column)))
(setq openP (make-array (- (column) (length Latoms))))
; Get index of open Parenthesis
(setq cOpenP 0)
(setq closeP (make-array (- (column) (length Latoms))))
;Get index of close Parenthesis
(setq cCloseP 0)
(setq index 0)
(loop
(when (char-equal (char input index) #\()
(progn
(setf (aref openP cOpenP) index)
(setq cOpenP (+ 1 cOpenP))
)
)
(when (char-equal (char input index) #\))
(progn
(setf (aref closeP cCloseP) index)
(setq cCloseP (+ 1 cCloseP))
)
)
(setq index (+ 1 index))
(when (= index (length input)) (return))
)
;(print openP)
;(print closeP)
(setq index 0)
(loop
(if (< index (length Latoms))
(progn
(setf (aref (aref tbl index) 0) (char Latoms index))
(setf (aref indexOFTBL index) index)
)
(progn
(setq OpIndex cOpenP)
(loop
(setq OpIndex (- OpIndex 1))
(setq CpIndex 0)
(loop
(if (or (> (aref openP OpIndex) (aref closeP CpIndex)) (= -1 (aref closeP CpIndex)))
(progn
(setq CpIndex (+ CpIndex 1))
)
(progn
(setf (aref (aref tbl index) 0) (subseq input (aref openP OpIndex) (+ 1 (aref closeP CpIndex))))
(setf (aref closeP CpIndex) -1)
(return)
)
)
(when (= CpIndex (length closeP))(return))
)
(setq index (+ index 1))
(when (= OpIndex 0) (return))
)
(return)
)
)
(setq index (+ index 1))
(when (= index (column)) (return))
)
)
watchTable and column function
(defun watchTable()
; View table
(setq ro 0)
(loop
(setq co 0)
(loop
(princ(aref (aref tbl co) ro))(format t "~C" #\tab)
(setq co (+ 1 co))
(when (= co (column))(return))
)
(format t "~C" #\linefeed)
(setq ro (+ 1 ro))
(when (= ro (+ (row) 1))(return))
)
)
(defun column()
; Get the number of columns
(+ (atoms) (symbols))
)
//edit 3 So for (OR A (NOT A)), the table lacks "not A" in @jkiiski's code
A | NOT A | (OR A (NOT A))
----+----------+--------
NIL | T | T
T | NIL | T
This expression is a Tautology.
Another example for reference: While P implies Q, this code accepts implies as: >
; Logical Connectives:
; ~ negation
; - biconditional
; > conditional
; ^ and
; v or
; Example Input:
; "(~((a^b)>c))"
; "(p>q)"
p q p>q
T T T
T NIL NIL
NIL T T
NIL NIL T
Another example:
Enter an expression: "((p>q)^r)"
T <- True
NIL <- False
--------------------------------------------
p q r (p>q) ((p>q)^r)
T T T T T
T T NIL T NIL
T NIL T NIL NIL
T NIL NIL NIL NIL
NIL T T T T
NIL T NIL T NIL
NIL NIL T T T
NIL NIL NIL T NIL
--------------------------------------------
So it in (p>q)^r it shows p, q, r, (p>q) and finally (p>q)^r on the truth table..
edit four//
(defun generate-value-combinations (variables)
(let ((combinations (list)))
(labels ((generate (variables &optional (acc (list)))
(if (endp variables)
(push (reverse acc) combinations)
(loop for value in '(t nil)
for var-cell = (cons (car variables) value)
do (generate (cdr variables) (cons var-cell acc))))))
(generate variables)
combinations)))
to this one?
(defun generate-value-combinations (variables)
(let ((combinations (list)))
(labels ((generate (variables &optional (acc (list)))
(if (endp variables)
(push (reverse acc) combinations)
(loop for value in '(t nil)
for var-cell = (cons (car variables) value)
do (generate (cdr variables) (cons var-cell acc))))))
(generate variables) nreverse combinations)))