From: Drew Krause
Subject: can-of-worms
Date: 
Message-ID: <hXarg.3966$PE1.1034@newsread2.news.pas.earthlink.net>
I'm battling with a programming problem that suggests a more 
stripped-down version:

Given the atoms +,*,1,2 and a number n, the function returns n expressed 
in terms of the atoms, e.g.

n = 15
=> (- (* 2 2 2 2) 1)

This has a whiff to me of macro-building, automata, maybe AI....Has 
anyone tackled an analogous problem? What would be some approaches that 
might be fruitful for me to pursue?

Always grateful,
Drew

From: Pascal Bourguignon
Subject: Re: can-of-worms
Date: 
Message-ID: <87lkr6pttg.fsf@thalassa.informatimago.com>
Drew Krause <········@mindspring.com> writes:

> I'm battling with a programming problem that suggests a more
> stripped-down version:
>
> Given the atoms +,*,1,2 and a number n, the function returns n
> expressed in terms of the atoms, e.g.
>
> n = 15
> => (- (* 2 2 2 2) 1)
>
> This has a whiff to me of macro-building, automata, maybe AI....Has
> anyone tackled an analogous problem? What would be some approaches
> that might be fruitful for me to pursue?


(defun can-of-worms (n)
  (cond 
   ((zerop n) `(- 1 1))
   ((oddp n)  `(+ 1 (* 2 ,(can-of-worms (truncate (- n 1) 2)))))
   (t         `(* 2 ,(can-of-worms (truncate n 2))))))



(loop for i to 15 do (format t "~4D = ~A --> ~D~%"
                               i (can-of-worms i) (eval  (can-of-worms i))))
   0 = (- 1 1) --> 0
   1 = (+ 1 (* 2 (- 1 1))) --> 1
   2 = (* 2 (+ 1 (* 2 (- 1 1)))) --> 2
   3 = (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))) --> 3
   4 = (* 2 (* 2 (+ 1 (* 2 (- 1 1))))) --> 4
   5 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 5
   6 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 6
   7 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 7
   8 = (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 8
   9 = (+ 1 (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 9
  10 = (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 10
  11 = (+ 1 (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 11
  12 = (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 12
  13 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 13
  14 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 14
  15 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))))) --> 15


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <L8brg.4329$cd3.591@newsread3.news.pas.earthlink.net>
Hey, thank you! this wasn't a school assignment (in case you were 
wondering...)

Pascal Bourguignon wrote:

> Drew Krause <········@mindspring.com> writes:
> 
> 
>>I'm battling with a programming problem that suggests a more
>>stripped-down version:
>>
>>Given the atoms +,*,1,2 and a number n, the function returns n
>>expressed in terms of the atoms, e.g.
>>
>>n = 15
>>=> (- (* 2 2 2 2) 1)
>>
>>This has a whiff to me of macro-building, automata, maybe AI....Has
>>anyone tackled an analogous problem? What would be some approaches
>>that might be fruitful for me to pursue?
> 
> 
> 
> (defun can-of-worms (n)
>   (cond 
>    ((zerop n) `(- 1 1))
>    ((oddp n)  `(+ 1 (* 2 ,(can-of-worms (truncate (- n 1) 2)))))
>    (t         `(* 2 ,(can-of-worms (truncate n 2))))))
> 
> 
> 
> (loop for i to 15 do (format t "~4D = ~A --> ~D~%"
>                                i (can-of-worms i) (eval  (can-of-worms i))))
>    0 = (- 1 1) --> 0
>    1 = (+ 1 (* 2 (- 1 1))) --> 1
>    2 = (* 2 (+ 1 (* 2 (- 1 1)))) --> 2
>    3 = (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))) --> 3
>    4 = (* 2 (* 2 (+ 1 (* 2 (- 1 1))))) --> 4
>    5 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 5
>    6 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 6
>    7 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 7
>    8 = (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 8
>    9 = (+ 1 (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 9
>   10 = (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 10
>   11 = (+ 1 (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 11
>   12 = (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 12
>   13 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 13
>   14 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 14
>   15 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))))) --> 15
> 
> 
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <ggbrg.4368$cd3.2375@newsread3.news.pas.earthlink.net>
Pascal's solution is very elegant. What if the problem depended less on 
domain-knowledge, so (abstractly):

given n, express n as s-expression using (func1, func2, atom1, atom2)?

Pascal Bourguignon wrote:

> Drew Krause <········@mindspring.com> writes:
> 
> 
>>I'm battling with a programming problem that suggests a more
>>stripped-down version:
>>
>>Given the atoms +,*,1,2 and a number n, the function returns n
>>expressed in terms of the atoms, e.g.
>>
>>n = 15
>>=> (- (* 2 2 2 2) 1)
>>
>>This has a whiff to me of macro-building, automata, maybe AI....Has
>>anyone tackled an analogous problem? What would be some approaches
>>that might be fruitful for me to pursue?
> 
> 
> 
> (defun can-of-worms (n)
>   (cond 
>    ((zerop n) `(- 1 1))
>    ((oddp n)  `(+ 1 (* 2 ,(can-of-worms (truncate (- n 1) 2)))))
>    (t         `(* 2 ,(can-of-worms (truncate n 2))))))
> 
> 
> 
> (loop for i to 15 do (format t "~4D = ~A --> ~D~%"
>                                i (can-of-worms i) (eval  (can-of-worms i))))
>    0 = (- 1 1) --> 0
>    1 = (+ 1 (* 2 (- 1 1))) --> 1
>    2 = (* 2 (+ 1 (* 2 (- 1 1)))) --> 2
>    3 = (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))) --> 3
>    4 = (* 2 (* 2 (+ 1 (* 2 (- 1 1))))) --> 4
>    5 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 5
>    6 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 6
>    7 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 7
>    8 = (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))) --> 8
>    9 = (+ 1 (* 2 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 9
>   10 = (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 10
>   11 = (+ 1 (* 2 (+ 1 (* 2 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 11
>   12 = (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))) --> 12
>   13 = (+ 1 (* 2 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 13
>   14 = (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1)))))))) --> 14
>   15 = (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (- 1 1))))))))) --> 15
> 
> 
From: Ken Tilton
Subject: Re: can-of-worms
Date: 
Message-ID: <E2drg.33$XF1.13@fe08.lga>
Drew Krause wrote:
> Pascal's solution is very elegant. What if the problem depended less on 
> domain-knowledge, so (abstractly):
> 
> given n, express n as s-expression using (func1, func2, atom1, atom2)?

Oh, man, thank god, I was hoping Pascal's response was unresponsive.

I was also going to ask:

>>> I'm battling with a programming problem that suggests a more
>>> stripped-down version:
>>>
>>> Given the atoms +,*,1,2 and a number n, the function returns n
>>> expressed in terms of the atoms, e.g.
>>>
>>> n = 15
>>> => (- (* 2 2 2 2) 1)

- is one of +,*,1,2? Typo, or are we allowed to invert operations? I 
guess the former now that we have to handle arbitrary funcs for which we 
could not guess the inverse.

Constraints? All numeric all the time? Looking for shorter paths? Is 
func1 always to be applied to the output of func2 applied to all atoms? 
no. sorry. but howseabout func1 always applied to ((output of func2 
applied to any number of atoms) and any number of atoms)? No iteration 
in the final form? etc etc.

kenny
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <QNdrg.4609$cd3.4010@newsread3.news.pas.earthlink.net>
Ken Tilton wrote:

> Constraints? All numeric all the time? Looking for shorter paths? Is 
> func1 always to be applied to the output of func2 applied to all atoms? 
> no. sorry. but howseabout func1 always applied to ((output of func2 
> applied to any number of atoms) and any number of atoms)? No iteration 
> in the final form? etc etc.

OK. To lay bare the problem I'm working on, I have:

a starting node,
and ending node,
several unary operations that can act on the first or any intermediate 
steps,
and no other restrictions that I'm aware of (*except* that failure is a 
possibility)

so for example, tg = target, s = start, op1...opn = operations

solution might look like tg = (op2 (op1 (op7084 (op10 (op2 (op5 s))))))

.. and yes, shortest path would be nice, but ITWICG (I'll take what I 
can get)..

DK
From: Ken Tilton
Subject: Re: can-of-worms
Date: 
Message-ID: <Dherg.5607$u55.710@fe09.lga>
Drew Krause wrote:
> Ken Tilton wrote:
> 
>> Constraints? All numeric all the time? Looking for shorter paths? Is 
>> func1 always to be applied to the output of func2 applied to all 
>> atoms? no. sorry. but howseabout func1 always applied to ((output of 
>> func2 applied to any number of atoms) and any number of atoms)? No 
>> iteration in the final form? etc etc.
> 
> 
> OK. To lay bare the problem I'm working on, I have:
> 
> a starting node,
> and ending node,
> several unary operations that can act on the first or any intermediate 
> steps,
> and no other restrictions that I'm aware of (*except* that failure is a 
> possibility)

Ah, new concepts, nodes and steps. Hmmm. Before we had op1 and op2 as 
given data atoms. Now I see just one, with other operands being 
generated by the operators. After which any number of operands can be 
used, and each can be used any number of times. Makes 3D chess sound 
like a small solution space.

So you want to try each operator on the original input (1 or more times) 
to see if it produces the target, if not saving the result if it has not 
been seen before. Rinse, repeat, and each time you have to experiment 
with 1 - infinity uses of each operand in the pool.

if you get a sweep with no new results, hasta la vista baby. Not sure 
how else you might determine nonconvergence, unless for each operator 
you pair optionally a "no mas" function that is allowed to see all 
results and all results generated by the paired generator and can 
indicate that the paired generator is no longer to be tried. If it can 
tell. Otherwise you have to impose an arbitrary depth.

Not sure if it helps to have an inverse operation for each operation. 
You could then search backwards populating a space of "solved 
intermediates". When this intersects with the "accomplished results" you 
can go home.

I wonder if something like Screamer or Prolog would make this easier to 
express. Have you done any Prolog? Now there is a mindf*ck. ACL trial 
might include its prolog. That might be harder though than writing it in 
Lisp (from painful experience trying to get Prolog to DWIM).

hth, kenny

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <11krg.744$vO.366@newsread4.news.pas.earthlink.net>
Yes, I thought of screamer...but it looks like this may be one for GA... 
  I'll report back --

Ken Tilton wrote:
> 
> 
> Drew Krause wrote:
> 
>> Ken Tilton wrote:
>>
>>> Constraints? All numeric all the time? Looking for shorter paths? Is 
>>> func1 always to be applied to the output of func2 applied to all 
>>> atoms? no. sorry. but howseabout func1 always applied to ((output of 
>>> func2 applied to any number of atoms) and any number of atoms)? No 
>>> iteration in the final form? etc etc.
>>
>>
>>
>> OK. To lay bare the problem I'm working on, I have:
>>
>> a starting node,
>> and ending node,
>> several unary operations that can act on the first or any intermediate 
>> steps,
>> and no other restrictions that I'm aware of (*except* that failure is 
>> a possibility)
> 
> 
> Ah, new concepts, nodes and steps. Hmmm. Before we had op1 and op2 as 
> given data atoms. Now I see just one, with other operands being 
> generated by the operators. After which any number of operands can be 
> used, and each can be used any number of times. Makes 3D chess sound 
> like a small solution space.
> 
> So you want to try each operator on the original input (1 or more times) 
> to see if it produces the target, if not saving the result if it has not 
> been seen before. Rinse, repeat, and each time you have to experiment 
> with 1 - infinity uses of each operand in the pool.
> 
> if you get a sweep with no new results, hasta la vista baby. Not sure 
> how else you might determine nonconvergence, unless for each operator 
> you pair optionally a "no mas" function that is allowed to see all 
> results and all results generated by the paired generator and can 
> indicate that the paired generator is no longer to be tried. If it can 
> tell. Otherwise you have to impose an arbitrary depth.
> 
> Not sure if it helps to have an inverse operation for each operation. 
> You could then search backwards populating a space of "solved 
> intermediates". When this intersects with the "accomplished results" you 
> can go home.
> 
> I wonder if something like Screamer or Prolog would make this easier to 
> express. Have you done any Prolog? Now there is a mindf*ck. ACL trial 
> might include its prolog. That might be harder though than writing it in 
> Lisp (from painful experience trying to get Prolog to DWIM).
> 
> hth, kenny
> 
From: Holger Schauer
Subject: Re: can-of-worms
Date: 
Message-ID: <yxz1wsy4ds0.fsf@gmx.de>
On 4691 September 1993, Drew Krause wrote:
> OK. To lay bare the problem I'm working on, I have:

> a starting node, and ending node, several unary operations that can
> act on the first or any intermediate steps, and no other
> restrictions that I'm aware of (*except* that failure is a
> possibility)

> so for example, tg = target, s = start, op1...opn = operations
> solution might look like tg = (op2 (op1 (op7084 (op10 (op2 (op5 s))))))

> .. and yes, shortest path would be nice, but ITWICG (I'll take what I
> can get)..

Isn't this just a classic planning game you're playing? Perhaps you
could view each result of an operation as some intermediate node in
the graph you've to traverse, perhaps, like in the original posting,
this is natural. In this case, you might be able to come up with a
heuristic, how far from the target you are at any current node. If so,
that just sounds pretty much like a case for A* search. I'm not sure
but I think you might find a sample implementation in PAIP, and if
not, I would bet there's one in the classic CMU archives.

Holger
From: Ray Dillinger
Subject: Re: can-of-worms
Date: 
Message-ID: <44af213e$0$96229$742ec2ed@news.sonic.net>
Drew Krause wrote:
> Ken Tilton wrote:
> 
>> Constraints? All numeric all the time? Looking for shorter paths? Is 
>> func1 always to be applied to the output of func2 applied to all 
>> atoms? no. sorry. but howseabout func1 always applied to ((output of 
>> func2 applied to any number of atoms) and any number of atoms)? No 
>> iteration in the final form? etc etc.
> 
> 
> OK. To lay bare the problem I'm working on, I have:
> 
> a starting node,
> and ending node,
> several unary operations that can act on the first or any intermediate 
> steps,
> and no other restrictions that I'm aware of (*except* that failure is a 
> possibility)
> 
> so for example, tg = target, s = start, op1...opn = operations
> 
> solution might look like tg = (op2 (op1 (op7084 (op10 (op2 (op5 s))))))
> 
> .. and yes, shortest path would be nice, but ITWICG (I'll take what I 
> can get)..
> 

sounds like an A* problem.  A* (A-star) is a search algorithm
that finds optimal paths in maze or near-maze conditions.  It's
basically an optimization of breadth-first search.

What it consists of is keeping a set of reachable points (numbers
in this problem domain, I guess) ordered by an estimate as to the
minimum possible number of steps from each point to the solution
space.  You use some kind of heuristic to come up with the estimate.
You repeatedly take the point with the smallest estimate, apply your
possible moves to that point to give you new points, apply your
heuristic to the new points to give estimates of remaining-steps
for each, and then repeat.

The heuristic is key.  As long as it's conservative (smaller than
the actual number of steps required to get there from that point)
the algorithm is guaranteed to find the shortest path.

				Bear
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <44B26041.3080900@mindspring.com>
Yes. This is the solution that I'll try. Thanks, Drew

Ray Dillinger wrote:

> sounds like an A* problem.  A* (A-star) is a search algorithm
> that finds optimal paths in maze or near-maze conditions.  It's
> basically an optimization of breadth-first search.
> 
> What it consists of is keeping a set of reachable points (numbers
> in this problem domain, I guess) ordered by an estimate as to the
> minimum possible number of steps from each point to the solution
> space.  You use some kind of heuristic to come up with the estimate.
> You repeatedly take the point with the smallest estimate, apply your
> possible moves to that point to give you new points, apply your
> heuristic to the new points to give estimates of remaining-steps
> for each, and then repeat.
> 
> The heuristic is key.  As long as it's conservative (smaller than
> the actual number of steps required to get there from that point)
> the algorithm is guaranteed to find the shortest path.
> 
>                 Bear
> 
> 
> 
> 
> 
> 
> 
> 
> 
From: Thomas A. Russ
Subject: Re: can-of-worms
Date: 
Message-ID: <ymisll91l2j.fsf@sevak.isi.edu>
Drew Krause <········@mindspring.com> writes:

> Ken Tilton wrote:
> 
> > Constraints? All numeric all the time? Looking for shorter paths? Is
> > func1 always to be applied to the output of func2 applied to all
> > atoms? no. sorry. but howseabout func1 always applied to ((output of
> > func2 applied to any number of atoms) and any number of atoms)? No
> > iteration in the final form? etc etc.
> 
> 
> OK. To lay bare the problem I'm working on, I have:
> 
> a starting node,
> and ending node,
> several unary operations that can act on the first or any intermediate
> steps,
> 
> and no other restrictions that I'm aware of (*except* that failure is a
> possibility)
> 
> 
> so for example, tg = target, s = start, op1...opn = operations
> 
> solution might look like tg = (op2 (op1 (op7084 (op10 (op2 (op5 s))))))
> 
> .. and yes, shortest path would be nice, but ITWICG (I'll take what I
> can get)..

Wouldn't a STRIPs style planner work for this?

Or to be more sophisticated, one of the newer planning algorithms?

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Drew Krause
Subject: Re: can-of-worms
Date: 
Message-ID: <MwSsg.6315$ye3.6100@newsread1.news.pas.earthlink.net>
The A* search enabled me to solve this problem. There are several 
implementations out there, but the one below worked for me right 'out of 
the box':

http://www.apl.jhu.edu/~hall/lisp/Search/A-Star.lisp

Many thanks to everyone for your help!

Drew

Drew Krause wrote:

> Pascal's solution is very elegant. What if the problem depended less on 
> domain-knowledge, so (abstractly):
> 
> given n, express n as s-expression using (func1, func2, atom1, atom2)?
>
From: Leonid Slobodov
Subject: Re: can-of-worms
Date: 
Message-ID: <44ad3f0b$0$26265$9b4e6d93@newsread2.arcor-online.net>
Drew Krause wrote:

> I'm battling with a programming problem that suggests a more
> stripped-down version:
> 
> Given the atoms +,*,1,2 and a number n, the function returns n expressed
> in terms of the atoms, e.g.
> 
> n = 15
> => (- (* 2 2 2 2) 1)
> 
> This has a whiff to me of macro-building, automata, maybe AI....Has
> anyone tackled an analogous problem? What would be some approaches that
> might be fruitful for me to pursue?
> 
> Always grateful,
> Drew

Two words: Genetic Programming (or alternatively Grammatical Evolution).

Although the current implementations are really hard to use and 
almost everyone using GP (including myself) has created his own little 
mad mix of a GP and a GE system, they are really a joy to work with.

Give it a try!
http://bc.tech.coop/blog/040619.html
(Warning: not for the easily discouraged :-)

I'm sure alternative solutions that use more conventional AI algorithms
exist, I'm just too lazy to think up something. I'm sure someone comes up
with an interesting solution.
From: John Thingstad
Subject: Re: can-of-worms
Date: 
Message-ID: <op.tcb41bpupqzri1@pandora.upc.no>
On Thu, 06 Jul 2006 18:33:17 +0200, Drew Krause <········@mindspring.com>  
wrote:

> I'm battling with a programming problem that suggests a more  
> stripped-down version:
>
> Given the atoms +,*,1,2 and a number n, the function returns n expressed  
> in terms of the atoms, e.g.
>
> n = 15
> => (- (* 2 2 2 2) 1)
>
> This has a whiff to me of macro-building, automata, maybe AI....Has  
> anyone tackled an analogous problem? What would be some approaches that  
> might be fruitful for me to pursue?
>
> Always grateful,
> Drew

That example uses '-' which is not one of the atoms.
With those atoms the only way to represent 15 is
(+ (* 2 2 2) (* 2 2) 2 1)
Which is just a alaborate form for a binary number.
Thus use the 2 logarith to reduce the expression.
This is a trivial reductive decomposition.
I also assume n >= 1 since there is no way to render 0.

Is this in fact what you mean?

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Pascal Bourguignon
Subject: Re: can-of-worms
Date: 
Message-ID: <873bddnp0k.fsf@thalassa.informatimago.com>
"John Thingstad" <··············@chello.no> writes:

> On Thu, 06 Jul 2006 18:33:17 +0200, Drew Krause
> <········@mindspring.com>  wrote:
>
>> I'm battling with a programming problem that suggests a more
>> stripped-down version:
>>
>> Given the atoms +,*,1,2 and a number n, the function returns n
>> expressed  in terms of the atoms, e.g.
>>
>> n = 15
>> => (- (* 2 2 2 2) 1)
>>
>> This has a whiff to me of macro-building, automata, maybe AI....Has
>> anyone tackled an analogous problem? What would be some approaches
>> that  might be fruitful for me to pursue?
>>
>> Always grateful,
>> Drew
>
> That example uses '-' which is not one of the atoms.
> With those atoms the only way to represent 15 is
> (+ (* 2 2 2) (* 2 2) 2 1)

Not the only way:

 (+ (* (+ 1 1) 2 2) (* 2 2) 2 1)

> Which is just a alaborate form for a binary number.
> Thus use the 2 logarith to reduce the expression.
> This is a trivial reductive decomposition.
> I also assume n >= 1 since there is no way to render 0.

 (+) --> 0


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

The world will now reboot.  don't bother saving your artefacts.
From: John Thingstad
Subject: Re: can-of-worms
Date: 
Message-ID: <op.tcb54yt6pqzri1@pandora.upc.no>
On Fri, 07 Jul 2006 22:22:51 +0200, Pascal Bourguignon  
<···@informatimago.com> wrote:

> "John Thingstad" <··············@chello.no> writes:
>
> Not the only way:
>
>  (+ (* (+ 1 1) 2 2) (* 2 2) 2 1)
>

I stand corrected. Uniquely the shortest way.

>> Which is just a alaborate form for a binary number.
>> Thus use the 2 logarith to reduce the expression.
>> This is a trivial reductive decomposition.
>> I also assume n >= 1 since there is no way to render 0.
>
>  (+) --> 0
>
>

If you consider that 0.
I don't since all other expressions use numbers.
(+) isn't well formed.


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Marcus Breiing
Subject: Re: can-of-worms
Date: 
Message-ID: <e8mj1i$ft0$1@chessie.cirr.com>
"John Thingstad" <··············@chello.no> writes:

> > Not the only way:
> >
> >  (+ (* (+ 1 1) 2 2) (* 2 2) 2 1)
> >
> 
> I stand corrected. Uniquely the shortest way.

(+ (* 2 2 2) 2 2 2 1)

-- 
Marcus Breiing
From: John Thingstad
Subject: Re: can-of-worms
Date: 
Message-ID: <op.tcb8ybwspqzri1@pandora.upc.no>
On Fri, 07 Jul 2006 23:17:21 +0200, Marcus Breiing  
<······@2006w27.mail.breiing.com> wrote:

> "John Thingstad" <··············@chello.no> writes:
>
>> > Not the only way:
>> >
>> >  (+ (* (+ 1 1) 2 2) (* 2 2) 2 1)
>> >
>>
>> I stand corrected. Uniquely the shortest way.
>
> (+ (* 2 2 2) 2 2 2 1)
>

Opps missed that one.
Of course it only works for the case (* 2 2) = (+ 2 2)
Still it seems to complicate the algorithm more than it's
worth to include this spesial case.
(To my mind)

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Pascal Bourguignon
Subject: Re: can-of-worms
Date: 
Message-ID: <87y7v5m6um.fsf@thalassa.informatimago.com>
"John Thingstad" <··············@chello.no> writes:

> On Fri, 07 Jul 2006 22:22:51 +0200, Pascal Bourguignon
> <···@informatimago.com> wrote:
>
>> "John Thingstad" <··············@chello.no> writes:
>>
>> Not the only way:
>>
>>  (+ (* (+ 1 1) 2 2) (* 2 2) 2 1)
>>
>
> I stand corrected. Uniquely the shortest way.
>
>>> Which is just a alaborate form for a binary number.
>>> Thus use the 2 logarith to reduce the expression.
>>> This is a trivial reductive decomposition.
>>> I also assume n >= 1 since there is no way to render 0.
>>
>>  (+) --> 0
>>
>>
>
> If you consider that 0.
> I don't since all other expressions use numbers.
> (+) isn't well formed.

In Common Lisp, (+) is well formed and precisely defined to return the
neutral element of the additive field, and (*) is defined to return
the neutral element of the multiplicative field.

[201]> (+)
0
[202]> (*)
1
[203]> 

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live.
From: Marcus Breiing
Subject: Re: can-of-worms
Date: 
Message-ID: <e8mfs6$flr$1@chessie.cirr.com>
"John Thingstad" <··············@chello.no> writes:

> With those atoms the only way to represent 15 is
> (+ (* 2 2 2) (* 2 2) 2 1)

(+ 1 (* 2 (+ 1 (* 2 (+ 1 2)))))

> I also assume n >= 1 since there is no way to render 0.

(+)

-- 
Marcus Breiing
From: Thomas A. Russ
Subject: Re: can-of-worms
Date: 
Message-ID: <ymiodvx1krv.fsf@sevak.isi.edu>
Drew Krause <········@mindspring.com> writes:

> I'm battling with a programming problem that suggests a more
> stripped-down version:
> 
> 
> Given the atoms +,*,1,2 and a number n, the function returns n expressed
> in terms of the atoms, e.g.
> 
> n = 15
> => (- (* 2 2 2 2) 1)

It seems to me that the simplest solution given the minimal constraints
above would be to not use * at all:

(defun can-of-worms (n)
  (if (oddp n)
      `(+ ,@(make-list (truncate n 2) :initial-element 2) 1)
      `(+ ,@(make-list (truncate n 2) :initial-element 2))))

or alternately:

(defun can-of-worms2 (n)
  (let ((twos (make-list (truncate n 2) :initial-element 2)))
    (if (oddp n)
        (cons '+ (cons 1 twos))
        (cons '+ twos))))


Test:

(loop for n from 0 to 21
      unless (= n (eval (can-of-worms n)))
      do (error "Failed for ~D" n)
      finally (return 'success))

-- 
Thomas A. Russ,  USC/Information Sciences Institute