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 codesIntRuleXXX
(XXX
counter for generated source files). - the converter
ConvertRubiUtilityFunctions.java
for converting the Rubi utility function rules/Rubi/IntegrationUtilityFunctions.m
into Java source codesUtilityFunctionsXXX
(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):
- AlgebraicFunctions
- Exponentials
- HyperbolicFunctions
- IndependentTestSuites
- InverseHyperbolicFunctions
- InverseTrigFunctions
- Logarithms
- SpecialFunctions
- TrigFunctions
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
- Load Rubi with the complete set of rules and with
$LoadShowSteps = False
- Define helper functions that return strings in
FullForm
andInputForm
without evaluating and make a function to replace symbols from the private context with their normal names: ``RubiPrivate
symbol` -> `symbol` - 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"]];