evaluating strings

Hello,

I would really appreciate any help with the problem I am currently
experiencing with the eval function.

s1='myif(plus(1,2),times(3,4))';
eval(s1);

When I do eval(s1) it executes plus(1,2) then times(3,4) then myif.
This is not acceptable since both plus and times are executed when
only one should be.

I have tried using function handles like this:

s2=@myif(@plus(1,2),@times(3,4));
eval(s2);

This works better however MATLAB executes either plus(1,2) or
times(3,4) and then myif. It executes the nested function first which
is also unacceptable.

I know this works perfectly:

s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
eval(s3);

It executes myif and then either plus(1,2) or times(3,4), depending
on the myif test.

So, what I would like to know is this, is there a way to go from s1
to s3 automatically?

s1='myif(plus(1,2),times(3,4))';
s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';

I have tried to write a program using the brackets to indicate how
many quotation marks to wrap each function in but it is a very messy
solution. I have used strtok and strcat etc. but I have problems when
several brackets (delimiters) are touching each another.

If anyone out there can think of a solution to my problem (or the
larger eval issue) I would be extremely grateful.

Thank you so much in advance for your help.

Matt.

free_wombat@hotmail.com
0
7/20/2006 12:40:59 AM
comp.soft-sys.matlab 209982 articles. 11 followers. lunamoonmoon (258) is leader. Post Follow

2 Replies
221 Views

Similar Articles

[PageSpeed] 21

In article <ef3c24f.-1@webcrossing.raydaftYaTP>,
 "Matt C" <free_wombat@hotmail.com> wrote:

> Hello,
> 
> I would really appreciate any help with the problem I am currently
> experiencing with the eval function.
> 
> s1='myif(plus(1,2),times(3,4))';
> eval(s1);
> 
> When I do eval(s1) it executes plus(1,2) then times(3,4) then myif.
> This is not acceptable since both plus and times are executed when
> only one should be.
> 
> I have tried using function handles like this:
> 
> s2=@myif(@plus(1,2),@times(3,4));
> eval(s2);
> 
> This works better however MATLAB executes either plus(1,2) or
> times(3,4) and then myif. It executes the nested function first which
> is also unacceptable.
> 
> I know this works perfectly:
> 
> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
> eval(s3);
> 
> It executes myif and then either plus(1,2) or times(3,4), depending
> on the myif test.
> 
> So, what I would like to know is this, is there a way to go from s1
> to s3 automatically?
> 
> s1='myif(plus(1,2),times(3,4))';
> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
> 
> I have tried to write a program using the brackets to indicate how
> many quotation marks to wrap each function in but it is a very messy
> solution. I have used strtok and strcat etc. but I have problems when
> several brackets (delimiters) are touching each another.
> 
> If anyone out there can think of a solution to my problem (or the
> larger eval issue) I would be extremely grateful.
> 
> Thank you so much in advance for your help.
> 
> Matt.
> 
> free_wombat@hotmail.com

This is one of the most bizarre questions I have seen.  Congratulations.

I have no idea what you're trying to do, but here are some observations.

1)  We have no idea what the function myif is.  Perhaps we don't need to 
know, but knowing helps put the question into context.

2)  How do you know when only one or the other argument is evaluated?

3)  s3 evaluates to

  >> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')' 
  s3 =
  myif('plus('1','2')','times('3','4')')


  plus('1','2') is not at all the same as plus(1,2).

4)  In the s1 example you seem surprised that both arguments are 
evaluated before they are passed into myif, but no other behavior is 
possible.  In your other examples you apparently defer execution by 
passing in a string instead of a value.  Why, I don't know.

5)  Since I don't know what myif is let's pretend that it's

  if A || B
    ...
  end

MATLAB uses "short_circuit" operators in this case so if you just wrote

  if plus(1,2) || times(3,4)

you should get the behavior you desire.

