Hi,
I'm working on a function that receives a list like this:
(c1 (p ?x ?y) <- (q ?x ?y) (r ?y ?z))
and looks for each element that starts with a '?' and makes the following
substitution: replace ?x with (? "x"), so after executing the module on
the previous example it will look like this:
(c1 (p (? "x") (? "y")) <- (q (? "x") (? "y")) (r (? "y") (? "z")))
I've made a recursive function that analyses each element of list, and any
time it finds a variable (?x element) makes the substitution. But I don't
know how to make this substitution, the code looks like this:
(defun convert_rule (rule)
(let
((elto nil))
; for each element on list
(dolist (elto rule)
(cond
; if it's a list, call function again
((listp elto)
(format t "(")
(convert_rule elto)
(format t ")"))
; is-variable returns T when it's a ?x element
((is-variable elto)
;;; My problem is here, I don't know how to transform
;;; ?x in (? "x")
;;; Also I don't know how to rejoin all elements
;;; in a new list, for the time being I use format
;;; to show it on screen
)
; if it isn't a variable or a list, do nothing
(t
(format t " ~S " elto))
) ;cond
) ;dolist
) ;let
) ;defun
Any help on this would be very appreciated
thanks in advance
javi wrote:
> Hi,
>
> I'm working on a function that receives a list like this:
>
> (c1 (p ?x ?y) <- (q ?x ?y) (r ?y ?z))
>
> and looks for each element that starts with a '?' and makes the following
> substitution: replace ?x with (? "x"), so after executing the module on
> the previous example it will look like this:
>
>
> (c1 (p (? "x") (? "y")) <- (q (? "x") (? "y")) (r (? "y") (? "z")))
>
> I've made a recursive function that analyses each element of list, and any
> time it finds a variable (?x element) makes the substitution. But I don't
> know how to make this substitution, the code looks like this:
>
> (defun convert_rule (rule)
> (let
> ((elto nil))
>
> ; for each element on list
> (dolist (elto rule)
> (cond
> ; if it's a list, call function again
> ((listp elto)
> (format t "(")
> (convert_rule elto)
> (format t ")"))
>
> ; is-variable returns T when it's a ?x element
> ((is-variable elto)
> ;;; My problem is here, I don't know how to transform
> ;;; ?x in (? "x")
> ;;; Also I don't know how to rejoin all elements
> ;;; in a new list, for the time being I use format
> ;;; to show it on screen
> )
>
> ; if it isn't a variable or a list, do nothing
> (t
> (format t " ~S " elto))
> ) ;cond
> ) ;dolist
> ) ;let
> ) ;defun
>
> Any help on this would be very appreciated
>
> thanks in advance
You could try to push elements onto a temporary list then reverse the
list before returning it from the defun. Also, (list '? (substring
(symbol-name elto) 1)) will return (? "x") if elto is ?x.
So your code would become something like this:
(defun convert_rule (rule)
(let (tmp-list)
(dolist (elto rule)
(cond
; if it's a list, call function again
((listp elto)
(push (convert_rule elto) tmp-list))
; is-variable returns T when it's a ?x element
((is-variable elto)
(push (list '? (substring (symbol-name elto) 1)) tmp-list))
; if it isn't a variable or a list, do nothing
(t
(push elto tmp-list))))
(reverse tmp-list)))
javi <·············@hotmail.com> writes:
> Hi,
>
> I'm working on a function that receives a list like this:
>
> (c1 (p ?x ?y) <- (q ?x ?y) (r ?y ?z))
>
> and looks for each element that starts with a '?' and makes the following
> substitution: replace ?x with (? "x"), so after executing the module on
> the previous example it will look like this:
>
>
> (c1 (p (? "x") (? "y")) <- (q (? "x") (? "y")) (r (? "y") (? "z")))
>
> I've made a recursive function that analyses each element of list, and any
> time it finds a variable (?x element) makes the substitution. But I don't
> know how to make this substitution, the code looks like this:
>
> (defun convert_rule (rule)
> (let
> ((elto nil))
>
> ; for each element on list
> (dolist (elto rule)
> (cond
> ; if it's a list, call function again
> ((listp elto)
> (format t "(")
> (convert_rule elto)
> (format t ")"))
>
> ; is-variable returns T when it's a ?x element
> ((is-variable elto)
> ;;; My problem is here, I don't know how to transform
> ;;; ?x in (? "x")
> ;;; Also I don't know how to rejoin all elements
> ;;; in a new list, for the time being I use format
> ;;; to show it on screen
Look at symbol-name and keyword for transforming symbols into strings,
where you can split them, and transforming back. (list '? "x") will
create lists.
Generally, manipulating symbol names as strings is a powerful
technique but I am not sure what is the actual problem you are trying
to solve. Is this homework?
> )
>
> ; if it isn't a variable or a list, do nothing
> (t
> (format t " ~S " elto))
> ) ;cond
> ) ;dolist
> ) ;let
> ) ;defun
>
This is not proper Lisp style, don't put lone parens on a new line by
themselves. Also, any decent editor/IDE will highlight the matching
paren, no need for comments like the ones above.
It appears that you are a newbie, I am not sure that manipulating
symbol names with techniques like this is what you should be doing on
day 1.
Tamas
On 17 Sep, 00:28, javi <·············@hotmail.com> wrote:
> ) ;cond
> ) ;dolist
> ) ;let
> ) ;defun
>
> Any help on this would be very appreciated
>
> thanks in advance
Have a look on the hyperspec, http://clhs.lisp.se/Front/index.htm for
symbol-name, push and nreverse, and try creating a function that
passes the reversed output as an accumulator parameter.
You should also try using an editor that highlights whole s-
expressions, so you don't have to comment to say what you are closing.
In article <············@filemon1.isp.telecable.es>,
javi <·············@hotmail.com> wrote:
> Hi,
>
> I'm working on a function that receives a list like this:
>
> (c1 (p ?x ?y) <- (q ?x ?y) (r ?y ?z))
>
> and looks for each element that starts with a '?' and makes the following
> substitution: replace ?x with (? "x"), so after executing the module on
> the previous example it will look like this:
>
>
> (c1 (p (? "x") (? "y")) <- (q (? "x") (? "y")) (r (? "y") (? "z")))
>
> I've made a recursive function that analyses each element of list, and any
> time it finds a variable (?x element) makes the substitution. But I don't
> know how to make this substitution, the code looks like this:
>
> (defun convert_rule (rule)
> (let
> ((elto nil))
>
> ; for each element on list
> (dolist (elto rule)
> (cond
> ; if it's a list, call function again
> ((listp elto)
> (format t "(")
> (convert_rule elto)
> (format t ")"))
>
> ; is-variable returns T when it's a ?x element
> ((is-variable elto)
> ;;; My problem is here, I don't know how to transform
> ;;; ?x in (? "x")
> ;;; Also I don't know how to rejoin all elements
> ;;; in a new list, for the time being I use format
> ;;; to show it on screen
> )
>
> ; if it isn't a variable or a list, do nothing
> (t
> (format t " ~S " elto))
> ) ;cond
> ) ;dolist
> ) ;let
> ) ;defun
>
> Any help on this would be very appreciated
>
> thanks in advance
You would write/use a general function that MAPs a function over a tree.
There is nothing rule-specific to this. The function you pass there
just has to return the right thing: if it is a variable it returns
the 'substitution', otherwise it returns the original element.
--
http://lispm.dyndns.org
On Sep 16, 7:28 pm, javi <·············@hotmail.com> wrote:
> Hi,
>
> I'm working on a function that receives a list like this:
>
> (c1 (p ?x ?y) <- (q ?x ?y) (r ?y ?z))
>
> and looks for each element that starts with a '?' and makes the following
> substitution: replace ?x with (? "x"), so after executing the module on
> the previous example it will look like this:
>
> (c1 (p (? "x") (? "y")) <- (q (? "x") (? "y")) (r (? "y") (? "z")))
>
> I've made a recursive function that analyses each element of list, and any
> time it finds a variable (?x element) makes the substitution. But I don't
> know how to make this substitution, the code looks like this:
>
> (defun convert_rule (rule)
> (let
> ((elto nil))
>
> ; for each element on list
> (dolist (elto rule)
> (cond
> ; if it's a list, call function again
> ((listp elto)
> (format t "(")
> (convert_rule elto)
> (format t ")"))
>
> ; is-variable returns T when it's a ?x element
> ((is-variable elto)
> ;;; My problem is here, I don't know how to transform
> ;;; ?x in (? "x")
> ;;; Also I don't know how to rejoin all elements
> ;;; in a new list, for the time being I use format
> ;;; to show it on screen
> )
>
> ; if it isn't a variable or a list, do nothing
> (t
> (format t " ~S " elto))
> ) ;cond
> ) ;dolist
> ) ;let
> ) ;defun
>
> Any help on this would be very appreciated
>
> thanks in advance
This is a very un-lisp-like thing to do. I hope it isn't homework.
If it's part of a serious project, consider redesigning.
You are also confusing printing and computing s-expressions (which are
printed automatically by the r-e-p loop if you are interacting with an
interpreter).
The code below will do the trick you asked for. Study this and read
the Hyperspec. Get a decent Lisp, editor, too. You'll drive yourself
nuts indenting and balancing parens by hand, and your code will be
forever ugly. ;-)
(defun replace-?-syms (x)
(typecase x
(symbol
(let ((name (symbol-name x)))
(if (char= (char name 0) #\?)
`(? ,(string (char name 1)))
x)))
(cons
(cons (replace-?-syms (car x))
(replace-?-syms (cdr x))))
(t x)))