I have the menu which is created in the options function and the functionality of that is to have the user input a number (1 or 2 or 3) in order to solve the problem with the chosen method (DFS, BFS, BESTFS). This method is supposed to return what the user selected in this line of code
(SearchProblem '(0 0 2 6 4) '(0 0 0 0 0) (Options)) in the end. The problem is that when I compile the problem it displays this error "Undefined function DFS called with arguments ().". How can I fix that?
Code
; ----------------------------------------------------------------------------
; ******** Search Code for DFS and other search methods
; ******** (expanding front and extending queue)
; ******** author: AI lab
; ********
; ******** Κώδικας για DFS και άλλες μεθόδους αναζήτησης
; ******** (επέκταση μετώπου και διαχείριση ουράς)
; ******** Συγγραφέας: Εργαστήριο ΤΝ
; ----------------------------------------------------------------------------
; **** starting search
; **** έναρξη αναζήτησης
(defun searchProblem (start-state goal method )
( cond
((StateValidation start-state)(print "Invalid data!") nil)
( T (findSolution (MakeFront start-state) (MakeQueue start-state) () goal method ) )
)
;(print '____BEGIN_SEARCHING_____ )
)
; **** Checking for valid states
(defun StateValidation (state)
(cond
( (or (> (first state) 3) (<(first state) 0)) t)
(T nil)
)
)
; ----------------------------------------------------------------------------
; **** Basic recursive function to create search tree (recursive tree expantion)
; **** Βασική αναδρομική συνάρτηση για δημιουργία δέντρου αναζήτησης (αναδρομική επέκταση δέντρου)
(defun FindSolution (front queue closed goal method )
(cond
((null front) 'no_solution)
((mymember (car front) closed) (FindSolution (cdr front) (cdr queue) closed goal method ))
((equal (car front) goal) (format T "This is the solution: ~a" (reverse (first queue))))
(T (FindSolution (ExpandFront front method) (ExtendQueue queue method) (cons (car front) closed) goal method ))
)
)
; ----------------------------------------------------------------------------
; **** FRONT
; **** Διαχείριση Μετώπου
; ----------------------------------------------------------------------------
; ** initialization of front
; ** Αρχικοποίηση Μετώπου
(defun MakeFront (node)
(list node)
)
; ----------------------------------------------------------------------------
; **** expanding front
; **** επέκταση μετώπου
(defun ExpandFront (front method)
(cond
( (eq method 'DFS) (append ( removeNils ( findchildren (car front))) (cdr front) ) )
( (eq method 'BFS) (append (cdr front) ( removeNils (findchildren (car front)))))
( (eq method 'BESTFS) (sort (append ( removeNils ( findchildren (car front))) (cdr front))#'check) )
( T "other methods to be added" )
)
)
; ----------------------------------------------------------------------------
; **** QUEUE
; **** Διαχείριση ουράς
; ----------------------------------------------------------------------------
; ** initialization of queue
; ** Αρχικοποίηση ουράς
(defun MakeQueue (node)
(list (list node))
)
; ----------------------------------------------------------------------------
; **** expanding queue
; **** επέκταση ουράς
;;; expanding queue
(defun ExtendQueue (queue method)
(cond
( (eq method 'DFS) (append ( growPath (car queue)) (rest queue) ) )
( (eq method 'BFS) (append (rest queue) (growPath (car queue)) ) )
( (eq method 'BESTFS) (sort (append ( growPath (car queue) ) (rest queue))#'check1) )
( T "other methods to be added" )
)
)
(defun check (s1 s2)
(< (+ (third s1) (fourth s1) (fifth s1)) (+ (third s2) (fourth s2) (fifth s2)) )
)
(defun check1 (s1 s2)
(< (+ (third (first s1)) (fourth (first s1)) (fifth (first s1))) (+ (third (first s2)) (fourth (first s2)) (fifth (first s2))))
)
(defvar opt 0) ;Variable definition for the menu
;----------Otptions menu------------------------------------------------------
(defun Options ()
( print "Searching methods." )
( print "For DFS method press 1." )
( print "For BFS method press 2." )
( print "For BESTFS method press 3." )
( print "Choose searching method" )
( let (opt (read)))
(cond
( ( = opt 1 ) (T (DFS) ) )
( ( = opt 2 ) (T (BFS) ) )
( ( = opt 3 ) (T (BESTFS) ) )
)
( T (nil) )
)
; ----------------------------------------------------------------------------
; **** growing path towards each different child of the selected parent node
; **** επεκταση μονοπατιου προς καθε διαφορετικό παιδί-κόμβο από τον επιλεγμένο γονέα-κόμβο
(defun growPath (path)
(removecycles (grow1 path (removeNils (findchildren (car path)))))
)
(defun grow1 (path children)
(cond
((null children) nil )
( T (cons (cons (car children) path) (grow1 path (cdr children))) )
)
)
; ----------------------------------------------------------------------------
; **** Supportive functions
; **** Υποστηρικτικές συναρτήσεις
(defun mymember(x Y)
(cond
((endp y) nil )
((equal x (first y)) T )
(T (mymember x (rest y)) )
)
)
(defun removeNils (X)
(cond
((endp x) nil )
((eq (first x) NIL) (removeNils (rest x)) )
(T (cons (first x) (removeNils (rest x))) )
)
)
(defun removecycles (paths)
(cond
((null paths) nil )
((member (caar paths) (cdar paths)) (removecycles (cdr paths)) )
(T (cons (car paths) (removecycles (cdr paths))) )
)
)
; ----------------------------------------------------------------------------
; **** Problem's World & Problem depending functions
; **** κόσμος του προβλήματος (αν απαιτείται) και συναρτήσεις σχετικές με το πρόβλημα
;;;; #### to be added ####
(defvar capacity 5)
(defun goToGround (state)
(cond
( (or (= (+ (third state) (fourth state) (fifth state)) 0) (= (second state) capacity))
(list 0 0 (third state)(fourth state)(fifth state))
)
(T nil)
)
)
(defun goToFirst (state)
(cond
(
(and (< (second state) capacity) (> (third state) 0))
(goToFirst (list 1 (+ (second state) 1) (- (third state) 1) (fourth state) (fifth state)))
)
(T (list (first state) (second state) (third state) (fourth state) (fifth state)))
)
)
(defun goToSecond (state)
(cond
(
(and (< (second state) capacity) (> (fourth state) 0))
(goToSecond (list 2 (+ (second state) 1) (third state) (- (fourth state) 1) (fifth state)))
)
(T (list (first state) (second state) (third state) (fourth state) (fifth state)))
)
)
(defun goToThird (state)
(cond
(
(and (< (second state) capacity) (> (fifth state) 0))
(goToThird (list 3 (+ (second state) 1) (third state) (fourth state) (- (fifth state) 1)))
)
(T (list (first state) (second state) (third state) (fourth state) (fifth state)))
)
)
; ----------------------------------------------------------------------------
; ** function to find the children nodes of a parent state node
; ** συνάρτηση εύρεσης απογόνων
(defun findchildren (state)
(list (goToGround state) (goToFirst state) (goToSecond state) (goToThird state))
)
; ----------------------------------------------------------------------------
; ** Executing the code
; ** κλήση εκτέλεσης κώδικα
;(trace SearchProblem)
(SearchProblem '(0 0 2 6 4) '(0 0 0 0 0) (Options) )
I heavily recommend you to properly indent common-lisp code following existing guidelines, else the parentheses are a mess.
Here, using slime and regex search and replace, I properly indented your code and simplified some stuff and also by this indenting - discovered some parenthesis mistakes.
And I corrected them.
By the level of the indentation, you can see, where paren mistakes occur.
To your question, I suggest:
(defun options ()
(print "Searching methods.")
(print "For DFS method press 1.")
(print "For BFS method press 2.")
(print "For BESTFS method press 3.")
(print "Choose searching method")
(let ((opt (read))) ;; here were some paren' mistakes!
(case opt ;; case is the `switch` in cl
(1 'DFS)
(2 'BFS)
(3 'BESTFS) ;; here was an erroneous parenthesis
(otherwise 'nil)))) ;; here one paren' added
The whole code correctly indented (using emacs SLIME mode for common-lisp) and with some changes for simplification:
;; --------------------------------------------------
;; ******** Search Code for DFS and other search methods
;; ******** (expanding front and extending queue)
;; ******** author: AI lab
;; ********
;; ******** Κώδικας για DFS και άλλες μεθόδους αναζήτησης
;; ******** (επέκταση μετώπου και διαχείριση ουράς)
;; ******** Συγγραφέας: Εργαστήριο ΤΝ
;; --------------------------------------------------
;; **** starting search
;; **** έναρξη αναζήτησης
(defun searchProblem (start-state goal method)
(if (StateValidation start-state)
(print "Invalid data!") ;; print returns nil
(findSolution (MakeFront start-state)
(MakeQueue start-state)
()
goal
method)))
;;**** Checking for valid states
(defun StateValidation
(or (> (first state) 3)
(< (first state) 0))) ;; if condition is true, returns T else nil
;;--------------------------------------------------
;;**** Basic recursive function to create search tree (recursive tree expantion)
;;**** Βασική αναδρομική συνάρτηση για δημιουργία δέντρου αναζήτησης (αναδρομική επέκταση δέντρου)
(defun FindSolution (front queue closed goal method)
(cond ((null front) 'no_solution)
((mymember (car front) closed)
(FindSolution (cdr front)
(cdr queue)
closed
goal
method))
((equal (car front) goal)
(format T "This is the solution: ~a" (reverse (first queue))))
(T (FindSolution (ExpandFront front method)
(ExtendQueue queue method)
(cons (car front) closed)
goal
method))))
;;--------------------------------------------------
;;**** FRONT
;;**** Διαχείριση Μετώπου
;;--------------------------------------------------
;;** initialization of front
;;** Αρχικοποίηση Μετώπου
(defun MakeFront (node)
(list node))
;;--------------------------------------------------
;;**** expanding front
;;**** επέκταση μετώπου
(defun ExpandFront (front method)
(case method
(DFS (append (removeNils (findchildren (car front)))
(cdr front)))
(BFS (append (cdr front)
(removeNils (findchildren (car front)))))
(BESTFS (sort (append (removeNils (findchildren (car front)))
(cdr front)) #'check))
(otherwise "other methods to be added")))
;;--------------------------------------------------
;;**** QUEUE
;;**** Διαχείριση ουράς
;;--------------------------------------------------
;;** initialization of queue
;;** Αρχικοποίηση ουράς
(defun MakeQueue (node)
(list (list node)))
;;--------------------------------------------------
;;**** expanding queue
;;**** επέκταση ουράς
;;; expanding queue
(defun ExtendQueue (queue method)
(case method
(DFS (append (growPath (car queue))
(rest queue)))
(BFS (append (rest queue)
(growPath (car queue))))
(BESTFS (sort (append (growPath (car queue))
(rest queue)) #'check1))
(otherwise "other methods to be added")))
#|
(defun check (s1 s2)
(< (+ (third s1)
(fourth s1)
(fifth s1))
(+ (third s2)
(fourth s2)
(fifth s2))))
|#
(defun sum-3rd-to-5th (s)
(+ (third s) (fourth s) (fifth s)))
(defun check (s1 s2)
(< (sum-3rd-to-5th s1)
(sum-3rd-to-5th s2)))
(defun check1 (s1 s2)
(check (first s1) (first s2))) ;; this is equivalent to before - uses `check` above
(defvar opt 0) ;Variable definition for the menu
;;----------Otptions menu------------------------------------------------------
(defun options ()
(print "Searching methods.")
(print "For DFS method press 1.")
(print "For BFS method press 2.")
(print "For BESTFS method press 3.")
(print "Choose searching method")
(let ((opt (read))) ;; parenthesis mistakes also here!
(case opt
(1 'DFS)
(2 'BFS)
(3 'BESTFS) ;; here was an erroneous paranthesis
(otherwise 'nil)))) ;; here one added
;;--------------------------------------------------
;;**** growing path towards each different child of the selected parent node
;;**** επεκταση μονοπατιου προς καθε διαφορετικό παιδί-κόμβο από τον επιλεγμένο γονέα-κόμβο
(defun growPath (path)
(removecycles (grow1 path (removeNils (findchildren (car path))))))
(defun grow1 (path children)
(cond ((null children) nil)
(T (cons (cons (car children) path)
(grow1 path (cdr children))))))
;;--------------------------------------------------
;;**** Supportive functions
;;**** Υποστηρικτικές συναρτήσεις
#|
(defun mymember(x y)
(cond ((null y) nil)
((equal x (first y)) T)
(T (mymember x (rest y)))))
(defun removeNils (x)
(cond ((null x) nil)
((eq (first x) NIL) (removeNils (rest x)))
(T (cons (first x)
(removeNils (rest x))))))
|#
(defun mymember (x y)
(member x y :test #'equal))
(defun removeNils (x)
(remove-if #'null x))
(defun removecycles (paths)
(cond ((null paths) nil)
((member (caar paths)
(cdar paths))
(removecycles (cdr paths)))
(T (cons (car paths)
(removecycles (cdr paths))))))
;;--------------------------------------------------
;;**** Problem's World & Problem depending functions
;;**** κόσμος του προβλήματος (αν απαιτείται) και συναρτήσεις σχετικές με το πρόβλημα
#| isn't state a list of 5 elements?
(list (first state)
(second state)
(third state)
(fourth state)
(fifth state)) ;; ===> state
|#
;;;; #### to be added ####
(defvar capacity 5)
(defun goToGround (state)
(if (or (zerop (sum-3rd-to-5th state))
(zerop (second state) capacity))
(list 0
0
(third state)
(fourth state)
(fifth state))
nil))
(defun goToFirst (state)
(if (and (< (second state) capacity)
(> (third state) 0))
(goToFirst (list 1
(1+ (second state))
(1- (third state))
(fourth state)
(fifth state)))
state))
(defun goToSecond (state)
(if (and (< (second state) capacity)
(> (fourth state) 0))
(goToSecond (list 2
(1+ (second state))
(third state)
(1- (fourth state))
(fifth state)))
state))
(defun goToThird (state)
(if (and (< (second state) capacity)
(> (fifth state) 0))
(goToThird (list 3
(1+ (second state))
(third state)
(fourth state)
(1- (fifth state))))
state))
;;--------------------------------------------------
;;** function to find the children nodes of a parent state node
;;** συνάρτηση εύρεσης απογόνων
(defun findchildren (state)
(list (goToGround state)
(goToFirst state)
(goToSecond state)
(goToThird state)))
;;--------------------------------------------------
;;** Executing the code
;;** κλήση εκτέλεσης κώδικα
;; (trace SearchProblem)
(SearchProblem '(0 0 2 6 4)
'(0 0 0 0 0)
(Options))
You're trying to call DFS, BFS, and BESTFS as functions. They're just symbols that should be returned, and they'll be passed on to other functions as parameters.
They shouldn't be wrapped in (T ...), either. And (T (nil)) needs to be a clause of the COND, not after it. And again, nil shouldn't be inside parentheses, that means to try to call it as a function. You don't really need this clause, though, since COND returns NIL by default if none of the conditions match.
The code that tests opt needs to be inside the let that binds it.
(defun Options ()
( print "Searching methods." )
( print "For DFS method press 1." )
( print "For BFS method press 2." )
( print "For BESTFS method press 3." )
( print "Choose searching method" )
( let (opt (read))
(cond
( ( = opt 1 ) 'DFS )
( ( = opt 2 ) 'BFS )
( ( = opt 3 ) 'BESTFS )
( T nil )))
)
)
Related
I'm encountering a worrying error in SBCL -- I suspect that it arises from pilot error, and would love some tips if you have them!
Here is the error:
Memory fault at 0x52 (pc=0x52cffa19 [code 0x52cff6d0+0x349 ID 0x86a2], fp=0x7ff37f29f6d0, sp=0x7ff37f29f698) tid 0x7ff38ca82180
The integrity of this image is possibly compromised.
Continuing with fingers crossed.
"derp"
debugger invoked on a SB-SYS:MEMORY-FAULT-ERROR in thread
#<THREAD "main thread" RUNNING {1000510083}>:
Unhandled memory fault at #x52.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(HMAKER-II)
source: (LIST (CAR (CDR (CDR IENTRY))))
Here is the code that I'm running. It is a few connected subroutines in a larger program. The overall program takes structured text input and adds to a hash table, this subroutine takes the contents of the table and is intended to organize it back into a single structured output in the same form as the input (it's not quite finished, I've only got as far as creating a new table with modified data in order to create a well-formed output).
I'm conscious that my code is messy and can be improved -- I would appreciate pointers on improving it, but my main goal is first to fix the error before focusing in better and more efficient code.
Here you go:
(defun hmaker-launcher ()
(setf table-entries-for-hmaker (alexandria:hash-table-alist etable))
(hmaker))
(defun hmaker ()
(if (equal table-entries-for-hmaker nil)
(progn
(setf sorted-list-of-ientries (sort (alexandria:hash-table-alist itable) #'> :key #'third))
(hmaker-II)))
(setf table-entry-for-hmaker (car table-entries-for-hmaker))
(setf entry-name-for-hmaker (car table-entry-for-hmaker))
(setf entry-number (car (reverse table-entry-for-hmaker)))
(setf processed-entry-for-hmaker (cdr (reverse (cdr (cdr (reverse table-entry-for-hmaker))))))
(if (equal entry-number 8)
(progn
(setf (gethash entry-name-for-hmaker itable) (list '8 (length (car processed-entry-for-hmaker)) processed-entry-for-hmaker))
)
)
(if (equal entry-number 9)
(progn
(setf number-of-elements (list-length processed-entry-for-hmaker))
(setf (gethash entry-name-for-hmaker itable) (list '9 number-of-elements processed-entry-for-hmaker))
))
(setf table-entries-for-hmaker (cdr table-entries-for-hmaker))
(hmaker)
)
(defun hmaker-II ()
(if (equal sorted-list-of-ientries nil)
(inputter))
(setf ientry (car sorted-list-of-ientries))
(if (equal '9 (car (cdr ientry)))
(progn
(setf complexity-atom (list (car (cdr (cdr ientry)))))
(setf hmaker-complexity-list (append hmaker-complexity-list complexity-atom))
(setf (nth hmaker-recursion-counter complexity-adder) (+ (car (cdr (cdr identry))) (nth hmaker-recursion-counter complexity-adder)))
(setf (second (gethash (car ientry) itable)) complexity-adder)
(setf rel-parts (cdr (cdr (cdr ientry))))
(push "padding" rel-parts)
(hmaker-III rel-parts)
)
(defun hmaker-III (parts)
(setf parts (cdr parts))
(if (equal parts nil)
(setf sorted-list-of-ientries (cdr sorted-list-of-ientries))
(hmaker-II)
)
(setf part-in-question (car parts))
(if (equal '9 (car (cdr (part-in-question))))
(progn
(setf hmaker-recursion-counter (+ hmaker-recursion-counter 1))
(setf (nth hmaker-recursion-counter complexity-adder) (+ (car (cdr (gethash part-in-question)) (nth hmaker-recursion-counter complexity-adder))))
(setf sub-parts (cdr (cdr (gethash part-in-question itable))))
(hmaker-III sub-parts)
)
(progn
(hmaker-III parts))
)
)
Thoughts?
I get the error mentioned in the title when I try to run my code with an example (included in the code provided below). I can not figure out where the issue is. Help is highly appreciated
Code:
(defun l-tree(left)
(cond
((or (null left) (not (listp left)))nil)
(t (car (cdr left)))))
(defun r-tree(right)
(cond
((or (null right)(not (listp right)))nil)
(t (car ( cdr (cdr right))))))
(defun in-order(tree)
(append
(in-order (l-tree tree))
(list (car tree))
(in-order (r-tree tree))
)
)
(defparameter *tree2* '(40 (30 (25 () ()) (35 a() ())) (60 (50 () ()) ())))
(print (in-order *tree2*))
It would help if you wrote when the program must stop the recursion, which in this program is (unless (null tree) ); otherwise, the program keeps running until it reaches the memory limit.
(defun l-tree (left)
(cond
((or (null left) (not (listp left))) nil)
(t (car (cdr left)))))
(defun r-tree (right)
(cond
((or (null right)(not (listp right))) nil)
(t (car ( cdr (cdr right))))))
(defun in-order (tree)
(unless (null tree) ;; Stop condtion
(append (in-order (l-tree tree))
(list (car tree))
(in-order (r-tree tree)))))
(defparameter *tree2* '(40
(30
(25
() ())
(35
() ()))
(60
(50
() ())
())))
(print (in-order *tree2*))
I want to get a function argument value, using an argument name.
The following code don't works, because symbol-value working only with global variables:
(defun test1 (&key v1)
(format t "V1: ~A~%" (symbol-value (intern "V1"))))
Is there a portable way to do this in Common Lisp?
You can use a custom environment to map strings to functions:
(use-package :alexandria)
(defvar *env* nil)
(defun resolve (name &optional (env *env*))
(if-let (entry (assoc name env :test #'string=))
(cdr entry)
(error "~s not found in ~a" name env)))
(defmacro bind (bindings env &body body)
(assert (symbolp env))
(let ((env (or env '*env*)))
(loop
for (n v) in bindings
collect `(cons ,n ,v) into fresh-list
finally
(return
`(let ((,env (list* ,#fresh-list ,env)))
,#body)))))
(defmacro call (name &rest args)
`(funcall (resolve ,name) ,#args))
For example:
(bind (("a" (lambda (u) (+ 3 u)))
("b" (lambda (v) (* 5 v))))
nil
(call "a" (call "b" 10)))
Here is another version of an explicit named-binding hack. Note this isn't well (or at all) tested, and also note the performance is not going to be great.
(defun named-binding (n)
;; Get a binding by its name: this is an error outside
;; WITH-NAMED-BINDINGS
(declare (ignore n))
(error "out of scope"))
(defun (setf named-binding) (val n)
;; Set a binding by its name: this is an error outside
;; WITH-NAMED-BINDINGS
(declare (ignore val n))
(error "out of scope"))
(defmacro with-named-bindings ((&rest bindings) &body decls/forms)
;; establish a bunch of bindings (as LET) but allow access to them
;; by name
(let ((varnames (mapcar (lambda (b)
(cond
((symbolp b) b)
((and (consp b)
(= (length b) 2)
(symbolp (car b)))
(car b))
(t (error "bad binding ~S" b))))
bindings))
(decls (loop for df in decls/forms
while (and (consp df) (eql (car df) 'declare))
collect df))
(forms (loop for dft on decls/forms
for df = (first dft)
while (and (consp df) (eql (car df) 'declare))
finally (return dft)))
(btabn (make-symbol "BTAB")))
`(let (,#bindings)
,#decls
(let ((,btabn (list
,#(mapcar (lambda (v)
`(cons ',v (lambda (&optional (val nil valp))
(if valp
(setf ,v val)
,v))))
varnames))))
(flet ((named-binding (name)
(let ((found (assoc name ,btabn)))
(unless found
(error "no binding ~S" name))
(funcall (cdr found))))
((setf named-binding) (val name)
(let ((found (assoc name ,btabn)))
(unless found
(error "no binding ~S" name))
(funcall (cdr found) val))))
(declare (inline named-binding (setf named-binding)))
,#forms)))))
And now:
> (with-named-bindings ((x 1))
(setf (named-binding 'x) 2)
(named-binding 'x))
2
Even better:
(defun amusing (x y)
(with-named-bindings ((x x) (y y))
(values #'named-binding #'(setf named-binding))))
(multiple-value-bind (reader writer) (amusing 1 2)
(funcall writer 2 'x)
(funcall reader 'x))
will work.
I am writing a function called ptyper that takes a nested list, nl. This function replaces all occurrences of a number with n and all occurrences of a symbol with s. This is what I have now:
(define (ptyper nl) (cond
((null? nl) '())
((list? nl)
(let ((ls (car nl)))
(list (ptyper ls))))
((number? (car nl))
(cons "n" (cdr nl)))
((symbol? (car nl))
(cons "s" (cdr nl)))
(else
(cons (car nl) (cdr nl)))))
I ran this test (ptyper '(2 (abc () "abc"))) but received an error that their was a contract violation. I'm not exactly sure what I'm doing wrong so if could use some help. Thanks!
Here is a possible solution with one function:
(define (ptyper nl)
(cond
((null? nl) '()) ; if the argument is an empty list, return the empty list
((list? nl) ; if the argument is a list, then
(let* ((c (car nl)) ; get its first element
(nc (cond ((number? c) "n") ; transform it for numbers
((symbol? c) "s") ; and symbols
((list? c) (ptyper c)) ; if a list recur over it
(else c)))) ; otherwise (e.g. a string) return as it is
(cons nc (ptyper (cdr nl))))) ; recursive call on the rest of the list
(else nl))) ; this should never happen for the specification,
; return the parameter or cause an error
Note that the error in your case is caused by the recursive call. When the function is called on an atom, for instance 2, first it checks for null and list?, and those checks returns false. Then it checks for (number (car nl)), but nl is equal to 2 and so car fails.
Here is a data definition for an S-expression, this models your data.
; An S-expr is one of:
; – Atom
; – SL
; An SL is one of:
; – '()
; – (cons S-expr SL)
; An Atom is one of:
; – Number
; – String
; – Symbol
We have predicates for every kind of data except Atom, so we make atom?:
;; Any -> Boolean
;; is the x an atom?
(define (atom? x)
(not (list? x)))
We follow the structure of the data to build "templates" for our functions:
(define (func sexp)
(cond
[(atom? sexp) (func-atom sexp)]
[else (func-sl sexp)]))
(define (func-sl sl)
(cond
[(empty? sl) ...]
[else (... (func (first sl)) ... (func-sl (rest sl)) ...)]))
(define (func-atom at)
(cond
[(number? at) ...]
[(string? at) ...]
[(symbol? at) ...]))
We fill in the gaps:
; Atom -> String
(define (subs-atom at)
(cond
[(number? at) "n"]
[(string? at) at]
[(symbol? at) "s"]))
; SL -> SL
(define (subs-sl sl)
(cond
[(empty? sl) sl]
[else (cons (subs-sexp (first sl))
(subs-sexp (rest sl)))]))
; S-exp -> S-exp
(define (subs-sexp sexp)
(cond
[(atom? sexp) (subs-atom sexp)]
[else (subs-sl sexp)]))
Using the interface for ptyper:
(define (ptyper nl)
(subs-sexp nl))
(ptyper '(2 (abc () "abc")))
; => '("n" ("s" () "abc"))
I am getting an error "variable EQ has no value" when I run the following code. How to overcome this error?
(defun add_book(bookref title author publisher)
(setf (get bookref 'title) title)
(setf (get bookref 'author) author)
(setf (get bookref 'publisher) publisher)
(setq library (cons bookref library))
bookref)
(defun retrieve_by (property value)
(setq result nil)
(do ((L library (cdr L)))
((NULL L) result)
(cond (EQ (get (car L) property) value)
(cons (car L) result))))
Maybe better formatting and the output from the SBCL compiler will help you. See the compiler warnings. Try to consult the Lisp reference to look up the syntax of the various constructs: http://lispdoc.com
* (defun add_book(bookref title author publisher)
(setf (get bookref 'title) title)
(setf (get bookref 'author) author)
(setf (get bookref 'publisher) publisher)
(setq library (cons bookref library))
bookref)
; in: DEFUN ADD_BOOK
; (SETQ LIBRARY (CONS BOOKREF LIBRARY))
;
; caught WARNING:
; undefined variable: LIBRARY
;
; compilation unit finished
; Undefined variable:
; LIBRARY
; caught 1 WARNING condition
ADD_BOOK
* (defun retrieve_by (property value)
(setq result nil)
(do ((L library (cdr L)))
((NULL L) result)
(cond (EQ (get (car L) property) value)
(cons (car L) result))))
; in: DEFUN RETRIEVE_BY
; (COND (EQ (GET (CAR L) PROPERTY) VALUE) (CONS (CAR L) RESULT))
; --> IF COND
; ==>
; (IF CONS
; (PROGN (CAR L) RESULT)
; NIL)
;
; caught WARNING:
; undefined variable: CONS
; ==>
; (IF EQ
; (PROGN (GET (CAR L) PROPERTY) VALUE)
; (COND (CONS (CAR L) RESULT)))
;
; caught WARNING:
; undefined variable: EQ
; (DO ((L LIBRARY (CDR L)))
; ((NULL L) RESULT)
; (COND (EQ (GET (CAR L) PROPERTY) VALUE) (CONS (CAR L) RESULT)))
; --> BLOCK
; ==>
; (LET ((L LIBRARY))
; (TAGBODY
; (GO #:G1)
; #:G0
; (TAGBODY (COND (EQ # VALUE) (CONS # RESULT)))
; (PSETQ L (CDR L))
; #:G1
; (UNLESS (NULL L) (GO #:G0))
; (RETURN-FROM NIL (PROGN RESULT))))
;
; caught WARNING:
; undefined variable: LIBRARY
; (SETQ RESULT NIL)
;
; caught WARNING:
; undefined variable: RESULT
;
; compilation unit finished
; Undefined variables:
; CONS EQ LIBRARY RESULT
; caught 4 WARNING conditions
RETRIEVE_BY
*