Basic question from a beginner. Problem with definitions in a bucle. Maple - for-loop

Let's suppose we are in this case (I'm using Maple)
add:=function()
e1:=0;
e2:=1;
for j in [1..2]do
ej:=ej+1
od;
return e1,e2;
end;
This program gives me a global variable error. I understand why that happens -- because ej is not defined as local -- but if you define it then the program just doesn't do anything. ) I don't know how to solve it. My objective (in a bigger program) is to call e1,e2 in a for loop.
Maybe I didn't express myself correctly simplifying my problem, there is my Program, it is made with program GAP but it works similar to Maple:
G12Decode:=function(c)
localx,G,C,sG,sH,a,u,b1,e1,b2,e2,b3,e3,b4,e4,b5,e5,b6,e6,h1,h2,i,j;
x:=Codeword(c,GF(3));
G:=[[1,0,0,0,0,0,0,1,1,1,1,1],[0,1,0,0,0,0,1,0,1,2,2,1],
[0,0,1,0,0,0,1,1,0,1,2,2],[0,0,0,1,0,0,1,2,1,0,1,2],
[0,0,0,0,1,0,1,2,2,1,0,1],[0,0,0,0,0,1,1,1,2,2,1,0]];
C:=GeneratorMatCode(G,GF(3));
sG:=x*TransposedMat(GeneratorMat(C));
sH:=x*TransposedMat(CheckMat(C));
a:=[0,0,0,0,0,0];
b1:=Codeword([0,1,1,1,1,1],GF(3));
e1:=Codeword([1,0,0,0,0,0],GF(3));
b2:=Codeword([1,0,1,2,2,1],GF(3));
e2:=Codeword([0,1,0,0,0,0],GF(3));
b3:=Codeword([1,1,0,1,2,2],GF(3));
e3:=Codeword([0,0,1,0,0,0],GF(3));
b4:=Codeword([1,2,1,0,1,2],GF(3));
e4:=Codeword([0,0,0,1,0,0],GF(3));
b5:=Codeword([1,2,2,1,0,1],GF(3));
e5:=Codeword([0,0,0,0,1,0],GF(3));
b6:=Codeword([1,1,2,2,1,0],GF(3));
e6:=Codeword([0,0,0,0,0,1],GF(3));
if Weight(sH)<=2 then
sH:=ShallowCopy(VectorCodeword(sH));
Append(a,sH);
a:=Codeword(a,GF(3));
u:=x-a;
return u;
elif Weight(sG)<=2 then
sG:=ShallowCopy(VectorCodeword(sG));
Append(sG,a);
sG:=Codeword(sG,GF(3));
u:=x-sG;
return u;
else
for i in [1..6] do
for j in [1..6] do
if sG-bi=ej or sG-bi=2*ej then
h1:=sG-bi;
h2:=ei;
h1:=ShallowCopy(VectorCodeword(h1));
h2:=ShallowCopy(VectorCodeword(h2));
Append(h1,h2);
h1:=Codeword(h1,GF(3));
u:=x-h1;
return u;
elif sG-2*bi=ej or sG-2*bi=2*ej then
h1:=sG-2*bi;
h2:=ei;
h1:=ShallowCopy(VectorCodeword(h1));
h2:=ShallowCopy(VectorCodeword(h2));
Append(h1,h2);
h1:=Codeword(h1,GF(3));
u:=x-h1;
return u;
fi;
od;
od;
fi;
end;
The program dont send me an error but i know it don't work because of the ej,bi and ei. I want to do what it says after the last "else" but i don't know how to solve it to make it work.

