Working with Groovy

Note: the functionality described in this article is not released yet.

Contents


Getting the current MathEclipse Groovy DSL

From version 0.0.7 on the MathEclipse scripting engine contains a basic domain specific language (DSL) for implementing symbolic math functions in Groovy.

I've uploaded a first test version here:

This version contains an Eclipse Groovy project named org.matheclipse.groovy.function with some basic tests for the DSL. The groovy JAR file (currently groovy-all-1.5.1.jar) is currently not included.

MathEclipse DSL definitions

There are three parts which define the DSL:

  1. the DSL.groovy definition for adding behaviour to the Groovy Integer class.
  2. the F.java file defines a lot of static methods like (Cos(), Sin(), D(), Expand(), Factor(),...) for easier expression building.
  3. the IExpr.java implementation of the following method signatures for operator overloading:

	//
	// Groovy operator overloading
	//
	public boolean isCase(IExpr that);

	public IExpr negative();

	public IExpr plus(final IExpr that);

	public IExpr minus(final IExpr that);

	public IExpr multiply(final IExpr that);

	public IExpr power(final Integer n);

	public IExpr power(final IExpr that);

	public IExpr div(final IExpr that);

	public IExpr mod(final IExpr that);

	public IExpr and(final IExpr that);

	public IExpr or(final IExpr that);

	public IExpr getAt(final int index);

DSL tests

This is a simple example for a new MathEclipse function called DSLTest[<argument>]. For a given argument it returns some new symbolic math expressions:

package org.matheclipse.groovy.system

import org.matheclipse.core.eval.interfaces.*;
import org.matheclipse.core.interfaces.*;
import org.matheclipse.core.eval.*;
import org.matheclipse.core.expression.*;
import static org.matheclipse.core.expression.F.*;
import static org.matheclipse.core.interfaces.AbstractExpressionFactory.*;

class DSLTest extends AbstractArg1 {
	public IExpr e1ObjArg(final IExpr o) {
		F factory = EvalEngine.get().getExpressionFactory();
		ISymbol x = factory.createSymbol("x");
		switch(o){ 
		case 1:
			return True;
		case 2:
			return LessEqual(o,3.v);
		case 3: 
			// generate a derivative:
			return D(Sin(x)**Cos(x),x);
		case 4:
			// Factor a simple polynomial
			return Factor(4+x**2+2*x+3*x**3);
		case 5:
			// "Expand a polynomial
			return Expand((1+x)*(4-2*x+3*x**2));
		}
		// some combinations for tests
		return -Sin(4.v-o)*Cos(4+o)[1]**2; 
	}
}

The Test.groovy source below shows how a complete org.matheclipse.groovy.syste package of such Groovy functions could be integrated into the MathEclipse namespace. The scripting engine's eval() call examples show how the DSLTest[ ] function is called from a MathEclipse script:

package org.matheclipse.groovy.dsl

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.matheclipse.core.eval.SystemNamespace;
import org.matheclipse.core.interfaces.*;

class Test {
	static void main(args) {
		// this adds the package for new functions implemented in Groovy to the MathEclipse namespace:
		SystemNamespace.DEFAULT.add("org.matheclipse.groovy.system");
		// load the MathEclipse JSR 223 scripting engine (requires Java version >= 1.6)
	    ScriptEngineManager scriptManager = new ScriptEngineManager();

	    String stringResult = null;
	    ScriptEngine meEngine = scriptManager.getEngineByExtension("m");
	    try {
				stringResult = (String) meEngine.eval("DSLTest[1]");
				System.out.println(stringResult);
			} catch (Exception ex) {
				System.out.println(ex.getMessage());
			}
		try {
				stringResult = (String) meEngine.eval("DSLTest[2]");
				System.out.println(stringResult);
		} catch (Exception ex) {
				System.out.println(ex.getMessage());
		} 
		try {
			stringResult = (String) meEngine.eval("DSLTest[3]");
			System.out.println(stringResult);
	    } catch (Exception ex) {
			System.out.println(ex.getMessage());
	    }  
	    try {
		    stringResult = (String) meEngine.eval("DSLTest[4]");
			System.out.println(stringResult);
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		} 
		try {
	       stringResult = (String) meEngine.eval("DSLTest[5]");
		   System.out.println(stringResult);
	    } catch (Exception ex) {
		    System.out.println(ex.getMessage());
	    } 
	    try { 
			stringResult = (String) meEngine.eval("DSLTest[f[x]]");
			System.out.println(stringResult);
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}
}

To Do

Determine best syntax for

  • pattern symbols in pattern matching rules like f[x_,y_,z_]:={x,y,z}?
  • matrices which are seen as a list of vector lists with the same length in MathEclipse (example: {{1, 2, 3}, {3, 4, 11}, {13, 7, 8}} )