Esempio n. 1
0
        public void ExponentSimplificationPass(MathExpression input, MathExpression expect, MathExpression[] expectRestrictions, bool allowRestrictions)
        {
            var context = OptimizationContext.CreateWith(new DefaultOptimizationSettings
            {
                AllowDomainChangingOptimizations = allowRestrictions
            }, new BuiltinExponentSimplificationPass());

            var restrictions = DomainRestrictionSettings.GetDomainRestrictionsFor(context);

            var actual = context.Optimize(input);

            Assert.Equal(expect, actual);
            Assert.Equal(expectRestrictions.Length, restrictions.Count);
            foreach (var restrict in expectRestrictions)
            {
                Assert.Contains(restrict, restrictions);
            }
        }
        /// <summary>
        /// Compiles the given expression using the provided context.
        /// </summary>
        /// <param name="expr">the <see cref="MathExpression"/> to compile</param>
        /// <param name="ctx">the context to compile in</param>
        /// <returns>the compiled <see cref="Expression"/></returns>
        public override Expression ApplyTo(MathExpression expr, ICompilationContext <TSettings> ctx)
        {
            try
            {
                if (!IsRootExpression(ctx))
                {
                    return(base.ApplyTo(expr, ctx));
                }

                SetRootExpression(ctx);

                SetTypeHint(ctx, ctx.Settings.ExpectReturn);
                var subexpr = base.ApplyTo(expr, ctx);
                if (subexpr.Type != ctx.Settings.ExpectReturn)
                {
                    subexpr = CompilerHelpers.ConvertToType(subexpr, ctx.Settings.ExpectReturn);
                }

                if (ctx.Settings is IDomainRestrictionSettings domainSettings && !domainSettings.IgnoreDomainRestrictions)
                {
                    var overflowCtor = Helpers.GetConstructor <Action>(() => new OverflowException(""));
                    subexpr = DomainRestrictionSettings.GetDomainRestrictionsFor(ctx)
                              .Select(e =>
                    {
                        SetTypeHint(ctx, typeof(bool));
                        return(x: CompilerHelpers.ConvertToType(base.ApplyTo(e, ctx), typeof(bool)), e);
                    })
                              .Aggregate(subexpr, (start, restrict) =>
                                         Expression.Condition(restrict.x,
                                                              Expression.Throw(Expression.New(overflowCtor, Expression.Constant($"{restrict.e} not in domain")), start.Type),
                                                              start));
                }

                return(subexpr);
            }
            catch (CompilationException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new CompilationException(expr, e);
            }
        }
Esempio n. 3
0
        public void CompileDomainRestriction(MathExpression expr, MathExpression restrict, Type expectType, object xarg, object result, bool shouldThrow)
        {
            var context = CompilationContext.CreateWith(new DefaultLinqExpressionCompilerSettings
            {
                ExpectReturn             = expectType,
                IgnoreDomainRestrictions = false,
            }, new DefaultLinqExpressionCompiler <DefaultLinqExpressionCompilerSettings>());

            var objParam = Expression.Parameter(typeof(object));
            var var      = Expression.Variable(expectType);

            context.Settings.ParameterMap.Add(new VariableExpression("x"), var);

            var restrictions = DomainRestrictionSettings.GetDomainRestrictionsFor(context);

            restrictions.Add(restrict);

            var fn = Expression.Lambda <Func <object, object> >(
                Expression.Block(
                    new[] { var },
                    Expression.Assign(var, Expression.Convert(objParam, expectType)),
                    Expression.Convert(
                        context.Compile(expr),
                        typeof(object)
                        )
                    ),
                objParam
                ).Compile();

            try
            {
                Assert.Equal(fn(xarg), result);
                Assert.False(shouldThrow, "Function should have thrown");
            }
            catch (Exception e)
            {
                Assert.True(shouldThrow, $"Function threw when it shouldn't have {e}");
            }
        }
Esempio n. 4
0
 private ICollection <MathExpression> GetDomainRestrictions(IDataContext ctx)
 => DomainRestrictionSettings.GetDomainRestrictionsFor(ctx);