예제 #1
0
		public MathFunc(string str, string v = null, bool simplify = true, bool precompile = false)
		{
			if (!Helper.Parser.Parse(str))
				throw new Exception("Impossible to parse input string");

			LeftNode = Helper.Parser.FirstStatement.LeftNode;
			RightNode = Helper.Parser.FirstStatement.RightNode;
			Root = RightNode;

			if (string.IsNullOrEmpty(v))
				ConstToVars();
			else
			{
				Variable = new VarNode(v);
				ConstToVar(Root);
			}

			FindParamsAndUnknownFuncs(Root);

			Root.Sort();
			if (simplify)
				Root = Simplify(Root);
			if (precompile)
				Root = Precompile(null, Root);
		}
예제 #2
0
		public MathFunc(MathFuncNode root, 
			VarNode variable = null, IEnumerable<ConstNode> parameters = null,
			bool calculateConstants = false, bool simplify = false)
			: this(new FuncNode("f", new List<MathFuncNode>() { variable }), root, variable, parameters,
				calculateConstants, simplify)
		{
		}
		private MathFuncNode Precompile(MathFuncNode parent, MathFuncNode node)
		{
			if (node.Type == MathNodeType.Value)
				return new CalculatedNode(((ValueNode)node).Value);
			else if (node.Type == MathNodeType.Function)
			{
				for (int i = 0; i < node.Childs.Count; i++)
					node.Childs[i] = Precompile(node, node.Childs[i]);

				FuncNode func = (FuncNode)node;
				switch (func.FunctionType)
				{
					case KnownFuncType.Add:
						node = PrecompileAddFunc(func);
						break;

					case KnownFuncType.Mult:
						node = PrecompileMultFunc(func);
						break;

					case KnownFuncType.Pow:
						node = PrecompileExpFunc(parent, func);
						break;
				}

				if (node.Childs.Count > 0 && node.Childs.All(child => child.Type == MathNodeType.Value || child.Type == MathNodeType.Calculated))
					return (MathFuncNode)CalculateValues(((FuncNode)node).FunctionType, node.Childs) ?? (MathFuncNode)node;
				else
					return node;
			}
			else
				return node;
		}
		private void GetDerivatives(MathFuncNode root)
		{
			for (int i = 0; i < root.Childs.Count; i++)
				if (root.Childs[i].Type == MathNodeType.Function)
					if (((FuncNode)root.Childs[i]).FunctionType == KnownFuncType.Diff)
						root.Childs[i] = GetDerivative(root.Childs[i].Childs[0]);
					else
						GetDerivatives(root.Childs[i]);
		}
		private bool ContainsNaNHelper(MathFuncNode node)
		{
			for (int i = 0; i < node.Childs.Count; i++)
				if (ContainsNaNHelper(node.Childs[i]))
					return true;

			CalculatedNode calcNode = node as CalculatedNode;
			if (calcNode != null && double.IsNaN(calcNode.DoubleValue))
				return true;
			else
				return false;
		}
    protected void PushFunction(string mathFunction)
    {
        var lastArgsCount = ArgsCount[ArgsCount.Count - 1];
        var args          = new MathFuncNode[lastArgsCount];

        for (int i = 0; i < lastArgsCount; i++)
        {
            args[lastArgsCount - 1 - i] = Nodes.Pop();
        }

        Nodes.Push(new FuncNode(mathFunction, args));
        ArgsCount.RemoveAt(ArgsCount.Count - 1);
        ArgsFuncTypes.RemoveAt(ArgsFuncTypes.Count - 1);
    }
		private MathFuncNode GetDerivative(MathFuncNode node)
		{
			switch (node.Type)
			{
				case MathNodeType.Calculated:
					return new CalculatedNode(0.0);
				case MathNodeType.Value:
				case MathNodeType.Constant:
					return new ValueNode(0);
				case MathNodeType.Variable:
					return new ValueNode(1);
				case MathNodeType.Function:
					return GetFuncDerivative((FuncNode)node);
			}
			return null;
		}
