// This file contains transformation rules suitable for finding
// integrals of expressions.
//
// At the moment, this is just a proof of concept. Further development
// will probably use the very nice set of rules derived by Albert D. Rich
// for computer-based evaluation of integrals:
//
// http://www.apmaths.uwo.ca/~arich/index.html
//
// It appears possible to use his machine-readable rules written for
// Mathematica and transform them automatically into Frink (some mathematical
// functions will of course need to be added.)
//
// Perhaps a better method will involve Risch integration which is very
// complex to implement but provides a decision procedure which can decide
// if an expression *can* be integrated.
//
transformations integrals
{
// Multiple integrals
// Bail-out condition for first integral
Integrate[_n, _x, 1] <-> Integrate[_n, _x]
// Otherwise take one integral and decrement.
Integrate[_n, _x, _times is isInteger] <-> Integrate[Integrate[_n,_x], _x, _times-1]
// Integrate both sides of an equation.
Integrate[_a === _b, _x] <-> Integrate[_a, _x] === Integrate[_b, _x]
// Expression entirely free of x
Integrate[_a, _x] :: freeOf[_a, _x] <-> _a _x
// Separate out multiplicative parts that are free of x
Integrate[_a _b, _x] :: freeOf[_a, _x] and expressionContains[_b, _x] <-> _a Integrate[_b, _x]
// Chain rules for sums
Integrate[_a + _b, _x] <-> Integrate[_a, _x] + Integrate[_b, _x]
// Powers of x
Integrate[_x^(_y:1), _x] :: _y != -1 <-> _x^(_y+1)/(_y+1)
// Special case of 1/x (also written as x^-1)
Integrate[_x^-1, _x] <-> ln[_x]
// b^(a x)
Integrate[_b^((_a:1) _x), _x] :: freeOf[_b,_x] and freeOf[_a, _x] <-> _b^(_a _x) / (_a ln[_b])
// ln[x]
Integrate[ln[_x], _x] <-> _x ln[_x] - _x
// Trigonometric functions
Integrate[sin[(_a:1) _x], _x] :: freeOf[_a,_x] <-> -1/_a cos[_a _x]
Integrate[cos[(_a:1) _x], _x] :: freeOf[_a,_x] <-> 1/_a sin[_a _x]
Integrate[tan[(_a:1) _x], _x] :: freeOf[_a,_x] <-> -1/_a ln[cos[_a _x]]
Integrate[sec[(_a:1) _x]^2, _x] :: freeOf[_a,_x] <-> 1/_a tan[_a _x]
Integrate[(1/cos[(_a:1) _x])^2, _x] :: freeOf[_a,_x] <-> 1/_a tan[_a _x]
Integrate[sin[_x] / (1-sin[_x]^2), _x] :: freeOf[_a,_x] <-> sec[_x]
Integrate[sin[_a _x] / (1-sin[_a _x]^2), _x] :: freeOf[_a,_x] <-> sec[_a _x]
// Definite integral.
// This is inefficient because it has to integrate the same expression twice.
// We need a way to define a variable and use that twice. And the
// substituteExpression is awkward, as it's not evaluated until an eval is
// called on the expression.. We need an operator form that is
// replaced at transformation time.
Integrate[_n, _x, _fromX, _toX] <-> substituteExpression[Integrate[_n, _x], _x, _toX] - substituteExpression[Integrate[_n, _x], _x, _fromX]
// Multiple definite integral
// Otherwise take one integral and decrement.
Integrate[_n, _x, _times is isInteger, _fromX, _toX] <-> substituteExpression[Integrate[_n, _x, _times], _x, _toX] - substituteExpression[Integrate[_n, _x, _times], _x, _fromX]
/* Integration by parts.
"When you apply integration by parts, there is
usually a choice of what to call u and what to call dv. The "LIATE"
heuristic provides a suggestion of how to do that. It doesn't always work,
but it works so often that it is worth remembering and using it as the
first attempt.
LIATE stands for:
Logarithmic
Inverse trigonometric
Algebraic
Trigonometric
Exponential
The heuristic says: when there are two factors in the integrand, choose u
as the one furthest to the left in LIATE and choose dv as the one furthest
to the right.
https://en.wikipedia.org/wiki/Integration_by_parts#LIATE_rule
TODO: Complete this. The problem is that if you choose poorly, this will
loop forever.
*/
// Note that this solves an integral twice.
// Integrate[_v _u, _x] <-> _u Integrate[_v, _x] - Integrate[D[_u, _x] * Integrate[_v, _x], _x]
}