Ââåäåíèå â ïðîãðàììèðîâàíèå íà Maxima
=====================================

Maxima ïðåäîñòàâëÿåò öèêë do, äëÿ èòåðàöèè, à òàêæå áîëåå ïðîñòûå óïðàâëÿþùèå êîíñòðóêöèè, òàêèå êàê go.

Ôóíêöèè è ïåðåìåííûå äëÿ ïðîãðàììèðîâàíèÿ íà Maxima
===================================================

 -- Ôóíêöèÿ: backtrace ()
 -- Ôóíêöèÿ: backtrace (N)
     Ïå÷àòàåò ñòåê âûçîâîâ, ò.å. ñïèñîê ôóíêöèé, êîòîðûå âûçûâàþò òåêóùóþ àêòèâíóþ ôóíêöèþ.

     Âûçîâ backtrace() ïå÷àòàåò âåñü ñòåê âûçîâîâ.

     Âûçîâ backtrace (N) ïå÷àòàåò N ïîñëåäíèõ ôóíêöèé, âêëþ÷àÿ òåêóùóþ.

     Ôóíêöèÿ backtrace ìîæåò âûçûâàòüñÿ âíóòðè ïðîãðàììû, ôóíêöèè èëè èç èíòåðàêòèâíîãî ïðèãëàøåíèå à íå òîëüêî èç êîíòåêñòà îòëàäêè.

     Ïðèìåðû:

       * Âûçîâ backtrace() ïå÷àòàåò âåñü ñòåê âûçîâîâ.

               (%i1) h(x) := g(x/7)$
               (%i2) g(x) := f(x-11)$
               (%i3) f(x) := e(x^2)$
               (%i4) e(x) := (backtrace(), 2*x + 13)$
               (%i5) h(10);
               #0: e(x=4489/49)
               #1: f(x=-67/7)
               #2: g(x=10/7)
               #3: h(x=10)
                                             9615
               (%o5)                         ----
                                              49

       * Âûçîâ backtrace (N) ïå÷àòàåò N ïîñëåäíèõ ôóíêöèé, âêëþ÷àÿ òåêóùóþ.

               (%i1) h(x) := (backtrace(1), g(x/7))$
               (%i2) g(x) := (backtrace(1), f(x-11))$
               (%i3) f(x) := (backtrace(1), e(x^2))$
               (%i4) e(x) := (backtrace(1), 2*x + 13)$
               (%i5) h(10);
               #0: h(x=10)
               #0: g(x=10/7)
               #0: f(x=-67/7)
               #0: e(x=4489/49)
                                             9615
               (%o5)                         ----
                                              49

     Îòëàäêà

 -- Ñïåöèàëüíûé îïåðàòîð: do
     Êîìàíäà do èñïîëüçóåòñÿ äëÿ âûïîëíåíèÿ èòåðàöèé.  Ò.ê. êîìàíäà do äîâîëüíî îáùà, òî îíà áóäåò îïèñàíà â äâóõ ÷àñòÿõ. Ñíà÷àëà áóäåò îïèñàíà îáû÷íàÿ ôîðìà, àíàëîãè÷íà èñïîëüçóåìûì â íåñêîëüêèõ äðóãèõ ÿçûêàõ ïðîãðàììèðîâàíèÿ (Fortran, Algol, PL/I è ò.ä.). Äàëåå áóäóò îïèñàíû äðóãèå âîçìîæíîñòè.

     Ñóùåñòâóåò òðè ôîðìû êîìàíäû, îòëè÷àþùèåñÿ òîëüêî óñëîâèåì çàâåðøåíèÿ.  À èìåííî:

       * for VARIABLE: INITIAL_VALUE step INCREMENT thru LIMIT do BODY

       * for VARIABLE: INITIAL_VALUE step INCREMENT while CONDITION do BODY

       * for VARIABLE: INITIAL_VALUE step INCREMENT unless CONDITION do BODY

     (Êàê àëüòåðíàòèâà, êîìàíäà step ìîæåò áûòü çàäàíà ïîñëå óñëîâèÿ çàâåðøåíèÿ èëè ãðàíèöû.)

     Ïàðàìåòðû INITIAL_VALUE, INCREMENT, LIMIT è BODY ìîãóò áûòü ïðîèçâîëüíûìè âûðàæåíèÿìè.  Åñëè ïðèðàùåíèå ðàâíî 1, òî êîìàíäà "step 1" ìîæåò áûòü îïóùåíà.

     Ïåðåä âûïîëíåíèå êîìàíäû do, ïåðåìåííîé VARIABLE (äàëåå íàçûâàåìîé óïðàâëÿþùåé ïåðåìåííîé) ïðèñâàèâàåòñÿ íà÷àëüíîå çíà÷åíèå INITIAL_VALUE. Äàëåå: (1) åñëè çíà÷åíèå óïðàâëÿþùåé ïåðåìåííîé ïðåâûøàåò âåðõíþþ ãðàíèöó, çàäàâàåìóþ thru, èëè åñëè óñëîâèå unless ðàâíî true, èëè óñëîâèå while ðàâíî false, òî do çàâåðøàåòñÿ. (2) Âû÷èñëÿåòñÿ BODY.  (3) Ïðèðàùåíèå äîáàâëÿåòñÿ ê óïðàâëÿþùåé ïåðåìåíîé. Øàãè (1) -- (3) ïîâòîðÿþòñÿ äî âûïîëíåíèÿ óñëîâèÿ çàâåðøåíèÿ. Ìîæíî çàäàâàòü íåñêîëüêî óñëîâèé çàâåðøåíèÿ.  Â ýòîì ñëó÷àå êîìàíäà do çàâåðøàåòñÿ ïðè óäîâëåòâîðåíèè ëþáîãî èç íèõ.

     Îáû÷íî òåñò thru âûïîëíÿåòñÿ, êîãäà óïðàâëÿþùàÿ ïåðåìåííàÿ ñòàíîâèòñÿ áîëüøå LIMIT, êîãäà ïðèðàùåíèå INCREMENT íåîòðèöàòåëüíî, èëè, åñëè ïåðåìåííàÿ ñòàíîâèòñÿ ìåíüøå LIMIT, êîãäà ïðèðàùåíèå INCREMENT îòðèöàòåëüíî. Ïàðàìåòðû INCREMENT è LIMIT ìîãóò áûòü íå÷èñëîâûìè âûðàæåíèÿìè, åñëè ìîæåò áûòü îïðåäåëåíî èõ íåðàâåíñòâî.  Îäíàêî, åñëè INCREMENT íå ÿâëÿåòñÿ ñèíòàêñè÷åñêè îòðèöàòåëüíûì (íàïðèìåð, îòðèöàòåëüíûì ÷èñëîì) â ìîìåíò íà÷àëà âûïîëíåíèÿ êîìàíäû do, òî Maxima ïðåäïîëàãàåò ïîëîæèòåëüíîñòü INCREMENT âî âðåìÿ âûïîëíåíèÿ do. Åñëè íà ñàìîì äåëå INCREMENT îêàæåòñÿ íåïîëîæèòåëüíûì, òî do ìîæåò íå çàâåðøèòüñÿ íàäëåæàùèì îáðàçîì.

     Îòìåòèì, ÷òî LIMIT, INCREMENT è óñëîâèå çàâåðøåíèÿ âû÷èñëÿþòñÿ çàíîâî äëÿ êàæäîé èòåðàöèè.  Òàêèì îáðàçîì, åñëè êàêîå-ëèáî èç ýòèõ âûðàæåíèé òðåáóåò äëèòåëüíîãî âû÷èñëåíèÿ, íî íå ìåíÿåòñÿ îò èòåðàöèè ê èòåðàöèè ïðè âû÷èñëåíèè BODY, òî áóäåò áîëåå ýôôåêòèâíûì ïðèñâîèòü èõ çíà÷åíèå ïåðåìåííîé äî âûïîëíåíèÿ do è èñïîëüçîâàòü ýòó ïåðåìåííóþ.

     Çíà÷åíèå, îáû÷íî âîçâðàùàåìîå êîìàíäîé do, åñòü àòîì done. Îäíàêî, ôóíêöèÿ return ìîæåò áûòü èñïîëüçîâàíà âíóòðè BODY äëÿ çàâåðøåíèÿ do è çàäàíèÿ âîçâðàùàåìîãî çíà÷åíèÿ. Îòìåòèì, ÷òî âûçîâ return âíóòðè öèêëà do, ðàñïîëîæåííîãî  â áëîêå block, çàâåðøàåò do à íå áëîê block. Ôóíêöèÿ go íå ìîæåò áûòü èñïîëüçîâàíà äëÿ âûõîäà èç êîìàíäû do â îáúåìëþùèé áëîê block.

     Óïðàâëÿþùàÿ ïåðåìåííàÿ âñåãäà ëîêàëüíà â ðàìêàõ do, ò.å. ýòó ïåðåìåííóþ ìîæíî èñïîëüçîâàòü âíóòðè öèêëà è ýòî íå îêàæåò âëèÿíèÿ íà ïåðåìåííóþ ñ òåì æå èìåíåì âíå do. Ïîñëå çàâåðøåíèÿ do, óïðàâëÿþùàÿ ïåðåìåííàÿ îñòàåòñÿ íåñâÿçàííîé.

          (%i1) for a:-3 thru 26 step 7 do display(a)$
                                       a = - 3

                                        a = 4

                                       a = 11

                                       a = 18

                                       a = 25

          (%i1) s: 0$
          (%i2) for i: 1 while i <= 10 do s: s+i;
          (%o2)                         done
          (%i3) s;
          (%o3)                          55

     Îòìåòèì, ÷òî óñëîâèå while i <= 10 ýêâèâàëåíòíî óñëîâèþ unless i > 10 èëè óñëîâèþ thru 10.

          (%i1) series: 1$
          (%i2) term: exp (sin (x))$
          (%i3) for p: 1 unless p > 7 do
                    (term: diff (term, x)/p,
                     series: series + subst (x=0, term)*x^p)$
          (%i4) series;
                            7    6     5    4    2
                           x    x     x    x    x
          (%o4)            -- - --- - -- - -- + -- + x + 1
                           90   240   15   8    2

     ÷òî äàåò 8 ÷ëåíîâ ðÿäà Òåéëîðà äëÿ e^sin(x).

          (%i1) poly: 0$
          (%i2) for i: 1 thru 5 do
                    for j: i step -1 thru 1 do
                        poly: poly + i*x^j$
          (%i3) poly;
                            5      4       3       2
          (%o3)          5 x  + 9 x  + 12 x  + 14 x  + 15 x
          (%i4) guess: -3.0$
          (%i5) for i: 1 thru 10 do
                    (guess: subst (guess, x, 0.5*(x + 10/x)),
                     if abs (guess^2 - 10) < 0.00005 then return (guess));
          (%o5)                  - 3.162280701754386

     Â ýòîì ïðèìåðå âû÷èñëÿåòñÿ îòðèöàòåëüíûé êâàäðàòíûé êîðåíü ÷èñëà 10 ñ èñïîëüçîâàíèåì ìåòîäà Íüþòîíà-Ðàôñîíà ñ ìàêñèìàëüíûì ÷èñëîì èòåðàöèé 10. Åñëè óñëîâèå ñõîäèìîñòè íå áóäåò âûïîëíåíî, òî âîçâðàùàåòñÿ çíà÷åíèå done.

     Âìåñòî äîáàâëåíèÿ çíà÷åíèÿ ê óïðàâëÿþùåé ïåðåìåííîé âîçìîæåí äðóãîé ñïîñîá åå èçìåíåíèÿ íà êàæäîì öèêëå èòåðàöèè. Â ýòîì ñëó÷àå ìîæíî èñïîëüçîâàòü next EXPRESSION âìåñòî step INCREMENT. ×òî âûçûâàåò ïðèñâàèâàíèå óïðàâëÿþùåé ïåðåìåííîé çíà÷åíèÿ EXPRESSION ïðè êàæäîé èòåðàöèè.

          (%i6) for count: 2 next 3*count thru 20 do display (count)$
                                      count = 2

                                      count = 6

                                     count = 18

     Ñèíòàêñèñ for VARIABLE from VALUE ...do... ìîæåò áûòü èñïîëüçîâàí êàê àëüòåðíàòèâà for VARIABLE: VALUE ...do.... ×òî ïîçâîëÿåò ðàñïîëàãàòü from VALUE ïîñëå çíà÷åíèé step èëè next, èëè ïîñëå óñëîâèÿ çàâåðøåíèÿ.  Åñëè from VALUE îïóùåíî, òî â êà÷åñòâå íà÷àëüíîãî çíà÷åíèÿ ïðåäïîëàãàåòñÿ 1.

     Èíîãäà òðåáóåòñÿ âûïîëíèòü èòåðàöèè áåç èñïîëüçîâàíèÿ óïðàâëÿþùåé ïåðåìåííîé. Â ýòîì ñëó÷àå ìîæíî çàäàòü òîëüêî óñëîâèå çàâåðøåíèÿ áåç êîìàíä èíèöèàëèçàöèè è èçìåíåíèÿ óïðàâëÿþùåé ïåðåìåííîé, êàê ñäåëàíî â ñëåäóþùåì ïðèìåðå, âû÷èñëÿþùåì êâàäðàòíûé êîðåíü ÷èñëà 5 ïðè íåòî÷íîì çàòðàâî÷íîì çíà÷åíèè.

          (%i1) x: 1000$
          (%i2) thru 20 do x: 0.5*(x + 5.0/x)$
          (%i3) x;
          (%o3)                   2.23606797749979
          (%i4) sqrt(5), numer;
          (%o4)                   2.23606797749979

     Åñëè íåîáõîäèìî, òî ìîæíî ïîëíîñòüþ îïóñòèòü óñëîâèÿ çàâåðøåíèÿ è èñïîëüçîâàòü òîëüêî do BODY, ÷òî âûçûâàåò áåñêîíå÷íîå âû÷èñëåíèå BODY.  Â ýòîì ñëó÷àå äëÿ çàâåðøåíèÿ do ñëåäóåò èñïîëüçîâàòü return.

          (%i1) newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
                    do (y: ev(df), x: x - f(x)/y,
                        if abs (f (x)) < 5e-6 then return (x)))$
          (%i2) sqr (x) := x^2 - 5.0$
          (%i3) newton (sqr, 1000);
          (%o3)                   2.236068027062195

     (Çàìåòèì, ÷òî return âûçûâàåò âîçâðàùåíèå òåêóùåãî çíà÷åíèÿ x â êà÷åñòâå çíà÷åíèÿ do.  Áëîê block çàâåðøàåòñÿ, è çíà÷åíèå do âîçâðàùàåòñÿ â êà÷åñòâå çíà÷åíèÿ áëîêà, ò.ê. do ÿâëÿåòñÿ ïîñëåäíåé êîìàíäîé block.)

     Â Maxima äîñòóïíà åùå îäíà ôîðìà êîìàíäû do.  Åå ñèíòàêñèñ:

          for VARIABLE in LIST END_TESTS do BODY

     Ýëåìåíòû ñïèñêà LIST (ïðîèçâîëüíûå âûðàæåíèÿ) ïîñëåäîâàòåëüíî ïðèñâàèâàþòñÿ ïåðåìåííîé VARIABLE Äëÿ êàæäîé èòåðàöèè âû÷èñëåíèÿ BODY. Íåîáÿçàòåëüíîå óñëîâèå END_TESTS ìîæåò èñïîëüçîâàòüñÿ äëÿ çàâåðøåíèÿ do, èíà÷å öèêë çàâåðøèòñÿ ïðè èñ÷åðïàíèè LIST èëè ïðè âûïîëíåíèè return âíóòðè BODY.  (Íà ñàìîì äåëå, LIST ìîæåò áûòü ëþáûì íåàòîìàðíûì âûðàæåíèåì, ïîñëåäîâàòåëüíûå ÷àñòè êîòîðîãî áóäóò èñïîëüçîâàíû â èòåðàöèè.)

          (%i1)  for f in [log, rho, atan] do ldisp(f(1))$
          (%t1)                                  0
          (%t2)                                rho(1)
                                               %pi
          (%t3)                                 ---
                                                4
          (%i4) ev(%t3,numer);
          (%o4)                             0.78539816

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: errcatch (EXPR_1, ..., EXPR_N)
     Âû÷èñëÿåò îäíî çà äðóãèì âûðàæåíèÿ  EXPR_1, ..., EXPR_N è, åñëè íå âîçíèêàåò îøèáîê, âîçâðàùàåò [EXPR_N] (ñïèñîê). Åñëè ïðè âû÷èñëåíèè îäíîãî èç àðãóìåíòîâ âîçíèêàåò îøèáêà, òî errcatch ïðåäîòâðàùàåò äàëüíåéøåå ðàñïðîñòðàíåíèå îøèáêè è âîçâðàùàåò ïóñòîé ñïèñîê [] áåç äàëüíåéøåãî âû÷èñëåíèÿ àðãóìåíòîâ.

     Ôóíêöèÿ errcatch ïîëåçíà â ïàêåòíûõ batch ôàéëàõ, åñëè îæèäàåòñÿ âîçìîæíîå âîçíèêíîâåíèå îøèáêè, ÷òî áåç ïåðåõâàòà îøèáêè ïðèâîäèò ê çàâåðøåíèþ batch.

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: error (EXPR_1, ..., EXPR_N)
 -- Ñèñòåìíàÿ ïåðåìåííàÿ: error
     Âû÷èñëÿåò è ïå÷àòàåò EXPR_1, ..., EXPR_N, è çàòåì âûçûâàåò îøèáêó, ÷òî âîçâðàùàåò óïðàâëåíèå íà âåðõíèé óðîâåíü Maxima èëè áëèæàéøåìó îáúåìëþùåìó errcatch.

     Çíà÷åíèåì ïåðåìåííîé error ÿâëÿåòñÿ ñïèñîê, îïèñûâàþùèé îøèáêó. Ïåðâûé ýëåìåíò error -- ñòðîêà ôîðìàòèðîâàíèÿ, êîòîðàÿ îáúåäèíÿåò âñå ñòðîêè èç ïàðàìåòðîâ EXPR_1, ..., EXPR_N, îñòàëüíûå ýëåìåíòû -- åñòü çíà÷åíèÿ íåñòðîêîâûõ àðãóìåíòîâ.

     Ôóíêöèÿ errormsg() ôîðìàòèðóåò è ïå÷àòàåò error, ÷òî ïîâòîðÿåò ïå÷àòü ñàìîé ïîñëåäíåé îøèáêè.

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: errormsg ()
     Ïîâòîðÿåò ïå÷àòü ñàìîé ïîñëåäíåé îøèáêè. Èíôîðìàöèÿ îá îøèáêå ñîäåðæèòñÿ â ïåðåìåííîé error, è errormsg ôîðìàòèðóåò è ïå÷àòàåò åå.

     Ïðîãðàììèðîâàíèå

 -- Ñïåöèàëüíûé îïåðàòîð: for
     Èñïîëüçóåòñÿ â öèêëàõ. Ñì. do äëÿ îïèñàíèÿ ñðåäñòâ Maxima äëÿ îðãàíèçàöèè èòåðàöèé.

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: go (TAG)
     Èñïîëüçóåòñÿ âíóòðè áëîêà block äëÿ ïåðåäà÷è óïðàâëåíèÿ íà êîìàíäó, ïîìå÷åííóþ ïàðàìåòðîì go.  Äëÿ ïîìåòêè êîìàíäû â áëîêå, ïåðåä íåé ïîìåùàþò äðóãóþ êîìàíäó â âèäå àòîìà (ìåòêè).  Íàïðèìåð:

          block ([x], x:1, loop, x+1, ..., go(loop), ...)

     Àðãóìåíòîì go äîëæíà áûòü ìåòêà, îïðåäåëåííàÿ â òîì æå áëîêå block. Íåëüçÿ èñïîëüçîâàòü go äëÿ ïåðåäà÷è óïðàâëåíèÿ íà ìåòêó â áëîêå îòëè÷íîì îò òîãî, ãäå íàõîäèòñÿ ñàìà êîìàíäà go.

     Ïðîãðàììèðîâàíèå

 -- Ñïåöèàëüíûé îïåðàòîð: if
     Óñëîâíîå âû÷èñëåíèå. Ñóùåñòâóþò ðàçëè÷íûå ôîðìû óñëîâíîãî âûðàæåíèÿ if.

     if COND_1 then EXPR_1 else EXPR_0 âû÷èñëÿåò è âîçâðàùàåò çíà÷åíèå EXPR_1, åñëè çíà÷åíèå COND_1 ðàâíî true, èíà÷å âû÷èñëÿåò è âîçâðàùàåò çíà÷åíèå expr_0.

     if COND_1 then EXPR_1 elseif COND_2 then EXPR_2 elseif ... else EXPR_0 âû÷èñëÿåò è âîçâðàùàåò çíà÷åíèå EXPR_K, åñëè COND_K ðàâíî true à âñå ïðåäûäóùèå óñëîâèÿ ðàâíû false. Åñëè íå îäíî èç óñëîâèé íå ðàâíî true, òî âû÷èñëÿåòñÿ è âîçâðàùàåòñÿ çíà÷åíèå EXPR_0.

     Åñëè çàâåðøàþùåå else îòñóòñòâóåò, òî â êîíöå ïîäðàçóìåâàåòñÿ else false. Ò.å. if COND_1 then EXPR_1 ýêâèâàëåíòíî if COND_1 then EXPR_1 else false, à if COND_1 then EXPR_1 elseif ... elseif COND_N then EXPR_N ýêâèâàëåíòíî if COND_1 then EXPR_1 elseif ... elseif COND_N then EXPR_N else false.

     Àëüòåðíàòèâû EXPR_0, ..., EXPR_N ìîãóò áûòü ïðîèçâîëüíûìè âûðàæåíèÿìè Maxima, âêëþ÷àÿ âëîæåííûå if âûðàæåíèÿ. Àëüòåðíàòèâû íå óïðîùàþòñÿ è íå âû÷èñëÿþòñÿ äî òåõ ïîð ïîêà ñîîòâåòñòâóþùåå óñëîâèå íå ðàâíî true.

     Óñëîâèÿ COND_1, ..., COND_N ÿâëÿþòñÿ âûðàæåíèÿìè, êîòîðûå ïîòåíöèàëüíî èëè ôàêòè÷åñêè âû÷èñëÿþòñÿ â true èëè false. Åñëè çíà÷åíèå óñëîâèÿ íå ðàâíî íè true, íè false, òî ïîâåäåíèå if óïðàâëÿåòñÿ ãëîáàëüíîé ïåðåìåííîé prederror. Åñëè prederror ðàâíà true, òî ëþáîå çíà÷åíèå óñëîâèÿ, îòëè÷íîå îò true èëè false, ñ÷èòàåòñÿ îøèáêîé.  Èíà÷å, óñëîâèÿ, êîòîðûå íå âû÷èñëÿþòñÿ â true èëè false, ñ÷èòàþòñÿ äîïóñòèìûìè è ðåçóëüòàòîì âû÷èñëåíèÿ ÿâëÿåòñÿ óñëîâíîå âûðàæåíèå.

     Âìåñòå ñ äðóãèìè ýëåìåíòàìè, óñëîâèÿ ìîãóò âêëþ÷àòü ñëåäóþùèå ëîãè÷åñêèå îïåðàòîðû è îïåðàòîðû îòíîøåíèÿ.

          Îïåðàöèÿ                    Ñèìâîë      Òèï

          ìåíüøå                      <           îòíîøåíèå, èíôèêñíûé
          ìåíüøå èëè ðàâíî            <=          îòíîøåíèå, èíôèêñíûé
          ðàâåíñòâî (ñèíòàêñè÷åñêîå)  =           îòíîøåíèå, èíôèêñíûé
          îòðèöàíèå =                 #           îòíîøåíèå, èíôèêñíûé
          ðàâåíñòâî (çíà÷åíèå)        equal       îòíîøåíèå, ôóíêöèÿ
          îòðèöàíå equal              notequal    îòíîøåíèå, ôóíêöèÿ
          áîëüøå èëè ðàâíî            >=          îòíîøåíèå, èíôèêñíûé
          áîëüøå                      >           îòíîøåíèå, èíôèêñíûé
          è                           and         ëîãè÷åñêèé, èíôèêñíûé
          èëè                         or          ëîãè÷åñêèé, èíôèêñíûé
          íåò                         not         ëîãè÷åñêèé, ïðåôèêñíûé

     Ïðîãðàììèðîâàíèå Ôóíêöèè ïðåäèêàòû

 -- Ôóíêöèÿ: map (F, EXPR_1, ..., EXPR_N)
     Âîçâðàùàåò âûðàæåíèå, ñ îïåðàòîðîì âåðõíåãî óðîâíÿ òàêèì æå êàê ó âûðàæåíèé EXPR_1, ..., EXPR_N íî àðãóìåíòû êîòîðîãî ÿâëÿþòñÿ ðåçóëüòàòàìè ïðèìåíåíèÿ F ê ñîîòâåòñòâóþùèì àðãóìåíòàì âûðàæåíèé EXPR_I. Çäåñü, F -- ëèáî ôóíêöèÿ n àðãóìåíòîâ, ëèáî lambda âûðàæåíèå ñ n àðãóìåíòàìè.

     Åñëè ïåðåìåííàÿ maperror ðàâíà false, òî map: (1) îñòàíîâèòñÿ íà ñàìîì êîðîòêîì âûðàæåíèè EXPR_I, åñëè íå âñå EXPR_I èìåþò îäèíàêîâóþ äëèíó; (2) ïðèìåíèò F ê [EXPR_1, EXPR_2,...], åñëè íå âñå EXPR_I èìåþò îäèíàêîâûé òèï.  Åñëè maperror ðàâíà true, òî â îáà âûøåóêàçàííûõ ñëó÷àÿ ñ÷èòàþòñÿ îøèáêîé.

     Îäíèì èç ïðèìåíåíèé ôóíêöèè map ÿâëÿåòñÿ ïðèìåíåíèå êàêîé-ëèáî ôóíêöèè (íàïðèìåð, partfrac) ê êàæäîìó ÷ëåíó áîëüøîãî âûðàæåíèÿ âìåñòî ïðèìåíåíèÿ åå ê âûðàæåíèþ öåëèêîì, ÷òî ìîæåò ïðèâåñòè ê ñëèøêîì ñëîæíûì âû÷èñëåíèÿì è, êàê ñëåäñòâèå, ê íåõâàòêå ïàìÿòè.

          (%i1) map(f,x+a*y+b*z);
          (%o1)                        f(b z) + f(a y) + f(x)
          (%i2) map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2));
                                     1       1        1
          (%o2)                     ----- - ----- + -------- + x
                                   x + 2   x + 1          2
                                                   (x + 1)
          (%i3) map(ratsimp, x/(x^2+x)+(y^2+y)/y);
                                                1
          (%o3)                            y + ----- + 1
                                              x + 1
          (%i4) map("=",[a,b],[-0.5,3]);
          (%o4)                          [a = - 0.5, b = 3]

     Ïðèìåíåíèå ôóíêöèé

 -- Ôóíêöèÿ: mapatom (EXPR)
     Âîçâðàùàåò true òîãäà è òîëüêî òîãäà, êîãäà âûðàæåíèå EXPR ðàññìàòðèâàåòñÿ map-ïðîöåäóðàìè êàê àòîìàðíîå âûðàæåíèå.  Ê òàêèì "mapatoms" îòíîñÿòñÿ àòîìû, ÷èñëà (âêëþ÷àÿ ðàöèîíàëüíûå) è ïåðåìåííûå ñ èíäåêñîì.

     Ôóíêöèè ïðåäèêàòû

 -- Óïðàâëÿþùàÿ ïåðåìåííàÿ: maperror
     Çíà÷åíèå ïî óìîë÷àíèþ: true

     Åñëè ïåðåìåííàÿ maperror ðàâíà false, òî âñå map ôóíêöèè, íàïðèìåð:

          map (F, EXPR_1, EXPR_2, ...)

     (1) îñòàíîâèòñÿ íà ñàìîì êîðîòêîì âûðàæåíèè EXPR_I, åñëè íå âñå EXPR_I èìåþò îäèíàêîâóþ äëèíó; (2) ïðèìåíèò F ê [EXPR_1, EXPR_2,...], åñëè íå âñå EXPR_I èìåþò îäèíàêîâûé òèï.

     Åñëè maperror ðàâíà true, òî â îáà âûøåóêàçàííûõ ñëó÷àÿ ñ÷èòàþòñÿ îøèáêàìè.

     Ïðèìåíåíèå ôóíêöèé

 -- Óïðàâëÿþùàÿ ïåðåìåííàÿ: mapprint
     Çíà÷åíèå ïî óìîë÷àíèþ: true

     Åñëè ïåðåìåííàÿ mapprint ðàâíà true, òî ôóíêöèè map, mapl è fullmap â îïðåäåëåííûõ ñèòóàöèÿõ âûäàþò ðàçëè÷íûå ñîîáùåíèÿ.  Âêëþ÷àÿ ñèòóàöèè, êîãäà map èñïîëüçóåò apply èëè map îáðåçàåò äî ñàìîãî êîðîòêîãî ñïèñêà.

     Åñëè mapprint ðàâíà false, òî äàííûå ñîîáùåíèÿ ïîäàâëÿþòñÿ.

     Ïðèìåíåíèå ôóíêöèé

 -- Ôóíêöèÿ: maplist (F, EXPR_1, ..., EXPR_N)
     Âîçâðàùàåò ñïèñîê ñ F, ïðèìåíåííîé ê ÷àñòÿì âûðàæåíèé EXPR_1, ..., EXPR_N. F -- åñòü èìÿ ôóíêöèè èëè ëÿìáäà-âûðàæåíèå.

     Ôóíêöèÿ maplist îòëè÷àåòñÿ îò map (F, EXPR_1, ..., EXPR_N), êîòîðàÿ âîçâðàùàåò âûðàæåíèå ñ ãëàâíûì îïåðàòîðîì, îäíèì äëÿ âñåõ âûðàæåíèé EXPR_I (çà èñêëþ÷åíèì óïðîùåíèé è ñëó÷àÿ, êîãäà map âûïîëíÿåò apply).

     Ïðèìåíåíèå ôóíêöèé

 -- Óïðàâëÿþùàÿ ïåðåìåííàÿ: prederror
     Çíà÷åíèå ïî óìîë÷àíèþ: false

     Åñëè prederror ðàâíà true, òî îøèáêà ñëó÷àåòñÿ âñÿêèé ðàç, êàê òîëüêî âû÷èñëåííîå çíà÷åíèå ïðåäèêàòà êîìàíäû if èëè ôóíêöèè is îòëè÷íî îò true èëè false.

     Åñëè  false, òî â ýòîì ñëó÷àå âîçâðàùàåòñÿ unknown. Ðàáîòà ñ prederror: false íå ïîääåðæèâàåòñÿ òðàíñëèðîâàííîì êîäå. Îäíàêî, maybe ïîääåðæèâàåòñÿ â òðàíñëèðîâàííîì êîäå.

     Ñì. òàêæå is è maybe.

     Ïðîãðàììèðîâàíèå Ôóíêöèè ïðåäèêàòû

 -- Ôóíêöèÿ: return (VALUE)
     Èñïîëüçóåòñÿ äëÿ ÿâíîãî âûõîäà èç áëîêà, äåëàÿ VALUE çíà÷åíèåì ýòîãî áëîêà. Ñì. block äëÿ áîëåå äåòàëüíîãî îïèñàíèÿ.

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: scanmap (F, EXPR)
 -- Ôóíêöèÿ: scanmap (F, EXPR, bottomup)
     Ïðèìåíÿåò ôóíêöèþ F ê EXPR ðåêóðñèâíî íà÷èíàÿ ñ âåðõíåãî óðîâíÿ è ãëóáæå. Ýòî ìîæåò áûòü ïîëåçíî, åñëè, íàïðèìåð, òðåáóåòñÿ ïîëíàÿ ôàêòîðèçàöèÿ:

          (%i1) exp:(a^2+2*a+1)*y + x^2$
          (%i2) scanmap(factor,exp);
                                              2      2
          (%o2)                         (a + 1)  y + x

     Îòìåòèì, ÷òî òî, êàê scanmap ïðèìåíÿåò äàííóþ ôóíêöèþ factor ê ïîäâûðàæåíèÿì EXPR, çàâèñèò îò ôîðìû ýòîãî âûðàæåíèÿ.  È åñëè äàíà äðóãàÿ ôîðìà EXPR, òî ðåçóëüòàò scanmap ìîæåò áûòü äðóãèì.  Òàê, %o2 íå ïîëó÷èòñÿ, åñëè scanmap ïðèìåíèòü ê ðàñêðûòîìó âàðèàíòó exp:

          (%i3) scanmap(factor,expand(exp));
                                     2                  2
          (%o3)                      a  y + 2 a y + y + x

     Åùå îäèí ïðèìåð ðåêóðñèâíîãî ïðèìåíåíèÿ scanmap êî âñåì ïîäâûðàæåíèÿì, âêëþ÷àÿ ýêñïîíåíòû:

          (%i4) expr : u*v^(a*x+b) + c$
          (%i5) scanmap('f, expr);
                              f(f(f(a) f(x)) + f(b))
          (%o5) f(f(f(u) f(f(v)                      )) + f(c))

     scanmap (F, EXPR, bottomup) ïðèìåíÿåò F ê EXPR ñ ñàìîãî ãëóáîêîãî óðîâíÿ ââåðõ.  Íàïðèìåð, äëÿ íåîïðåäåëåííîé ôóíêöèè f,

          scanmap(f,a*x+b) ->
             f(a*x+b) -> f(f(a*x)+f(b)) -> f(f(f(a)*f(x))+f(b))
          scanmap(f,a*x+b,bottomup) -> f(a)*f(x)+f(b)
              -> f(f(a)*f(x))+f(b) ->
               f(f(f(a)*f(x))+f(b))

     Â äàííîì ñëó÷àå ðåçóëüòàò îäèíàêîâ äëÿ îáîèõ âàðèàíòîâ âûçîâà.

     Ïðèìåíåíèå ôóíêöèé

 -- Ôóíêöèÿ: throw (EXPR)
     Âû÷èñëÿåò âûðàæåíèå EXPR è "áðîñàåò" åãî çíà÷åíèå ââåðõ äî áëèæàéøåãî catch. Ôóíêöèè throw è catch ðåàëèçóþò ìåõàíèçì íåëîêàëüíîãî âîçâðàòà.

     Ïðîãðàììèðîâàíèå

 -- Ñïåöèàëüíûé îïåðàòîð: while
 -- Ñïåöèàëüíûé îïåðàòîð: unless
     Ñì. do.

     Ïðîãðàììèðîâàíèå

 -- Ôóíêöèÿ: outermap (F, A_1, ..., A_N)
     Ïðèìåíÿåò ôóíêöèþ F ê êàæäîìó ýëåìåíòó âíåøíåãî ïðîèçâåäåíèÿ A_1 x A_2 ... x A_N.

     F -- åñòü èìÿ ôóíêöèè ñ n àðãóìåíòàìè èëè ëÿìáäà-âûðàæåíèå ñ n àðãóìåíòàìè. Êàæäûé ýëåìåíò A_K ìîæåò áûòü ñïèñêîì, ñïèñêîì ñïèñêîâ, ìàòðèöåé èëè ëþáûì äðóãèì âûðàæåíèåì.

     Çíà÷åíèå outermap ÿâëÿåòñÿ âëîæåííîé ñòðóêòóðîé. Ïóñòü X ÿâëÿåòñÿ âîçâðàùàåìûì çíà÷åíèåì. Òîãäà X èìååò òó æå ñòðóêòóðó, êàê ïåðâûé àðãóìåíò (ñïèñîê, ñïèñîê ñïèñêîâ èëè ìàòðèöà), X[i_1]...[i_m] èìååò òó æå ñòðóêòóðó, êàê âòîðîé àðãóìåíò (ñïèñîê, ñïèñîê ñïèñêîâ èëè ìàòðèöà), X[i_1]...[i_m][j_1]...[j_n] èìååò òó æå ñòðóêòóðó, êàê òðåòèé àðãóìåíò (ñïèñîê, ñïèñîê ñïèñêîâ èëè ìàòðèöà), è ò.ä., ãäå M, N, ... -- åñòü ÷èñëî èíäåêñîâ, íåîáõîäèìûõ äëÿ äëÿ äîñòóïà ê ýëåìåíòàì êàæäîãî èç àðãóìåíòîâ (îäèí äëÿ ñïèñêà, äâà äëÿ ìàòðèöû, åùå îäèí äëÿ âëîæåííîãî ñïèñêà). Àðãóìåíòû, íå ÿâëÿþùèåñÿ ñïèñêàìè è ìàòðèöàìè, íå îêàçûâàþò âëèÿíèÿ íà âîçâðàùàåìîå çíà÷åíèå.

     Îòìåòèì, ÷òî ðåçóëüòàò outermap îòëè÷àåòñÿ îò ïðèìåíåíèÿ F êî âñåì ýëåìåíòàì âíåøíåãî ïðîèçâåäåíèÿ, âîçâðàùàåìîãî cartesian_product. Ôóíêöèÿ outermap ñîõðàíÿåò ñòðóêòóðó àðãóìåíòîâ â âîçâðàùàåìîì çíà÷åíèè, à cartesian_product íåò.

     Ôóíêöèÿ outermap âû÷èñëÿåò ñâîè àðãóìåíòû.

     Ñì. òàêæå map, maplist è apply.

     Ïðèìåðû:

     Ïðîñòûå ïðèìåðû outermap. Äëÿ ïðîÿñíåíèÿ êîìáèíàöèè àðãóìåíòîâ, F îñòàâëåíà íåîïðåäåëåííîé.

          (%i1) outermap (F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) outermap (F, matrix ([a, b], [c, d]), matrix ([1, 2], [3, 4]));
                   [ [ F(a, 1)  F(a, 2) ]  [ F(b, 1)  F(b, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(a, 3)  F(a, 4) ]  [ F(b, 3)  F(b, 4) ] ]
          (%o2)    [                                            ]
                   [ [ F(c, 1)  F(c, 2) ]  [ F(d, 1)  F(d, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(c, 3)  F(c, 4) ]  [ F(d, 3)  F(d, 4) ] ]
          (%i3) outermap (F, [a, b], x, matrix ([1, 2], [3, 4]));
                 [ F(a, x, 1)  F(a, x, 2) ]  [ F(b, x, 1)  F(b, x, 2) ]
          (%o3) [[                        ], [                        ]]
                 [ F(a, x, 3)  F(a, x, 4) ]  [ F(b, x, 3)  F(b, x, 4) ]
          (%i4) outermap (F, [a, b], matrix ([1, 2]), matrix ([x], [y]));
                 [ [ F(a, 1, x) ]  [ F(a, 2, x) ] ]
          (%o4) [[ [            ]  [            ] ],
                 [ [ F(a, 1, y) ]  [ F(a, 2, y) ] ]
                                        [ [ F(b, 1, x) ]  [ F(b, 2, x) ] ]
                                        [ [            ]  [            ] ]]
                                        [ [ F(b, 1, y) ]  [ F(b, 2, y) ] ]
          (%i5) outermap ("+", [a, b, c], [1, 2, 3]);
          (%o5) [[a + 1, a + 2, a + 3], [b + 1, b + 2, b + 3],
                                                     [c + 1, c + 2, c + 3]]

     Áîëåå äåòàëüíîå èññëåäîâàíèå ðàáîòû outermap. Ïåðâûé, âòîðîé è òðåòèé àðãóìåíòû ÿâëÿþòñÿ ìàòðèöåé, ñïèñêîì è ìàòðèöåé ñîîòâåòñòâåííî. Âîçâðàùàåìîå çíà÷åíèå ÿâëÿåòñÿ ìàòðèöåé. Êàæäûé ýëåìåíò ýòîé ìàòðèöû åñòü ñïèñîê, è êàæäûé ýëåìåíò äàííîãî ñïèñêà -- ìàòðèöà.

          (%i1) arg_1 :  matrix ([a, b], [c, d]);
                                      [ a  b ]
          (%o1)                       [      ]
                                      [ c  d ]
          (%i2) arg_2 : [11, 22];
          (%o2)                       [11, 22]
          (%i3) arg_3 : matrix ([xx, yy]);
          (%o3)                      [ xx  yy ]
          (%i4) xx_0 : outermap (lambda ([x, y, z], x / y + z), arg_1,
                                                               arg_2, arg_3);
                         [  [      a        a  ]  [      a        a  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
          (%o4)  Col 1 = [                                              ]
                         [  [      c        c  ]  [      c        c  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
                           [  [      b        b  ]  [      b        b  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
                   Col 2 = [                                              ]
                           [  [      d        d  ]  [      d        d  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
          (%i5) xx_1 : xx_0 [1][1];
                     [      a        a  ]  [      a        a  ]
          (%o5)     [[ xx + --  yy + -- ], [ xx + --  yy + -- ]]
                     [      11       11 ]  [      22       22 ]
          (%i6) xx_2 : xx_0 [1][1] [1];
                                [      a        a  ]
          (%o6)                 [ xx + --  yy + -- ]
                                [      11       11 ]
          (%i7) xx_3 : xx_0 [1][1] [1] [1][1];
                                            a
          (%o7)                        xx + --
                                            11
          (%i8) [op (arg_1), op (arg_2), op (arg_3)];
          (%o8)                  [matrix, [, matrix]
          (%i9) [op (xx_0), op (xx_1), op (xx_2)];
          (%o9)                  [matrix, [, matrix]

     Ôóíêöèÿ outermap ñîõðàíÿåò ñòðóêòóðó àðãóìåíòîâ â âîçâðàùàåìîì çíà÷åíèè, à cartesian_product íåò.

          (%i1) outermap (F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) setify (flatten (%));
          (%o2) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i3) map (lambda ([L], apply (F, L)),
          (%o3) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i4) is (equal (%, %th (2)));
          (%o4)                         true

     Ïðèìåíåíèå ôóíêöèé