예제 #8
0
		public MathFunc(MathFuncNode left, MathFuncNode right,
			VarNode variable = null, IEnumerable<ConstNode> parameters = null,
			bool simplify = true, bool calculateConstants = false)
		{
			LeftNode = left;
			RightNode = right;
			Root = RightNode;

			Variable = variable;
			if (Variable == null)
				ConstToVars();
			if (parameters != null)
				Parameters = parameters.Except(parameters.Where(p => p.Name == Variable.Name)).ToDictionary(node => node.Name);

			FindParamsAndUnknownFuncs(Root);

			Root.Sort();
			if (simplify)
				Root = Simplify(Root);
			if (calculateConstants)
				Root = Precompile(null, Root);
		}
		private void EmitNode(MathFuncNode node, bool negExpAbs = false)
		{
			switch (node.Type)
			{
				case MathNodeType.Calculated:
					IlInstructions.Add(new OpCodeArg(OpCodes.Ldc_R8,
						negExpAbs ? Math.Abs(((CalculatedNode)node).Value) : ((CalculatedNode)node).Value));
					break;
				case MathNodeType.Value:
					IlInstructions.Add(new OpCodeArg(OpCodes.Ldc_R8,
						negExpAbs ? Math.Abs(((ValueNode)node).Value.ToDouble()) : ((ValueNode)node).Value.ToDouble()));
					break;

				case MathNodeType.Constant:
				case MathNodeType.Variable:
					IlInstructions.Add(new OpCodeArg(OpCodes.Ldarg, node.ArgNumber));
					break;

				case MathNodeType.Function:
					var funcNode = node as FuncNode;
					var func = FuncNodes[funcNode];
					if (!func.Calculated)
					{
						EmitFunc(funcNode, negExpAbs);
						func.Calculated = true;
						// if (FuncNodes[funcNode].Count > 1) TODO: this optimization disallowed due to derivatives.
						{
							IlInstructions.Add(new OpCodeArg(OpCodes.Stloc, funcNode.Number));
							IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number));
						}
					}
					else
						IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number));
					break;
			}
		}
		private void InvertLocalVariablesNumbers(MathFuncNode node)
		{
			var funcNode = node as FuncNode;
			if (funcNode != null)
			{
				funcNode.Number = LocalVarNumber - funcNode.Number - funcNode.Childs.Count;
				FuncNodes[funcNode].Number = funcNode.Number;

				foreach (var child in funcNode.Childs)
					InvertLocalVariablesNumbers(child);
			}
		}
		private void DefineLocals(MathFuncNode node)
		{
			var funcNode = node as FuncNode;
			if (funcNode == null)
				return;

			CountNumber value;
			var hash = funcNode.GetHashCode();
			if (FuncNodes.TryGetValue(funcNode, out value))
			{
				funcNode.Number = value.Number;
				FuncNodes[funcNode].Count += 1;
			}
			else
			{
				FuncNodes.Add(funcNode, new CountNumber() { Number = LocalVarNumber, Count = 1, Calculated = false });
				funcNode.Number = LocalVarNumber;
				LocalVarNumber += funcNode.Childs.Count;
			}

			foreach (var child in node.Childs)
				DefineLocals(child);
		}
		protected void SetParamsAndUnknownFuncsArgNumbers(MathFuncNode node)
		{
			foreach (var child in node.Childs)
				SetParamsAndUnknownFuncsArgNumbers(child);

			if (node.Type == MathNodeType.Function && !((FuncNode)node).IsKnown)
				node.ArgNumber = UnknownFuncs[node.Name].ArgNumber;
			else if (node.Type == MathNodeType.Constant)
				node.ArgNumber = Parameters[node.Name].ArgNumber;
			else if (node.Type == MathNodeType.Variable)
				node.ArgNumber = Variable.ArgNumber;
		}
예제 #13
0
		protected void ConstToVar(MathFuncNode node)
		{
			for (int i = 0; i < node.Childs.Count; i++)
				if (node.Childs[i] == null || node.Childs[i].Name == Variable.Name)
					node.Childs[i] = Variable;
				else if (node.Childs[i].Type == MathNodeType.Variable)
					node.Childs[i] = new ConstNode(node.Childs[i].Name);
				else
					ConstToVar(node.Childs[i]);
		}
