nl_tokens: integral ( f ( a * x + b ) x ) = 1 / a * F ( a * x + b ) where F ( u ) = integral ( f ( u ) u ) We also only handle the case where u shows up only once in f ( u )
pl_tokens: function ( expr , context , subIntegral ) { var createIntegralWrapper = null ; var uniqueParent = getParentOfUniqueVariable ( expr ) ; if ( uniqueParent !== null && uniqueParent . type === "OperatorNode" ) { if ( uniqueParent . op === '+' || uniqueParent . op === '-' ) { if ( uniqueParent . args . length === 1 ) { // unary + or - createIntegralWrapper = function ( int ) { return new OperatorNode ( uniqueParent . op , uniqueParent . fn , [ int ] ) ; } } else { createIntegralWrapper = function ( int ) { return int ; } } } else if ( uniqueParent . op === '*' ) { createIntegralWrapper = function ( int ) { return new OperatorNode ( '/' , 'divide' , [ int , // "remove" the variable of integration replaceNodeInTree ( uniqueParent , context . variable , new ConstantNode ( 1 ) ) ] ) ; } ; } if ( createIntegralWrapper !== null ) { var preIntegral = replaceNodeInTree ( expr , uniqueParent , context . variable . clone ( ) ) ; var int = subIntegral ( preIntegral , context , "linear substitution" ) ; if ( int ) { var backSubstituted = replaceNodeInTree ( int , context . variable , uniqueParent ) ; return createIntegralWrapper ( backSubstituted ) ; } } } function replaceNodeInTree ( expr , node , replacement ) { return replaceHelper ( expr ) ; function replaceHelper ( curNode ) { return node . equals ( curNode ) ? replacement : curNode . map ( replaceHelper ) ; } } function getParentOfUniqueVariable ( expr ) { return helper ( expr , null ) ; function helper ( expr , parent ) { if ( context . isConstant ( expr ) ) { return null ; } else if ( expr . type === "SymbolNode" && expr . name === <mask> . variable . name ) { return parent ; } else { var nonConstantChildren = [ ] ; expr . forEach ( function ( child ) { if ( ! context . isConstant ( child ) ) { nonConstantChildren . push ( child ) ; } } ) ; if ( nonConstantChildren . length === 1 ) { return helper ( nonConstantChildren [ 0 ] , expr ) ; } else { return null ; } } } } }