From: Colette Hughes
Subject: need help again!
Date: 
Message-ID: <3A9C8B89.78773AEA@yahoo.com>
Hi. all.

I just modified my Lisp program and run it successfully,

Please see the following.

Programs
********************
transitive closure of R
*********************
(defun transi(f)
   (setq f1 nil)
   (mapcar (lambda(x) (setq f1 (append f1 (tran1 (car x) (cadr x) f))))
f)
   f1)

(defun tran1(a b f)
   (setq s nil)
   (loop  (setq s (append s (list (list a b))))
          (if (assoc b f) (setq b (cadr (assoc b f))) (return))
          (if (find1 (list a b) (append f s)) (return)))
   s)
 ********************
Reflective closure of R
*********************
(defun reflex(f)
    (setq f1 f)
    (mapcar (lambda(x) (if (find1 (reverse x) f) nil (setq f1 (append
f1 (list(reverse x))))))f)
    f1)

(defun find1(a s)
    (setq n nil)
    (mapcar (lambda(x) (if (equal a x) (setq n 't) nil)) s)  n)
********************
reflective transitive closure of R
*********************
(defun reftran(f)
    (print (reflex (transi f))))


********************
canonical form( it will transit the program to the end .
*********************
(defun canon(a f)
 (mapcan(lambda(x) (if (equal a (car x))(if (assoc(cadr x)f) nil
(list(cadr x))))) (transi f)))


; test inputs
;(transi  '((a b) (b c) (b k) (c e) ))
;(transi  '((a b) (b c) (d e) (c e) ))
;(transi  '((a b) (b c) (b k) (c e) ))
;(transi  '((a b) (a c) (d e) (c e) ))
(transi  '((a b) (b d) (d f) (b c) (c e) ))
;(reflex  '((a b) (a c) (d e) (c e) ))
;(reftran '((a b) (a c) (d e) (c e) ))
;(canon 'a '((a b) (a c) (d e) (c e) (e f)))
;(canon 'b '((a b) (b c) (d e) (c b) ))

**********************************
can you help me to change LOOP to the other recursive language.? I need
to modify recursive in two expression.

One more question. I tried to add the print command in first and second
parts, but when I run  the  (print (reflex (transi f))))   it will
express outcome twice.
What's wrong?

When I did the transitive closure. there always has the (a b) (a c)
..... at the last , it always has .....
I don't know how to erase ".....".


Waiting your reply.

Thanks

From: Janis Dzerins
Subject: Re: need help again!
Date: 
Message-ID: <87ae772jpm.fsf@asaka.latnet.lv>
Colette Hughes <········@yahoo.com> writes:

> can you help me to change LOOP to the other recursive language.? I need
> to modify recursive in two expression.

I don't understand what you want here.

> One more question. I tried to add the print command in first and second
> parts, but when I run  the  (print (reflex (transi f))))   it will
> express outcome twice.
> What's wrong?

When one enters expressions in top-level, it evaluates the expression
and prints the result of the expression. Function print returns the
object it prints. So you see what PRINT prints and the result of the
expression, which is the same as what is printed out.

(You don't have to print the result of expression entered in top-level
-- it does it for you).

> When I did the transitive closure. there always has the (a b) (a c)
> ..... at the last , it always has .....
> I don't know how to erase ".....".

Try setting *print-length* to nil (consult Common Lisp HyperSpec if
you really want to learn more).

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Thomas A. Russ
Subject: Re: need help again!
Date: 
Message-ID: <ymi66hsq8tc.fsf@sevak.isi.edu>
Janis Dzerins <·····@latnet.lv> writes:

> Colette Hughes <········@yahoo.com> writes:
>
> > When I did the transitive closure. there always has the (a b) (a c)
> > ..... at the last , it always has .....
> > I don't know how to erase ".....".
> 
> Try setting *print-length* to nil (consult Common Lisp HyperSpec if
> you really want to learn more).

I will note that some Lisp systems use a different special variable to
control the print-length at the top level.  Allegro Common Lisp (ACL) is
one of them.  It uses TPL:*PRINT-LENGTH* for printing in the top level
read-eval-print loop.

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Martti Halminen
Subject: Re: need help again!
Date: 
Message-ID: <3A9D505A.625BD008@solibri.com>
Colette Hughes wrote:

> Programs
> ********************
> transitive closure of R
> *********************
> (defun transi(f)
>    (setq f1 nil)
>    (mapcar (lambda(x) (setq f1 (append f1 (tran1 (car x) (cadr x) f))))
> f)
>    f1)

Some style points:

 - Unless you specifically intend to use F1 (or is that FL ?) as a
special variable outside this function, it should be defined using LET
instead of SETQ. (In this case it works, but generally unintended use of
special variables is a serious risk of bugs. For example, if your
function TRAN1 also used it, the results here would be rather
unpredictable.) LET uses lexical scoping, i.e. the variable only exists
inside its textual extent, so it is safer. Faster, too, in
performance-critical places.

 - MAPCAR returns a value. As you are not using the value here, why not
use MAPC instead?

 - I tend to use  #'(lambda ... ) instead of a bare (lambda ...). Both
are legal code, but the explicit #' makes it more visible that here we
are playing with functions intead of data.

 - You could use FIRST and SECOND instead of CAR and CADR. They are
functionally identical, but some people find them more readable.


> (defun tran1(a b f)
>    (setq s nil)
>    (loop  (setq s (append s (list (list a b))))
>           (if (assoc b f) (setq b (cadr (assoc b f))) (return))
>           (if (find1 (list a b) (append f s)) (return)))
>    s)

(defun tran1(a b f)
  (let ((s nil))
    (loop
      (setq s (append s (list (list a b))))
      (if (assoc b f)
          (setq b (cadr (assoc b f)))
        (return))
      (when (find1 (list a b) (append f s))
        (return)))
    s))

- Here I indented this in a more usual style. Writing an IF statement
all on one line makes separating its parts rather painful: you have to
count parentheses. It's better to let your editor do that. (In case
nobody has told you, most of serious Lisp programmers use some variant
of Emacs, because it has very good support for Lisp programming.)

- I prefer using WHEN instead of IF when I don't have an ELSE -branch:
no time needed to find out whether there is an ELSE clause or not.

>  ********************
> Reflective closure of R
> *********************
> (defun reflex(f)
>     (setq f1 f)
>     (mapcar (lambda(x) (if (find1 (reverse x) f) nil (setq f1 (append
> f1 (list(reverse x))))))f)
>     f1)


(defun reflex (f)
  (let ((f1 f))
    (mapc #'(lambda (x)
              (if (find1 (reverse x) f)
                  nil
                (setq f1 (append f1 (list(reverse x))))))
          f)
    f1))
- Re-indented for better readability


> (defun find1(a s)
>     (setq n nil)
>     (mapcar (lambda(x) (if (equal a x) (setq n 't) nil)) s)  n)

- This has the usual problems, but the bigger question is, why not use
already existing parts of the language? I'd replace this with:

(member a s :test #'equal)


> ********************
> canonical form( it will transit the program to the end .
> *********************
> (defun canon(a f)
>  (mapcan(lambda(x) (if (equal a (car x))(if (assoc(cadr x)f) nil
> (list(cadr x))))) (transi f)))

(defun canon(a f)
  (mapcan #'(lambda(x)
              (if (equal a (car x))
                  (if (assoc (cadr x) f)
                      nil
                    (list(cadr x)))))
          (transi f)))

- Again, this is more readable with better indentation.

Two alternate ways of doing approximately the same thing:

(defun canon2 (a f)
  (loop for x in (transi f)
      if (equal a (car x))
      unless (assoc (cadr x) f)
      collect (cadr x)))

(defun canon3 (a f)
  (let ((result nil))
    (dolist (x (transi f))
      (when (and (equal a (car x))
                 (not (assoc (cadr x) f)))
        (push (cadr x) result)))
    (nreverse result)))


> can you help me to change LOOP to the other recursive language.? I need
> to modify recursive in two expression.

Why bother? Iteration is a quite well-working construct in CL.
(OK, recursion is nice, too, when used in correct places. Generally,
it's best in working with recursive data structures, especially trees.)

Usually, I write my recursive list-handling functions with this kind of
template:

(defun <my-func> (<arg>)
  "doc string here"
  (cond ((null <arg>) <do something. Often, return NIL.>)
        ((atom <arg>) <do something else>)
        (T (<combiner-func> (<handle-first-element> (first <arg>))
                            (<my-func> (rest <arg>))))))



> One more question. I tried to add the print command in first and second
> parts, but when I run  the  (print (reflex (transi f))))   it will
> express outcome twice.
> What's wrong?

Probably nothing. Sounds like the normal interaction of a function and
the Lisp toplevel read-eval-print -loop. PRINT has a side effect: it
prints its argument with whatever printer control variable settings are
current, and a result: it returns its argument. And, whenever you
evaluate something in Lisp toplevel, it calls PRINT on the result. So,
try it without the explicit PRINT call.


> When I did the transitive closure. there always has the (a b) (a c)
> ..... at the last , it always has .....
> I don't know how to erase ".....".

Sounds like normal printer operation; Allegro produces only ... ,
though.
Read the documentation on *PRINT-LENGTH*. (Or call PPRINT instead of
PRINT.)(On Allegro also see TPL:*PRINT-LENGTH*.)

--