예제 #14
0
		protected void FindParamsAndUnknownFuncs(MathFuncNode node)
		{
			foreach (var child in node.Childs)
				FindParamsAndUnknownFuncs(child);

			if (node.Type == MathNodeType.Function && !((FuncNode)node).IsKnown)
			{
				if (!UnknownFuncs.ContainsKey(node.Name))
					UnknownFuncs.Add(node.Name, (FuncNode)node);
			}
			else if (node.Type == MathNodeType.Constant)
			{
				if (!Parameters.ContainsKey(node.Name))
					Parameters.Add(node.Name, (ConstNode)node);
			}
		}
예제 #15
0
	protected void PushFunction(string mathFunction)
	{
		var lastArgsCount = ArgsCount[ArgsCount.Count - 1];
		var args = new MathFuncNode[lastArgsCount];
		for (int i = 0; i < lastArgsCount; i++)
			args[lastArgsCount - 1 - i] = Nodes.Pop();

		Nodes.Push(new FuncNode(mathFunction, args));
		ArgsCount.RemoveAt(ArgsCount.Count - 1);
		ArgsFuncTypes.RemoveAt(ArgsFuncTypes.Count - 1);
	}
		private MathFuncNode UnderPowerExpr(MathFuncNode node)
		{
			return (node.Type == MathNodeType.Function &&
					   ((FuncNode)node).FunctionType == KnownFuncType.Exp) ?
					   node.Childs[0] : node;
		}
		private MathFuncNode PowerExpr(MathFuncNode node)
		{
			return (node.Type == MathNodeType.Function &&
					   ((FuncNode)node).FunctionType == KnownFuncType.Exp) ?
					   node.Childs[1] : new ValueNode(1);
		}
		private MathFuncNode MultValues(MathFuncNode funcNode)
		{
			var values = funcNode.Childs
				.Where(child => child.Type == MathNodeType.Value)
				.Select(valueChild => ((ValueNode)valueChild).Value);

			values = values.Concat(funcNode.Childs
				.Where(child => child.Type == MathNodeType.Function && ((FuncNode)child).FunctionType == KnownFuncType.Neg)
				.Select(valueChild => new Rational<long>(-1, 1)));

			Rational<long> result = 1;
			foreach (var value in values)
				result *= value;

			if (result == 0)
				return new ValueNode(0);

			var notValuesNodes = funcNode.Childs
				.Where(child => child.Type != MathNodeType.Value && !(child.Type == MathNodeType.Function && ((FuncNode)child).FunctionType == KnownFuncType.Neg))
				.Concat(funcNode.Childs
				.Where(child => child.Type == MathNodeType.Function && ((FuncNode)child).FunctionType == KnownFuncType.Neg)
				.Select(negChild => negChild.Childs[0])).ToList();

			if (result == 1)
			{
				return notValuesNodes.Count == 0 ? new ValueNode(1) :
					notValuesNodes.Count == 1 ? notValuesNodes.First() :
					new FuncNode(KnownFuncType.Mult, notValuesNodes);
			}
			else if (result == -1)
			{
				return notValuesNodes.Count == 0 ? (MathFuncNode)(new ValueNode(-1)) :
					notValuesNodes.Count == 1 ? new FuncNode(KnownFuncType.Neg, notValuesNodes.First()) :
					new FuncNode(KnownFuncType.Neg, new FuncNode(KnownFuncType.Mult, notValuesNodes));
			}
			else
			{
				if (notValuesNodes.Count == 0)
					return new ValueNode(result);
				else
				{
					if (result < 0)
					{
						notValuesNodes.Add(new ValueNode(-result));
						return new FuncNode(KnownFuncType.Neg, new FuncNode(KnownFuncType.Mult, notValuesNodes));
					}
					else
					{
						notValuesNodes.Add(new ValueNode(result));
						return new FuncNode(KnownFuncType.Mult, notValuesNodes);
					}
				}
			}
		}
		private MathFuncNode MakeSubstitution(MathFuncNode node)
		{
			int ind = -1;
			for (int j = 0; j < LeftNode.Childs.Count; j++)
				if (LeftNode.Childs[j].Name == node.Name)
				{
					ind = j;
					break;
				}
			if (ind != -1)
			{
				if (_currentFunc.Childs[ind].IsTerminal)
					return _currentFunc.Childs[ind];
				else
					return new FuncNode((FuncNode)_currentFunc.Childs[ind]);
			}

			MathFuncNode result;
			switch (node.Type)
			{
				case MathNodeType.Calculated:
					result = new CalculatedNode(((CalculatedNode)node).Value);
					break;
				case MathNodeType.Value:
					result = new ValueNode((ValueNode)node);
					break;
				case MathNodeType.Constant:
				case MathNodeType.Variable:
					result = node;
					break;
				default:
				case MathNodeType.Function:
					result = ((FuncNode)node).FunctionType != null ?
						new FuncNode((KnownFuncType)((FuncNode)node).FunctionType) :
						new FuncNode(node.Name);
					break;
			}

			for (int i = 0; i < node.Childs.Count; i++)
				switch (node.Childs[i].Type)
				{
					case MathNodeType.Calculated:
						result.Childs.Add(new CalculatedNode((CalculatedNode)node.Childs[i]));
						break;
					case MathNodeType.Value:
						result.Childs.Add(new ValueNode((ValueNode)node.Childs[i]));
						break;
					case MathNodeType.Constant:
					case MathNodeType.Variable:
						result.Childs.Add(node.Childs[i]);
						break;
					case MathNodeType.Function:
						result.Childs.Add(MakeSubstitution((FuncNode)node.Childs[i]));
						break;
				}
			return result;
		}
		private MathFuncNode MakeSubstitution(MathFuncNode left, MathFuncNode right, FuncNode currentFunc)
		{
			LeftNode = left;
			RightNode = right;
			_currentFunc = currentFunc;
			return MakeSubstitution(right);
		}
		private MathFuncNode ReduceAddition(MathFuncNode node1, MathFuncNode node2)
		{
			var node1neg = node1.Type == MathNodeType.Function && (node1 as FuncNode).FunctionType == KnownFuncType.Neg;
			var node2neg = node2.Type == MathNodeType.Function && (node2 as FuncNode).FunctionType == KnownFuncType.Neg;
			var node11 = node1neg ? node1.Childs[0] : node1;
			var node21 = node2neg ? node2.Childs[0] : node2;

			MathFuncNode valueNode1 = null;
			if (node11.Type == MathNodeType.Function &&
				(node11 as FuncNode).FunctionType == KnownFuncType.Mult)
					valueNode1 = node11.Childs.Where(child => child.IsValueOrCalculated).FirstOrDefault();
			if (valueNode1 == null)
				valueNode1 = node11.IsValueOrCalculated ? node11 : new ValueNode(new Rational<long>(1, 1));
			var value1 = ((ValueNode)valueNode1).Value;
			if (node1neg)
				value1 *= -1;

			MathFuncNode valueNode2 = null;
			if (node21.Type == MathNodeType.Function &&
				(node21 as FuncNode).FunctionType == KnownFuncType.Mult)
				valueNode2 = node21.Childs.Where(child => child.IsValueOrCalculated).FirstOrDefault();
			if (valueNode2 == null)
				valueNode2 = node21.IsValueOrCalculated ? node21 : new ValueNode(new Rational<long>(1, 1));
			var value2 = ((ValueNode)valueNode2).Value;
			if (node2neg)
				value2 *= -1;

			var notValueNodes1 = node11.Type == MathNodeType.Function &&
				(node11 as FuncNode).FunctionType == KnownFuncType.Mult ?
				node11.Childs.Where(child => !child.IsValueOrCalculated).ToList() :
				node11.IsValueOrCalculated ?
				new List<MathFuncNode>() { } :
				new List<MathFuncNode>() { node11 };
			var notValueNodes2 = node21.Type == MathNodeType.Function &&
				(node21 as FuncNode).FunctionType == KnownFuncType.Mult ?
				node21.Childs.Where(child => !child.IsValueOrCalculated).ToList() :
				node21.IsValueOrCalculated ?
				new List<MathFuncNode>() { } :
				new List<MathFuncNode>() { node21 };

			var mult1 = new FuncNode(KnownFuncType.Mult, notValueNodes1.ToList());
			var mult2 = new FuncNode(KnownFuncType.Mult, notValueNodes2.ToList());
			mult1.Sort();
			mult2.Sort();

			if (mult1.Equals(mult2))
			{
				var resultNodes = new List<MathFuncNode>();
				resultNodes.Add(new ValueNode(value1 + value2));
				resultNodes.AddRange(notValueNodes1);
				return Simplify(new FuncNode(KnownFuncType.Mult, resultNodes));
			}
			else
				return null;
		}
		private MathFuncNode Simplify(MathFuncNode node)
		{
			var funcNode = node as FuncNode;
			if (funcNode != null)
			{
				for (int i = 0; i < funcNode.Childs.Count; i++)
					funcNode.Childs[i] = Simplify(funcNode.Childs[i]);

				switch (funcNode.FunctionType)
				{
					case KnownFuncType.Neg:
						if (funcNode.Childs[0].Type == MathNodeType.Value)
							return new ValueNode(-((ValueNode)funcNode.Childs[0]).Value);
						else if (funcNode.Childs[0].Type == MathNodeType.Function && ((FuncNode)funcNode.Childs[0]).FunctionType == KnownFuncType.Neg)
							return funcNode.Childs[0].Childs[0];
						break;

					case KnownFuncType.Add:
						BuildMultichildTree(funcNode);
						ReduceSummands(funcNode);
						return FoldValues(funcNode);

					case KnownFuncType.Mult:
						BuildMultichildTree(funcNode);
						var addResult = BreakOnAddNodes(funcNode);
						var multResult = MultValues(funcNode);
						bool isNeg = multResult.Type == MathNodeType.Function && ((FuncNode)multResult).FunctionType == KnownFuncType.Neg;
						var powerNode = ReducePowers(isNeg ? multResult.Childs[0] : multResult);
						powerNode.Childs = powerNode.Childs.Except(powerNode.Childs.Where(child => child.Type == MathNodeType.Value &&
							((ValueNode)child).Value == 1)).ToList();

						return addResult != null && addResult.NodeCount <= (isNeg ? powerNode.NodeCount + 1 : powerNode.NodeCount) ?
							addResult :
								(isNeg ? (powerNode.Type == MathNodeType.Value ?
									(MathFuncNode)(new ValueNode(-((ValueNode)powerNode).Value)) : new FuncNode(KnownFuncType.Neg, powerNode)) : powerNode);

					case KnownFuncType.Exp:
						if (funcNode.Childs[0].Type == MathNodeType.Function)
						{
							if ((funcNode.Childs[0] as FuncNode).FunctionType == KnownFuncType.Exp)
							{
								funcNode.Childs[1] = Simplify(
									new FuncNode(KnownFuncType.Mult, funcNode.Childs[0].Childs[1], funcNode.Childs[1]));
								funcNode.Childs[0] = funcNode.Childs[0].Childs[0];
								return ExpValue(funcNode);
							}
							else if ((funcNode.Childs[0] as FuncNode).FunctionType == KnownFuncType.Mult)
							{
								var expResult = ExpValue(funcNode);
								var multNode = PowerIntoMult(funcNode.Childs[0].Childs, funcNode.Childs[1]);
								return (multNode.NodeCount <= expResult.NodeCount) ? multNode : expResult;
							}
						}

						return ExpValue(funcNode);

					/*case KnownFuncType.Diff:
						return Simplify(GetDerivative(funcNode.Childs[0]));*/

					default:
						if (funcNode.Childs.All(child => child.Type == MathNodeType.Value))
							return (MathFuncNode)SimplifyValues(funcNode.FunctionType, funcNode.Childs.Select(child => (ValueNode)child).ToList())
								?? (MathFuncNode)funcNode;
						break;
				}

				return funcNode;
			}

			return node;
		}