Your syntax is invalid. It is proc, not function.
And add is already a Maple command, so it's a protected name and cannot be assigned to. You have to use another name.
And your syntax for the do-loop is likely not what you want. You probably want for j from 1 to 2 do .
And you really should initialize ej with a value before doing the recursive assignment ej:=ej+1 .
And you might as well declare the procedure's local variables.
Personally, I favour using end do instead of od , and end proc instead of just end , in modern Maple. It makes it easier to tell what's being terminated.
For example,
restart;
my_add:=proc()
local e1,e2,ej,j;
e1:=0;
e2:=1;
ej:=0;
for j from 1 to 5 do
ej:=ej+1
end do;
return ej,e1,e2;
end proc:
my_add();
5, 0, 1
There is a Maple Programming Guide, which you can read online or inside Maple's own Help system. It has a nice introduction to writing procedures. And there is a more detailed Help page for the proc command.

Related

How does the pascal for loop work?

I've got a question related to the way the for loop works in Pascal:
Program example;
var i:integer;
Begin
i:=7;
for i:=1 to i do write(i);
End.
This piece of code outputs: 1234567.
I think that the compiler makes a secondary copy of the variable i, and then uses that one in the for loop.
Note that this is REQUIRED to work in Pascal according to the ISO7185 standard. The "end value" should be copied before the loop counter is modified.
https://github.com/Leporacanthicus/lacsap/blob/master/test/Basic/iso7185pat.pas#L761
In the for loop in Pascal we have variable called loop counter which controls the iterations of the loop, and this variable changes in each iteration of the loop, so it's that i which is declared here: i:=1 in your code.
The second is the variable declared above the loop which is called also i but it's a variable which is the final value for the loop.
Consider this:
Program example;
var i:integer;
var addr:^word;
Begin
i:=10;
for i:=1 to i do addr:=#i;
addr^ := addr^+1; { I add 1 to the last loop counter }
writeln(i); { This is final variable, I don't add anything to the final variable of the loop }
writeln(addr^); { This is value of the last loop counter index }
{ Both variables give us the same result }
{ Proposal: In my opinion, your guess about the copy is correct }
End.
As in comment in the code - in my opinion, pascal creates a copy of this variable.
Hope it will help!
If yes please let me know by voting up.
Regards!
The point here is the Pascal compiler will set the parameters for the for once, at the first execution. Then it sets a start point i:=1 and and end point 7 before doing anything with the control value, then starts the loop.
But I should point that this is bad practice in programming. Unless you are just making an academical or speculative question, I see no reason to "save" a variable name doing something like this.
It is interesting to notice too that this abuse of the control variable name may cause unpredictable results if this is done inside the loop.
As they use to say in those programs who show dangerous adventures, don't try to do this at home!

Lua pathfinding code needs optimization

After working on my code for a while, optimizing the most obvious things, I've resulted in this:
function FindPath(start, finish, path)
--Define a table to hold the paths
local paths = {}
--Make a default argument
path = path or {start}
--Loop through connected nodes
for i,v in ipairs(start:GetConnectedParts()) do
--Determine if backtracking
local loop = false
for i,vv in ipairs(path) do
if v == vv then
loop = true
end
end
if not loop then
--Make a path clone
local npath = {unpack(path)}
npath[#npath+1] = v
if v == finish then
--If we reach the end add the path
return npath
else
--Otherwise add the shortest part extending from this node
paths[#paths+1] = FindPath(v, finish, npath) --NOTED HERE
end
end
end
--Find and return the shortest path
if #paths > 0 then
local lengths = {}
for i,v in ipairs(paths) do
lengths[#lengths+1] = #v
end
local least = math.min(unpack(lengths))
for i,v in ipairs(paths) do
if #v == least then
return v
end
end
end
end
The problem being, the line noted gets some sort of game script timeout error (which I believe is a because of mass recursion with no yielding). I also feel like once that problem is fixed, it'll probably be rather slow even on the scale of a pacman board. Is there a way I can further optimize it, or perhaps a better method I can look into similar to this?
UPDATE: I finally decided to trash my algorithm due to inefficiency, and implemented a Dijkstra algorithm for pathfinding. For anybody interested in the source code it can be found here: http://pastebin.com/Xivf9mwv
You know that Roblox provides you with the PathfindingService? It uses C-side A* pathing to calculate quite quickly. I'd recommend using it
http://wiki.roblox.com/index.php?title=API:Class/PathfindingService
Try to remodel your algorithm to make use of tail calls. This is a great mechanism available in Lua.
A tail call is a type of recursion where your function returns a function call as the last thing it does. Lua has proper tail calls implementation and it will dress this recursion as a 'goto' under the scenes, so your stack will never blow.
Passing 'paths' as one of the arguments of FindPath might help with that.
I saw your edit about ditching the code, but just to help others stumbling on this question:
ipairs is slower than pairs, which is slower than a numeric for-loop.
If performance matters, never use ipairs, but use a for i=1,#tab loop
If you want to clone a table, use a for-loop. Sometimes, you have to use unpack (returning dynamic amount of trailing nils), but this is not such a case. Unpack is also a slow function.
Replacing ipairs with pairs or numeric for-loops and using loops instead of unpack will increase the performance a lot.
If you want to get the lowest value in a table, use this code snippet:
local lowestValue = values[1]
for k,v in pairs(values) do
if v < lowestValue then
lowestValue = k,v
end
end
This could be rewritten for your path example as so:
local least = #path[1]
for k,v in pairs(path) do
if #v < least then
least = v
end
end
I have to admit, you're very inventive. Not a lot of people would use math.min(unpack(tab)) (not counting the fact it's bad)

I keep getting a comparison between number and nil when trying to sort a table by myself

taula = {};
function randomNumber()
return math.random(100);
end
function startArray()
for x=0, 10 do
taula[x]=randomNumber();
end
end
function printArray()
for i=0,#taula do
print(taula[i]);
end
end
function organizeArray()
for i=0,#taula do
for j=1,#taula do
if taula[i]>taula[j] then
tmp = taula[j];
taula[j]=taula[i];
taula[i]=taula[tmp];
end
end
end
end
startArray()
organizeArray()
printArray()
This is not working! The initial idea is to have printed the table declared as 'taula' but in the function organizeArray() there is a problem in the if, it says I compare a number with a nil value when I have both j and i variables declared. I need help.
You're referencing tala[tmp] instead of tmp (at line 27) when you're shuffling the array around. That's what's causing the bug.
A few pointers:
You're using globals for everything. This can cause headaches later on, when globals collide (i.e tmp could be set to something, and you do something with it). See: Local Variables and Blocks
Using randomNumber() makes your code kind of obscure, since randomNumber is just an alias for math.random(100).
Lua starts at 1, not 0. You can start at 0, but this is just something to keep in mind. #table will not count the index 0.
When asking questions, please give the full error message -- this'll let us look at the code without having to run it ourselves :)
You can put print(x) in your code, so you can see what's happening. This'll help you find bugs, since you know whats going on.

How can i know if a variable is a number or a letter with Pascal?

I'm trying to make a (very) little code to determine whether a given variable x is a number or a letter. It has to be done by hand without things like type(x) -assuming there is such thing in Pascal-.
My plan was to verify that x is not a number one by one, then i wrote this:
(*let ischar be a boolean and let x be a letter or a number.*)
for i:=0 to 9 do
begin
if (x=i) then
ischar = false;
end;
if ischar then
write('x is a number!');
else
write('x is a letter');
I was hoping that the test "x=i" would return false if x is a letter, but here i don't even get to compile because of the following error: "Got char, expected long int". It seems that i can't compare x and i, i knew that but i tought that under that circumstances if would return false.
Is there another way to do this 'by hand'?
It's generally not possible to directly compare variables of different types. The compilation error suggests x is declared as a char, while i is a longint.
The available options may depend on what Pascal compiler you use.
My only experience is with the Borland (later CodeGear and Embarcadero) products "Turbo Pascal" and "Delphi".
Those compilers have the ord function which gives the numeric value of an ordinal type.
In the case of a char, the ord function should give you the ASCII code of the character, which you can test to see if it's in the code range of '0'..'9'.
You don't need the for loop. This should work:
if (ord(x)<48) or (ord(x)>57) then ischar:=true else ischar:=false;
Edit: Here's the Free Pascal documentation for the ord function:
http://www.freepascal.org/docs-html/rtl/system/ord.html

Automated GOTO removal algorithm

I've heard that it's been proven theoretically possible to express any control flow in a Turing-complete language using only structured programming constructs, (conditionals, loops and loop-breaks, and subroutine calls,) without any arbitrary GOTO statements. Is there any way to use that theory to automate refactoring of code that contains GOTOs into code that does not?
Let's say I have an arbitrary single subroutine in a simple imperative language, such as C or Pascal. I also have a parser that can verify that this subroutine is valid, and produce an Abstract Syntax Tree from it. But the code contains GOTOs and Labels, which could jump forwards or backwards to any arbitrary point, including into or out of conditional or loop blocks, but not outside of the subroutine itself.
Is there an algorithm that could take this AST and rework it into new code which is semantically identical, but does not contain any Labels or GOTO statements?
In principle, it is always possible to do this, though the results might not be pretty.
One way to always eliminate gotos is to transform the program in the following way. Start off by numbering all the instructions in the original program. For example, given this program:
start:
while (true) {
if (x < 5) goto start;
x++
}
You could number the statements like this:
0 start:
1 while (x < 3) {
2 if (x < 5) goto start;
3 x++
}
To eliminate all gotos, you can simulate the flow of the control through this function by using a while loop, an explicit variable holding the program counter, and a bunch of if statements. For example, you might translate the above code like this:
int PC = 0;
while (PC <= 3) {
if (PC == 0) {
PC = 1; // Label has no effect
} else if (PC == 1) {
if (x < 3) PC = 4; // Skip loop, which ends this function.
else PC = 2; // Enter loop.
} else if (PC == 2) {
if (x < 5) PC = 0; // Simulate goto
else PC = 3; // Simulate if-statement fall-through
} else if (PC == 3) {
x++;
PC = 1; // Simulate jump back up to the top of the loop.
}
}
This is a really, really bad way to do the translation, but it shows that in theory it is always possible to do this. Actually implementing this would be very messy - you'd probably number the basic blocks of the function, then generate code that puts the basic blocks into a loop, tracks which basic block is currently executing, then simulates the effect of running a basic block and the transition from that basic block to the appropriate next basic block.
Hope this helps!
I think you want to read Taming Control Flow by Erosa and Hendren, 1994. (Earlier link on Google scholar).
By the way, loop-breaks are also easy to eliminate. There is a simple mechanical procedure involving the creating of a boolean state variable and the restructuring of nested conditionals to create straight-line control flow. It does not produce pretty code :)
If your target language has tail-call optimization (and, ideally, inlining), you can mechanically remove both break and continue by turning the loop into a tail-recursive function. (If the index variable is modified by the loop body, you need to work harder at this. I'll just show the simplest case.) Here's the transformation of a simple loop:
for (Type Index = Start; function loop(Index: Type):
Condition(Index); if (Condition)
Index = Advance(Index)){ return // break
Body Body
} return loop(Advance(Index)) // continue
loop(Start)
The return statements labeled "continue" and "break" are precisely the transformation of continue and break. Indeed, the first step in the procedure might have been to rewrite the loop into its equivalent form in the original language:
{
Type Index = Start;
while (true) {
if (!Condition(Index))
break;
Body;
continue;
}
}
I use either/both Polyhedron's spag and vast's 77to90 to begin the process of refactoring fortran and then converting it to matlab source. However, these tools always leave 1/4 to 1/2 of the goto's in the program.
I wrote up a goto remover which accomplishes something similar to what you were describing: it takes fortran code and refactors all the remaining goto's from a program and replacing them with conditionals and do/cycle/exit's which can then be converted into other languages like matlab. You can read more about the process I use here:
http://engineering.dartmouth.edu/~d30574x/consulting/consulting_gotorefactor.html
This program could be adapted to work with other languages, but I have not gotten than far yet.

Resources