private string ExpressionToString(SteExpression expr) { if (expr.IsAtomic) { if (expr.IsVariable) return _evaluationData[expr.HeadText].ToString(); return expr.HeadText; } var s = new StringBuilder(); s.Append(expr.HeadText) .Append("["); for (var i = 0; i < expr.ArgumentsCount; i++) { if (i > 0) s.Append(","); s.Append(ExpressionToString(expr[i])); } s.Append("]"); return s.ToString(); }
internal GMacCbTempVariable(string lowLevelName, SteExpression rhsExpr, bool isFactoreSubExpression) : base(lowLevelName, rhsExpr) { LowLevelId = -1; IsFactoredSubExpression = isFactoreSubExpression; NameIndex = -1; }
/// <summary> /// /// </summary> /// <param name="rhsExpr"></param> /// <returns></returns> private SteExpression BybassSingleTempVariableRhsExpr(SteExpression rhsExpr) { while (true) { //The RHS expression is not a variable name. Return the full expression if (rhsExpr.IsVariable == false) { return(rhsExpr); } //The RHS expression is a variable name var rhsExprVarName = rhsExpr.HeadText; //The RHS expression is not a low-level variable name. Return the full expression if (LowLevelUtils.IsLowLevelVariableName(rhsExprVarName) == false) { return(rhsExpr); } var llItem = _dataTable.GetItemByName(rhsExprVarName); //The RHS expression is not a temp item. Return the full expression if (llItem.IsTemp == false) { return(rhsExpr); } //Iterate over the RHS of the temp low-level item whos name is given in rhsExprVarName rhsExpr = llItem.AssignedRhsSymbolicScalar.ToTextExpressionTree(); } }
/// <summary> /// Analyze the contents of the initial expression. /// If an atomic expression is found stop and return true. /// If a single temp variable is found analyze its RHS expression and iterate. /// If any other type of expression is found stop and return false. /// </summary> /// <param name="initialExpr"></param> /// <param name="finalExpr"></param> /// <returns></returns> private bool FollowExpression(SteExpression initialExpr, out SteExpression finalExpr) { //Start at the initial expression finalExpr = initialExpr; while (true) { //If the current expression is atomic return true if (IsAtomicExpression(finalExpr)) { return(true); } //If the current expression is not a symbol return false if (finalExpr.IsSymbolic == false) { return(false); } //If the current expression is not a variable name symbol return false //if (LlUtils.IsLowLevelVariableName(finalExpr.Head) == false) // return false; //If the current expression is not a temp variable name symbol return false GMacCbTempVariable tempVar; if (_oldTempVars.TryGetValue(finalExpr.HeadText, out tempVar) == false) { return(false); } //Make the current expression the RHS of the temp variable and continue the loop finalExpr = tempVar.RhsExpr; } }
/// <summary> /// Convert the given Mathematica Expr object into a SymbolicExpr object /// </summary> /// <param name="expr"></param> /// <returns></returns> public static SteExpression ToTextExpressionTree(this Expr expr) { var isNumber = expr.NumberQ(); var isSymbol = expr.SymbolQ(); if (isNumber) { return(isSymbol ? SteExpressionUtils.CreateSymbolicNumber(expr.ToString()) : SteExpressionUtils.CreateLiteralNumber(expr.ToString())); } if (isSymbol) { return(SteExpressionUtils.CreateVariable(expr.ToString())); } if (expr.Args.Length == 0) { return(SteExpressionUtils.CreateFunction(expr.ToString())); } //return new SymbolicExpr(expr.ToString(), isSymbol, isNumber); var args = new SteExpression[expr.Args.Length]; for (var i = 0; i < expr.Args.Length; i++) { args[i] = ToTextExpressionTree(expr.Args[i]); } return(SteExpressionUtils.CreateFunction(expr.Head.ToString(), args)); }
private void AddOutputVariable(GMacCbOutputVariable outputVar) { SteExpression rhsExpr; //An atomic expression or an undefined symbol is found for the variable's RHS side if (FollowExpression(outputVar.RhsExpr, out rhsExpr) || rhsExpr.IsAtomic) { outputVar.RhsExpr = rhsExpr; _outputVars.Add(outputVar); return; } //A compound expression is found for the variable's RHS side rhsExpr = ReshapePlus(rhsExpr); var rhsExprNewArgs = new SteExpression[rhsExpr.ArgumentsCount]; for (var i = 0; i < rhsExpr.ArgumentsCount; i++) { rhsExprNewArgs[i] = ReduceSubExpression(rhsExpr[i]); } outputVar.RhsExpr = SteExpressionUtils.CreateFunction(rhsExpr.HeadText, rhsExprNewArgs); _outputVars.Add(outputVar); }
public static bool Equals(this SteExpression symbolicExpr1, SteExpression symbolicExpr2) { if (ReferenceEquals(symbolicExpr1, null) || ReferenceEquals(symbolicExpr2, null)) { return(false); } if (ReferenceEquals(symbolicExpr1, symbolicExpr2)) { return(true); } if (symbolicExpr1.HeadText != symbolicExpr2.HeadText) { return(false); } if (symbolicExpr1.ArgumentsCount == 0 && symbolicExpr2.ArgumentsCount == 0) { return(true); } if (symbolicExpr1.ArgumentsCount != symbolicExpr2.ArgumentsCount) { return(false); } return(symbolicExpr1.Arguments.Zip(symbolicExpr2.Arguments, (t, s) => t.Equals(s)).All(b => b)); }
public SteAssign AssignToLocalVariable(string varName, SteExpression varValue) { return(new SteAssign() { LocalAssignment = true, LeftHandSide = new SteFixedCode(varName), RightHandSide = varValue }); }
/// <summary> /// For example, convert Plus[a, b, c, d] expression into Plus[Plus[a, b, c], d] /// </summary> /// <param name="expr"></param> /// <returns></returns> private SteExpression ReshapePlus(SteExpression expr) { if (expr.ArgumentsCount < 3 || expr.HeadText != "Plus") { return(expr); } var arg1 = SteExpressionUtils.CreateFunction(expr.HeadText, expr.Arguments.Take(expr.ArgumentsCount - 1).ToArray()); var arg2 = expr.LastArgument; return(SteExpressionUtils.CreateFunction(expr.HeadText, arg1, arg2)); }
public static IEnumerable <string> GetLowLevelVariablesNames(this SteExpression expr) { //var list1 = expr.Variables().Where(IsLowLevelVariableName); //var s1 = list1.Distinct().OrderBy(item => item).Aggregate("", (acc, item) => acc + item + ", "); //var list2 = GetLowLevelVariablesNames(expr.ToString()); //var s2 = list2.Distinct().OrderBy(item => item).Aggregate("", (acc, item) => acc + item + ", "); //return list1; return(expr.Variables.Where(IsLowLevelVariableName)); }
/// <summary> /// An atomic expression is a simple constant or an input variable symbol /// </summary> /// <param name="expr"></param> /// <returns></returns> private bool IsAtomicExpression(SteExpression expr) { if (expr.IsNumber) { return(true); } if (expr.IsSymbolic == false) { return(false); } //return LlUtils.IsLowLevelVariableName(expr.Head) && _inputVars.ContainsKey(expr.Head); return(_inputVars.ContainsKey(expr.HeadText)); }
public override SteExpression Convert(SteExpression expr) { //A number if (expr.IsNumberLiteral) { return(ConvertNumber(expr)); } //This has a problem with the Rational[] numbers //expr.CreateCopy(); //A variable if (expr.IsVariable) { //Try convert a low-level Mathematica variable name into a target variable name GMacCbVariable targetVar; if (ActiveCodeBlock != null && ActiveCodeBlock.VariablesDictionary.TryGetValue(expr.HeadText, out targetVar)) { return(SteExpressionUtils.CreateVariable(targetVar.TargetVariableName)); } return(expr.CreateCopy()); } //A symbolic constant if (expr.IsNumberSymbol) { switch (expr.HeadText) { case "Pi": return(SteExpressionUtils.CreateSymbolicNumber("Math.PI")); case "E": return(SteExpressionUtils.CreateSymbolicNumber("Math.E")); } return(expr.CreateCopy()); } //A function; the arguments are converted before creating the main function expression return(expr.IsFunction ? ConvertFunction(expr.HeadText, expr.Arguments.Select(Convert).ToArray()) : expr.CreateCopy()); }
/// <summary> /// Reduce a complex expression into a simpler one by refactoring all of the sub-expressions into /// temp variables. If the initial expression is already simple just return it as is. /// </summary> /// <param name="initialExpr"></param> /// <returns></returns> private SteExpression ReduceSubExpression(SteExpression initialExpr) { string initialExprText = initialExpr.ToString(); SteExpression reducedExpr; //Try to find the initial expression in the cache if (_reducedSubExpressionsCache.TryGetValue(initialExprText, out reducedExpr)) { return(reducedExpr); } //An atomic expression or an undefined symbol is found for the sub-expression if (FollowExpression(initialExpr, out reducedExpr) || reducedExpr.IsAtomic) { _reducedSubExpressionsCache.Add(initialExprText, reducedExpr); return(reducedExpr); } //A compound expression is found for the sub-expression reducedExpr = ReshapePlus(reducedExpr); var rhsExprNewArgs = new SteExpression[reducedExpr.ArgumentsCount]; //Convert all arguments into simple constants, undefined symbols, or temp variable symbols for (var i = 0; i < reducedExpr.ArgumentsCount; i++) { rhsExprNewArgs[i] = ReduceSubExpression(reducedExpr[i]); } //Create a new RHS expression from the converted arguments reducedExpr = SteExpressionUtils.CreateFunction(reducedExpr.HeadText, rhsExprNewArgs); //Find or create a temp variable to hold the new RHS expression var tempVar = GetTempVariable(reducedExpr); //Return the final temp variable symbol expression reducedExpr = SteExpressionUtils.CreateVariable(tempVar.LowLevelName); //Add reduced expression to cache _reducedSubExpressionsCache.Add(initialExprText, reducedExpr); return(reducedExpr); }
/// <summary> /// Find or create a temp variable holding the given expression as its RHS /// </summary> /// <param name="subExpr"></param> /// <returns></returns> private GMacCbTempVariable GetTempVariable(SteExpression subExpr) { GMacCbTempVariable tempVar; var subExprText = subExpr.ToString(); //A temp is found; return it if (_subExpressionsDictionary.TryGetValue(subExprText, out tempVar)) { return(tempVar); } //A temp is not found; create it and return it tempVar = new GMacCbTempVariable(CodeBlock.GetNewVarName(), subExpr, true); _subExpressionsDictionary.Add(subExprText, tempVar); _newTempVars.Add(tempVar.LowLevelName, tempVar); return(tempVar); }
/// <summary> /// Converts a symbolic text expression tree into a method call in C# syntax /// </summary> /// <param name="textExpr"></param> /// <returns></returns> public static string ToCSharpCodeMethodCall(this SteExpression textExpr) { var s = new StringBuilder(); s.Append(textExpr.HeadText).Append('('); if (textExpr.ArgumentsCount > 0) { foreach (var argExpr in textExpr.Arguments) { s.Append(argExpr.ToCSharpCodeMethodCall()).Append(", "); } s.Length -= 2; } s.Append(')'); return(s.ToString()); }
private static SteExpression ConvertNumber(SteExpression numberExpr) { var rationalHeadIndex = numberExpr.HeadText.IndexOf(@"Rational[", StringComparison.Ordinal); //This is an ordinary number, return as-is if (rationalHeadIndex < 0) { return(numberExpr.CreateCopy()); } //This is a rational atomic number; for example Rational[1, 2]. //Extract components and convert to floating point var numberTextFull = numberExpr.HeadText.Substring(@"Rational[".Length); var commaIndex = numberTextFull.IndexOf(','); var bracketIndex = numberTextFull.IndexOf(']'); var num1Text = numberTextFull.Substring(0, commaIndex); var num2Text = numberTextFull.Substring(commaIndex + 1, bracketIndex - commaIndex - 1); return(SteExpressionUtils.CreateLiteralNumber( double.Parse(num1Text) / double.Parse(num2Text) )); }
/// <summary> /// Create a copy of the given text expression tree /// </summary> /// <param name="expr"></param> /// <returns></returns> public SteExpression CopyExpression(SteExpression expr) { return(expr.CreateCopy()); }
public void Visit(SteExpression code) { if (code.IsAtomic) { TextComposer.Append(code.HeadText); return; } if (code.IsFunction) { TextComposer.Append(code.HeadText).Append("("); var flag = false; foreach (var argCode in code.Arguments) { if (flag) { TextComposer.Append(", "); } else { flag = true; } argCode.AcceptVisitor(this); } TextComposer.Append(")"); } if (code.IsArrayAccess) { TextComposer.Append(code.HeadText).Append("["); var flag = false; foreach (var argCode in code.Arguments) { if (flag) { TextComposer.Append(", "); } else { flag = true; } argCode.AcceptVisitor(this); } TextComposer.Append("]"); } if (code.IsOperator) { var opHeaderSpecs = (SteOperatorSpecs)code.HeadSpecs; if (opHeaderSpecs.Position == TccOperatorPosition.Infix) { var flag = false; foreach (var argCode in code.Arguments) { if (flag) { TextComposer.Append(opHeaderSpecs.Symbol); } else { flag = true; } if (argCode.Precedence > code.Precedence) { TextComposer.Append("("); argCode.AcceptVisitor(this); TextComposer.Append(")"); } else { argCode.AcceptVisitor(this); } } return; } var argCode1 = code.FirstArgument; if (ReferenceEquals(argCode1, null) == false) { if (opHeaderSpecs.Position == TccOperatorPosition.Prefix) { TextComposer.Append(opHeaderSpecs.Symbol); } if (argCode1.Precedence > code.Precedence) { TextComposer.Append("("); argCode1.AcceptVisitor(this); TextComposer.Append(")"); } else { argCode1.AcceptVisitor(this); } if (opHeaderSpecs.Position == TccOperatorPosition.Suffix) { TextComposer.Append(opHeaderSpecs.Symbol); } } } }
internal GMacCbOutputVariable(string lowLevelName, int lowLevelId, LanguageValueAccess valueAccess, SteExpression rhsExpr) : base(lowLevelName, rhsExpr) { LowLevelId = lowLevelId; ValueAccess = valueAccess.ToAstDatastoreValueAccess(); }
//public static int ComputationsCount(this Expr expr) //{ // return // expr // .SubExpressions() // .Count(subExpr => !(subExpr.Args.Length == 0 || subExpr.IsSimpleConstantOrLowLevelVariable())); //} //public static bool IsConstantOrLowLevelVariable(this Expr expr) //{ // return // LlVarOnlyRegex.IsMatch(expr.ToString()) || // (LlVarRegex.IsMatch(expr.ToString()) == false); //} public static bool IsLowLevelVariable(this SteExpression expr) { return(expr.IsSymbolic && IsLowLevelVariableName(expr.HeadText)); }
//public static bool IsSimpleConstantOrLowLevelVariable(this Expr expr) //{ // return expr.NumberQ() || (expr.SymbolQ() && IsLowLevelVariableName(expr.ToString())); //} public static bool IsSimpleConstantOrLowLevelVariable(this SteExpression expr) { return(expr.IsNumber || (expr.IsSymbolic && IsLowLevelVariableName(expr.HeadText))); }
/// <summary> /// Convert this symbolic expression into a Mathematica expression object /// </summary> /// <param name="symbolicExpr"></param> /// <param name="cas"></param> /// <returns></returns> public static Expr SimplifyToExpr(this SteExpression symbolicExpr, MathematicaInterface cas) { return(cas[Mfs.Simplify[symbolicExpr.ToString()]]); }
/// <summary> /// Convert this symbolic expression into a Mathematica expression object /// </summary> /// <param name="symbolicExpr"></param> /// <param name="cas"></param> /// <returns></returns> public static Expr ToExpr(this SteExpression symbolicExpr, MathematicaInterface cas) { return(cas[symbolicExpr.ToString()]); }
public virtual ISyntaxTreeElement Visit(SteExpression expr) { return(Convert(expr)); }
private Expr EvaluateExpression(SteExpression expr) { return SymbolicUtils.Cas[Mfs.Simplify[ExpressionToString(expr)]]; }
/// <summary> /// Replace a sub-expression in the RHS expression of this computed variable by a temp variable name /// </summary> /// <param name="oldSubExpr"></param> /// <param name="newTempVarName"></param> internal void ReplaceRhsSubExpression(SteExpression oldSubExpr, string newTempVarName) { RhsExpr.ReplaceAllByVariableInPlace(oldSubExpr, newTempVarName); }
public abstract SteExpression Convert(SteExpression expr);
//protected GMacCbComputedVariable(string lowLevelName, Expr rhsExpr) // : base(lowLevelName) //{ // RhsExpr = rhsExpr.ToTextExpressionTree(); //} protected GMacCbComputedVariable(string lowLevelName, SteExpression rhsExpr) : base(lowLevelName) { RhsExpr = rhsExpr.CreateCopy(); }