NAME
    PerlMaple - Perl binding for Maplesoft's Maple mathematical package

VERSION
    This document describes PerlMaple 0.07 released on Nov 20, 2009.

SYNOPSIS
      use PerlMaple;

      $maple = PerlMaple->new or
          die $maple->error;
      $ans = $maple->eval_cmd('int(2*x^3,x);');
      defined $ans or die $maple->error;

      $maple->eval_cmd(<<'.');
      lc := proc( s, u, t, v )
               description "form a linear combination of the arguments";
               s * u + t * v
      end proc;
      .

      $maple = PerlMaple->new(
        PrintError => 0,
        RaiseError => 1,
      );

      print $maple->eval('solve(x^2+2*x+4, x)');  # got: -1+I*3^(1/2), -1-I*3^(1/2)
      print $maple->solve('x^2+2*x+4', 'x');  # ditto
      print $maple->eval('int(2*x^3,x)', 'x=2');  # got: 8s
      print $maple->int('2*x^3', 'x=0..2');  # ditto

      $maple->PrintError(1);
      $maple->RaiseError(0);

      print $maple->diff('2*x^3', 'x'); # got: 6*x^2
      print $maple->ifactor('1000!');  # will get a lot of stuff...

      # Advanced usage (manipulating Maple ASTs directly):
      $ast = $maple->to_ast('[1,2,3]');
      foreach ($ast->ops) {
          print;  # got 1, 2, and 3 respectively
      }

      # Get eval_cmd and other AUTOLOADed Maple function
      # to return ASTs automagically:
      $maple->ReturnAST(1);
      $ast = $maple->solve('x^2+x=0', 'x');
      if ($ast and $ast->type('exprseq')) {
        foreach ($ast->ops) {
            push @roots, $_;
        }
      }
      print "@roots";  # got: 0 -1

      $maple->ReturnAST(1);
      $res = $maple->solve('{x+y=2,x-y=3}', '{x,y}');
      if ($res->type('set')) {
          $x = first { $_->lhs eq 'x' } $res->ops;
          print $x->rhs;  # 5/2
      }

DESCRIPTION
    Maple is a great tool for solving mathematical problems and creating
    interactive technical applications provided by Maplesoft. Its power of
    symbolic calculation is extremely impressive.

    This is a simple (but already powerful) Perl binding for Maple's
    OpenMaple C interface. To try out this binding, you have to purchase and
    install the Maple software first:

    <http://www.maplesoft.com>.

    The Maple software is *not* free, sigh, unlike this CPAN distribution.

INSTALLATION
    Currently this software is only tested on Win32 against Maple 9.01 and
    Maple 10.00, but it's believed to work with other versions higher than
    9. If you get it work with a specific version of Maple, please send me a
    mail and let me know. :=)

    To build this module properly, you must first have Maple 9 or better
    installed on your system and append the paths of maplec.h and maplec.lib
    in your Maple installation to the environments LIB and INC respectively.
    Because this module use Maple's C interface (OpenMaple) via XS.

    Both maplec.h and maplec.lib (or maplec.a on *NIX systems?) are provided
    by your Maple installation itself. A typical path of maplec.h is
    "C:\Program Files\Maple 9\extern\include", which should be appended to
    the INCLUDE environment. And a typical path of maplec.lib is "C:\Program
    Files\Maple 9\bin.win", which should be appended to the LIB environment.
    These paths may be different on your machine but do depend on your
    Maple's version and location.

    It may be similar on UNIX, but I haven't tried that.

    It's known that this library's XS part won't work with Maple 7 on Win32.
    Sigh.

  EXPORT
    None by default.