예제 #23
0
		protected void GetFirstParam(MathFuncNode node)
		{
			if (Variable == null)
				for (int i = 0; i < node.Childs.Count; i++)
					if (Variable == null)
						if (node.Childs[i].Type == MathNodeType.Constant)
						{
							Variable = new VarNode(node.Childs[i].Name);
							break;
						}
						else if (node.Childs[i].Type == MathNodeType.Variable)
						{
							Variable = (VarNode)node.Childs[i];
							break;
						}
						else
							GetFirstParam(node.Childs[i]);
		}
		private MathFuncNode ReducePowers(MathFuncNode funcNode)
		{
			if (funcNode.Type != MathNodeType.Function)
				return funcNode;

			var newChilds = new List<MathFuncNode>();
			bool[] markedNodes = new bool[funcNode.Childs.Count];

			for (int i = 0; i < funcNode.Childs.Count; i++)
			{
				var basis = UnderPowerExpr(funcNode.Childs[i]);
				var nodesWithSameBasis = new List<MathFuncNode>();
				if (!markedNodes[i])
					nodesWithSameBasis.Add(funcNode.Childs[i]);

				for (int j = i + 1; j < funcNode.Childs.Count; j++)
					if (basis.Equals(UnderPowerExpr(funcNode.Childs[j])) && !markedNodes[j])
					{
						nodesWithSameBasis.Add(funcNode.Childs[j]);
						markedNodes[j] = true;
					}

				if (nodesWithSameBasis.Count > 1)
				{
					newChilds.Add(Simplify(new FuncNode(KnownFuncType.Exp,
						basis,
						Simplify(new FuncNode(KnownFuncType.Add,
							nodesWithSameBasis.Select(node => PowerExpr(node)).ToList()))
					)));
				}
				else if (!markedNodes[i])
					newChilds.Add(funcNode.Childs[i]);
			}

			if (funcNode.Childs.Count != newChilds.Count)
			{
				if (newChilds.Count == 1)
					return newChilds[0];
				else
					return new FuncNode(KnownFuncType.Mult, newChilds);
			}
			else
				return funcNode;
		}
