예제 #1
0
        //constructors
        public DiophantineRewriter()
        {
            _rewriter = new ExpressionRewriter();

            //Identity
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 1 * x, x => x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 0 * x, x => 0);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x + 0, x => x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 0 + x, x => x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x.Power(1), x => x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x.Power(0), x => 1);

            //Commutation
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType == ExpressionType.Constant &&
                p["x"].NodeType != ExpressionType.Constant,
                (x, y) => x * y,
                (x, y) => y * x);

            //Association
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >(
                p => p["x"].NodeType != ExpressionType.Constant ||
                p["y"].NodeType == ExpressionType.Constant,
                (x, y, z) => x * (y * z),
                (x, y, z) => (x * y) * z);
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >(
                p => p["x"].NodeType == ExpressionType.Constant &&
                p["y"].NodeType != ExpressionType.Constant,
                (x, y, z) => (x * y) * z,
                (x, y, z) => x * (y * z));

            //Distribution
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType != ExpressionType.Constant ||
                p["z"].NodeType != ExpressionType.Constant,
                (x, y, z) => x * (y + z),
                (x, y, z) => x * y + x * z);
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType != ExpressionType.Constant ||
                p["z"].NodeType != ExpressionType.Constant,
                (x, y, z) => (y + z) * x,
                (x, y, z) => y * x + z * x);

            //Factoring
            //_rewriter.AppendRule<Func<BigInteger, BigInteger, BigInteger>>((x, y) => x / y, (x, y) => x * y.Power(-1));
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >((x, y) => x - y, (x, y) => x + -1 * y);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => - x, x => - 1 * x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType == ExpressionType.Constant &&
                p["z"].NodeType == ExpressionType.Constant,
                (x, y, z) => (y * x) + (z * x),
                (x, y, z) => (y + z) * x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType == ExpressionType.Constant,
                (x, y) => x + y * x,
                (x, y) => (y + 1) * x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >(
                p => p["y"].NodeType == ExpressionType.Constant,
                (x, y) => y * x + x,
                (x, y) => (y + 1) * x);
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x + x, x => 2 * x);

            //Exponentation
            _rewriter.AppendRule <Func <BigInteger, BigInteger> >(
                p => p["x"].NodeType != ExpressionType.Add,
                x => x * x,
                x => x.Power(2));
            _rewriter.AppendRule <Func <BigInteger, int, BigInteger> >(
                p => p["x"].NodeType != ExpressionType.Add,
                (x, y) => x * x.Power(y),
                (x, y) => x.Power(y + 1));
            _rewriter.AppendRule <Func <int, BigInteger, BigInteger, BigInteger> >(
                p => p["x"].NodeType == ExpressionType.Constant && (int)((ConstantExpression)p["x"]).Value > 1,
                (x, y, z) => (y + z).Power(x),
                (x, y, z) => (y + z).Power(x - 1) * (y + z));
            _rewriter.AppendRule <Func <int, BigInteger, BigInteger, BigInteger> >((x, y, z) => (y * z).Power(x), (x, y, z) => y.Power(x) * z.Power(x));
            _rewriter.AppendRule <Func <BigInteger, int, int, BigInteger> >((x, y, z) => x.Power(y).Power(z), (x, y, z) => x.Power(y * z));
            _rewriter.AppendRule <Func <BigInteger, int, int, BigInteger> >((x, y, z) => x.Power(y) * x.Power(z), (x, y, z) => x.Power(y + z));
        }
