From: dave madden
Subject: [Q] equality of symbols?
Date: 
Message-ID: <3A0A3C6A.2B05D9FC@loopback.mersenne.com>
I'm slowly approaching my goal of a genetic system to solve the
even-3-parity problem described in _Genetic_Programming_III_: I can
create an initial random population, evaluate each individual, and
produce new individuals by swapping subtrees from parents.  However, I
can't get the new individuals to execute, because the half the symbols
are from each parent, and although they have the same print name, they
are somehow different.

That is, I create individuals:

(defstruct auto-function
  args          ; (arg0 arg1 arg2 fun0)
  flets         ; ((adf0 (&rest args) (apply fun0 args)))
  body          ; body form, e.g. (and arg0 (adf0 arg1))
  compiled-code ; (eval `(lambda ,args (flet ,flets ,body)))
  adfs          ; list of single-arg auto-functions
  )

Each individual's :compiled-code can be executed:

(apply (auto-function-compiled-code i) (append '(t t nil)
(auto-function-adfs i)))
  => t or nil, depending on the ADF (==Automatically Defined Function)

[The business with the "fun0" argument seems crufty, but was the first
way I was able to pass in an independent lambda expression and call it
cleanly from within the auto function.  I can -- I believe -- swap in
arbitrary functions, even from unrelated individuals, as long as the
number of arguments are the same.]

However, when I combine code from two individuals to produce an
offspring, its :compiled-code complains about unused arguments
"#:|arg0|", "#:|arg1|", and "#:|arg2|"; and undefined variables
"#:|arg0|", "#:|arg1|", and "#:|arg2|".

When building the pieces of the auto-function, I create the symbols by
running make-symbol on a string...but I believe I'll have to do
something else instead.

Can anybody suggest a good next step?

thanks,
d.
-- 
header address is anti-spamified.  use caution when replying by
email to  <···@loopback.mersenne.com>  because my real address
omits the hostname.

From: Thomas A. Russ
Subject: Re: [Q] equality of symbols?
Date: 
Message-ID: <ymik8ad11un.fsf@sevak.isi.edu>
dave madden <··········@loopback.mersenne.com> writes:

> (apply (auto-function-compiled-code i) (append '(t t nil)
> (auto-function-adfs i)))
>   => t or nil, depending on the ADF (==Automatically Defined Function)

Style note:  You don't need the APPEND call.  APPLY takes a variable
number of arguments, culminating in a list so you could just write:

 (apply (auto-function-compiled-code i) t t nil (auto-function-adfs i))



Kent Pitman answered the following in some detail, so I'll just put in a
few short comments:

> However, when I combine code from two individuals to produce an
> offspring, its :compiled-code complains about unused arguments
> "#:|arg0|", "#:|arg1|", and "#:|arg2|"; and undefined variables
> "#:|arg0|", "#:|arg1|", and "#:|arg2|".
> 
> When building the pieces of the auto-function, I create the symbols by
> running make-symbol on a string...but I believe I'll have to do
> something else instead.

Well, the simplest solution might be to use INTERN instead of
MAKE-SYMBOL.

Otherwise would need to physically substitute the actual symbol object
and not use its name.  A code walker would be the safest way to do it,
but you may be able to use SUBST as a simple although less safe
alternative.  It still means that when using uninterned symbols, you
always need to get the symbol object itself -- which you cannot ever get
from its name.

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Kent M Pitman
Subject: Re: [Q] equality of symbols?
Date: 
Message-ID: <sfwem0ly88z.fsf@world.std.com>
dave madden <··········@loopback.mersenne.com> writes:

> However, when I combine code from two individuals to produce an
> offspring, its :compiled-code complains about unused arguments
> "#:|arg0|", "#:|arg1|", and "#:|arg2|"; and undefined variables
> "#:|arg0|", "#:|arg1|", and "#:|arg2|".
> 
> When building the pieces of the auto-function, I create the symbols by
> running make-symbol on a string...but I believe I'll have to do
> something else instead.
> 
> Can anybody suggest a good next step?

I don't have a copy of the book so don't know what's involved in the
combining step, but here are some obvious thoughts:

* If you really have arguments that might need to be legitimately ignored,
  you want to do 
   (eval `(lambda ,args (declare (ignorable ,@args)) (flet ,flets ,body)))

* If you are using MAKE-SYMBOL because one parent is contributing an arg0
  that is trying to be different than the arg0 contributed by the other,
  you have to code-walk the body to figure out which is being used and flush
  the other.   I assume this is not what's happening, but can imagine genetic
  situations in which this would be relevant.

* If the arg0 from one parent wants to be the same as the arg0 from another
  parent, then it sounds like you should maybe be using INTERN and not 
  MAKE-SYMBOL, since otherwise you will get incompatible (non-EQ) but
  similar looking symbols.  Another way to do this kind of thing would be to
  make a little factory that uses MAKE-SYMBOL but caches the result in a
  hash table or in a package made for this purpose.  [The latter meaning
  you'd do (intern (format nil "ARG~D" index) "AUTOPARAM") or some such
  thing so that you could just talk about them as autoparam::arg0 but they
  wouldn't be symbols you found in other packages.  You'd make such a package
  with (MAKE-PACKAGE "AUTOPARAM" :USE '()) probably.]

* The fact that your args are called #:|arg0| may be intentional but if
  you want them to look more like #:arg0 then remember that symbol names are
  uppercase internally, so use (intern (format nil "ARG~D" ...)) not
  (intern (format nil "arg~D" ...)), or as someone in another thread here
  suggested, you can do   (intern (format nil "~A~D" 'arg ...)) and then
  you won't have to "see" the case translation going on.

I hope one or more of these pieces of advice will help some.