public NumericListElementExpression(IObjectExpression listExpr, INumericExpression indexExpr) { this.listExpr = listExpr; this.indexExpr = indexExpr; Type objectType = listExpr.ObjectType; Type itemType; if (objectType.IsArray) { itemType = objectType.GetElementType(); } else if (ReflectionHelper.IsList(objectType)) { itemType = objectType.GetGenericArguments()[0]; } else { throw new NotSupportedException(); } MethodInfo generateEvaluatorMethod = GetType() .GetMethod("GenerateEvaluator", BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(itemType); Func <Func <object, int, double> > generateEvaluatorDelegate = ReflectionHelper.CreateDelegate <Func <object, int, double> >(generateEvaluatorMethod); evaluator = generateEvaluatorDelegate(); }
public void ObjectMethodFunctionTest() { ExpressionParser parser = new ExpressionParser(); parser.RegisterVariable("a", typeof(A)); INumericExpression expr = parser.ParseNumericExpression("1 + a.g(2,\"foo\",true).Id"); Assert.NotNull(expr); Assert.Equal("1 a.g(2,\"foo\",true).Id +", expr.ToString()); A a = new A { Bs = new List <B> { new B { Id = 1 }, new B { Id = 2 }, new B { Id = 3 }, } }; Assert.Equal(1 + a.g(2, "foo", true).Id, expr.Evaluate(new Dictionary <string, object> { { "a", a } })); }
/// <summary> /// Constructs the literal from the given expression. /// </summary> /// <param name="relOperator">Relational operator.</param> /// <param name="leftArgument">Left argument term.</param> /// <param name="rightArgument">Right argument term.</param> /// <param name="isNegated">Is the literal negated?</param> public NumericCompareLiteralCNF(NumericCompareExpression.RelationalOperator relOperator, INumericExpression leftArgument, INumericExpression rightArgument, bool isNegated) { Operator = relOperator; LeftArgument = leftArgument; RightArgument = rightArgument; IsNegated = isNegated; }
/// <summary> /// Constructs the literal from the given expression. /// </summary> /// <param name="expression">Source expression.</param> /// <param name="isNegated">Is the literal negated?</param> public NumericCompareLiteralCNF(NumericCompareExpression expression, bool isNegated) { Operator = expression.Operator; LeftArgument = expression.LeftArgument; RightArgument = expression.RightArgument; IsNegated = isNegated; }
/// <summary> /// Visits the given input data node. /// </summary> /// <param name="data">Input data node.</param> public override void PostVisit(InputData.PDDL.Divide data) { INumericExpression secondArgument = ExpressionStack.Pop(); INumericExpression firstArgument = ExpressionStack.Pop(); ExpressionStack.Push(new Divide(firstArgument, secondArgument)); }
/// <summary> /// Visits the given input data node. /// </summary> /// <param name="data">Input data node.</param> public override void PostVisit(InputData.PDDL.NumericAssignEffect data) { int functionNameId = IdManager.Functions.GetId(data.Function.Name, data.Function.Terms.Count); List <ITerm> terms = new List <ITerm>(); data.Function.Terms.ForEach(term => terms.Add(TermsBuilder.Value.Build(term))); NumericExpressionsBuilder numericExpressionsBuilder = new NumericExpressionsBuilder(IdManager); INumericExpression valueExpression = numericExpressionsBuilder.Build(data.Value); IAtom functionAtom = new Atom(functionNameId, terms); IEffect newEffect = null; switch (data.AssignOperator) { case InputData.PDDL.Traits.AssignOperator.ASSIGN: { newEffect = new NumericAssignEffect(functionAtom, valueExpression, IdManager); break; } case InputData.PDDL.Traits.AssignOperator.INCREASE: { newEffect = new NumericIncreaseEffect(functionAtom, valueExpression, IdManager); break; } case InputData.PDDL.Traits.AssignOperator.DECREASE: { newEffect = new NumericDecreaseEffect(functionAtom, valueExpression, IdManager); break; } case InputData.PDDL.Traits.AssignOperator.SCALE_UP: { newEffect = new NumericScaleUpEffect(functionAtom, valueExpression, IdManager); break; } case InputData.PDDL.Traits.AssignOperator.SCALE_DOWN: { newEffect = new NumericScaleDownEffect(functionAtom, valueExpression, IdManager); break; } default: { Debug.Assert(false); break; } } EffectsStack.Push(newEffect); }
public void NumericExpressionTest(string expression, string expectedRpn, double expectedValue) { ExpressionParser parser = new ExpressionParser(); parser.RegisterAssembly(GetType().Assembly); INumericExpression expr = parser.ParseNumericExpression(expression); Assert.NotNull(expr); Assert.Equal(expectedRpn, expr.ToString()); Assert.Equal(expectedValue, expr.Evaluate()); }
public void NumericFunctionTest() { Func <double, double> func = n => Math.Cos(n); ExpressionParser parser = new ExpressionParser(); parser.RegisterFunction("cos", func); INumericExpression expr = parser.ParseNumericExpression("1 + cos(12)"); Assert.NotNull(expr); Assert.Equal("1 cos(12) +", expr.ToString()); Assert.Equal(1 + Math.Cos(12), expr.Evaluate()); }
/// <summary> /// Collects used numeric functions in the given numeric expression. /// </summary> /// <param name="expression">Numeric expression.</param> /// <returns>Collected numeric functions.</returns> public HashSet <NumericFunction> Collect(INumericExpression expression) { Debug.Assert(NumericFunctions.Count == 0); NumericFunctions.Clear(); expression.Accept(this); HashSet <NumericFunction> result = NumericFunctions; NumericFunctions = new HashSet <NumericFunction>(); return(result); }
public void NumericArrayVariableTest() { ExpressionParser parser = new ExpressionParser(); parser.RegisterVariable <int[]>("a"); int[] a = new[] { 1, 2 }; INumericExpression expr = parser.ParseNumericExpression("1 + a[1]"); Assert.NotNull(expr); Assert.Equal("1 a[1] +", expr.ToString()); Assert.Equal(1 + a[1], expr.Evaluate(new Dictionary <string, object> { { "a", a } })); }
public void NumericVariableTest() { ExpressionParser parser = new ExpressionParser(); parser.RegisterVariable <int>("a"); int a = 2; INumericExpression expr = parser.ParseNumericExpression("1 + a"); Assert.NotNull(expr); Assert.Equal("1 a +", expr.ToString()); Assert.Equal(1 + a, expr.Evaluate(new Dictionary <string, object> { { "a", a } })); }
/// <summary> /// Visits the given input data node. /// </summary> /// <param name="data">Input data node.</param> public override void PostVisit(InputData.PDDL.NumericCompareExpression data) { NumericExpressionsBuilder numericExpressionsBuilder = new NumericExpressionsBuilder(IdManager); INumericExpression firstArgument = numericExpressionsBuilder.Build(data.NumericExpression1); INumericExpression secondArgument = numericExpressionsBuilder.Build(data.NumericExpression2); NumericCompareExpression.RelationalOperator relOperator = NumericCompareExpression.RelationalOperator.EQ; switch (data.NumericComparer) { case InputData.PDDL.Traits.NumericComparer.EQ: { relOperator = NumericCompareExpression.RelationalOperator.EQ; break; } case InputData.PDDL.Traits.NumericComparer.LT: { relOperator = NumericCompareExpression.RelationalOperator.LT; break; } case InputData.PDDL.Traits.NumericComparer.LTE: { relOperator = NumericCompareExpression.RelationalOperator.LTE; break; } case InputData.PDDL.Traits.NumericComparer.GT: { relOperator = NumericCompareExpression.RelationalOperator.GT; break; } case InputData.PDDL.Traits.NumericComparer.GTE: { relOperator = NumericCompareExpression.RelationalOperator.GTE; break; } default: { Debug.Assert(false, "Unhandled operator!"); break; } } ExpressionStack.Push(new NumericCompareExpression(relOperator, firstArgument, secondArgument)); }
public void EnumFuncParam() { ExpressionParser parser = new ExpressionParser(); parser.RegisterAssembly(GetType().Assembly); Func <Color, Color> colorFunc = c => c; parser.RegisterFunction("color", colorFunc); INumericExpression expr = parser.ParseNumericExpression("color(Color.Green)"); Assert.NotNull(expr); Assert.Equal("color(Color.Green)", expr.ToString()); Assert.Equal((int)Color.Green, expr.Evaluate()); }
/// <summary> /// Processes primitive effects. /// </summary> /// <param name="relativeState">Relative state to be modified.</param> private void ProcessPrimitiveEffects(IRelativeState relativeState) { foreach (var positivePredicate in Effects.GroundedPositivePredicateEffects) { if (relativeState.HasPredicate(positivePredicate)) { relativeState.RemovePredicate(positivePredicate); } } foreach (var negatedPredicate in Effects.GroundedNegativePredicateEffects) { if (relativeState.HasNegatedPredicate(negatedPredicate)) { relativeState.RemoveNegatedPredicate(negatedPredicate); } } foreach (var objectFunction in Effects.GroundedObjectFunctionAssignmentEffects) { var groundedValue = GroundingManager.GroundTermDeep(objectFunction.Value, OperatorSubstitution, relativeState); ConstantTerm constantValue = groundedValue as ConstantTerm; if (constantValue != null) { if (relativeState.GetObjectFunctionValue(objectFunction.Key) == constantValue.NameId) { relativeState.AssignObjectFunction(objectFunction.Key, ObjectFunctionTerm.UndefinedValue); } } } foreach (var numericFunction in Effects.GroundedNumericFunctionAssignmentEffects) { NumericAssignmentsBackwardsReplacer replacer = new NumericAssignmentsBackwardsReplacer(Effects.GroundedNumericFunctionAssignmentEffects, GroundingManager, OperatorSubstitution, new Substitution()); INumericExpression reducedAssignExpression = replacer.Replace(numericFunction.Value); Number assignNumber = reducedAssignExpression as Number; if (assignNumber != null) { if (relativeState.GetNumericFunctionValue(numericFunction.Key).Equals(assignNumber.Value)) { relativeState.AssignNumericFunction(numericFunction.Key, NumericFunction.UndefinedValue); } } } }
public void NumericMethodFunctionTest() { ExpressionParser parser = new ExpressionParser(); parser.RegisterVariable("a", typeof(A)); INumericExpression expr = parser.ParseNumericExpression("1 + a.f(2,\"foo\",true)"); Assert.NotNull(expr); Assert.Equal("1 a.f(2,\"foo\",true) +", expr.ToString()); A a = new A(); Assert.Equal(1 + a.f(2, "foo", true), expr.Evaluate(new Dictionary <string, object> { { "a", a } })); }
public Func <Dictionary <string, object>, T> GetItemGetter <T>(int index) { IExpression itemExpr = Expressions[index]; Type itemType = typeof(T); if (ReflectionHelper.IsNumber(itemType)) { INumericExpression numericExpr = (INumericExpression)itemExpr; Func <double, T> converter = ReflectionHelper.GenerateFromDoubleConverter <T>(); return(variables => converter(numericExpr.Evaluate(variables))); } else if (itemType == typeof(bool)) { MethodInfo generateGetterMethod = GetType() .GetMethod("GetBooleanItemGetter", BindingFlags.NonPublic | BindingFlags.Static); Func <IBooleanExpression, Func <Dictionary <string, object>, T> > generateGetterDelegate = ReflectionHelper.CreateDelegate <IBooleanExpression, Func <Dictionary <string, object>, T> >(generateGetterMethod); IBooleanExpression booleanExpr = (IBooleanExpression)itemExpr; return(generateGetterDelegate(booleanExpr)); } else if (itemType == typeof(string)) { MethodInfo generateGetterMethod = GetType() .GetMethod("GetStringItemGetter", BindingFlags.NonPublic | BindingFlags.Static); Func <IStringExpression, Func <Dictionary <string, object>, T> > generateGetterDelegate = ReflectionHelper.CreateDelegate <IStringExpression, Func <Dictionary <string, object>, T> >(generateGetterMethod); IStringExpression booleanExpr = (IStringExpression)itemExpr; return(generateGetterDelegate(booleanExpr)); } else { IObjectExpression objectExpr = (IObjectExpression)itemExpr; return(variables => (T)objectExpr.GetInstance(variables)); } }
public void MemberAccessExpressionTest() { ExpressionParser parser = new ExpressionParser(); parser.RegisterVariable <A>("a"); INumericExpression expr = parser.ParseNumericExpression("1 + a.B.Id"); Assert.NotNull(expr); Assert.Equal("1 a.B.Id +", expr.ToString()); A a = new A { B = new B { Id = 12 } }; Assert.Equal(13, expr.Evaluate(new Dictionary <string, object> { { "a", a } })); }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public IElementCNF Visit(NumericCompareLiteralCNF expression) { // 1.) Evaluates both of the arguments by NumericAssignmentsBackwardsReplacer - every numeric function instance is replaced by // the available numeric assignments from effects and the whole numeric expression is reduced (partially or fully evaluated). // 2.) In case of the full reduction of both arguments, the numeric comparison is evaluated - if successfully, the whole condition // is satisfied and we can remove it (i.e. return null). // 3.) Otherwise, the modified numeric compare expression is returned, replacing the original condition. var numericAssignEffects = Effects.GroundedNumericFunctionAssignmentEffects; if (numericAssignEffects.Count == 0) { // no assignment effects available, just return a copy of the original expression return(expression.Clone()); } NumericAssignmentsBackwardsReplacer replacer = new NumericAssignmentsBackwardsReplacer(numericAssignEffects, GroundingManager, OperatorSubstitution, ExpressionSubstitution); INumericExpression newLeftNumericExpression = replacer.Replace(expression.LeftArgument); INumericExpression newRightNumericExpression = replacer.Replace(expression.RightArgument); UsedGroundedFunctions.UnionWith(replacer.ReplacedFunctionAtomsInSubExpression); Number leftNumber = newLeftNumericExpression as Number; Number rightNumber = newRightNumericExpression as Number; if (leftNumber != null && rightNumber != null) { bool relationHolds = NumericCompareExpression.ApplyCompare(expression.Operator, leftNumber.Value, rightNumber.Value); if ((relationHolds && !expression.IsNegated) || (!relationHolds && expression.IsNegated)) { // the numeric comparison was successful -> condition is satisfied, i.e. remove return(null); } } // modified numeric compare expression, replacing the original one return(new NumericCompareLiteralCNF(expression.Operator, newLeftNumericExpression, newRightNumericExpression, expression.IsNegated)); }
public void ObjectFunctionTest() { B[] items = new[] { new B { Id = 12 }, new B { Id = 13 } }; Func <int, B> func = n => items[n]; ExpressionParser parser = new ExpressionParser(); parser.RegisterFunction("item", func); INumericExpression expr = parser.ParseNumericExpression("1 + item(1).Id"); Assert.NotNull(expr); Assert.Equal("1 item(1).Id +", expr.ToString()); Assert.Equal(1 + items[1].Id, expr.Evaluate()); }
/// <summary> /// Transforms the numeric expression. /// </summary> /// <param name="expression">Numeric expression.</param> /// <returns>Transformed numeric expression.</returns> public INumericExpression Visit(NumericFunction expression) { IAtom functionAtom = GroundingManager.GroundAtom(expression.FunctionAtom, ExpressionSubstitution); if (!ReplacedFunctionAtomsInSubExpression.Contains(functionAtom)) { INumericExpression substitutedValue; if (NumericFunctionAssignments.TryGetValue(functionAtom, out substitutedValue)) { ReplacedFunctionAtomsInSubExpression.Add(functionAtom); ExpressionSubstitution.AddLocalSubstitution(OperatorSubstitution); INumericExpression transformedValue = substitutedValue.Accept(this); ExpressionSubstitution.RemoveLocalSubstitution(OperatorSubstitution); ReplacedFunctionAtomsInSubExpression.Remove(functionAtom); return(transformedValue); } } return(expression.Clone()); }
private IExpression ElementExpression(IExpression expr) { if (lexer.Peek(TokenType.OpenBracket)) { INumericExpression indexExpr = (INumericExpression)BracketExpression(); IObjectExpression listExpr = expr as IObjectExpression; if (listExpr == null) { throw BuildException("Cannot apply indexing with [] on expression", expr); } if (ReflectionHelper.IsNumberList(listExpr.ObjectType)) { expr = new NumericListElementExpression(listExpr, indexExpr); } else { expr = new ObjectListElementExpression(listExpr, indexExpr); } } return(expr); }
/// <summary> /// Replaces numeric function instances in the given numeric expression and the whole expression is partially or fully reduced. /// </summary> /// <param name="numericExpression">Numeric expression to be evaluated.</param> /// <returns>Transformed numeric expression.</returns> public INumericExpression Replace(INumericExpression numericExpression) { return(numericExpression.Accept(this)); }
/// <summary> /// Constructs the effect. /// </summary> /// <param name="functionAtom">Numeric function atom.</param> /// <param name="value">Numeric value to be assigned.</param> /// <param name="idManager">ID manager.</param> public NumericScaleUpEffect(IAtom functionAtom, INumericExpression value, IdManager idManager) : base(functionAtom, value, idManager) { }
/// <summary> /// Grounds the numeric expression by the given substitution and returns it. /// </summary> /// <param name="numericExpression">Numeric expression.</param> /// <param name="substitution">Substitution.</param> /// <returns>Grounded numeric expression.</returns> public INumericExpression GroundNumericExpression(INumericExpression numericExpression, ISubstitution substitution) { return(Grounder.Value.GroundNumericExpression(numericExpression, substitution)); }
/// <summary> /// Constructs the "unary minus" numeric expression. /// </summary> /// <param name="child">Child numeric expression.</param> public UnaryMinus(INumericExpression child) { Child = child; }
/// <summary> /// Constructs the "multiply" numeric expression. /// </summary> /// <param name="leftChild">Left numeric expression.</param> /// <param name="rightChild">Right numeric expression.</param> public Multiply(INumericExpression leftChild, INumericExpression rightChild) { Children = new List<INumericExpression> {leftChild, rightChild}; }
/// <summary> /// Grounds the expression. /// </summary> /// <param name="numericExpression">Numeric expression.</param> /// <param name="substitution">Variables substitution.</param> /// <returns>Grounded expression.</returns> public INumericExpression Ground(INumericExpression numericExpression, ISubstitution substitution) { Substitution = substitution; return(numericExpression.Accept(this)); }
/// <summary> /// Constructs the relation operator expression. /// </summary> /// <param name="relationalOperator">Relational operator.</param> /// <param name="leftArgument">Left numeric expression.</param> /// <param name="rightArgument">Right numeric expression.</param> public NumericCompareExpression(RelationalOperator relationalOperator, INumericExpression leftArgument, INumericExpression rightArgument) { Operator = relationalOperator; LeftArgument = leftArgument; RightArgument = rightArgument; }
/// <summary> /// Constructs the "minus" numeric expression. /// </summary> /// <param name="leftChild">Left numeric expression.</param> /// <param name="rightChild">Right numeric expression.</param> public Minus(INumericExpression leftChild, INumericExpression rightChild) { LeftChild = leftChild; RightChild = rightChild; }
/// <summary> /// Grounds the specified numeric expression. /// </summary> /// <param name="numericExpression">Numeric expression.</param> /// <returns>Grounded numeric expression.</returns> private INumericExpression GroundNumericExpression(INumericExpression numericExpression) { return(NumericExpressionsGrounder.Value.Ground(numericExpression, Substitution)); }