예제 #2
0
        //constructors
        public RealRewriter()
        {
            _rewriter = new ExpressionRewriter(exp => exp.NodeType == ExpressionType.Call && ((MethodCallExpression)exp).Method.Name == "Diff");

            //Identity
            _rewriter.AppendRule <Func <double, double> >(x => 1.0 * x, x => x);
            _rewriter.AppendRule <Func <double, double> >(x => 0.0 * x, x => 0.0);
            _rewriter.AppendRule <Func <double, double> >(x => x + 0.0, x => x);
            _rewriter.AppendRule <Func <double, double> >(x => 0.0 + x, x => x);
            _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(x, 1.0), x => x);
            _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(1.0, x), x => 1.0);
            _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(x, 0.0), x => 1.0);
            _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(0.0, x), x => 0.0);

            //Commutation
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["y"].NodeType == ExpressionType.Constant &&
                p["x"].NodeType != ExpressionType.Constant,
                (x, y) => x * y,
                (x, y) => y * x);

            //Association
            _rewriter.AppendRule <Func <double, double, double, double> >(
                p => p["x"].NodeType != ExpressionType.Constant ||
                p["y"].NodeType == ExpressionType.Constant,
                (x, y, z) => x * (y * z),
                (x, y, z) => (x * y) * z);
            _rewriter.AppendRule <Func <double, double, double, double> >(
                p => p["x"].NodeType == ExpressionType.Constant &&
                p["y"].NodeType != ExpressionType.Constant,
                (x, y, z) => (x * y) * z,
                (x, y, z) => x * (y * z));

            //Distribution
            _rewriter.AppendRule <Func <double, double, double, double> >(
                p => p["y"].NodeType != ExpressionType.Constant ||
                p["z"].NodeType != ExpressionType.Constant,
                (x, y, z) => x * (y + z),
                (x, y, z) => x * y + x * z);
            _rewriter.AppendRule <Func <double, double, double, double> >(
                p => p["y"].NodeType != ExpressionType.Constant ||
                p["z"].NodeType != ExpressionType.Constant,
                (x, y, z) => (y + z) * x,
                (x, y, z) => y * x + z * x);

            //Factoring
            _rewriter.AppendRule <Func <double, double, double> >((x, y) => x / y, (x, y) => x * Math.Pow(y, -1.0));
            _rewriter.AppendRule <Func <double, double, double> >((x, y) => x - y, (x, y) => x + -1.0 * y);
            _rewriter.AppendRule <Func <double, double> >(x => - x, x => - 1.0 * x);
            _rewriter.AppendRule <Func <double, double, double, double> >(
                p => p["y"].NodeType == ExpressionType.Constant &&
                p["z"].NodeType == ExpressionType.Constant,
                (x, y, z) => (y * x) + (z * x),
                (x, y, z) => (y + z) * x);
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["y"].NodeType == ExpressionType.Constant,
                (x, y) => x + y * x,
                (x, y) => (y + 1.0) * x);
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["y"].NodeType == ExpressionType.Constant,
                (x, y) => y * x + x,
                (x, y) => (y + 1.0) * x);
            _rewriter.AppendRule <Func <double, double> >(x => x + x, x => 2.0 * x);

            //Exponentation
            _rewriter.AppendRule <Func <double, double> >(
                p => p["x"].NodeType != ExpressionType.Add,
                x => x * x,
                x => Math.Pow(x, 2.0));
            _rewriter.AppendRule <Func <double, int, double> >(
                p => p["x"].NodeType != ExpressionType.Add,
                (x, y) => x * Math.Pow(x, y),
                (x, y) => Math.Pow(x, y + 1.0));
            _rewriter.AppendRule <Func <int, double, double, double> >(
                p => p["x"].NodeType == ExpressionType.Constant && Math.Abs((double)((ConstantExpression)p["x"]).Value) > 1.0,
                (x, y, z) => Math.Pow(y + z, x),
                (x, y, z) => Math.Pow(y + z, x - 1.0) * (y + z));
            _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(y * z, x), (x, y, z) => Math.Pow(y, x) * Math.Pow(z, x));
            _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(Math.Pow(x, y), z), (x, y, z) => Math.Pow(x, y * z));
            _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(x, y) * Math.Pow(x, z), (x, y, z) => Math.Pow(x, y + z));
            _rewriter.AppendRule <Func <double, double> >(x => Math.Sqrt(x), x => Math.Pow(x, 0.5));
            _rewriter.AppendRule <Func <double, double> >(x => Math.Log10(x), x => Math.Log(x, 10.0));
            _rewriter.AppendRule <Func <double, double> >(x => Math.Abs(x) * Math.Abs(x), x => Math.Pow(x, 2.0));

            //general differentation
            _rewriter.AppendRule <Func <double, double, double> >(
                (x, y) => MathExt2.Diff(x * y),
                (x, y) => MathExt2.Diff(x) * y + x * MathExt2.Diff(y));
            _rewriter.AppendRule <Func <double, double, double> >(
                (x, y) => MathExt2.Diff(x + y),
                (x, y) => MathExt2.Diff(x) + MathExt2.Diff(y));

            //simple differentiation
            _rewriter.AppendRule <Func <double, double> >(
                p => p["c"].NodeType == ExpressionType.Constant,
                c => MathExt2.Diff(c),
                c => 0.0);
            _rewriter.AppendRule <Func <double, double> >(
                p => p["x"].NodeType == ExpressionType.Parameter,
                x => MathExt2.Diff(x),
                x => 1.0);
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Abs(x)),
                x => MathExt2.Diff(x) * x * Math.Pow(Math.Abs(x), -1.0));
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["c"].NodeType == ExpressionType.Constant,
                (x, c) => MathExt2.Diff(Math.Pow(x, c)),
                (x, c) => MathExt2.Diff(x) * c * Math.Pow(x, c - 1.0));

            //exponential and logarithm differentiation
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["c"].NodeType == ExpressionType.Constant,
                (c, x) => MathExt2.Diff(Math.Pow(c, x)),
                (c, x) => MathExt2.Diff(x) * Math.Pow(c, x) * Math.Log(c));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Exp(x)),
                x => Math.Exp(x));
            _rewriter.AppendRule <Func <double, double, double> >(
                p => p["c"].NodeType == ExpressionType.Constant,
                (c, x) => MathExt2.Diff(Math.Log(x, c)),
                (c, x) => MathExt2.Diff(x) * Math.Pow(x * Math.Log(c), -1.0));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Log(x)),
                x => MathExt2.Diff(x) * Math.Pow(x, -1.0));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Pow(x, x)),
                x => MathExt2.Diff(x) * Math.Pow(x, x) * (1.0 + Math.Log(x)));

            //trigonometric differentiation
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Sin(x)),
                x => MathExt2.Diff(x) * Math.Cos(x));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Cos(x)),
                x => MathExt2.Diff(x) * -1.0 * Math.Sin(x));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Tan(x)),
                x => MathExt2.Diff(x) * Math.Pow(Math.Cos(x), -2.0));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Asin(x)),
                x => MathExt2.Diff(x) * Math.Pow(1.0 - Math.Pow(x, 2.0), -0.5));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Acos(x)),
                x => MathExt2.Diff(x) * -1.0 * Math.Pow(1.0 - Math.Pow(x, 2.0), -0.5));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Atan(x)),
                x => MathExt2.Diff(x) * Math.Pow(1.0 + Math.Pow(x, 2.0), -1.0));

            //hyperbolic differentiation
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Sinh(x)),
                x => MathExt2.Diff(x) * Math.Cosh(x));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Cosh(x)),
                x => MathExt2.Diff(x) * Math.Sinh(x));
            _rewriter.AppendRule <Func <double, double> >(
                x => MathExt2.Diff(Math.Tan(x)),
                x => MathExt2.Diff(x) * Math.Pow(Math.Cosh(x), -2.0));
        }