I am trying to write a function which compares two lists for homework. When the function run it should be something like this ;(cmp ‘(cat ?x mat ?x) ‘(cat bat mat bat)) => t ;(cmp ‘(cat ?x mat ?x) ‘(cat bat mat sat)) => nil. meaning that in the first list when equal to ?x and the second ?x return true if both are pointing to the same value.
When I run the program now is giving me “error while parsing arguments to special form if: invalid number of elements” Here is my code if you can give me some feedback. Thanks.
;cmp algorithm
;1 if the both lists are empty return true
;2 if only one of the lists is empty return fasle
;3 compare first of the list1 and the first of list2
;if equal go on to the rest of the list with recursive call else return false
(defun cmp (list1 list2)
(setq y '())
(setq z '())
(defparameter *counter* 0)
(cond
((and (null list1) (null list2))
t
)
((or (null list1) (null list2))
nil
)
((or (eq (first list1) (first list2))
(eq (first list1) '?x) )
(cmp (rest list1) (rest list2) )
;if (first list is equal to '?x)
;set the counter to 1
;give the value of (first(rest list2)) to y
;if (first list is equal to '?x) again
;set the counter to 2
;give the value of (first (rest list2)) to z
;i need to compare y and z if eq return true
(if (eq (first list1) '?x)
(princ (first list1 ))
(princ (first(rest list2)))
(1+ *counter*)
(set y (first(rest list2)))
(if (= *counter* 2)
(set z (first (rest list2)))
)
)
(if (= y z) t)
)
(t
nil)
)
)
;(cmp ‘(cat ?x mat ?x) ‘(cat bat mat bat)) => t
;(cmp ‘(cat ?x mat ?x) ‘(cat bat mat sat)) => nil
You’re almost there. You’re missing how to match generically on any symbol whose first character is
?and how to pass matches to recursive calls.You need to save your matches somewhere between calls. A possible approach is pass them in an optional association list of matches:
A very similar approach to this one which uses a dynamic variable:
Both could be called this way:
However, if you already start with an association list of matches, the first one is called like this:
While the second one is to be used like this:
Exercise: Make
cmpalways match'?(a symbol whose name is solely the question mark) to anything.This may be useful if you want an element to be there but you want to ignore it otherwise.
Exercise: Make
cmpmore useful and return the list of found associations instead oft:The idea is to return only the found associations, and not the unused ones. So, even though the second test returns non-
nil,?zdoesn’t appear in the result.