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;
 }
Beispiel #5
0
        /// <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 }
            }));
        }
Beispiel #12
0
        /// <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 }
            }));
        }
Beispiel #16
0
        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 }
            }));
        }
Beispiel #18
0
        /// <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());
        }
Beispiel #20
0
        /// <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);
        }
Beispiel #22
0
 /// <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));
 }
Beispiel #23
0
 /// <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));
 }
Beispiel #25
0
 /// <summary>
 /// Constructs the "unary minus" numeric expression.
 /// </summary>
 /// <param name="child">Child numeric expression.</param>
 public UnaryMinus(INumericExpression child)
 {
     Child = child;
 }
Beispiel #26
0
 /// <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;
 }
Beispiel #29
0
 /// <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));
 }