0

So the following is my code in lisp and I am using emacs

(defun eval-var (var state)
  (cond (( atom state) nil)
        ((eql(caar state) var) (cadr (car state)));;(caar state))
        ((eval-var var (cdr state))) ) )

(defvar *clause* '( (not a) (not b) c))

(defvar *state*  '( (a t) (b t) (c t) (d t) ))

(defun eval-clause (clause state)
  (let ((d (cond ((if (equal (car clause) 'a) (eval-var (car clause) state) (not(eval-var (cadr (car clause)) state)))) ))
        (e (cond ((if (equal (cadr clause) 'b) (eval-var (cadr clause) state) (not(eval-var (cadr  (car clause)) state)))) ))
        (f (cond ((if (equal (caddr clause) 'c) (eval-var (caddr clause) state) (not(eval-var (caddr (car clause)) state)))) )) )
    (if (equal d e) t nil )))

Below is when I tried to run the functions.

* (load "3sat.lisp")

; Loading #P"/Network/Servers/fs.labs.encs/Volumes/raid1/users_a/vetterc7/Desktop/wsu16/cs355/3sat/3sat.lisp".
T
* (eval-clause *clause* *state*)

; Note: Variable F defined but never used.
;
T
* *clause*

((NOT A) (NOT B) C)
* clause

(A (NOT B) C)
* (eval-clause clause *state*)


Type-error in KERNEL::OBJECT-NOT-LIST-ERROR-HANDLER:  A is not of type LIST
   [Condition of type TYPE-ERROR]

Restarts:
  0: [ABORT] Return to Top-Level.

Debug  (type H for help)

(CADR 1 A)[:EXTERNAL]
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM:  Source file no longer exists:
  target:code/list.lisp.
0]

I was hoping that someone could help me out and explain why im getting this error and what I need to do to correct it.

1
  • You have cond clauses which are only conditions that look like (if (equal (car clause) 'a) (eval-var (car clause) state) (not(eval-var (cadr (car clause)) state))) but without a corresponding value. Did you intend to have (let ((d (if (...? Commented Mar 11, 2016 at 19:06

2 Answers 2

3

If you use SBCL you can see the source where the error happens.

The code needs to be compiled with a higher debug value:

(declaim (optimize (debug 3)))

Example:

CL-USER> (eval-clause '(A (NOT B) C) *state*)

debugger invoked on a TYPE-ERROR: The value A is not of type LIST.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY            ] Retry SLIME REPL evaluation request.
  1: [ABORT            ] Return to SLIME's top level.
  2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 12: #<CLOSURE (LABELS SWANK-BACKEND::RUN :IN SWANK-BACKEND:ADD-FD-HANDLER) {1004DC423B}>>
  3:                     Exit debugger, returning to top level.
(EVAL-CLAUSE (A (NOT B) C) ((A T) (B T) (C T) (D T)))
   source: (CADR (CAR CLAUSE))

You can find out about the source:

0] source

(CADR (CAR CLAUSE)) 

You can't call CAR on a symbol A.

One more enclosing form:

0] source 1

(EVAL-VAR (#:***HERE*** (CADR (CAR CLAUSE))) STATE) 

Two more enclosing forms:

0] source 2

(NOT (EVAL-VAR (#:***HERE*** (CADR (CAR CLAUSE))) STATE)) 

0] source 3

(IF (EQUAL (CADR CLAUSE) 'B)
    (EVAL-VAR (CADR CLAUSE) STATE)
    (NOT (EVAL-VAR (#:***HERE*** (CADR (CAR CLAUSE))) STATE))) 

You now see the form where it happens in enough context.

Sign up to request clarification or add additional context in comments.

Comments

0

It seems like what you're trying to achieve is to evaluate a set of logical expressions in *clause* using variables from *state*. Your current code is kinda messy, so I just wrote a solution myself instead of fixing it.

I used a library called Optima for pattern matching. You can install it with quicklisp by running (ql:quickload :optima) before loading the below code.

;; My solution supports NOT, AND and OR operators. AND and OR can only
;; be used with exactly two arguments. These will be evaluated
;; recursively, so they can be nested too.
(defparameter *clause* '((or b c)
                         (not b)
                         (or c (and a b))))

;; I used cons cells here instead of lists. More efficient this way.
;; You can use CAR and CDR to access the parts of a cons cell. Note
;; that accessing the second part is done with just a CDR, rather than
;; with CADR like with lists.
(defparameter *state* '((a . t)
                        (b . t)
                        (c . nil)
                        (d . nil)))

(defun get-var (var state)
  "Get VAR in STATE. Signals an error if VAR doesn't exist."
  ;; You can use ASSOC to find values in an "association list" like
  ;; *STATE*. ASSOC returns the whole cons, so CDR is used to return
  ;; the value of the variable.
  (cdr (or (assoc var state)
           (error "Unknown variable ~a." var))))

(defun eval-clause (clause state)
  "Recursively evaluate CLAUSE using variables in STATE."
  ;; OPTIMA:MATCH performs pattern matching with the first argument
  ;; (CLAUSE in this case). Pattern matching is much like a CASE,
  ;; except it allows you to match against various kinds of patterns
  ;; instead of simple values.
  (optima:match clause
    ;; This matches a single atom (such as A or B) and returns its
    ;; value.
    ((optima:guard var (atom var)) (get-var var state))
    ;; The patterns like `(LIST 'AND a b)` match a list that starts
    ;; with AND and has two elements after it; the two elements will
    ;; be bound to variables A and B, which can then be used in the
    ;; following form.
    ((list 'not a) (not (eval-clause a state)))
    ((list 'and a b) (and (eval-clause a state)
                          (eval-clause b state)))
    ((list 'or a b) (or (eval-clause a state)
                        (eval-clause b state)))
    ;; If CLAUSE doesn't match anything above, signal an error.
    (err-form (error "Unknown expression: ~a." err-form))))

(defun eval-all-clauses (clauses state)
  "Evaluate all logical expressions in CLAUSES using variables in STATE.
Returns a list of results."
  (mapcar (lambda (c) (eval-clause c state)) clauses))

;; Run it
(eval-all-clauses *clause* *state*)
; => (T NIL T)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.