Porting Rubi Integration rules to Symja - axkr/symja_android_library GitHub Wiki

From the Rubi website:

Rubi is an extensive system of symbolic integration rules that can be systematically applied to determine the antiderivative of a wide variety of mathematical expressions. Organized as a decision tree based on the form of the integrand, the 6600+ rules Rubi uses can be viewed in human-readable form or downloaded in machine-readable form.

The Symja project has ported these Rubi rules into an internal Java based structure. This wiki page describes how to create these Java rules.

The Java converter programs are maintained in the tools package: org.matheclipse.core.rubi.

The converter include 2 programs which generate Java files for the Symja package org.matheclipse.core.integrate.rubi

  • the converter ConvertRubi.java for converting the Rubi integration rules /Rubi/RubiRules4.16.0_FullLHS.m into Java source codes IntRuleXXX (XXX counter for generated source files).
  • the converter ConvertRubiUtilityFunctions.java for converting the Rubi utility function rules /Rubi/IntegrationUtilityFunctions.m into Java source codes UtilityFunctionsXXX (XXX counter for generated source files).

The generated rules for the package org.matheclipse.core.integrate.rubi are loaded in the Integrate#setUp() method.

Notes:

  • in the file RubiRules4.16.0_FullLHS.m the line number in which a rule appears corresponds to the Rubi rule number.
  • the priority in which a rule is used in the pattern-matching corresponds to the Rubi rule number.

The JUnit Rubi tests suite include the following files (not working completly at the moment; see failed_rubi_tests.txt):

Rule-preparation and JUnit creation from within Mathematica

The full-form of all Rubi rules is directly created from the within Mathematica's internal DownValues to ensure that they are in the correct order and that we are working with the exact same syntax, that Mathematica sees. We store the rules on separate lines in the form lhs := rhs, where lhs is the FullForm of the left-hand-side of the rule and rhs is the right-hand-side in InputForm. We do this to be absolutely sure that SymJa gets the correct pattern in lhs. If any problems appear, we could use FullForm for the rhs as well, but this would substentially increase the file-size.

The conversion consists of the following steps

  1. Load Rubi with the complete set of rules and with $LoadShowSteps = False
  2. Define helper functions that return strings in FullForm and InputForm without evaluating and make a function to replace symbols from the private context with their normal names: ``RubiPrivatesymbol` -> `symbol`
  3. Convert all Int downvalues to strings and export them as one big file
$LoadShowSteps = False;
<< Rubi`

$dv = DownValues[Int];

fullFormString[Hold[expr_]] := ToString[Unevaluated[FullForm[expr]]];
inputFormString[Hold[expr_]] := ToString[Unevaluated[expr], InputForm];
replaceContext[Hold[expr_]] :=  Hold[expr] /. s_Symbol /; Context[s] === "Rubi`Private`" :> 
   With[{ss = Symbol[SymbolName[s]]}, ss /; True]

convert[Verbatim[HoldPattern][lhs_] :> rhs_] := With[{
    l = replaceContext[Hold[lhs]],
    r = replaceContext[Hold[rhs]]
    },
   convert[fullFormString[l], inputFormString[r]]
   ];
convert[lstr_String, rstr_String] := StringTemplate["`lhs` := `rhs`"]@Association[
   "lhs" -> lstr,
   "rhs" -> rstr
   ]

Export["~/tmp/RubiRules.txt", StringRiffle[convert /@ $dv, "\n"]];