From: javi
Subject: How to replace elements on a list
Date: 
Message-ID: <46edbc21$1_3@filemon1.isp.telecable.es>
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

From: ··············@gmail.com
Subject: Re: How to replace elements on a list
Date: 
Message-ID: <1189989202.151362.163780@y42g2000hsy.googlegroups.com>
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)))
From: Tamas Papp
Subject: Re: How to replace elements on a list
Date: 
Message-ID: <871wcyuo9o.fsf@pu100877.student.princeton.edu>
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
From: Chris Russell
Subject: Re: How to replace elements on a list
Date: 
Message-ID: <1189988821.013375.259260@k79g2000hse.googlegroups.com>
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.
From: Rainer Joswig
Subject: Re: How to replace elements on a list
Date: 
Message-ID: <joswig-1B0CAB.11000917092007@news-europe.giganews.com>
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
From: Gene
Subject: Re: How to replace elements on a list
Date: 
Message-ID: <1190166521.729130.319270@22g2000hsm.googlegroups.com>
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)))