Proced\372r\341k (elj\341r\341sok)Bevezet\351s \351s els\365 p\351ldaVizsg\341ljuk meg az egyik kor\341bbi, 3n+1 probl\351m\341hoz k\351sz\355tett programunkat.Feladat: a Maple el\365re megadott n \351s m sz\341mok k\366z\366tt ellen\365rizze a sejt\351s helyess\351g\351t.restart;m:= 10: n:= 20:for i from m to n do
j:= i:
while j>1 do
if j mod 2=0 then j:= j/2 else j:= 3*j+1 end if:
end do:
end do:
printf("rendben"):Vagy egy m\341sik, amelyik ki\355rja a lefut\341sokat is:restart;m:=7: n:=10:for k from m to n do
z:=k;
while z>1 do
if modp(z,2)=0 then z:=(z/2)
else z:=3*z+1
end if;
printf("%d, ",z);
end do;
end do;Ha azonban a sejt\351s helyess\351g\351t m\341s sz\341mok k\366z\366tt szeretn\351nk ellen\365rizni, m-nek \351s n-nek \372j \351rt\351ket kellene adnunk, majd a programot \372j ra le kellene futtatnunk. Karakteres \374zemm\363dban ez m\351g bonyolultabb\341 v\341lna, hiszen a program \372jb\363li haszn\341lat\341hoz le is kellene m\341solnuk azt. J\363l l\341that\363, hogy ez igen neh\351zkess\351 \351s hosszadalmass\341 v\341lhat. Ezt a probl\351m\341t oldhatjuk meg azzal, ha programunkat elj\341r\341sk\351nt \355rjuk meg.A proced\372r\341k alakja a Mapleben \341ltal\341nosan a k\366vetkez\365: proc(param\351terek list\341ja)
utas\355t\341sok end proc;Ahhoz, hogy hivatkozhassunk r\341, \351rdemes nevet adni neki, azaz az els\365 sort \355gy kezdeni: n\351v := proc(param\351terek list\341ja)
Az \355gy meg\355rt elj\341r\341s a n\351v(param\351terek list\341ja) paranccsal futtathat\363 le.N\351zz\374k meg, hogy is n\351zne ez ki az el\365bbi p\351ld\341n:sejtes := proc(m,n)
local i,j;
for i from m to n do
j:=i;
while j>1 do
if j mod 2=0 then j:=j/2
else j:=3*j+1
end if
end do
end do;
printf("rendben")
end proc;A program \341ltal ki\355rt output most eg\351szen m\341s, mint az el\365z\365 esetben, hiszen m\341s jelleg\373 volt a parancs is. Most nem lefuttatuk a programot, hanem a sejtes v\341ltoz\363nak adtunk \351rt\351ket, teh\341t a Maple csak az \351rt\351kad\341s megt\366rt\351nt\351t jelezte vissza. Az elj\341r\341s elej\351n szerepl\365 local i,j; sorra, azaz a lok\341lis illetve glob\341lis v\341ltoz\363k k\351rd\351s\351re nemsok\341ra visszat\351r\374nk.Futtassuk le az \355gy elk\351sz\355tett proced\372r\341nkat tetsz\365leges sz\341mokra:sejtes(2,22); sejtes(10,100);Maple-ben a proced\372r\341k fontos tulajdons\341ga, hogy megh\355v\341sukkor a megadott param\351terek sz\341ma nem lehet kevesebb, mint a felhaszn\341lt param\351terek sz\341ma. T\366bb viszont lehet. \315gy asejtes(5,11,30);parancsnak ugyanaz az \351rtelme, mint a sejtes(5,11)-nek, m\355g az al\341bbi utas\355t\341sra hiba\374zenet a v\341lasz:sejtes();Param\351ter\341tad\341sFigyelj\374k meg, mi a hiba az al\341bbi proced\372r\341ban!sejtes1:=proc(m)
while m>1 do
if m mod 2 = 0 then m:=m/2
else m:=3*m+1
end if;
end do;
end proc; sejtes1(14);Az\351rt nem lehet ezt \355gy megoldani, mert az m param\351tert a fut\341s sor\341n nem tudja a Maple megv\341ltoztatni. Nincs az m:=m/2-nek \351rtelme, mert az a 14-es \351rt\351kkel val\363 megh\355v\341skor a 14:=14/2 utast\341st kapjuk, ami \351rtelmetlen. Megold\341s: \372j v\341ltoz\363t kell bevezetni, \351s annak \341tadni a param\351tert, majd ezt az \372jat lehet v\341ltoztatni:sejtes2:=proc(m)
local k;
k:=m;
while k>1 do
if k mod 2 = 0 then k:=k/2
else k:=3*k+1
end if;
end do;
end proc;sejtes2(14);Visszat\351r\351si \351rt\351kAz elj\341r\341soknak Maple-ben mindig van visszat\351r\351si \351rt\351k\374k: ez alapesetben az utols\363 v\351grehajtott m\373velet eredm\351nye. Ha m\341s visszat\351r\351si \351rt\351ket szeretn\351nk, akkor a RETURN parancsot kell haszn\341lnunk, ez a proced\372ra fut\341s\341t is megszak\355tja. N\351zz\374k meg ezt egy egyszer\373 p\351ld\341n:a:=proc(x)
if x>=0 then RETURN(x);
else print(-x)
end if;
print(x+1);
x^2;
end:b:=a(3); b:=a(-2);Lok\341lis \351s glob\341lis v\341ltoz\363kItt kell m\351g besz\351ln\374nk az \372gynevezett lok\341lis \351s glob\341lis v\341ltoz\363kr\363l is. Lok\341lisnak nevezz\374k azokat a v\341ltoz\363kat, melyeket csak egy adott elj\341r\341son bel\374l l\341thatunk, \351rt\351k\374k csak ott \351rv\351nyes. \311ppen ez\351rt nem is igaz\341n lok\341lis v\341ltoz\363kr\363l, ink\341bb egy adott proced\372ra lok\341lis v\341ltoz\363ir\363l besz\351lhet\374nk. Ha m\341st nem mondunk, akkor a program az elj\341r\341sban nem param\351terk\351nt szerepl\365 v\341ltoz\363kat mind lok\341lisnak tekinti. Glob\341lisnak azokat a v\341ltoz\363kat nevezz\374k, melyek munk\341nk sor\341n b\341rhol el\351rhet\365ek: ha a parancssorba \351rt\351kad\341st \355runk, az mindig glob\341lis v\341ltoz\363t hoz l\351tre.Az elj\341r\341sok \355r\341sa sor\341n sokszor van sz\374ks\351g\374nk arra, hogy megadjuk, hogy a lok\341lis vagy glob\341lis v\341ltoz\363t szeretn\351nk-e haszn\341lni. Ezt a proc(param\351terek) ut\341n k\366zvetlen\374l be\355rt global v\341ltoz\363lista; vagy local v\341ltoz\363lista; parancsokkal \351rhetj\374k el. Egy elj\341r\341son bel\374l egy v\341ltoz\363 nem lehet egyszerre glob\341lis \351s lok\341lis is. Ha glob\341lisnak defini\341ljuk, akkor a proced\372ra "l\341tja" a parancssorban be\355rt \351rt\351k\351t, \351s megv\341ltoztatni is k\351pes azt, de csak futtat\341sa sor\341n (azaz az elj\341r\341s defini\341l\341sa \366nmag\341ban nem okozhatja az \351rt\351kek megv\341ltoz\341s\341t). Ha lok\341lisnak defini\341ljuk, akkor az \351ppen olyan, mintha egy m\351g \351rt\351k n\351lk\374li, \372j v\341ltoz\363t vezetn\351nk be: az elj\341r\341s nem l\341tja a k\355v\374l defini\341lt \351rt\351ket, \351s megv\341ltoztatni sem tudja azt. Hogy \351rthet\365bb legyen, l\341ssunk egy p\351ld\341t:restart;
i:=2; j:=3;
p:=proc()
global i; local j;
print(i,j);
i:=4; j:=5;
print(i,j);
end proc:i,j;p(); #els\365 fut\341si,j;Azaz i \351s j \351rt\351k\351n nem v\341ltoztat semmit a p v\341ltoz\363nak val\363 \351rt\351kad\341s (az elj\341r\341st nem futtattuk m\351g le!) Els\365 futtat\341sakor pedig v\351gigk\355s\351rhetj\374k, mint vette be i \351rt\351k\351t m\341r mint 2-t, (glob\341lis), \351s mint kezelte egyel\365re ismeretlenk\351nt j-t (lok\341lis), hogy ut\341na i-t megv\341ltoztatva annak hat\341sa a proced\372r\341n k\355v\374l is megmaradt (i t\351nyleg 4 lett), m\355g j hi\341ba lett a proced\372r\341n bel\374l 5, a proced\372r\341n k\355v\374l megmaradt 3-nak:Tov\341bbi p\351lda:restart: s:=3;f:=proc()
s:=s^2;
end proc;
s;f();s;A hiba oka, hogy a programbeli lok\303\241lis 's' k\303\274l\303\266nb\303\266zik a k\303\274ls\305\221 glob\303\241lis 's'-t\305\221l.f2:=proc()
global s;
s:=s^2;
end proc;
f2();s;A k\351rt param\351ter t\355pusaN\351ha sz\374ks\351g lehet arra, hogy szab\341lyozzuk, a program milyen t\355pus\372 param\351tereket fogadjon el.A fenti, sejtes nev\303\273 programot szab\303\241lytalan t\303\255pus\303\272 param\303\251terrel megh\303\255vva ilyen hiba\303\274zenetet kapunk: (Teh\303\241t csak a fut\303\241s sor\303\241n der\303\274l ki, hogy az egyik m\305\261velet nem v\303\251gezhet\305\221 el.)sejtes(.2,10);Ha azonban a k\366vetkez\365 kis v\341ltoztat\341st eszk\366z\366lj\374k:sejtes2:=proc(m::posint,n::posint)
local i,j;
for i from m to n do
j:=i;
while j>1 do
if j mod 2=0 then j:=j/2
else j:=3*j+1
end if
end do
end do;
print('helyes')
end proc;akkor ezzel megadtuk, hogy mindk\351t param\351tert pozit\355v eg\351sz t\355pus\372nak v\341rjuk, \355gy ha nem ilyet kap az elj\341r\341s, akkor hiba\374zenetet ad (a t\355pusok nev\351t a Help seg\355ts\351g\351vel illetve a whattype parancs haszn\341lat\341val lehet megtudni).sejtes2(0.1,9);