Gluing external functions in the interpreter

In order to glue C++ functions in the mathemagix interpretor, the steps are needed:

  1. Write mmx files which define the correspondance between the mathemagix functions and the C++ functions.

  2. Generate cpp files from the mmx files using autoglue, to define the glue functions.

  3. Compile the generated cpp files to build the dynamic library to be loaded in the interpretor.

1.The mmx dictionnary files

The mmx files for the correspondance between the mathemagix functions and the external functions in the mathemagix interpretor are put in the folder glue. Here is a first example.

require "basix/glue_double.mmx";

foreign cpp import {
  cpp_include "my_fct.hpp";
  
  f : Double  -> Double == my_fct; 
}

In this example, the function f of the interpretor uses the C++ function

double my_fct(double)

declared in the file my_fct.hpp.

A important rule to keep in mind is the following:

The glue of a function is generated iff the types in its signature are specialized.

In our example, the inclusion of the file basix/glue_double.mmx defines the required specialization for the type Double, so that the fonction f will be defined.

Here is a second example:

foreign cpp import {
  cpp_preamble /"
     using namespace std;
     inline double make_tropical(double x) {return x;}
  "/;
  class Tropical == double;
  tropical : Tropical  -> Tropical == make_tropical; 
  infix +: (Tropical, Tropical) -> Tropical == max;
  infix *: (Tropical, Tropical) -> Tropical == infix +;
}
specialize Tropical;

We define a new type Tropical in the interpretor, which is implemented in C++ as double. We define a function tropical which corresponds to the C++ function make_tropical and operators + corresponding to max and * corresponding to the C++ operator +. The function make_tropical is defined in the preamble part which will copied verbatim in the generated glue file. The specialize instruction is needed to generate the glue for all these functions. These functions can be used in the mathemagix as follows:

a: Tropical := tropical(2.2);
b: Tropical := tropical(0.1);
a+b;
a*b;

In the next example, we glue template functions:

include "basix/categories.mmx
require "basix/glue_int.mmx";
require "basix/glue_double.mmx";

foreign cpp import {
  cpp_preamble /"using namespace std;"/;
  cpp_include "dual_number.hpp";
  
  forall(C: Class) {
    class Dual C == pair C;
    dual : (C,C) -> Dual C == pair C; 
  }
  
  forall(C: Ring) { 
    infix +: (Dual C, Dual C)  -> Dual C == dual_add;
    infix *: (Dual C, Dual C)  -> Dual C == dual_mul ;
  } 
  
  forall(C: Field) {
    infix /: (Dual C, Dual C)  -> Dual C == dual_div ;
  }
}

specialize Dual Int;
specialize Dual Double;

In this example, the parameterised type Dual C of dual numbers is implemented as std::pair<C>. The constructor dual is valid for any type of coefficients C, but the operators + and * are glued only if C is a ring (here for Int and Double) whereas the link of the operator / is valid is C is a field (here for Double). The glue of these functions is generated throught the instructions specialize Dual Int; specialize Dual Double;

2.Generating the glue files

Supose that the name of the package is pkg. By convention, the glue files which provide specialization should be put in the folder pkg/glue. Then running

mmxglue

in the folder pkg will generate the corresponding cpp glue files in the folder pkg/glue. The CMakeLists.txt will be uptable. To generate the dynamic library which can be uploaded in the interpretor, the following command can be run:

cmake ../pkg -DGLUE=ON && make

The library libmmxpkg(.so,.dyl) will be compiled in the local folder lib and can be loaded with

use "tropical";

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License. If you don't have this file, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.