-- 
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.
0
see9548 (1248)
7/20/2006 1:05:26 AM
Doug Schwarz wrote:
>
>
> In article <ef3c24f.-1@webcrossing.raydaftYaTP>,
> "Matt C" <free_wombat@hotmail.com> wrote:
>
>> Hello,
>>
>> I would really appreciate any help with the problem I am
> currently
>> experiencing with the eval function.
>>
>> s1='myif(plus(1,2),times(3,4))';
>> eval(s1);
>>
>> When I do eval(s1) it executes plus(1,2) then times(3,4) then
> myif.
>> This is not acceptable since both plus and times are executed
> when
>> only one should be.
>>
>> I have tried using function handles like this:
>>
>> s2=@myif(@plus(1,2),@times(3,4));
>> eval(s2);
>>
>> This works better however MATLAB executes either plus(1,2) or
>> times(3,4) and then myif. It executes the nested function first
> which
>> is also unacceptable.
>>
>> I know this works perfectly:
>>
>> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
>> eval(s3);
>>
>> It executes myif and then either plus(1,2) or times(3,4),
> depending
>> on the myif test.
>>
>> So, what I would like to know is this, is there a way to go
from
> s1
>> to s3 automatically?
>>
>> s1='myif(plus(1,2),times(3,4))';
>> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
>>
>> I have tried to write a program using the brackets to indicate
> how
>> many quotation marks to wrap each function in but it is a very
> messy
>> solution. I have used strtok and strcat etc. but I have
problems
> when
>> several brackets (delimiters) are touching each another.
>>
>> If anyone out there can think of a solution to my problem (or
the
>> larger eval issue) I would be extremely grateful.
>>
>> Thank you so much in advance for your help.
>>
>> Matt.
>>
>> free_wombat@hotmail.com
>
> This is one of the most bizarre questions I have seen.
> Congratulations.
>
> I have no idea what you're trying to do, but here are some
> observations.
>
> 1) We have no idea what the function myif is. Perhaps we don't
> need to
> know, but knowing helps put the question into context.
>
> 2) How do you know when only one or the other argument is
> evaluated?
>
> 3) s3 evaluates to
>
> >> s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')'
> s3 =
> myif('plus('1','2')','times('3','4')')
>
>
> plus('1','2') is not at all the same as plus(1,2).
>
> 4) In the s1 example you seem surprised that both arguments are
> evaluated before they are passed into myif, but no other behavior
> is
> possible. In your other examples you apparently defer execution by
>
> passing in a string instead of a value. Why, I don't know.
>
> 5) Since I don't know what myif is let's pretend that it's
>
> if A || B
> ...
> end
>
> MATLAB uses "short_circuit" operators in this case so if you just
> wrote
>
> if plus(1,2) || times(3,4)
>
> you should get the behavior you desire.
>
> --
> Doug Schwarz
> dmschwarz&ieee,org
> Make obvious changes to get real email address.
>
  

Hello,

I would really appreciate any help with the problem I am currently
experiencing with the eval function.

s1='myif(plus(1,2),times(3,4))';
eval(s1);

When I do eval(s1) it executes plus(1,2) then times(3,4) then myif.
This is not acceptable since both plus and times are executed when
only one should be.

I have tried using function handles like this:

s2=@myif(@plus(1,2),@times(3,4));
eval(s2);

This works better however MATLAB executes either plus(1,2) or
times(3,4) and then myif. It executes the nested function first which
is also unacceptable.

I know this works perfectly:

s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';
eval(s3);

It executes myif and then either plus(1,2) or times(3,4), depending
on the myif test.

So, what I would like to know is this, is there a way to go from s1
to s3 automatically?

s1='myif(plus(1,2),times(3,4))';
s3='myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')';

I have tried to write a program using the brackets to indicate how
many quotation marks to wrap each function in but it is a very messy
solution. I have used strtok and strcat etc. but I have problems when
several brackets (delimiters) are touching each another.

