I am building a program and lisp and need to check if a Cons exist in a list of cons, but for some reason it keep returning nil in the if statement, here is the current code I am using for it.
(defun countVertexTriangles (graph numOfVertices)
(findTriangle graph numOfVertices)
)
(defun findTriangle(graph numOfVertices)
(loop for (x y) in graph do
(loop for z from 1 to numOfVertices do
(write graph)
(terpri)
(write (cons z (cons y nil)))
(terpri)
(write (cons z (cons x nil)))
(terpri)
; (if (AND (member (cons z (cons y nil)) graph) (member (cons z (cons x nil)) graph))
; then (write (cons y z))
; )
)
(terpri)
)
)
; (defun findEdge(graph edge)
; (loop for x in graph do
; (write x)
; (write edge)
; (if (eql x edge)
; (write "A")
; (write "B")
; )
; )
; )
(defun testFunct ()
(setf g1 '((1 2)(2 3)(1 3)(2 4)(3 4)(4 5)(3 5)))
(countVertexTriangles g1 5)
)
(testFunct)
Why does the member(cons z (cons y nil)) return nil even when in the first iteration we can see (1 2) exists in the list?
Edit:
Currently even when it is true it returns nil, why would this be the case given the following code?
(defun countVertexTriangles (graph numOfVertices)
(findTriangle graph numOfVertices)
)
(defun findTriangle(graph numOfVertices)
(loop for (x y) in graph do
(loop for z from 1 to numOfVertices do
; (write graph)
; (terpri)
; (write (list z y ))
; (terpri)
(write (findEdge graph (list z y)))
(terpri)
; (if (AND (member (list z x) graph) (member (list z x ) graph))
; then (write "TEST")
; )
)
(terpri)
)
)
(defun findEdge(graph edge)
(loop for x in graph do
(if (equal x edge)
(return-true)
(return-false)
)
)
)
(defun return-true ()
t)
(defun return-false ()
nil)
(defun testFunct ()
(setf g1 '((1 2)(2 3)(1 3)(2 4)(3 4)(4 5)(3 5)))
(countVertexTriangles g1 5)
)
findEdge doesn't return anything. Calling return-true and return-false doesn't return from findEdge. You also shouldn't return until you find a match.
(defun findEdge(graph edge)
(loop for x in graph do
(if (equal x edge)
(return-from findEdge (return-true))
)
)
(return-false)
)
This can be simplified to just:
(defun findEdge (graph edge)
(member edge findEdge :test #'equal))
Related
Starting to learn LISP and wrote two simple programs, which uses functions as params.
The first:
;gnu clisp 2.49.60
(defun pf (x f123) (cond ((null x) nil)
(T (cons ( f123 (car x) ) (pf (cdr x) f123)))))
(defun f2 (x) (* x x))
(print (pf '(1 2 3 4) 'f2 ) )
The second:
(defun some1(P1 P2 x)
(if (not( = (length x) 0))
(cond
(
(or ( P1 (car x) ) ( P2 (car x)) )
(cons (car x) (some1 P1 P2 (cdr x) ))
)
(t (some1 P1 P2 (cdr x) ))
)
)
)
(print (some1 'atom 'null '( 5 1 0 (1 2) 10 a b c) ) )
The both of program aren't working. And I don't know how to fix it :(
(funcall f123 x y z) is works, so results:
;gnu clisp 2.49.60
(defun pf (x f123)
(cond ((null x) nil)
(T (cons (funcall f123 (car x))
(pf (cdr x) f123)))))
(defun f2 (x) (* x x))
(print (pf '(1 2 3 4) 'f2))
And
;gnu clisp 2.49.60
(defun eq0(x)
(if (= x 0)
t
nil))
(defun bg10(x)
(if (> x 10)
t
nil))
(defun some1 (P1 P2 x)
(if (not (= (length x) 0))
(cond
((or (funcall P1 (car x)) (funcall P2 (car x)))
(cons (car x) (some1 P1 P2 (cdr x))))
(t (some1 P1 P2 (cdr x))))))
(print (some1 'eq0 'bg10 '(5 0 0 11)))
Maybe it will be useful for someone :)
The function i'm looking for has to return the index of the first , that is out of a pair of " ".
For example, with the sequence
{ " h i , a l l " : 3 , " h o w , i s " : " x " }
'( #\{ #\" #\h #\i #\, #\a #\l ... )
The function should return 11, not 4 (first occurrence of comma) because it is between " ".
I tried with this:
(defun control-comma (x p)
(cond ((eql (car x) #\")
(control-comma (subseq x (+ (position #\" x :start (+ 1 p)) 1)) p))
((eql (car x) #\,)
p)
(t
(control-comma (cdr x) (+ 1 p)))
)
)
Using x as list of input and p as a 0-parameter to count the position, but it doesn't work and seems to be far away from the solution i'm looking for.
Thank you for every suggestion.
Instead of defining a complex function, I suggest you to use the predefined position-if operator:
(defun first-comma (string start)
(let ((in-double-quote nil))
(position-if
(lambda (x)
(case x
((#\") (progn (setf in-double-quote (not in-double-quote)) nil))
((#\,) (not in-double-quote))))
string
:start start)))
CL-USER> (first-comma (coerce "{ \"hi, all\" : 3, \"how, is\" : \"x\" }" 'list) 0)
15
A more complex, recursive solution based again on the idea of scanning the input list one character at time, is given by the following function, where the state “inside double-quote” is encoded through a couple of recursive local functions:
(defun fist-comma (x pos)
(labels ((looking-for-comma (x pos)
(cond ((null x) nil)
((eql (car x) #\,) pos)
((eql (car x) #\") (looking-for-double-quote (cdr x) (1+ pos)))
(t (looking-for-comma (cdr x) (1+ pos)))))
(looking-for-double-quote (x pos)
(cond ((null x) nil)
((eql (car x) #\") (looking-for-comma (cdr x) (1+ pos)))
(t (looking-for-double-quote (cdr x) (1+ pos))))))
(looking-for-comma (nthcdr pos x) pos)))
Finally, note that in both the above functions one should take into account possible escaping of the double quote with appropriate means.
I don't understand why my program is behaving as it does.
(defvar A '((X Y Z) (J L O P) (G W U))
(defvar Z '(X W D U G))
(defvar STOP 'G)
(defun ADD_to_Z(A2)
(prog()
(cond
((equal (Member_Of_Z (list A2)) 0) )
(t (setq Z (append Z (list A2))) )
)
)
)
(defun Member_of_Z(cdr_A1)
(prog(n temp)
(setq n 0)
(setq temp cdr_A1)
repeat
(cond
((null temp) (return n))
((null (member (car temp) Z) ) (setq n (+ n 1)) (setq temp (cdr temp)))
(t (setq n (+ n 0)) (setq temp (cdr temp)))
)
(go repeat)
)
)
(defun TEST(A)
(prog(A1 A2)
(cond
((null A ) (return 'Fail))
(t (setq A1 (car A)) (setq A (cdr A)) (setq A2 (car A1))
(cond
((equal (Member_Of_Z (cdr A1)) 0)
(cond
((equal A2 STOP) (return 'SUCCESS))
(t (ADD_to_Z A2) (setq A (cdr A)) (TEST A) )
)
)
(t (TEST A) )
)
)
)
)
)
Goal of the functions :
- Member_of_Z will verify if all elements of cdr A1 belong to Z. If they do , it will return 0 (some other number else otherwise). This is what is not happening It was suppose to return SUCCESS when A is equal to ((G W U))
ADD_to_Z will add A2 to Z when Member_Of_Z does not return 0
Problem : Not only A seems to be never modified (at the end of the function TEST, A is still equal to its original value set by defvar even though I'm modifying it with (setq A (cdr A)). Also SUCCESS is never returned.
Could you help me ?
Step 1: use standard formatting (repairing the first toplevel form).
(defvar A '((X Y Z) (J L O P) (G W U)))
(defvar Z '(X W D U G))
(defvar STOP 'G)
(defun ADD_to_Z (A2)
(prog ()
(cond ((equal (Member_Of_Z (list A2)) 0))
(t (setq Z (append Z (list A2)))))))
(defun Member_of_Z (cdr_A1)
(prog (n temp)
(setq n 0)
(setq temp cdr_A1)
repeat
(cond ((null temp) (return n))
((null (member (car temp) Z) ) (setq n (+ n 1)) (setq temp (cdr temp)))
(t (setq n (+ n 0)) (setq temp (cdr temp))))
(go repeat)))
(defun TEST (A)
(prog (A1 A2)
(cond ((null A ) (return 'Fail))
(t (setq A1 (car A))
(setq A (cdr A))
(setq A2 (car A1))
(cond ((equal (Member_Of_Z (cdr A1)) 0)
(cond ((equal A2 STOP) (return 'SUCCESS))
(t (ADD_to_Z A2) (setq A (cdr A)) (TEST A) )))
(t (TEST A)))))))
Step 2: use standard naming.
(defvar *a* '((x y z) (j l o p) (g w u)))
(defvar *z* '(x w d u g))
(defvar *stop* 'g)
(defun add-to-z (a2)
(prog ()
(cond ((equal (member-of-z (list a2)) 0))
(t (setq *z* (append *z* (list a2)))))))
(defun member-of-z (cdr-a1)
(prog (n temp)
(setq n 0)
(setq temp cdr-a1)
repeat
(cond ((null temp) (return n))
((null (member (car temp) *z*)) (setq n (+ n 1)) (setq temp (cdr temp)))
(t (setq n (+ n 0)) (setq temp (cdr temp))))
(go repeat)))
(defun test (a)
(prog (a1 a2)
(cond ((null a) (return 'fail))
(t (setq a1 (car a))
(setq a (cdr a))
(setq a2 (car a1))
(cond ((equal (member-of-z (cdr a1)) 0)
(cond ((equal a2 *stop*) (return 'success))
(t (add-to-z a2) (setq a (cdr a)) (test a))))
(t (test a)))))))
Step 3: get rid of PROG.
(defvar *a* '((x y z) (j l o p) (g w u)))
(defvar *z* '(x w d u g))
(defvar *stop* 'g)
(defun add-to-z (a2)
(cond ((equal (member-of-z (list a2)) 0))
(t (setq *z* (append *z* (list a2))))))
(defun member-of-z (cdr-a1)
(let ((n 0)
(temp cdr-a1))
repeat
(cond ((null temp) (return n))
((null (member (car temp) z)) (setq n (+ n 1)) (setq temp (cdr temp)))
(t (setq n (+ n 0)) (setq temp (cdr temp))))
(go repeat)))
(defun test (a)
(cond ((null a) (return 'fail))
(t (let ((a1 (car a))
(a (cdr a))
(a2 (car a1)))
(cond ((equal (member-of-z (cdr a1)) 0)
(cond ((equal a2 *stop*) (return 'success))
(t (add-to-z a2) (setq a (cdr a)) (test a))))
(t (test a)))))))
Step 4: replace hand-rolled loop with a structured one.
(defvar *a* '((x y z) (j l o p) (g w u)))
(defvar *z* '(x w d u g))
(defvar *stop* 'g)
(defun add-to-z (a2)
(cond ((equal (member-of-z (list a2)) 0))
(t (setq *z* (append *z* (list a2))))))
(defun member-of-z (cdr-a1)
(let ((n 0)
(temp cdr-a1))
(loop :for element :in temp
:unless (member element *z*)
:do (incf n))
n))
(defun test (a)
(cond ((null a) (return 'fail))
(t (let ((a1 (car a))
(a (cdr a))
(a2 (car a1)))
(cond ((equal (member-of-z (cdr a1)) 0)
(cond ((equal a2 *stop*) (return 'success))
(t (add-to-z a2) (setq a (cdr a)) (test a))))
(t (test a)))))))
Step 5: replace two-clause COND with IF. Reduce RETURN forms when they are in
tail position anyway (and they don't work like that).
(defvar *a* '((x y z) (j l o p) (g w u)))
(defvar *z* '(x w d u g))
(defvar *stop* 'g)
(defun add-to-z (a2)
(if (equal (member-of-z (list a2)) 0)
nil
(setq *z* (append *z* (list a2)))))
(defun member-of-z (cdr-a1)
(let ((n 0)
(temp cdr-a1))
(loop :for element :in temp
:unless (member element *z*)
:do (incf n))
n))
(defun test (a)
(if (null a)
'fail
(let ((a1 (car a))
(a (cdr a))
(a2 (car a1)))
(if (equal (member-of-z (cdr a1)) 0)
(if (equal a2 *stop*)
'success
(progn (add-to-z a2) (setq a (cdr a)) (test a)))
(test a)))))
Step 6: replace loop with simple counting function.
(defvar *a* '((x y z) (j l o p) (g w u)))
(defvar *z* '(x w d u g))
(defvar *stop* 'g)
(defun add-to-z (a2)
(if (equal (member-of-z (list a2)) 0)
nil
(setq *z* (append *z* (list a2)))))
(defun member-of-z (cdr-a1)
(count-if-not (lambda (element)
(member element *z*))
cdr-a1))
(defun test (a)
(if (null a)
'fail
(let ((a1 (car a))
(a (cdr a))
(a2 (car a1)))
(if (equal (member-of-z (cdr a1)) 0)
(if (equal a2 *stop*)
'success
(progn
(add-to-z a2)
(setq a (cdr a))
(test a)))
(test a)))))
At this point, I still have no idea what you are trying to do. Perhaps you want
to find a list in *a* that is completely contained in *z*:
(defun test (a)
(find-if (lambda (list)
(every (lambda (element)
(member element *z*))
list))
a))
I have a non-linear list. I need to find out the number of sub-lists at any level in the initial list, for which the sum of the numerical atoms at the odd levels, is an even number. The superficial level is counted as 1. I wrote something like:
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
)
)
(defun verify (n)
;returns true if the parameter "n" is even, or NIL, otherwise
(cond
((numberp n)(= (mod n 2) 0))
(T f)
)
)
(defun sumlist (l)
;returns the sum of the numerical atoms from a list, at its superficial level
(cond
((null l) 0)
((numberp (car l)) (+ (car l) (sumlist(cdr l))))
(T (sumlist(cdr l)))
)
)
(defun mainNumbering (l)
; main function, for initializing the level with 1
(numbering l 1)
)
If I run "(mainnum '(1 2 (a b 4) 8 (6 g)))" I get the error: " Undefined function MAPCAR# called with arguments ((LAMBDA (A) (NUMEROTARE A #)) (1 2 (A B 4) 8 (6 G)))."
Does anyone know, what am I missing? Thanks in advance!
Well, that's true, there is no such function as mapcar#, it's just a typo, you missing space in this line:
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
It should be:
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
Here is a possible solution, if I have interpreted correctly your specification:
(defun sum(l)
(loop for x in l when (numberp x) sum x))
(defun test(l &optional (level 1))
(+ (if (and (oddp level) (evenp (sum l))) 1 0)
(loop for x in l when (listp x) sum (test x (1+ level)))))
(test '(1 2 (a b 4) 7 (6 2 g) (7 1 (2 (3) (4 4) 2) 1 a))) ; => 2
The function sum applied to a list returns the sum of all its numbers (without entering in its sublists).
The function test, for a list with an odd level, sum its numbers, and, if the result is even, add 1 to the sum of the results of the function applied to the sublists of l, 0 otherwise.
in numbering you should add the case when l is a number,so
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((atom l)0)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar #' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
)
)
will resolve the problem
I don't understand the purpose of the 1st LET in condlet-clause below.
`(,(car cl) (let ,(mapcar #'cdr vars)
Is this necessary since it does not define specific value here?
It just declare the local variables instead. Why bother to do this?
(defmacro condlet (clauses &body body)
(let ((bodfn (gensym))
(vars (mapcar #'(lambda (v) (cons v (gensym)))
(remove-duplicates
(mapcar #'car
(mappend #'cdr clauses))))))
`(labels ((,bodfn ,(mapcar #'car vars)
,#body))
(cond ,#(mapcar #'(lambda (cl)
(condlet-clause vars cl bodfn))
clauses)))))
(defun condlet-clause (vars cl bodfn)
`(,(car cl) (let ,(mapcar #'cdr vars)
(let ,(condlet-binds vars cl)
(,bodfn ,#(mapcar #'cdr vars))))))
(defun condlet-binds (vars cl)
(mapcar #'(lambda (bindform)
(if (consp bindform)
(cons (cdr (assoc (car bindform) vars))
(cdr bindform))))
(cdr cl)))
Based on this implementation of CONDLET, condlet can be used like this:
(condlet (((= 1 2) (x 1) (y 2))
((= 1 1) (x 2) (y 1))
(t (x 3) (z 3)))
(list x y z))
Notice that there are three variables that appear in the body part, x, y, and z, but each of those clauses only binds two: the first and second bind x and y, and the third binds x and z. By doing
(let (x y z)
(let <bindings from actual clause>
(bodyfn x y z)))
the macro guarantees that x, y, and z all have default values of nil. The <bindings from actual clause> will lexically shadow the variables that the actual clause is responsible for binding. That's a bit of a simplification, though. To see what's actually happening, let's look at the macroexpansion of that example:
(pprint (macroexpand-1 '(condlet (((= 1 2) (x 1) (y 2))
((= 1 1) (x 2) (y 1))
(t (x 3) (z 3)))
(list x y z))))
;=>
(LABELS ((#:G973 (Y X Z) ; g973 = bodfn
(LIST X Y Z)))
(COND
((= 1 2)
(LET (#:G974 #:G975 #:G976) ; y(g974) = nil, x(g975) = nil, z(g976) = nil
(LET ((#:G975 1) (#:G974 2)) ; x = 1, y = 2
(#:G973 #:G974 #:G975 #:G976)))) ; (bodfn y x z)
((= 1 1)
(LET (#:G974 #:G975 #:G976) ; y = nil, x = nil, z = nil
(LET ((#:G975 2) (#:G974 1)) ; x = 2, y = 1
(#:G973 #:G974 #:G975 #:G976)))) ; (bodfn y x z)
(T
(LET (#:G974 #:G975 #:G976) ; y = nil, x = nil, z = nil
(LET ((#:G975 3) (#:G976 3)) ; x = 3, z = 4
(#:G973 #:G974 #:G975 #:G976)))))) ; (bodfn y x z)