private Expression.Expression ConvertSubtraction(SubtractionNode node)
 {
     return(new Subtraction
     {
         Left = ConvertToExpression(node.Left),
         Right = ConvertToExpression(node.Right)
     });
 }
        public override ASTNode VisitBinaryOperatorExpression(EquationGrammarParser.BinaryOperatorExpressionContext context)
        {
            InfixExpressionNode node;
            int type = context.op.Type;

            switch (type)
            {
            case EquationGrammarLexer.CARET:
                node = new PowerNode();
                break;

            case EquationGrammarLexer.PLUS:
                node = new AdditionNode();
                break;

            case EquationGrammarLexer.MINUS:
                node = new SubtractionNode();
                break;

            case EquationGrammarLexer.ASTERISK:
                node = new MultiplicationNode();
                break;

            case EquationGrammarLexer.DIVISION:
                node = new DivisionNode();
                break;

            default:
                throw new NotSupportedException();
            }
            node.Left     = (ExpressionNode)Visit(context.left);
            node.Right    = (ExpressionNode)Visit(context.right);
            node.Line     = context.start.Line;
            node.Position = context.start.Column;
            return(node);
        }
        private NonlinearEquationDescription CompileEquations(RootNode root)
        {
            List <RPNExpression>         rpnEquations = new List <RPNExpression>();
            List <Expression.Expression> equations    = new List <Expression.Expression>();

            foreach (var constant in root.constants)
            {
                Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(constant.Right));
                //ExpressionNode right = simplify(constant.Right);
                if (right is Float)
                {
                    constants.Add(constant.Identifier, ((Float)right).Value);
                }
                else
                {
                    constants.Add(constant.Identifier, float.NaN);
                    compilerErrors.Add(new ErrorMessage("Определение константы " + constant.Identifier + " не является константным выражением"));
                }
            }

            foreach (var equation in root.equations)
            {
                SubtractionNode subtraction = new SubtractionNode
                {
                    Left     = equation.Left,
                    Right    = equation.Right,
                    Line     = equation.Line,
                    Position = equation.Position
                };
                Expression.Expression expression = ExpressionSimplifier.Simplify(ConvertToExpression(subtraction));
                equations.Add(expression);
            }

            //initialValues aren't important
            foreach (var initialValue in root.initialValues)
            {
                if (variables.ContainsKey(initialValue.Identifier))
                {
                    Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(initialValue.Right));
                    //Expression expression = ConvertToExpression(right)
                    if (right is Float)
                    {
                        initialValues[variables[initialValue.Identifier]] = ((Float)right).Value;
                    }
                    else
                    {
                        //add error message
                        compilerErrors.Add(new ErrorMessage("Определение начального приближения переменной" +
                                                            initialValue.Identifier + " не является константным выражением"));
                    }
                }
                else
                {
                    //add error message
                    compilerErrors.Add(new ErrorMessage("Определение начального приближения несуществующей переменной"));
                }
            }
            //check that number of variables = number of equations
            if (variableNames.Count != equations.Count)
            {
                compilerErrors.Add(new ErrorMessage($"Количество переменных не совпадает с количеством уравнений: {variableNames.Count} переменных, {equations.Count} уравнений"));
            }
            if (equations.Count == 0)
            {
                compilerErrors.Add(new ErrorMessage("Пустая система уравнений"));
            }
            if (compilerErrors.Count > 0)
            {
                throw new CompilerException(compilerErrors);
                //fall back;
            }
            Expression.Compiler expCompiler = new Expression.Compiler(variables);
            for (int i = 0; i < equations.Count; i++)
            {
                rpnEquations.Add(expCompiler.Compile(equations[i]));
            }
            RPNExpression [,] jacobiMatrix = new RPNExpression[equations.Count, equations.Count];
            Expression.DifferentiationVisitor difVisitor = new Expression.DifferentiationVisitor();
            int j = 0;

            foreach (var equation in equations)
            {
                int i = 0;
                foreach (var variable in variableNames)
                {
                    //find derivative for variable
                    Expression.Expression derivative = ExpressionSimplifier.Simplify(difVisitor.Differentiate(equation, variable));
                    //simplify derivative expression
                    RPNExpression exp = expCompiler.Compile(derivative);
                    jacobiMatrix[i, j] = exp;
                    i++;
                }
                j++;
            }
            NonlinearEquationDescription ned = new NonlinearEquationDescription(initialValues.ToArray(), variableNames.ToArray(),
                                                                                rpnEquations, jacobiMatrix);

            return(ned);
        }