lib/simplifyExpression/distributeSearch/index.js
// Returns a Node.Status object with substeps
Returns a Node.Status object with substeps
Returns a Node . Status object with substeps
function distributeAndSimplifyMultiplication(node) {
  if (!Node.Type.isOperator(node) || node.op !== '*') {
    return Node.Status.noChange(node);
  }
  for (let i = 0; i+1 < node.args.length; i++) {
    if (!isParenthesisOfAddition(node.args[i]) &&
        !isParenthesisOfAddition(node.args[i+1])) {
      continue;
    }
    let newNode = node.cloneDeep();
    const substeps = [];
    let status;
    const combinedNode = distributeTwoNodes(newNode.args[i], newNode.args[i+1]);
    node.args[i].changeGroup = 1;
    node.args[i+1].changeGroup = 1;
    combinedNode.changeGroup = 1;
    if (newNode.args.length > 2) {
      newNode.args.splice(i, 2, combinedNode);
      newNode.args[i].changeGroup = 1;
    }
    else {
      newNode = combinedNode;
      newNode.changeGroup = 1;
    }
    status = Node.Status.nodeChanged(
      ChangeTypes.DISTRIBUTE, node, newNode, false);
    substeps.push(status);
    newNode = Node.Status.resetChangeGroups(status.newNode);
    if (Node.Type.isOperator(newNode, '*')) {
      const childStatus = simplifyWithParens(newNode.args[i]);
      if (childStatus.hasChanged()) {
        status = Node.Status.childChanged(newNode, childStatus, i);
        substeps.push(status);
        newNode = Node.Status.resetChangeGroups(status.newNode);
      }
    }
    else if (Node.Type.isParenthesis(newNode)){
      status = simplifyWithParens(newNode);
      if (status.hasChanged()) {
        substeps.push(status);
        newNode = Node.Status.resetChangeGroups(status.newNode);
      }
    }
    else {
      throw Error('Unsupported node type for distribution: ' + node);
    }
    if (substeps.length === 1) {
      return substeps[0];
    }
    return Node.Status.nodeChanged(
      ChangeTypes.DISTRIBUTE, node, newNode, false, substeps);
  }
  return Node.Status.noChange(node);
}
function distributeAndSimplifyMultiplication ( node ) { if ( ! Node . Type . isOperator ( node ) || node . op !== '*' ) { return Node . Status . noChange ( node ) ; } for ( let i = 0 ; i + 1 < node . args . length ; i ++ ) { if ( ! isParenthesisOfAddition ( node . args [ i ] ) && ! isParenthesisOfAddition ( node . args [ i + 1 ] ) ) { continue ; } let newNode = node . cloneDeep ( ) ; const substeps = [ ] ; let status ; const combinedNode = distributeTwoNodes ( newNode . args [ i ] , newNode . args [ i + 1 ] ) ; node . args [ i ] . changeGroup = 1 ; node . args [ i + 1 ] . changeGroup = 1 ; combinedNode . changeGroup = 1 ; if ( newNode . args . length > 2 ) { newNode . args . splice ( i , 2 , combinedNode ) ; newNode . args [ i ] . changeGroup = 1 ; } else { newNode = combinedNode ; newNode . changeGroup = 1 ; } status = Node . Status . nodeChanged ( ChangeTypes . DISTRIBUTE , node , newNode , false ) ; substeps . push ( status ) ; newNode = Node . Status . resetChangeGroups ( status . newNode ) ; if ( Node . Type . isOperator ( newNode , '*' ) ) { const childStatus = simplifyWithParens ( newNode . args [ i ] ) ; if ( childStatus . hasChanged ( ) ) { status = Node . Status . childChanged ( newNode , childStatus , i ) ; substeps . push ( status ) ; newNode = Node . Status . resetChangeGroups ( status . newNode ) ; } } else if ( Node . Type . isParenthesis ( newNode ) ) { status = simplifyWithParens ( newNode ) ; if ( status . hasChanged ( ) ) { substeps . push ( status ) ; newNode = Node . Status . resetChangeGroups ( status . newNode ) ; } } else { throw Error ( 'Unsupported node type for distribution: ' + node ) ; } if ( substeps . length === 1 ) { return substeps [ 0 ] ; } return Node . Status . nodeChanged ( ChangeTypes . DISTRIBUTE , node , newNode , false , substeps ) ; } return Node . Status . noChange ( node ) ; }
Returns a Node.Status object with substeps
Returns a Node . Status object with substeps
// STEP 1: distribute with `distributeTwoNodes` // e.g. x*(2+x) -> x*2 + x*x // STEP 2: simplifications of each operand in the new sum with `simplify` // e.g. x*2 + x*x -> ... -> 2x + x^2 // case 1: there were more than two operands in this multiplication // e.g. 3*7*(2+x)*(3+x)*(4+x) is a multiplication node with 5 children // and the new node will be 3*(14+7x)*(3+x)*(4+x) with 4 children. // case 2: there were only two operands and we multiplied them together. // e.g. 7*(2+x) -> (7*2 + 7*x) // Now we can just simplify it.