예제 #25
0
		public FuncNode(KnownFuncType type, MathFuncNode arg)
			: this(type, new List<MathFuncNode>() { arg })
		{
		}
		private MathFuncNode PowerIntoMult(IEnumerable<MathFuncNode> multChilds, MathFuncNode expNode)
		{
			var newChilds = multChilds.Select(child => 
				Simplify(new FuncNode(KnownFuncType.Exp, child, expNode)));
			return Simplify(new FuncNode(KnownFuncType.Mult, newChilds.ToList()));
		}
예제 #27
0
		public FuncNode(KnownFuncType type, MathFuncNode arg1, MathFuncNode arg2, MathFuncNode arg3)
			: this(type, new List<MathFuncNode>() { arg1, arg2, arg3 })
		{
		}
		private FuncNode PrecompileExpFunc(MathFuncNode parent, FuncNode funcNode)
		{
			if ((parent == null ||
				((FuncNode)parent).FunctionType != KnownFuncType.Mult) &&
				funcNode.Childs[1].LessThenZero())
			{
				if (!funcNode.Childs[1].IsValueOrCalculated || funcNode.Childs[1].DoubleValue != -1.0)
				{
					FuncNode second;
					if (!funcNode.Childs[1].IsValueOrCalculated)
						second = new FuncNode(KnownFuncType.Pow, funcNode.Childs[0], funcNode.Childs[1].Abs());
					else
						second = Math.Abs(funcNode.Childs[1].DoubleValue) != 0.5 ?
							new FuncNode(KnownFuncType.Pow, funcNode.Childs[0], funcNode.Childs[1].Abs()) :
							new FuncNode(KnownFuncType.Sqrt, funcNode.Childs[0]);
					return new FuncNode(KnownFuncType.Div, new CalculatedNode(1.0), second);
				}
				else
					return new FuncNode(KnownFuncType.Div, new CalculatedNode(1.0), funcNode.Childs[0]);
			}
			if (funcNode.Childs[1].IsValueOrCalculated && funcNode.Childs[1].DoubleValue == 0.5)
				return new FuncNode(KnownFuncType.Sqrt, funcNode.Childs[0]);
			return funcNode;
		}
예제 #29
0
		public void ConstToVars()
		{
			if (LeftNode.Type == MathNodeType.Variable)
				Variable = (VarNode)LeftNode;
			if (LeftNode.Type == MathNodeType.Constant)
				Variable = new VarNode(LeftNode.Name);
			else
				if (LeftNode.Type == MathNodeType.Function)
				{
					Variable = null;
					if (LeftNode.Childs.Count > 1 && ((FuncNode)LeftNode).Childs[1] != null)
					{
						var secondNode = ((FuncNode)LeftNode).Childs[1];
						if (secondNode.Type == MathNodeType.Constant)
							Variable = new VarNode(secondNode.Name);
						else if (secondNode.Type == MathNodeType.Variable)
							Variable = (VarNode)secondNode;
					}
					GetFirstParam(RightNode);
					if (Variable == null)
						Variable = new VarNode("x");
				}

			ConstToVar(Root);
			if (Root.Name == Variable.Name)
				Root = Variable;
		}