If anyone out there can think of a solution to my problem (or the
larger eval issue) I would be extremely grateful.

Thank you so much in advance for your help.

Matt.

Thank you very much to those people who have looked at my problem and
especially to Doug Schwarz for replying.

I apologise if the way I originally presented my problem was not
clear. I guess the short version was too simplified so here�s the
long one. Although I do admit to making one error in my first post in
that s3 should have been written as

'myif(''plus(''''1'''',''''2'''')'',''times(''''3'''', ''''4'''')'')'


rather than

'myif(''plus(''1'',''2'')'',''times(''3'',''4'')'')'

as Doug realised.

This question has to do with the MATLAB genetic programming toolbox
written by Sara Silva which is available open source from <http://gplab.sourceforge.net/index.html>.



I believe it currently has one major unresolved problem and it
involves the eval function.

The GP program generates a population of random programs
(�individuals�) to solve problems. These generated programs are
represented as �trees� which are stored in nested structs. The
algorithm needs to evaluate each program to determine which ones work
the best.

Currently, programs are evaluated by first converting the tree struct
into a single layered string. In the artificial ant problem for
example, a program might look like this

string = 'antif(antif(antmove,antright),antleft)'

GPLAB then simply does eval(string) to evaluate the programs.
However, this does not work correctly (see my example programs at the
end).

About a year ago some French researchers using GPLAB wrote a program
to convert the tree structure into the strings with levels which
GPLAB could then evaluate correctly like this:

string = ' antif(''antif(''''antmove'''', ''''antright'''') '',
''antleft'') '

Unfortunately the toolbox is very large and making this change
affects many other programs.

It would be much simpler to have a new program that just converts
this

string = 'antif(antif(antmove,antright),antleft)'

to this

string = ' antif(''antif(''''antmove'''', ''''antright'''') '',
''antleft'') '

whenever an individual needs to be evaluated.

So there you have it. If anyone can think of an easy way to do this,
that would be great.

If you want to see how the eval function (mis)behaves then try out
each case of the following evalif program.

Thanks.

%evalif
 
clear all
clc
 
global x switchvar
x=0;
 
fprintf('\neval if')
fprintf('\n-----------------------\n')
 
switchvar='1';
 
switch switchvar
  
    case '1' % does NOT evaluate correctly
        iffunction(acttrue,actfalse);
    
    case '2' % does NOT evaluate correctly
        str='iffunction(acttrue,actfalse)';
        ans=eval(str);
        
    case '3' % does evaluate correctly
        iffunction(@acttrue,@actfalse);
        
    case '4' % but this does NOT evaluate correctly
        iffunction(iffunction(@acttrue,@actfalse),@actfalse);
        
    case '5' % does evaluate correctly
        str='iffunction(''acttrue'',''actfalse'')';
        ans=eval(str);
   
end
 
fprintf('\n-----------------------\n')
fprintf('\nfinal result: x = %d',x)
fprintf('\ncorrect result: x = 1\n')
 

function x=iffunction(a,b)
 
global x switchvar
 
fprintf('\nif function\n')
 
switch switchvar
    
    case '1' % if passing one string
        if 1
            a;
        else
            b;
        end
        
    case '2' % if calling functions directly
        if 1
            a;
        else
            b;
        end
        
    case '3' % if passing function handles
        if 1
            feval(a);
        else
            feval(b);
        end
        
    case '4' % if passing function handles
        if 1
            feval(a);
        else
            feval(b);
        end
        
    case '5' % if passing multiple strings
        if 1
            ans=eval(a);
        else
            ans=eval(b);
        end
 
end

function x=action1
 
global x
 
x=x+1;
 
fprintf('\nact true: x = %d\n',x)
 

function x=action2
 
global x
 
x=x+2;
 
fprintf('\nact false: x = %d\n',x)
0
7/20/2006 3:09:50 AM
Reply: