Why are the effective statements invalid when put them in a proc?

Hi,the following is my confused problem

the effective statements 
   restart;
   with(group):with(StringTools):with(Maplets[Examples]):
   a:=GetInput("Input the moves.");#input: IMIM10IM2IM9IM7IM8IM10
   i:=0:b:=Explode(a):
   M10:=[[2, 12, 7, 4, 11, 6, 10, 8, 9, 5, 3]]:
   M2:=[[2, 5, 8, 6, 4, 12, 3, 9, 10, 11, 7]]:
   M8:=[[2, 4, 10, 5, 12, 11, 8, 3, 7, 6, 9]]:
   M6:=[[2, 6, 3, 11, 5, 4, 9, 7, 8, 12, 10]]:
   M7:=[[2, 11, 9, 12, 6, 5, 7, 10, 3, 4, 8]]:
   M:=[[2, 3, 5, 9, 8, 10, 6, 11, 4, 7, 12]]:
   M9:=[[2, 7, 11, 10, 9, 3, 12, 4, 6, 8, 5]]:
   M3:=[[2, 9, 6, 7, 3, 8, 11, 12, 5, 10, 4]]:
   M4:=[[2, 8, 4, 3, 10, 7, 5, 6, 12, 9, 11]]:
   M5:=[[2, 10, 12, 8, 7, 9, 4, 5, 11, 3, 6]]:
   X:=[[1, 12], [2, 11], [3, 10], [4, 9], [5, 8], [6, 7]]:
   for d in b do 
     i:=i+1;
     if d>"0" and d<="9" then i:=i-1;s[i]:=Join(["M",d],"");
       elif d="0" then i:=i-1;s[i]:="M10";
       elif d="I" then s[i]:="X";
       else s[i]:="M";
     end if;
   end do:
   s:=convert(s,list);
   i:=0:for d in convert(s,list) do i:=i+1;s[i]:=convert(s[i],symbol);end do:
   s:=op(s);
   foldl(`mulperms`,s);

but this is invalid!Why?

   restart;
   with(group):with(StringTools):with(Maplets[Examples]):
IM:=proc()
   a:=GetInput("Input the moves.");#input: IMIM10IM2IM9IM7IM8IM10
   i:=0:b:=Explode(a):
   M10:=[[2, 12, 7, 4, 11, 6, 10, 8, 9, 5, 3]]:
   M2:=[[2, 5, 8, 6, 4, 12, 3, 9, 10, 11, 7]]:
   M8:=[[2, 4, 10, 5, 12, 11, 8, 3, 7, 6, 9]]:
   M6:=[[2, 6, 3, 11, 5, 4, 9, 7, 8, 12, 10]]:
   M7:=[[2, 11, 9, 12, 6, 5, 7, 10, 3, 4, 8]]:
   M:=[[2, 3, 5, 9, 8, 10, 6, 11, 4, 7, 12]]:
   M9:=[[2, 7, 11, 10, 9, 3, 12, 4, 6, 8, 5]]:
   M3:=[[2, 9, 6, 7, 3, 8, 11, 12, 5, 10, 4]]:
   M4:=[[2, 8, 4, 3, 10, 7, 5, 6, 12, 9, 11]]:
   M5:=[[2, 10, 12, 8, 7, 9, 4, 5, 11, 3, 6]]:
   X:=[[1, 12], [2, 11], [3, 10], [4, 9], [5, 8], [6, 7]]:
   for d in b do 
     i:=i+1;
     if d>"0" and d<="9" then i:=i-1;s[i]:=Join(["M",d],"");
       elif d="0" then i:=i-1;s[i]:="M10";
       elif d="I" then s[i]:="X";
       else s[i]:="M";
     end if;
   end do:
   s:=convert(s,list);
   i:=0:for d in convert(s,list) do i:=i+1;s[i]:=convert(s[i],symbol);end do:
   s:=op(s);
   foldl(`mulperms`,s);
end proc:
 

 

I'm sorry.In proc,I forgot

I'm sorry.In proc,I forgot to add "return" before foldl(`mulperms`,s);

acer's picture

not necessary

The return directive isn't required, for the last statement in the procedure.

acer

suggestions

It's generally best if a procedure does not depend on a package having been 'withed'.  That is, rather than doing

with(group): with(StringTools): with(Maplets[Examples]):
IM := proc() ... end proc:

you should do

IM := proc()
uses group, StringTools, Maplets:-Examples;
...
end proc:

There appears to be a superfluous convert(s,'list') in the procedure (s was previously converted to a list).  Regardless, if I understand what you intend, it is better to do s := map(convert, s, symbol) rather than assigning elements of a list, which is not efficient and only works for relatively small lists (less than 100 elements).

Also, backquotes around foldl serve no useful purpose

there is another problem:the

there is another problem:the symbols in s can not take the corresponding value assigned before!

>   IM:= proc (a::string)
>   uses group, StringTools;
>   local b,d,i,ans,s,M,M2,M3,M4,M5,M6,M7,M8,M9,M10,X;
>  
>   i:=0:b:=Explode(a);
>   for d in b do
>     i:=i+1;
>     if d>"0" and d<="9" then i:=i-1;s[i]:=Join(["M",d],"");
>       elif d="0" then i:=i-1;s[i]:="M10";
>       elif d="I" then s[i]:="X";
>       else s[i]:="M";
>     end if;
>   end do:
>   s:=convert(s,list);
>   s:=map(convert, s, symbol);
>   X:=[[1, 12], [2, 11], [3, 10], [4, 9], [5, 8], [6, 7]]:
>   M10:=[[2, 12, 7, 4, 11, 6, 10, 8, 9, 5, 3]]:
>   M2:=[[2, 5, 8, 6, 4, 12, 3, 9, 10, 11, 7]]:
>   M8:=[[2, 4, 10, 5, 12, 11, 8, 3, 7, 6, 9]]:
>   M6:=[[2, 6, 3, 11, 5, 4, 9, 7, 8, 12, 10]]:
>   M7:=[[2, 11, 9, 12, 6, 5, 7, 10, 3, 4, 8]]:
>   M:=[[2, 3, 5, 9, 8, 10, 6, 11, 4, 7, 12]]:
>   M9:=[[2, 7, 11, 10, 9, 3, 12, 4, 6, 8, 5]]:
>   M3:=[[2, 9, 6, 7, 3, 8, 11, 12, 5, 10, 4]]:
>   M4:=[[2, 8, 4, 3, 10, 7, 5, 6, 12, 9, 11]]:
>   M5:=[[2, 10, 12, 8, 7, 9, 4, 5, 11, 3, 6]]:
>   print(X,s[1]);#this output can tell us s[1] cannot take [[1, 12], [2, 11], [3, 10], [4, 9], [5, 8], [6, 7]],why?
>   s:=op(s):
>   foldl(`mulperms`,s);
> end proc:
 

> IM("IMIM3IM2IM9IM7IM8");
        [[1, 12], [2, 11], [3, 10], [4, 9], [5, 8], [6, 7]], X

Error, (in convert/plist) bad index into Array

 

evaluation

There are two related problems, both somewhat subtle, with this routine.  First, the Maple procedure convert/symbol returns a global symbol.  As such, it will not match the local symbols (variables) in the procedure.  A better way to handle this translation is via a table, however, for now let's just use what you have.  The simplest change is to redeclare the symbols M, M2, ..., M10, and X to be global.  That, alas, does not suffice.  The reason is that inside a procedure Maple only evaluates expressions one level.  When you do map(convert, s, symbol) the result is a list of symbols, not a list of their values.  It is those values which foldl gets and chokes.  A work-around for that is to fully evaluate the list, that is add the statement s := eval(s) [before the call to op(s)).  With those changes the procedure operates.

As mentioned, a better way to do this is with a table.  Create the table

MIX := table(["X" = [[1,12], ...], "M" = [...], ..., "M10" = [...]):

then instead of converting s to symbols, look up the strings in the table

s := [seq([MIX[char], char in s)];

Actually, I'd probably do that inside the loop that parses the individual characters.

That's great!Thank you!

That's great!Thank you!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}