METHODS
    PerlMaple uses AUTOLOAD mechanism so that any Maple functions are also
    valid methods of your PerlMaple object, even those Maple procedures
    defined by yourself.

    When the ReturnAST attribute is on, all AUTOLOADed methods, along with
    the "eval_cmd" method will return a PerlMaple::Expression object
    constructed from the resulting expression. Because there's a cost
    involved in constructing an AST from the given Maple expression, so the
    ReturnAST attribute is off by default.

    WARNING: The "eval" method is now incompatible with that of the first
    release (0.01). It is AUTOLOADed as the Maple counterpart. So you have
    to turn to "eval_cmd" when Maple's eval function can't fit your needs.
    Sorry.

    $obj->new()
    $obj->new(RaiseError => 0, PrintError => 1, ReturnAST => 0)
        Class constructor. It starts a Maple session if it does not exist.
        It should be noting that although you're able to create more than
        one PerlMaple objects, all these maple objects share the same Maple
        session. So the context of each PerlMaple objects may be corrupted
        intentionally. If any error occurs, this method will return undef
        value, and set the internal error buffer which you can read by the
        "error" method.

        This method also accepts two optional named arguments. When
        RaiseError is set true, the constructor sets the RaiseError
        attribute of the new object internally. And it is the same for the
        PrintError and ReturnAST attributes.

    $obj->eval_cmd($command)
        This method may be the most important one for the implementation of
        this class. It evaluates the command stored in the argument, and
        returns a string containing the result when the ReturnAST attribute
        is off. (It's off by default.) If an error occurs, it will return
        undef, and set the internal error buffer which you can read by the
        "error" method.

        Frankly speaking, most of the time you can use "eval" method instead
        of invoking this method directly. However, this method is a bit
        faster, because any AUTOLOADed method is invoked this one
        internally. Moreover, there exists something that can only be
        eval'ed properly by "eval_cmd". Here is a small example:

            $maple->eval_cmd(<<'.');
            lc := proc( s, u, t, v )
                     description "form a linear combination of the arguments";
                     s * u + t * v
            end proc;
            .

        If you use "eval" instead, you will get the following error message:

            `:=` unexpected

        That's because "eval" is a normal Maple function and hence you can't
        use assignment statement as the argument.

        When the ReturnAST attribute is on, this method will return a
        PerlMaple::Expression object constructed from the expression
        returned by Maple automatically.

    $obj->to_ast($maple_expr, ?$verified)
        This method is a shortcut for constructing a PerlMaple::Expression
        instance. For more information on the PerlMaple::Expression class
        and the second optional argument of this method, please turn to
        PerlMaple::Expression.

        Here is a quick demo to illustrate the power of the
        PerlMaple::Expression class (you can get many more in the doc for
        PerlMaple::Expression.

            $ast = $maple->to_ast('[1,2,3]');
            my @list;
            foreach ($ast->ops) {
                push @list, $_->expr;
            }
            # now @list contains numbers 1, 2, and 3.

    $obj->error()
        It returns the error message issued by the Maple kernel.

ATTRIBUTES
    All the attributes specified below can be set by passing name-value
    pairs to the "new" method.

    $obj->PrintError()
    $obj->PrintError($new_value)
        The PrintError attribute can be used to force errors to generate
        warnings (using Carp::carp) in addition to returning error codes in
        the normal way. When set ``on'' (say, a true value), any method
        which results in an error occurring will cause the PerlMaple to
        effectively do a "carp("PerlMaple error: ", $self->error, " when
        evaluating \"$exp\"";)". Any warnings from the Maple kernel will
        also be sent to stderr via carp if PrintError is on.

        By default, the constructor "new" sets PrintError ``on''.

    $obj->RaiseError()
    $obj->RaiseError($new_value)
        The RaiseError attribute can be used to force errors to raise
        exceptions rather than simply return error codes in the normal way.
        It is ``off'' (say, a false value in Perl) by default. When set
        ``on'', any method which results in an error will cause the
        PerlMaple to effectively do a "croak("PerlMaple error: ",
        $self->error, " when evaluating \"$exp\"";)".

        If you turn RaiseError on then you'd normally turn PrintError off.
        If PrintError is also on, then the PrintError is done first
        (naturally).

    $obj->ReturnAST()
    $obj->ReturnAST($new_value)
        The ReturnAST attribute can be used to force the "eval_cmd" method
        and hence all AUTOLOADed Maple functions to return a Abstract
        Syntactic Tree (AST). Because there is a cost to evaluate the
        "to_ast" method every time, so this attribute is off by default.

INTERNAL FUNCTIONS
    maple_error
        Returns the raw error message issued by the Maple kernel.

    maple_warning
        Returns the raw warning message returned by the Maple kernel.

    maple_eval
        Raw XS C method that evaluates any Maple commands.

    maple_result
        Returns the raw output of the Maple kernel.

    maple_start
        Starts the global Maple kernel. (No that all PerlMaple objects share
        the same Maple engine, so preventing context clashes is the duty of
        the user.

    maple_success
        Indicates whether the last Maple evaluation is successful.

CODE COVERAGE
    I use Devel::Cover to test the code coverage of my tests, below is the
    Devel::Cover report on this module's test suite (version 0.06):

        ---------------------------- ------ ------ ------ ------ ------ ------ ------
        File                           stmt   bran   cond    sub    pod   time  total
        ---------------------------- ------ ------ ------ ------ ------ ------ ------
        blib/lib/PerlMaple.pm          92.4   80.8   66.7  100.0  100.0  100.0   89.9
        ...b/PerlMaple/Expression.pm   98.7   88.9   66.7  100.0  100.0    0.0   94.6
        Total                          95.9   85.5   66.7  100.0  100.0  100.0   92.5
        ---------------------------- ------ ------ ------ ------ ------ ------ ------

BUGS
        At this point, every PerlMaple objects are merely a bunch of options
        (e.g. PrintError, RaiseError, and ReturnAST). They actually share
        the same Maple engine for performance reasons. So the evaluating
        contexts for each PerlMaple objects may corrupt together. So please
        don't store permanent values in Maple variables, avoid reference
        Maple special variables, like %, %%, and don't trust the Maple
        contexts. Since they may be changed accidentally by other PerlMaple
        objects, even those used by PerlMaple::Expression instances, in the
        duration.

TODO
    *   Add facilities to ease importing of Perl complex data structures to
        Maple environment, i.e. a list of lists of numbers.

    *   Port this binding to Linux Maple users and (hopefully) to MATLAB
        users as well.

    *   Add the "LogCommand" attribute so that PerlMaple will log down all
        the Maple commands sent to the Maple engine in disk files.

    *   Added PerlMaple::Cookbook and PerlMaple::Tutorial to the
        distribution. Programming Maple in Perl is extremely interesting and
        useful, so I believe these docs are really worth my while.

REPOSITORY
    You can always get the latest version from the following SVN repository:

    <https://svn.berlios.de/svnroot/repos/win32maple>

    If you want a committer bit, please let me know.

SEE ALSO
    PerlMaple::Expression, <http://www.maplesoft.com>.

AUTHOR
    Agent Zhang, <agentzh@gmail.com>

COPYRIGHT AND LICENSE
    Copyright (C) 2005-2006 Agent Zhang

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

