// 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] }