home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / prolog / tutorial / algebra / algebra.txt next >
Text File  |  1987-04-12  |  59KB  |  2,179 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.            
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.                             ECOMPUTER  ALGEBRA  IN  PROLOGF
  16.  
  17.                                          by
  18.                                   Sergio Vaghi (*) 
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.                                      April 1987
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.           (*)  ESTEC,
  38.                P.O. Box 299,
  39.                2200 AG Noordwijk (ZH),
  40.                The Netherlands.
  41.  
  42.                tel. +31  1719 83453  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.                                                                      Page 2
  71.  
  72.  
  73.                Many   applications   which   are  usually  associated  with
  74.           Artificial Intelligence do not necessarily need an AI language to
  75.           be implemented.  Expert systems,  for  example, can be, and often
  76.           are, written in traditional procedural languages such as FORTRAN,
  77.           Pascal and Basic. 
  78.  
  79.              But are there applications for which the use of  AI  languages
  80.           such  as  LISP  and  Prolog  is  mandatory,  or  at  least highly
  81.           advisable ?  The answer is obviously affirmative, otherwhise such
  82.           languages wouldn't exist, and some nice examples can be provided.
  83.              One of them is  symbolic  mathematical computation or computer
  84.           algebra.  This can be described as the ability of the computer to
  85.           perform  algebraic  manipulations,  as   opposed   to   numerical
  86.           calculations.
  87.           A  computer  performing symbolic differentiation, for example, is
  88.           able to find that the derivative of  y  = xS2T with respect to x is
  89.           dy/dx = 2x  for any value of x, instead of simply calculating the
  90.           numerical value of the same derivative for a given value of x.
  91.  
  92.              Computer algebra, at various levels of complexity, is  already
  93.           more  than twenty years old, with some well established programs,
  94.           such as MACSYMA and REDUCE,  and important results at its credit,
  95.           particularly in the fields of  celestial  mechanics  and  quantum
  96.           electrodynamics.
  97.           Algebraic  manipulators  have  been  written, to be sure, both in
  98.           procedural  and  declarative   languages,   but   the  use  of  a
  99.           declarative language has the advantage  of  clarity,  conciseness
  100.           and  elegance,  while  procedural languages were mostly used when
  101.           little else was available.
  102.  
  103.  
  104.              In  this   article   I   describe   a   program  for  symbolic
  105.           differentiation in Prolog, which provides a good example  of  the
  106.           power  of  the language and, at the same time, will introduce you
  107.           to the fascinating world of computer algebra.
  108.           Symbolic differentiation is,  in  a  sense,  already  part of the
  109.           Prolog folklore.  An example is given in the book by Clocksin and
  110.           Mellish (ref.1) and another in the collection of Prolog  programs
  111.           by  Coelho,  Cotta  and  Pereira  (ref.2).    But  the  former is
  112.           incomplete (and in the  first  edition  of  the book contained an
  113.           error) and the latter is both incomplete and partially incorrect.
  114.           I have tried to offer something that, I hope, comes a bit  closer
  115.           to   a   reasonably   efficient  symbolic  differentiator.    Its
  116.           application is limited to algebraic functions, but you can easily
  117.           extend it to  include  logarithmic,  trigonometric and hyperbolic
  118.           functions thanks to the incremental nature of the Prolog code.
  119.  
  120.              While this article is in no way a  comprehensive  introduction
  121.           to  either Prolog or computer algebra, I hope it will give you an
  122.           impression of the many  nice  characteristics of the language and
  123.           perhaps  stimulate  your  interest  in  symbolic  computation  by
  124.           computer.
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.                                                                      Page 3
  137.  
  138.  
  139.            EGetting started.F
  140.  
  141.  
  142.  
  143.              If you are not already familiar with Prolog,  a  good  way  to
  144.           start  is  to read the book Programming in Prolog by Clocksin and
  145.           Mellish (ref.1).  It describes the basic elements of the language
  146.           and introduces the so-called  Edimburgh  syntax, now used in most
  147.           Prolog implementations.  The book has become a de facto  standard
  148.           of  sorts for Prolog and is highly readable.  The many errors and
  149.           misprints which plagued  the  first  edition  have  now also been
  150.           corrected.
  151.           But you can't learn a new programming language  without  actually
  152.           writing  some program.  For this you need a Prolog interpreter or
  153.           compiler.  Several are available on  the IBM-PC market, some at a
  154.           reasonable price.
  155.           A Prolog interpreter has also been placed in the  public  domain.
  156.           It is called PD Prolog and is a good entry point for newcomers to
  157.           the  language,  who  wish  to get a feeling for the possibilities
  158.           offered by Prolog without having to buy a commercial product.
  159.           I  have  chosen   it   to   develop   the  program  for  symbolic
  160.           differentiation . This has imposed  some  constraints,  since  PD
  161.           Prolog  has a number of limitations with respect to more advanced
  162.           implementations  (for   example,   only   integer  arithmetic  is
  163.           supported), but will give you the possibility to run the  program
  164.           on your IBM-PC or compatible once you have obtained a copy of the
  165.           interpreter   (version   1.9  or  higher)  from  Automata  Design
  166.           Associates,  1570  Arran  Way,  Dresher,   PA  1905,  or  from  a
  167.           distributor of public domain software.
  168.           The program will also run with little or  no  modification  under
  169.           other Prolog implementations following the Edimburgh syntax.
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.                                                                      Page 4
  203.  
  204.  
  205.            EMinimum program.F
  206.  
  207.  
  208.  
  209.              The  rules  of  differentiation  for  algebraic  functions are
  210.           listed in Fig.1.   Before  translating  them  into Prolog code we
  211.           have to define those mathematical operators which are not already
  212.           provided  by  our  Prolog   implementation.      They   are   the
  213.           exponentiation, identified by the symbol '^' (so that x^2 means x
  214.           to  the  power 2), the minus sign as unary operator (as in -x, as
  215.           opposed to the minus sign as  binary operator, as in x-y) denoted
  216.           by ~, and the natural logarithm, ln.
  217.           They are defined as follows
  218.                                        ?-op(11, yfx,  '^').
  219.                                        ?-op( 9,  fx,  '~').
  220.                                        ?-op(11,  fx, 'ln').
  221.  
  222.           I will not go into the details of these  definitions,  which  are
  223.           explained  in the book by Clocksin and Mellish.  Just assume that
  224.           the above operators are  now  available,  together with the other
  225.           mathematical operators +, -, * and /.
  226.  
  227.              Writing the program is now fairly simple.   Let's  agree  that
  228.           the Prolog structure
  229.                                 d(Y,X,DY).
  230.           means  'DY  is the derivative of Y with respect to X'.  The rules
  231.           of differentiation of Fig.1 can  now  be coded as Prolog clauses.
  232.           The first rule, for example, is coded as
  233.                                                     d(X,X,1).
  234.           meaning that for any X the derivative of X with respect to  X  is
  235.           equal to 1.  The second rule is coded as
  236.                    d(C,X,0):- atomic(C), C \= X.
  237.           which means that the derivative with respect to X of any quantity
  238.           C which is either an atom - that is a non numerical constant - or
  239.           an integer is always 0, provided that C is different from X.
  240.              All  the  rules  of Fig.1 are similarly translated into Prolog
  241.           clauses to form the minimum program  of Fig.2.
  242.              To find the derivative of  y  =  xS2T  with respect to x you now
  243.           simply enter
  244.                                                   d(x^2, x, DY).
  245.           after the Prolog prompt '?-'.
  246.           In the Prolog parlance one says that the variables Y and  X  have
  247.           been  instantiated  to,  respectively, x^2 and x, and the program
  248.           has been requested to  determine  the  value  of the variable DY.
  249.           Remember that in Prolog any name beginning with a capital  letter
  250.           is  assumed  to  be  a  variable,  which may be instantiated to a
  251.           constant beginning with a lower-case letter.
  252.              Note that  writing  the  program  simply  meant re-writing the
  253.           rules of differentiation in the sintax of  Prolog,  after  having
  254.           arbitrarily defined the meaning of the structure d(Y,X,DY).
  255.           This  is  what is meant when it is said that in logic programming
  256.           the specifications are the program.
  257.              The  program  is  now  able  to  find  the  derivative  of any
  258.           algebraic function, from the most simple  to  the  most  complex.
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.                                                                      Page 5
  269.  
  270.  
  271.           While  in a procedural language one must tell the computer how to
  272.           proceed at each step  of  the  differentiation process, in Prolog
  273.           one simply states the basic rules,  and  the  computer  does  the
  274.           rest.
  275.              Too  good  to be true? well, yes and no.  The program of Fig.2
  276.           is  indeed  able  to  handle  the  derivative  of  any  algebraic
  277.           function, but the result it produces  may  not be in the form you
  278.           expect to see it.
  279.           Let's try the very simple example of the derivative  of  y  =  xS2T
  280.           with  respect  to  x.    The  result  is shown in Fig.3.  It will
  281.           probably take you a  few  seconds  to  realize that the resulting
  282.           expression, DY, is indeed equivalent to 2x.
  283.           The problem is that the program contains only the basic rules  of
  284.           differentiation.   Other derived rules are not included.  In this
  285.           particular case a human  would  immediately  use the derived rule
  286.           stating that, when c is a constant, the derivative of y = xScT with
  287.           respect to x is  c xS(c-1)T.  This rule can  be  derived  from  the
  288.           last rule in Fig.1, but it is so much part of the heuristics used
  289.           by humans that it is advantageous to include it explicitly in the
  290.           program.
  291.              Derived rules of this type are added to the minimum program to
  292.           produce  the program of Fig.4.  Note that the new clauses include
  293.           the symbol '!', called cut  in  Prolog.    Its effect is to avoid
  294.           backtracking, that is the search of an alternative solution  once
  295.           one  has been found.  Indeed the new clauses are special cases of
  296.           those of the minimum program.   If backtracking were allowed, one
  297.           would obtain - in certain cases - two solutions, one from  a  new
  298.           clause and one from an old one.  The former is more specific and,
  299.           therefore,  simpler  and  should be retained.  The latter becomes
  300.           useless and need not be shown.  The cut obtains this effect.
  301.            
  302.              If you run the new program for    y = xS2T you will now find the
  303.           expression of Fig.5.  It is already an improvement  with  respect
  304.           to  the  previous result, but still unsatisfactory.  The computer
  305.           doesn't seem to know that 2*1 = 2 and 2-1 = 1. In fact it can not
  306.           simplify an expression.
  307.  
  308.              Simplification is indeed a  major problem in computer algebra.
  309.           I'll come back to it later.
  310.           First I want to  discuss  two  other  nice  features  of  Prolog.
  311.           Starting from our definition of the structure  d(Y,X,DY). we have
  312.           obtained the derivative of  xS2T with respect to x by instantiating
  313.           Y  to  x^2  and X to x.  Prolog has then derived the value of the
  314.           variable DY which satisfies the rule, that is  (2*1)*(x^(2-1)).
  315.           Nothing, in principle, forbids us to instantiate X to x and DY to
  316.           (2*1)*(x^(2-1))  and let  Prolog  determine  the value of Y which
  317.           satisfies the rule.  This is shown in Fig.6, where indeed  Prolog
  318.           finds for Y the value x^2.
  319.           This  is  very important because it demonstrates that the program
  320.           of Fig.4 can not only be used for its original pourpose, symbolic
  321.           differentiation of algebraic functions,  but also for the inverse
  322.           operation, that is symbolic integration of the same functions.
  323.           This is the property of logic programming  called  invertibility,
  324.           or  the ability to perform inverse computations.  Prolog programs
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.                                                                      Page 6
  335.  
  336.  
  337.           which,  like  the   one   in   Fig.4,   strictly  adhere  to  the
  338.           prescriptions of logic programming allow  invertibility.    Once,
  339.           however,  procedural elements are added to the program, such as a
  340.           numerical  calculation,  the  property   is  lost,  because  such
  341.           elements are not themselves invertible.
  342.           Also note that, for integration, the Prolog variable DY has  been
  343.           instantiated  to    (2*1)*(x^(2-1))    ,  using  exactly the same
  344.           notation used by the  program  when calculating the derivative of
  345.           x^2.   Using the more familiar notation  2*x    would  not  work,
  346.           because  the  computer does not know that the two expressions are
  347.           equivalent.  Even with these restrictions invertibility remains a
  348.           powerful and useful characteristic of the language.
  349.            
  350.              The second nice feature of Prolog which should be mentioned is
  351.           the incremental nature of its code.
  352.           Suppose  that  you  now  decide  to  extend  the  program  to the
  353.           differentiation of, say, the trigonometric  functions  sinus  and
  354.           cosinus.  You don't have to re-write the entire program for that.
  355.           Simply  add sin and cos to the list of operators already defined,
  356.           and the differentiation rules for  sinus  and cosinus you want to
  357.           use to  the  rules  already  present  in  the  program.  Existing
  358.           definitions and clauses need not be changed.
  359.           Once  sinus  and  cosinus  have  been introduced, you may wish to
  360.           introduce their inverse functions,  then the hyperbolic functions
  361.           and their inverses and so on.  At each step you  simply  add  the
  362.           operators  and  the relevant rules to the program obtained at the
  363.           previous step.    Contrary  to  what  all  too  often  happens in
  364.           procedural languages, adding new features  to  a  Prolog  program
  365.           does not involve the complete re-writing of the code.
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.                                                                      Page 7
  401.  
  402.  
  403.            EThe politics of simplification.F
  404.  
  405.  
  406.  
  407.              I  come  back  now to the problem of simplification.  This has
  408.           always been a major problem  in  computer algebra.  The preferred
  409.           form af an expression may depend on several factors, such as  the
  410.           context  in  which it is derived (in relativity, for example, one
  411.           would prefer to obtain the expression
  412.                                                   E = m cS2T
  413.           rather than the equivalent expression
  414.                                 1 / cS2T = m / E ),
  415.           the type  of  application  (purely  symbolic  manipulation,  or a
  416.           mixture of symbolic manipulation and numerical  computation)  and
  417.           personal   taste   of  the  user.    Moreover,  when  complicated
  418.           expressions are involved,  it  is  difficult  for the computer to
  419.           recognize that an expression - or a part of it -  is  identically
  420.           equal to zero and can consequently be suppressed.
  421.  
  422.              Without  entering  into  too many details, it is indicative of
  423.           the complexity of the problem the  fact that already 15 years ago
  424.           Joel Moses of the MIT could write a short dissertation  on  the  
  425.           politics of simplification (ref.3).
  426.           The  criterion  considered  was  the degree to which an algebraic
  427.           manipulation system would force  the  user  to write (or read) an
  428.           expression in a form acceptable to the system.
  429.           A radical system would insist in completely changing the form  of
  430.           the expression before being able to handle it.  Our program which
  431.           pretends  to  have  2*x written as (2*1)*(x^(2-1))  to be able to
  432.           find its integral can be taken as an example of radical system.
  433.           Conservative systems are those which  would leave to the user the
  434.           burden of simplifying the expressions they found.   Our  program,
  435.           when  used  to  find  the  derivative of xS2T with respect to x, is
  436.           conservative in this sense,  since  it  leaves to you to simplify
  437.           the expression (2*1)*(x^(2-1)).  Note that,  in  differentiation,
  438.           the program is not a radical one, because you can enter xS2T in its
  439.           simplest form x^2.
  440.           Liberal  systems  will  perform  some  simplifications, but leave
  441.           others to the user.  New  left  systems are variations of the old
  442.           radical systems, with some added features to be selected  by  the
  443.           user.
  444.           Catholic  systems  are  those  which  take  advantage of the good
  445.           points of the  other  systems,  and  adopt  them depending on the
  446.           application at hand.
  447.           I recommend Moses' article  to  anybody  interested  in  computer
  448.           algebra.
  449.            
  450.              The  simplification  program I have written is listed in Fig.7
  451.           and  can  be  classified  as  liberal,  in  that  it  imposes  no
  452.           constraint in the form of  the  input expression, and will do its
  453.           best to simplify the resulting expression so that  it  will  look
  454.           sufficiently familiar to you.  It is meant for use in association
  455.           with the differentiation program, but can also be used as a stand
  456.           alone  program  to simplify algebraic expressions.  The fact that
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.                                                                      Page 8
  467.  
  468.  
  469.           it is much longer than the differentiation program shows that, if
  470.           not more complex, it is by far more tedious to write.  In fact it
  471.           essentially contains most of the rules of elementary algebra.
  472.            
  473.              I will  not  discuss  the  program  in  detail.    It contains
  474.           comments which should help you in understanding  the  code.    It
  475.           also includes some useful features, such as the capability of 
  476.           identifying  divisions  by  zero and indefinite forms of the type
  477.           0/0, and gives an example of  the  use of the Prolog recursion to
  478.           calculate the n-th power of a positive or negative integer.
  479.           Since PD  Prolog  uses  integer  arithmetic  only,  divisions  of
  480.           integer  numbers are never actually performed, to avoid round-off
  481.           errors.  Prolog purists will also note the unusually large number
  482.           of cuts in the code.  This  is to force the program to accept the
  483.           first solution it  finds  at  each  step  of  the  simplification
  484.           process,  consistent with the fact that clauses in each group are
  485.           listed in order of increasing generality.
  486.              The simplification is performed by entering
  487.                             simplify(Y,Z).
  488.           where Y is the expression  to  be simplified and Z the simplified
  489.           expression.  If you are not happy with the result you can  always
  490.           try a two pass simplification, that is
  491.                             simplify(Y,T), simplify(T,Z).
  492.           and so on.  In practice I found that two passes are sufficient in
  493.           most cases.  If you enter
  494.                                      s(Y,Z).
  495.           two passes will be automatically performed.
  496.            
  497.              To  use  the  program  in conjunction with the differentiation
  498.           program applied to the function  y = xS2T , simply enter
  499.                             Y = x^2 ,
  500.                             d( Y, x, Z),
  501.                             s( Z, DY).
  502.           after the Prolog prompt, as shown  in Fig.8, and you will finally
  503.           obtain the result in the familiar form DY = (2*x).
  504.           This is, of course, the result we were after.   The  price  paid,
  505.           however, is the loss of the invertibility property.  The program,
  506.           or  more  precisely  the combination of the two programs, will no
  507.           longer be able to  integrate  2*x  to  find  x^2.  The procedural
  508.           elements involved in the simplification have  made  invertibility
  509.           impossible.
  510.  
  511.              How  good  are the differentiation and simplification programs
  512.           when applied to functions less trivial than y = xS2T ?
  513.           I have tested the programs  using  the problems found in a manual
  514.           of calculus for college level students.  A few examples are found
  515.           in Fig.9.  Both the intermediate, nonsimplified, results and  the
  516.           simplified  ones  are  printed  in  all  cases, to illustrate the
  517.           advantage  of   simplification   in   making   the  results  more
  518.           understandable.  When complicated functions are involved you will
  519.           still have to find your way in  the  resulting  expression,  both
  520.           because  the program includes many brackets to avoid ambiguities,
  521.           and because certain  simplifications  seen  by  the  user are not
  522.           identified by the program.
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.                                                                      Page 9
  533.  
  534.  
  535.           In many applications simbolic  differentiation  is  coupled  with
  536.           numerical calculations, that is a symbolic derivative is fed to a
  537.           numerical  routine  which  calculates  its  values  for the given
  538.           values  of  parameters  and   independent   variable.    In  such
  539.           applications  the  fact  that  the  expression  is  not   totally
  540.           simplified  is  usually  immaterial  since  it  is  the numerical
  541.           routine which performs the  calculations  (but beware of possible
  542.           spurious singularities - writing  x or xS2T/x  is  not  numerically
  543.           equivalent for values of x close to 0).
  544.           Again,  thanks  to the incremental nature of the Prolog code, you
  545.           may also decide to add more  clauses  to the program to take into
  546.           account a larger number of simplification rules.  In view of  the
  547.           limits  of  PD  Prolog the programs of Figs. 4 and 7 go, I think,
  548.           some way towards  a  fairly satisfactory symbolic differentiation
  549.           system.
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.                                                                     Page 10
  599.  
  600.  
  601.            EApplications.F
  602.  
  603.  
  604.  
  605.              A program for symbolic differentiation is a powerful tool  for
  606.           several  applications.    Examples which come immediately to mind
  607.           are the calculation of  the  partial  derivatives of functions of
  608.           several variables and  the  determination  of  the  higher  order
  609.           derivatives of functions of one variable.
  610.           The chain rule
  611.                           dy/dx = dy/du * du/dx
  612.           can  also  be  directly  implemented, and derivatives of implicit
  613.           functions are easily obtained.
  614.           Fig.10 shows with a few examples how to proceed in these cases.
  615.            
  616.              The most interesting  applications  are,  however, those which
  617.           combine symbolic differentiation with numerical calculation.
  618.           A nice example is the determination of the recursive  formula  of
  619.           the   Newton-Raphson   method  for  solution  of  real  algebraic
  620.           equations of the type f(x) = 0, that is
  621.            xSk+1T = xSkT - (f(xSkT) / f'(xSkT))
  622.           where xSkT and xSk+1T are successive approximations to the solution.
  623.              The  Newton-Raphson  method   has   the   advantage  of  rapid
  624.           convergence (although it may diverge in certain cases),  but  the
  625.           disadvantage  that  the first derivative of the function y = f(x)
  626.           must be  calculated.    If  f(x)  is  a  complicated function its
  627.           derivative might be tedious to  calculate  by  hand,  and  errors
  628.           could  easily  slip  in.    The  alternative  is to calculate the
  629.           derivative of the function or, better, the entire right hand side
  630.           of the recursive  expression  symbolically  by computer, and feed
  631.           the result to a numerical routine.  How this can be done with our
  632.           programs is illustrated in Fig.11 for the simple equation
  633.                   xS3T - a = 0
  634.           which can be used to calculate iteratively the cubic root of a.
  635.           In practice one would, of  course,  use  the  programs  for  more
  636.           complicated  functions,  when  differentiation by hand takes much
  637.           longer than by computer.
  638.  
  639.              Other  areas  in   which   the   combination   of  a  symbolic
  640.           differentiator and a numerical routine can be very attractive are
  641.           the solution of  ordinary  differential  equations  using  Taylor
  642.           series   and   the   calculation   of   the  Jacobian  matrix  in
  643.           linearization problems.  If you  are familiar with these subjects
  644.           you should have  no  problem  in  using  the  programs  for  such
  645.           applications.
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.                                                                     Page 11
  665.  
  666.  
  667.            EReferencesF
  668.  
  669.  
  670.           1.  W.F.Clocksin  and  C.Mellish,  Programming  in Prolog (second
  671.           edition), 1984
  672.  
  673.           2. H.Coelo,  J.C.Cotta  and  L.M.Pereira,  How  to  solve it with
  674.           Prolog (3rd edition), 1982
  675.  
  676.           3. J.Moses, Algebraic simplification - a guide for the perplexed,
  677.           in Proceedings of the Second Symposium on Symbolic and  Algebraic
  678.           Manipulation, 1971
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.           dx/dx = 1
  740.  
  741.           dc/dx = 0 , c = const.
  742.  
  743.  
  744.           d(-u)/dx = -(du/dx)
  745.  
  746.  
  747.           d(u+v)/dx = du/dx + dv/dx
  748.  
  749.           d(u-v)/dx = du/dx - dv/dx
  750.  
  751.  
  752.           d(uv)/dx  = u dv/dx + du/dx v
  753.  
  754.           d(u/v)/dx = (v du/dx - u dv/dx) / vS2T
  755.  
  756.           d(uSvT)/dx  = uSvT ( v/u du/dx + dv/dx ln(u) )
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.   Fig. 1 - Rules of differentiation for algebraic functions.
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.    
  800.  
  801.  
  802.   /*  definition of operators */
  803.  
  804.  
  805.   ?-op(11, yfx,  '^').                 /*  exponentiation     */
  806.   ?-op( 9,  fx,  '~').                 /*  minus sign         */
  807.   ?-op(11,  fx, 'ln').                 /*  natural logarithm  */
  808.  
  809.  
  810.  
  811.   d(X,X,1).
  812.  
  813.   d(C,X,0) :- atomic(C), C \= X.
  814.  
  815.   d(~U,X,~D) :- d(U,X,D).
  816.  
  817.  
  818.   d(U+V,X,D1+D2) :- d(U,X,D1), d(V,X,D2).
  819.  
  820.  
  821.   d(U-V,X,D1-D2) :- d(U,X,D1), d(V,X,D2).
  822.  
  823.  
  824.   d(U*V, X, D2*U+D1*V) :- d(U,X,D1), d(V,X,D2).
  825.  
  826.  
  827.   d(U/V, X, (V*D1-U*D2)/(V^2) ) :- d(U,X,D1), d(V,X,D2).
  828.  
  829.  
  830.   d(U^V, X, U^V*(V*D1/U+D2*ln(U) )) :- d(U,X,D1), d(V,X,D2).
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.     Fig. 2 - Symbolic differentiation - minimum program
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.    
  866.  
  867.  
  868.                                                                               
  869.  
  870.                                                                               
  871.  
  872.   ?-/*               derivative of x^2 with respect to x            */
  873.  
  874.                                                                               
  875.  
  876.                             d( x^2, x, DY).
  877.  
  878.                                                                               
  879.  
  880.                                                                               
  881.  
  882.   DY = ((x ^ 2) * (((2 * 1) / x) + (0 * ln x )))
  883.  
  884.                                                                               
  885.  
  886.                                                                               
  887.  
  888.                                                                               
  889.  
  890.                                                                               
  891.  
  892.                                                                               
  893.  
  894.                                                                               
  895.  
  896.                                                                               
  897.  
  898.                                                                               
  899.  
  900.                                                                               
  901.  
  902.                                                                               
  903.  
  904.      Fig. 3 - Derivative of x^2 with respect to x, using the
  905.               minimum program of Fig.2
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.    /* -----------------------------------------------------------------
  932.  
  933.                                 DIFFSV.PRO
  934.  
  935.                                (version 1.0)
  936.  
  937.                           Copyright 1987 S.Vaghi
  938.  
  939.  
  940.                 Program for the symbolic differentiation of
  941.                              algebraic functions.
  942.  
  943.                 ...........................................
  944.  
  945.  
  946.        Example of how to use the program:
  947.  
  948.            to find the derivative, DY, of the function
  949.                                                          y = x^2
  950.            with respect to x, one can
  951.  
  952.                    a) simply enter
  953.                                                   d( x^2, x, DY).
  954.                       after the Prolog prompt,
  955.            or
  956.                    b) enter
  957.                                                    Y = x^2 ,
  958.                                                    d( Y, x, DY).
  959.                       after the prompt,
  960.            or
  961.                    c) enter the complete sequence including
  962.                       simplification, that is
  963.                                                     Y = x^2 ,
  964.                                                     d( Y, x, Z),
  965.                                                     s( Z, DY).
  966.  
  967.            Method c) is always recommended, in which case the
  968.            program is used in combination with SIMPSV.PRO
  969.  
  970.  
  971.      ----------------------------------------------------------------- */
  972.  
  973.  
  974.  
  975.                     /*  definition of operators */
  976.  
  977.  
  978.   ?-op(11, yfx,  '^').                 /*  exponentiation     */
  979.   ?-op( 9,  fx,  '~').                 /*  minus sign         */
  980.   ?-op(11,  fx, 'ln').                 /*  natural logarithm  */
  981.  
  982.  
  983.  
  984.   d(X,X,1).
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.   d(C,X,0) :- atomic(C), C \= X.
  999.  
  1000.   d(~U,X,~D) :- d(U,X,D).
  1001.  
  1002.  
  1003.           d(C+U,X,D) :- atomic(C), C \= X, d(U,X,D), ! .
  1004.           d(U+C,X,D) :- atomic(C), C \= X, d(U,X,D), ! .
  1005.  
  1006.   d(U+V,X,D1+D2) :- d(U,X,D1), d(V,X,D2).
  1007.  
  1008.  
  1009.           d(C-U,X,~D) :- atomic(C), C \= X, d(U,X,D), ! .
  1010.           d(U-C,X, D) :- atomic(C), C \= X, d(U,X,D), ! .
  1011.  
  1012.   d(U-V,X,D1-D2) :- d(U,X,D1), d(V,X,D2).
  1013.  
  1014.  
  1015.           d(C*U,X,C*D) :- atomic(C), C \= X, d(U,X,D), ! .
  1016.           d(U*C,X,C*D) :- atomic(C), C \= X, d(U,X,D), ! .
  1017.  
  1018.   d(U*V, X, D2*U+D1*V) :- d(U,X,D1), d(V,X,D2).
  1019.  
  1020.  
  1021.           d(1/U,X, ~D/(U^2) ) :- d(U,X,D), ! .
  1022.           d(C/U,X, C*DD) :- atomic(C), C \= X, d(1/U,X,DD), ! .
  1023.           d(U/C,X,  D/C) :- atomic(C), C \= X, d(U,X,D), ! .
  1024.  
  1025.   d(U/V, X, (V*D1-U*D2)/(V^2) ) :- d(U,X,D1), d(V,X,D2).
  1026.  
  1027.  
  1028.           d( U^C, X, C*D*U^(C-1) ) :- atomic(C), C \= X, d(U,X,D), ! .
  1029.           d(U^~C, X,            Z) :-  d( 1/(U^C), X, Z), ! .
  1030.           d( U^(A/B),X, (A/B)*D*U^(A/B-1) ) :- atomic(A), atomic(B),
  1031.                                                A \= X, B \= X,
  1032.                                                d(U,X,D), ! .
  1033.           d(U^~(A/B),X,                  Z) :- d(1/U^(A/B) , X, Z), ! .
  1034.  
  1035.   d(U^V, X, U^V*(V*D1/U+D2*ln(U) )) :- d(U,X,D1), d(V,X,D2).
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.      Fig. 4 - The program for symbolic differentiation
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.    
  1064.                                                                               
  1065.  
  1066.  
  1067.  
  1068.                                                                               
  1069.  
  1070.   ?-/*               derivative of x^2 with respect to x            */
  1071.  
  1072.                                                                               
  1073.  
  1074.                             d( x^2, x, DY).
  1075.  
  1076.                                                                               
  1077.  
  1078.                                                                               
  1079.  
  1080.   DY = ((2 * 1) * (x ^ (2 - 1)))
  1081.  
  1082.                                                                               
  1083.  
  1084.                                                                               
  1085.  
  1086.                                                                               
  1087.  
  1088.                                                                               
  1089.  
  1090.                                                                               
  1091.  
  1092.                                                                               
  1093.  
  1094.                                                                               
  1095.  
  1096.                                                                               
  1097.  
  1098.                                                                               
  1099.  
  1100.                                                                               
  1101.  
  1102.      Fig. 5 - Derivative of x^2 with respect to x, using the
  1103.               program DIFFSV.PRO
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.    
  1130.                                                                               
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.   ?-/*          integral of  (2*1)*(x^(2-1))  with respect to x        */
  1137.  
  1138.                                                                               
  1139.  
  1140.                         d( Y, x, (2*1)*(x^(2-1)) ).
  1141.  
  1142.                                                                               
  1143.  
  1144.                                                                               
  1145.  
  1146.   Y = (x ^ 2)
  1147.  
  1148.                                                                               
  1149.  
  1150.                                                                               
  1151.  
  1152.                                                                               
  1153.  
  1154.                                                                               
  1155.  
  1156.                                                                               
  1157.  
  1158.                                                                               
  1159.  
  1160.                                                                               
  1161.  
  1162.                                                                               
  1163.  
  1164.                                                                               
  1165.  
  1166.                                                                               
  1167.  
  1168.      Fig. 6 - Using DIFFSV.PRO to calculate the integral of
  1169.               (2*1)*(x^(2-1))
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.    /* -----------------------------------------------------------------
  1196.   --
  1197.  
  1198.                                  SIMPSV.PRO
  1199.  
  1200.                                 (version 1.0)
  1201.  
  1202.                             Copyright 1987 S.Vaghi
  1203.  
  1204.  
  1205.                   Program for the symbolic simplification of
  1206.                               algebraic functions.
  1207.  
  1208.                   ..........................................
  1209.  
  1210.  
  1211.           Example of how to use the program:
  1212.  
  1213.               to simplify the expression
  1214.                                                (2*1)*(x^(2-1))
  1215.               one can
  1216.  
  1217.                   a) simply enter
  1218.                                                s( (2*1)*(x^(2-1)), Z).
  1219.                      after the Prolog prompt,
  1220.               or
  1221.                   b) enter
  1222.                                                 Y = (2*1)*(x^(2-1)),
  1223.                                                 s( Y, Z).
  1224.                      after the prompt.
  1225.  
  1226.               In both cases a two pass simplification is performed.
  1227.  
  1228.  
  1229.   -----------------------------------------------------------------
  1230.   --- */
  1231.  
  1232.  
  1233.  
  1234.                    /*  definition of operators */
  1235.  
  1236.   ?-op(11, yfx,  '^').                 /*  exponentiation     */
  1237.   ?-op( 9,  fx,  '~').                 /*  minus sign         */
  1238.   ?-op(11,  fx, 'ln').                 /*  natural logarithm  */
  1239.  
  1240.  
  1241.  
  1242.                /*  two pass simplification clause  */
  1243.  
  1244.  
  1245.                s(X,Y) :- simplify(X,Z), simplify(Z,Y).
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.         /*  list processing of the expression to be simplified  */
  1262.  
  1263.  
  1264.   simplify(X,X) :- atomic(X), ! .
  1265.  
  1266.   simplify(X,Y) :- X =..[Op,Z], simplify(Z,Z1), u(Op,Z1,Y), ! .
  1267.  
  1268.   simplify(X,Y) :- X =..[Op,Z,W], simplify(Z,Z1),
  1269.                    simplify(W,W1),
  1270.                    r(Op,Z1,W1,Y), ! .
  1271.  
  1272.  
  1273.  
  1274.         /*  simplification clauses for addition  */
  1275.  
  1276.  
  1277.   r('+',~X,~X,Z) :- b('*',2,X,W), u('~',W,Z) , ! .
  1278.   r('+', X, X,Z) :- b('*',2,X,Z), ! .
  1279.  
  1280.   r('+', X,~Y,Z) :- b('-',X,Y,Z), ! .
  1281.   r('+',~X, Y,Z) :- b('-',Y,X,Z), ! .
  1282.   r('+',~X,~Y,Z) :- b('+',X,Y,W), u('~',W,Z), ! .
  1283.  
  1284.   r('+',   X, Y/Z, W) :- integer(X), integer(Y), integer(Z),
  1285.                          T is Z*X+Y,
  1286.                          b('/',T,Z,W), ! .
  1287.   r('+', X/Z,   Y, W) :- integer(X), integer(Y), integer(Z),
  1288.                          T is X+Y*Z,
  1289.                          b('/',T,Z,W), ! .
  1290.  
  1291.   r('+',   X, Y+Z, W) :- b('+',Y,Z,T), b('+',X,T,W), ! .
  1292.   r('+', X+Y,   Z, W) :- b('+',X,Y,T), b('+',T,Z,W), ! .
  1293.  
  1294.   r('+', X*Y,Z*Y,W) :- b('+',X,Z,T), b('*',Y,T,W), ! .
  1295.   r('+', X*Y,Y*Z,W) :- b('+',X,Z,T), b('*',Y,T,W), ! .
  1296.   r('+', Y*X,Z*Y,W) :- b('+',X,Z,T), b('*',Y,T,W), ! .
  1297.   r('+', Y*X,Y*Z,W) :- b('+',X,Z,T), b('*',Y,T,W), ! .
  1298.  
  1299.   r('+',X,Y,Z) :- integer(Y), b('+',Y,X,Z), ! .
  1300.  
  1301.  
  1302.  
  1303.         /*  simplification clauses for subtraction  */
  1304.  
  1305.  
  1306.   r('-', X,~X,Z) :- b('*',2,X,Z), ! .
  1307.   r('-',~X, X,Z) :- b('*',2,X,W), u('~',W,Z), ! .
  1308.  
  1309.   r('-', X,~Y,Z) :- b('+',X,Y,Z), ! .
  1310.   r('-',~X, Y,Z) :- b('+',X,Y,W), u('~',W,Z), ! .
  1311.   r('-',~X,~Y,Z) :- b('-',Y,X,Z), ! .
  1312.  
  1313.   r('-',   X, Y/Z, W) :- integer(X), integer(Y), integer(Z),
  1314.                          T is X*Z-Y,
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.                          b('/',T,Z,W), ! .
  1328.   r('-', X/Z,   Y, W) :- integer(X), integer(Y), integer(Z),
  1329.                          T is X-Y*Z,
  1330.                          b('/',T,Z,W), ! .
  1331.  
  1332.   r('-',   X, Y-Z, W) :- b('-',Y,Z,T), b('-',X,T,W), ! .
  1333.   r('-', X-Y,   Z, W) :- b('-',X,Y,T), b('-',T,Z,W), ! .
  1334.  
  1335.   r('-', X*Y, Z*Y, W) :- b('-',X,Z,T), b('*',Y,T,W), ! .
  1336.   r('-', X*Y, Y*Z, W) :- b('-',X,Z,T), b('*',Y,T,W), ! .
  1337.   r('-', Y*X, Z*Y, W) :- b('-',X,Z,T), b('*',Y,T,W), ! .
  1338.   r('-', Y*X, Y*Z, W) :- b('-',X,Z,T), b('*',Y,T,W), ! .
  1339.  
  1340.  
  1341.  
  1342.         /*  simplification clauses for multiplication  */
  1343.  
  1344.  
  1345.   r('*', X, X,Z) :- b('^',X,2,Z), ! .
  1346.   r('*',~X,~X,Z) :- b('^',X,2,Z), ! .
  1347.   r('*',~X, X,Z) :- b('^',X,2,W), u('~',W,Z), ! .
  1348.   r('*', X,~X,Z) :- b('^',X,2,W), u('~',W,Z), ! .
  1349.  
  1350.   r('*',      X, X^(~1), Z) :- b('/',X,X,Z), ! .
  1351.   r('*', X^(~1),      X, Z) :- b('/',X,X,Z), ! .
  1352.  
  1353.   r('*',   X, 1/X, Z) :- b('/',X,X,Z), ! .
  1354.   r('*', 1/X,   X, Z) :- b('/',X,X,Z), ! .
  1355.   r('*',   X, 1/Y, Z) :- b('/',X,Y,Z), ! .
  1356.   r('*', 1/X,   Y, Z) :- b('/',Y,X,Z), ! .
  1357.   r('*',   M, N/X, Z) :- atomic(M), atomic(N),
  1358.                          b('*',M,N,S), b('/',S,X,Z), ! .
  1359.   r('*', M/X,   N, Z) :- atomic(M), atomic(N),
  1360.                          b('*',M,N,S), b('/',S,X,Z), ! .
  1361.  
  1362.  
  1363.   r('*',  X, N/Y, Z) :- atomic(N), b('/',X,Y,S), b('*',N,S,Z), ! .
  1364.   r('*',N/Y,   X, Z) :- atomic(N), b('/',X,Y,S), b('*',N,S,Z), ! .
  1365.  
  1366.   r('*',     X,Y^(~1),Z) :- b('/',X,Y,Z), ! .
  1367.   r('*',     X,  X^~Y,Z) :- b('-',Y,1,S), b('^',X,S,T), b('/',1,T,Z), ! .
  1368.   r('*',X^(~1),     Y,Z) :- b('/',Y,X,Z), ! .
  1369.   r('*',  X^~Y,     X,Z) :- b('-',Y,1,S), b('^',X,S,T), b('/',1,T,Z), ! .
  1370.  
  1371.   r('*',  X,X^Y,Z) :- b('+',1,Y,S), b('^',X,S,Z), ! .
  1372.   r('*',X^Y,  X,Z) :- b('+',Y,1,S), b('^',X,S,Z), ! .
  1373.  
  1374.   r('*',~X,~Y,Z) :- b('*',X,Y,Z), ! .
  1375.   r('*', X,~Y,Z) :- b('*',X,Y,W), u('~',W,Z), ! .
  1376.   r('*',~X, Y,Z) :- b('*',X,Y,W), u('~',W,Z), ! .
  1377.  
  1378.   r('*',Z^~X,Z^~Y,W) :- b('+',X,Y,S), b('^',Z,S,T), b('/',1,T,W), ! .
  1379.   r('*',Z^~X, Z^Y,W) :- b('-',Y,X,S), b('^',Z,S,W), ! .
  1380.   r('*', Z^X,Z^~Y,W) :- b('-',X,Y,S), b('^',Z,S,W), ! .
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.   r('*', Z^X, Z^Y,W) :- b('+',X,Y,T), b('^',Z,T,W), ! .
  1394.   r('*',X^~Z,Y^~Z,W) :- b('*',X,Y,S), b('^',S,Z,T), b('/',1,T,W), ! .
  1395.   r('*', X^Z,Y^~Z,W) :- b('/',X,Y,S), b('^',S,Z,W), ! .
  1396.   r('*',X^~Z, Y^Z,W) :- b('/',Y,X,S), b('^',S,Z,W), ! .
  1397.   r('*', X^Z, Y^Z,W) :- b('*',X,Y,T), b('^',T,Z,W), ! .
  1398.  
  1399.   r('*', X*Y,   Y, Z) :- b('^',Y,2,S), b('*',X,S,Z), ! .
  1400.   r('*', Y*X,   Y, Z) :- b('^',Y,2,S), b('*',X,S,Z), ! .
  1401.   r('*',   Y, X*Y, Z) :- b('^',Y,2,S), b('*',X,S,Z), ! .
  1402.   r('*',   Y, Y*X, Z) :- b('^',Y,2,S), b('*',X,S,Z), ! .
  1403.  
  1404.   r('*', X*Y, X*Z, W) :- b('*',Y,Z,S), b('^',X,2,T), b('*',T,S,W), ! .
  1405.   r('*', Y*X, X*Z, W) :- b('*',Y,Z,S), b('^',X,2,T), b('*',T,S,W), ! .
  1406.   r('*', X*Y, Z*X, W) :- b('*',Y,Z,S), b('^',X,2,T), b('*',T,S,W), ! .
  1407.   r('*', Y*X, Z*X, W) :- b('*',Y,Z,S), b('^',X,2,T), b('*',T,S,W), ! .
  1408.  
  1409.   r('*',  M, N*X, W) :- atomic(M), atomic(N),
  1410.                         b('*',M,N,P), b('*',P,X,W), ! .
  1411.   r('*',M*X,   N, W) :- atomic(M), atomic(N),
  1412.                         b('*',M,N,P), b('*',P,X,W), ! .
  1413.  
  1414.   r('*',   X, Y*Z, W) :- b('*',Y,Z,T), b('*',X,T,W), ! .
  1415.   r('*', X*Y,   Z, W) :- b('*',X,Y,T), b('*',T,Z,W), ! .
  1416.  
  1417.   r('*',X,Y,Z) :- integer(Y), b('*',Y,X,Z), ! .
  1418.  
  1419.  
  1420.  
  1421.         /*    simplification clauses for division
  1422.              (division is never actually performed)  */
  1423.  
  1424.  
  1425.   r('/', 1, X/Y, Z) :- b('/',Y,X,Z), ! .
  1426.   r('/',~1, X/Y, Z) :- b('/',Y,X,W), u('~',W,Z), ! .
  1427.  
  1428.   r('/',~X,~Y,Z) :- b('/',X,Y,Z), ! .
  1429.   r('/', X,~Y,Z) :- b('/',X,Y,W), u('~',W,Z), ! .
  1430.   r('/',~X, Y,Z) :- b('/',X,Y,W), u('~',W,Z), ! .
  1431.  
  1432.   r('/',      X, Y^(~1), Z) :- b('*',X,Y,Z), ! .
  1433.   r('/', X^(~1),      Y, Z) :- b('*',X,Y,W), b('/',1,W,Z), ! .
  1434.  
  1435.   r('/',   X, Y/Z, W) :- b('*',X,Z,T), b('/',T,Y,W), ! .
  1436.   r('/', X/Y,   Z, W) :- b('*',Y,Z,T), b('/',X,T,W), ! .
  1437.  
  1438.   r('/',     X,Y^(~Z),W) :- b('^',Y,Z,T), b('*',X,T,W), ! .
  1439.   r('/',X^(~Z),     Y,W) :- b('^',X,Z,S), b('*',S,Y,T), b('/',1,T,W), ! .
  1440.  
  1441.   r('/',X,X^(~Y),Z) :- b('+',1,Y,S), b('^',X,S,Z), ! .
  1442.   r('/',X,   X^Y,Z) :- b('-',Y,1,S), b('^',X,S,T), b('/',1,T,Z), ! .
  1443.   r('/',X^(~Y),X,Z) :- b('+',Y,1,S), b('^',X,S,T), b('/',1,T,Z), ! .
  1444.  
  1445.   r('/',   X^Y,     X,Z) :- b('-',Y,1,S), b('^',X,S,Z), ! .
  1446.   r('/',   X^N,X^(~M),Z) :- b('+',N,M,S), b('^',X,S,Z), ! .
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.  
  1459.   r('/',X^(~N),   X^M,Z) :- b('+',N,M,S), b('^',X,S,T), b('/',1,T,Z), ! .
  1460.   r('/',X^(~N),X^(~M),Z) :- b('-',M,N,S), b('^',X,S,Z), ! .
  1461.   r('/',   X^N,   X^M,Z) :- b('-',N,M,W), b('^',X,W,Z), ! .
  1462.  
  1463.   r('/',X^(~Z),   Y^Z,W) :- b('*',X,Y,S), b('^',S,Z,T), b('/',1,T,W), ! .
  1464.   r('/',   X^Z,Y^(~Z),W) :- b('*',X,Y,S), b('^',S,Z,W), ! .
  1465.   r('/',X^(~Z),Y^(~Z),W) :- b('/',Y,X,S), b('^',S,Z,W), ! .
  1466.   r('/',   X^Z,   Y^Z,W) :- b('/',X,Y,T), b('^',T,Z,W), ! .
  1467.  
  1468.  
  1469.  
  1470.         /*  simplification clauses for exponentiation  */
  1471.  
  1472.  
  1473.   r('^',X,~1,Y) :- b('/',1,X,Y), ! .
  1474.  
  1475.   r('^',X,~Y,Z) :- b('^',X,Y,W), b('/',1,W,Z), ! .
  1476.  
  1477.   r('^',X^Y,Z,W) :- b('*',Y,Z,T), b('^',X,T,W), ! .
  1478.  
  1479.  
  1480.  
  1481.         /*  catch all clause to cover cases not covered
  1482.             by the previous clauses                      */
  1483.  
  1484.  
  1485.   r(X,Y,Z,W) :- b(X,Y,Z,W).
  1486.  
  1487.  
  1488.  
  1489.         /*  basic rules for the unary operator '~'  */
  1490.  
  1491.  
  1492.   u('~', 0, 0) :- ! .
  1493.   u('~',~X, X) :- ! .
  1494.   u('~', X,~X) :- ! .
  1495.   u('~',X^Y,~(X^Y) ) :- ! .
  1496.  
  1497.  
  1498.  
  1499.         /*  basic rules of addition  */
  1500.  
  1501.  
  1502.   b('+', X, 0, X) :- ! .
  1503.   b('+',~X, 0,~X) :- ! .
  1504.   b('+', 0, X, X) :- ! .
  1505.   b('+', 0,~X,~X) :- ! .
  1506.   b('+', X,~X, 0) :- ! .
  1507.   b('+',~X, X, 0) :- ! .
  1508.  
  1509.   b('+',X,Y,Z) :- integer(X), integer(Y),
  1510.                   Z is X+Y, ! .
  1511.  
  1512.   b('+',X,Y,X+Y).
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.         /*  basic rules of subtraction  */
  1528.  
  1529.  
  1530.   b('-', X, 0, X) :- ! .
  1531.   b('-',~X, 0,~X) :- ! .
  1532.   b('-', 0, X,~X) :- ! .
  1533.   b('-', 0,~X, X) :- ! .
  1534.   b('-',~X,~X, 0) :- ! .
  1535.   b('-', X, X, 0) :- ! .
  1536.  
  1537.   b('-',X,Y,Z) :- integer(X), integer(Y),
  1538.                   Z is X-Y, ! .
  1539.  
  1540.   b('-',X,Y,X-Y).
  1541.  
  1542.  
  1543.  
  1544.         /*  basic rules of multiplication  */
  1545.  
  1546.  
  1547.   b('*', 0, X,0) :- ! .
  1548.   b('*', 0,~X,0) :- ! .
  1549.   b('*', X, 0,0) :- ! .
  1550.   b('*',~X, 0,0) :- ! .
  1551.  
  1552.   b('*', 1, X, X) :- ! .
  1553.   b('*', 1,~X,~X) :- ! .
  1554.   b('*',~1, X,~X) :- ! .
  1555.   b('*',~1,~X, X) :- ! .
  1556.   b('*', X, 1, X) :- ! .
  1557.   b('*',~X, 1,~X) :- ! .
  1558.   b('*', X,~1,~X) :- ! .
  1559.   b('*',~X,~1, X) :- ! .
  1560.  
  1561.   b('*', X/Y,   Y, X) :- ! .
  1562.   b('*',   Y, X/Y, X) :- ! .
  1563.  
  1564.   b('*',X,Y,Z) :- integer(X), integer(Y),
  1565.                   Z is X*Y, ! .
  1566.  
  1567.   b('*',X,Y,X*Y).
  1568.  
  1569.  
  1570.  
  1571.         /*  basic rules of division  */
  1572.  
  1573.  
  1574.   b('/',0,0,'ERROR - indefinite form 0/0') :- ! .   /* indefinite form */
  1575.   b('/',X,0,'ERROR - division by 0      ') :- ! .   /* division by 0   */
  1576.  
  1577.   b('/',0, X,0) :- ! .
  1578.   b('/',0,~X,0) :- ! .
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.   b('/', X,1, X) :- ! .
  1593.   b('/',~X,1,~X) :- ! .
  1594.  
  1595.   b('/', 1,X,    1/X) :- ! .
  1596.   b('/',~1,X, ~(1/X)) :- ! .
  1597.  
  1598.   b('/', X,~1,~X) :- ! .
  1599.   b('/',~X,~1, X) :- ! .
  1600.  
  1601.   b('/', 1,  ~X,~(1/X)) :- ! .
  1602.   b('/',~1,  ~X,   1/X) :- ! .
  1603.   b('/', 1, 1/X,     X) :- ! .
  1604.   b('/',~1, 1/X,    ~X) :- ! .
  1605.  
  1606.   b('/', X,~X,~1) :- ! .
  1607.   b('/',~X, X,~1) :- ! .
  1608.   b('/',~X,~X, 1) :- ! .
  1609.   b('/', X, X, 1) :- ! .
  1610.  
  1611.   b('/',X,Y,X/Y).
  1612.  
  1613.  
  1614.  
  1615.         /*  basic rules of exponentiation  */
  1616.  
  1617.  
  1618.   b('^',1,X,1) :- ! .
  1619.  
  1620.                                                     /* indefinite forms */
  1621.  
  1622.   b('^',0, 0,'ERROR - indefinite form 0^0       ') :- ! .
  1623.   b('^',0,~1,'ERROR - indefinite form 0^~1 = 1/0') :- ! .
  1624.   b('^',0,~K,'ERROR - indefinite form 0^~K = 1/0') :- atomic(K), ! .
  1625.  
  1626.  
  1627.   b('^',~X,1,~X) :- ! .
  1628.   b('^', X,1, X) :- ! .
  1629.   b('^', X,0, 1) :- ! .
  1630.  
  1631.  
  1632.                                           /* recursive clauses to
  1633.                                              calculate the n-th power
  1634.                                              of positive and negative
  1635.                                              integers                 */
  1636.  
  1637.   b('^', X,N,Y) :- integer(X), integer(N),
  1638.                    M is N-1, b('^',X,M,Z),
  1639.                    Y is Z*X, ! .
  1640.   b('^',~X,N,Y) :- integer(X), integer(N),
  1641.                    R is (N mod 2), R \= 0,
  1642.                    b('^',X,N,Z), Y = ~Z, ! .
  1643.   b('^',~X,N,Y) :- integer(X), integer(Y),
  1644.                    R is (N mod 2), R = 0,
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.                    b('^',X,N,Z), Y =  Z, ! .
  1658.  
  1659.   b('^',~X,Y, ~(X^Y)) :- ! .
  1660.  
  1661.   b('^',X,Y,X^Y).
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.      Fig. 7 - The simplification program.
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.    
  1724.                                                                               
  1725.  
  1726.  
  1727.  
  1728.  
  1729.                                                                               
  1730.  
  1731.   ?-/*          derivative of x^2 with respect to x with simplification
  1732.   */   
  1733.                                                                               
  1734.  
  1735.                                      Y = x^2,
  1736.  
  1737.                                      d( Y, x, Z),
  1738.  
  1739.                                      s( Z, DY).
  1740.  
  1741.                                                                               
  1742.  
  1743.                                                                               
  1744.  
  1745.   Y = (x ^ 2),
  1746.  
  1747.   Z = ((2 * 1) * (x ^ (2 - 1))),
  1748.  
  1749.   DY = (2 * x)
  1750.  
  1751.                                                                               
  1752.  
  1753.                                                                               
  1754.  
  1755.                                                                               
  1756.  
  1757.                                                                               
  1758.  
  1759.                                                                               
  1760.  
  1761.                                                                               
  1762.  
  1763.      Fig. 8 - Derivative of x^2 with respect to x, using both
  1764.               programs DIFFSV.PRO and SIMPSV.PRO
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.    
  1790.                                                                               
  1791.  
  1792.                                                                               
  1793.  
  1794.   ?-/*          derivative of  y = (t^2-3)^4  with respect to t          */
  1795.  
  1796.                                                                               
  1797.  
  1798.                                     Y = (t^2-3)^4,
  1799.  
  1800.                                     d( Y, t, Z),
  1801.  
  1802.                                     s( Z, DY).
  1803.  
  1804.                                                                               
  1805.  
  1806.                                                                               
  1807.  
  1808.   Y = (((t ^ 2) - 3) ^ 4),
  1809.  
  1810.   Z = ((4 * ((2 * 1) * (t ^ (2 - 1)))) * (((t ^ 2) - 3) ^ (4 - 1))),
  1811.  
  1812.   DY = ((8 * t) * (((t ^ 2) - 3) ^ 3))
  1813.  
  1814.                                                                               
  1815.  
  1816.  
  1817.                                                                               
  1818.  
  1819.                                                                               
  1820.  
  1821.   ?-/*         derivative of  y = x^5 + 5*x^4 - 10*x^2 + 6   w.r.t. x     */
  1822.  
  1823.                                                                               
  1824.  
  1825.                                 Y = x^5 + 5*x^4 - 10*x^2 + 6,
  1826.  
  1827.                                 d( Y, x, Z),
  1828.  
  1829.                                 s( Z, DY).
  1830.  
  1831.                                                                               
  1832.  
  1833.                                                                               
  1834.  
  1835.   Y = ((((x ^ 5) + (5 * (x ^ 4))) - (10 * (x ^ 2))) + 6),
  1836.  
  1837.   Z = ((((5 * 1) * (x ^ (5 - 1))) + (5 * ((4 * 1) * (x ^ (4 - 1))))) - (10 *
  1838.   ((2 *
  1839.    1) * (x ^ (2 - 1))))),
  1840.  
  1841.   DY = (((5 * (x ^ 4)) + (20 * (x ^ 3))) - (20 * x))
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.                                                                               
  1856.  
  1857.                                                                               
  1858.  
  1859.                                                                               
  1860.  
  1861.                                                                               
  1862.  
  1863.                                                                               
  1864.  
  1865.   ?-/*        derivative of  y = (2*x)^(1/2) + 2*x^(1/2)   w.r.t.  x      */
  1866.  
  1867.                                                                               
  1868.  
  1869.                              Y = (2*x)^(1/2) + 2*x^(1/2),
  1870.  
  1871.                              d( Y, x, Z),
  1872.  
  1873.                              s( Z, DY).
  1874.  
  1875.                                                                               
  1876.  
  1877.                                                                               
  1878.  
  1879.   Y = (((2 * x) ^ (1 / 2)) + (2 * (x ^ (1 / 2)))),
  1880.  
  1881.   Z = ((((1 / 2) * (2 * 1)) * ((2 * x) ^ ((1 / 2) - 1))) + (2 * (((1 / 2) * 1)
  1882.   * (
  1883.   x ^ ((1 / 2) - 1))))),
  1884.  
  1885.   DY = (((2 * x) ^ (-1 / 2)) + (x ^ (-1 / 2)))
  1886.  
  1887.                                                                               
  1888.  
  1889.                                                                               
  1890.  
  1891.                                                                               
  1892.  
  1893.                                                                               
  1894.  
  1895.                                                                               
  1896.  
  1897.      Fig. 9 - Examples of derivatives obtained with the programs.
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.    
  1922.                                                                               
  1923.  
  1924.                                                                               
  1925.  
  1926.   ?-/*     partial derivatives of  y = a*u + 1/v   w.r.t. u and v      */
  1927.  
  1928.                                                                               
  1929.  
  1930.                               Y = a*u + 1/v,
  1931.  
  1932.                               d( Y, u, V), s( V, DYDU),
  1933.  
  1934.                               d( Y, v, W), s( W, DYDV).
  1935.  
  1936.                                                                               
  1937.  
  1938.                                                                               
  1939.  
  1940.   Y = ((a * u) + (1 / v)),
  1941.  
  1942.   V = ((a * 1) + (~ 0  / (v ^ 2))),
  1943.  
  1944.   DYDU = a,
  1945.  
  1946.   W = ((a * 0) + (~ 1  / (v ^ 2))),
  1947.  
  1948.   DYDV = ~ (1 / (v ^ 2))
  1949.  
  1950.                                                                               
  1951.  
  1952.                                                                               
  1953.  
  1954.  
  1955.                                                                               
  1956.  
  1957.                                                                               
  1958.  
  1959.   ?-/*   1st, 2nd and 3rd derivatives of   y = x^3+3*x^2-8*x+2   w.r.t.  x
  1960.   */  
  1961.                                                                               
  1962.  
  1963.                                Y = x^3+3*x^2-8*x+2,
  1964.  
  1965.                                d( Y, x, Z), s( Z, DY1),
  1966.  
  1967.                                d( DY1, x, V), s( V, DY2),
  1968.  
  1969.                                d( DY2, x, W), s( W, DY3).
  1970.  
  1971.                                                                               
  1972.  
  1973.                                                                               
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.   Y = ((((x ^ 3) + (3 * (x ^ 2))) - (8 * x)) + 2),
  1988.  
  1989.   Z = ((((3 * 1) * (x ^ (3 - 1))) + (3 * ((2 * 1) * (x ^ (2 - 1))))) - (8 *
  1990.   1)),  
  1991.   DY1 = (((3 * (x ^ 2)) + (6 * x)) - 8),
  1992.  
  1993.   V = ((3 * ((2 * 1) * (x ^ (2 - 1)))) + (6 * 1)),
  1994.  
  1995.   DY2 = (6 + (6 * x)),
  1996.  
  1997.   W = (6 * 1),
  1998.  
  1999.   DY3 = 6
  2000.  
  2001.                                                                               
  2002.  
  2003.                                                                               
  2004.  
  2005.  
  2006.                                                                               
  2007.  
  2008.                                                                               
  2009.  
  2010.   ?-/*  y = u^3+4  ,  u = x^2+2*x  ;  derivative of y   w.r.t.  x      */
  2011.  
  2012.                                                                               
  2013.  
  2014.                                 U = x^2+2*x,
  2015.  
  2016.                                 Y = U^3+4,
  2017.  
  2018.                                 d( Y, x, Z), s( Z, DY).
  2019.  
  2020.                                                                               
  2021.  
  2022.                                                                               
  2023.  
  2024.   U = ((x ^ 2) + (2 * x)),
  2025.  
  2026.   Y = ((((x ^ 2) + (2 * x)) ^ 3) + 4),
  2027.  
  2028.   Z = ((3 * (((2 * 1) * (x ^ (2 - 1))) + (2 * 1))) * (((x ^ 2) + (2 * x)) ^ (3
  2029.   - 1
  2030.   ))),
  2031.  
  2032.   DY = ((3 * (2 + (2 * x))) * (((x ^ 2) + (2 * x)) ^ 2))
  2033.  
  2034.                                                                               
  2035.  
  2036.                                                                               
  2037.  
  2038.                                                                               
  2039.  
  2040.                                                                               
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.                                                                               
  2055.  
  2056.  
  2057.   ?-/*    x = y * (1-y^2)^(1/2)  ;   derivative of y   w.r.t.  x          */
  2058.  
  2059.                                                                               
  2060.  
  2061.                              X = y*(1-y^2)^(1/2),
  2062.  
  2063.                              d( X, y, Z), s( Z, DX),
  2064.  
  2065.                              s( 1/DX, DY).
  2066.  
  2067.                                                                               
  2068.  
  2069.                                                                               
  2070.  
  2071.   X = (y * ((1 - (y ^ 2)) ^ (1 / 2))),
  2072.  
  2073.   Z = (((((1 / 2) * ~ ((2 * 1) * (y ^ (2 - 1))) ) * ((1 - (y ^ 2)) ^ ((1 / 2)
  2074.   - 1)
  2075.   )) * y) + (1 * ((1 - (y ^ 2)) ^ (1 / 2)))),
  2076.  
  2077.   DX = (((1 - (y ^ 2)) ^ (1 / 2)) - ((((2 * y) / 2) * ((1 - (y ^ 2)) ^ (-1 /
  2078.   2))) 
  2079.   * y)),
  2080.  
  2081.   DY = (1 / (((1 - (y ^ 2)) ^ (1 / 2)) - ((((2 * y) / 2) * ((1 - (y ^ 2)) ^
  2082.   (-1 / 
  2083.   2))) * y)))
  2084.  
  2085.                                                                               
  2086.  
  2087.                                                                               
  2088.  
  2089.                                                                               
  2090.  
  2091.                     
  2092.                                                                               
  2093.  
  2094.                                                                               
  2095.  
  2096.                                                                               
  2097.  
  2098.      Fig. 10 - Partial derivatives, higher order derivatives, chain rule
  2099.                and derivative of implicit function.
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.    
  2120.                                                                               
  2121.  
  2122.   ?-/*   application of the Newton-Raphson method to calculate the real root
  2123.   of   
  2124.                                                                               
  2125.  
  2126.                                  x^3 - a = 0
  2127.  
  2128.                                                                               
  2129.  
  2130.          ( x is the approximation to the solution at the k-th iteration and
  2131.  
  2132.            Xnew at the iteration k+1)
  2133.  
  2134.     */
  2135.                                                                               
  2136.  
  2137.                                                                               
  2138.  
  2139.                              F = x^3-a,
  2140.  
  2141.                              d( F, x, Z), s( Z, F1),
  2142.  
  2143.                              s( x-F/F1, Xnew).
  2144.  
  2145.                                                                               
  2146.  
  2147.                                                                               
  2148.  
  2149.   F = ((x ^ 3) - a),
  2150.  
  2151.   Z = ((3 * 1) * (x ^ (3 - 1))),
  2152.  
  2153.   F1 = (3 * (x ^ 2)),
  2154.  
  2155.   Xnew = (x - (((x ^ 3) - a) / (3 * (x ^ 2))))
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.      Fig. 11 - Example of use of the programs for the Newton-Raphson method.
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.