//Exp( p ) is // var t : Tree // t := P // while next is a binary operator and prec(binary(next)) >= p // const op := binary(next) // consume // const q := case associativity(op) // of Right: prec( op ) // Left: 1+prec( op ) // const t1 := Exp( q ) // t := mkNode( op, t, t1) // return t private Expression Exp(int p) { Expression l = P(); Operator op = new Operator(); while (true) { if (IsBinaryOperator(tokens.Tok, ref op) && Precedence(op) >= p) { tokens.Consume(); int q = Precedence(op) + (IsLeftAssociative(op) ? 1 : 0); Expression r = Exp(q); l = Binary.New(op, l, r); } else if (IsUnaryPostOperator(tokens.Tok, ref op) && Precedence(op) >= p) { tokens.Consume(); l = Unary.New(op, l); } else { break; } } return(l); }
private static Expression Split(Expression P) { int child = 0; if (P is Sum) { return(ComputerAlgebra.Sum.New(((ComputerAlgebra.Sum)P).Terms.Select(i => ChildPattern(ref child)))); } if (P is Product) { return(Product.New(((Product)P).Terms.Select(i => ChildPattern(ref child)))); } if (P is Binary) { return(Binary.New(((Binary)P).Operator, ChildPattern(ref child), ChildPattern(ref child))); } if (P is Unary) { return(Unary.New(((Unary)P).Operator, ChildPattern(ref child))); } if (P is Call) { return(Call.New(((Call)P).Target, ((Call)P).Arguments.Select(i => ChildPattern(ref child)))); } return(null); }
/// <summary> /// Distribute products across sums, using partial fractions if necessary. /// </summary> /// <param name="x"></param> /// <returns></returns> public static Expression Expand(this Expression f, Expression x) { if (f is Product) { return(ExpandMultiply(f, x)); } else if (f is Sum) { return(Sum.New(((Sum)f).Terms.Select(i => i.Expand(x)))); } else if (f is Power) { return(ExpandPower((Power)f, x)); } else if (f is Binary) { return(Binary.New(((Binary)f).Operator, ((Binary)f).Left.Expand(), ((Binary)f).Right.Expand())); } else if (f is Unary) { return(Unary.New(((Unary)f).Operator, ((Unary)f).Operand.Expand())); } return(f); }
/// <summary> /// Distribute products across sums, using partial fractions if necessary. /// </summary> /// <param name="x"></param> /// <returns></returns> public static Expression Expand(this Expression f, Expression x) { if (f is Product) { return(ExpandMultiply(f, x)); } else if (f is Sum sum) { return(Sum.New(sum.Terms.Select(i => i.Expand(x)))); } else if (f is Power power) { return(ExpandPower(power, x)); } else if (f is Binary binary) { return(Binary.New(binary.Operator, binary.Left.Expand(x), binary.Right.Expand(x))); } else if (f is Unary unary) { return(Unary.New(unary.Operator, unary.Operand.Expand())); } return(f); }
protected override Expression VisitUnary(Unary U) { Expression O = Visit(U.Operand); if (ReferenceEquals(O, null)) { return(null); } if (ReferenceEquals(O, U.Operand)) { return(U); } else { return(Unary.New(U.Operator, O)); } }
protected override Expression VisitUnary(Unary U) { Expression O = Visit(U.Operand); Real? C = AsReal(O); switch (U.Operator) { case Operator.Not: if (IsTrue(C)) { return(Constant.New(false)); } else if (IsFalse(C)) { return(Constant.New(true)); } break; } return(Unary.New(U.Operator, O)); }
//P is // if next is a unary operator // const op := unary(next) // consume // q := prec( op ) // const t := Exp( q ) // return mkNode( op, t ) // else if next = "(" // consume // const t := Exp( 0 ) // expect ")" // return t // else if next is a v // const t := mkLeaf( next ) // consume // return t // else // error private Expression P() { Operator op = new Operator(); if (tokens.Tok == "+") { // Skip unary +. tokens.Consume(); return(P()); } else if (IsUnaryPreOperator(tokens.Tok, ref op)) { // Unary operator. tokens.Consume(); Expression t = Exp(Precedence(op)); return(Unary.New(op, t)); } else if (tokens.Tok == "(") { // Group. tokens.Consume(); Expression t = Exp(0); tokens.Expect(")"); return(t); } else if (tokens.Tok == "{") { // Set. tokens.Consume(); return(Set.New(L(",", "}"))); } else if (tokens.Tok == "[") { // Matrix. tokens.Consume(); List <List <Expression> > entries = new List <List <Expression> >(); while (tokens.Tok == "[") { tokens.Consume(); entries.Add(L(",", "]")); } tokens.Expect("]"); return(Matrix.New(entries)); } else { string tok = tokens.Consume(); decimal dec = 0; double dbl = 0.0; if (decimal.TryParse(tok, NumberStyles.Float, culture, out dec)) { return(Constant.New(dec)); } if (double.TryParse(tok, NumberStyles.Float, culture, out dbl)) { return(Constant.New(dbl)); } else if (tok == "True") { return(Constant.New(true)); } else if (tok == "False") { return(Constant.New(false)); } else if (tok == "\u221E" || tok == "oo") { return(Constant.New(Real.Infinity)); } else if (tokens.Tok == "[") { // Bracket function call. tokens.Consume(); List <Expression> args = L(",", "]"); return(Call.New(Resolve(tok, args), args)); } else if (tokens.Tok == "(") { // Paren function call. tokens.Consume(); List <Expression> args = L(",", ")"); return(Call.New(Resolve(tok, args), args)); } else { return(Resolve(tok)); } } }