예제 #1
0
        public static MathObject CheckVariableEqLs(this List <Equation> eqs, Symbol sym)
        {
            // (a == 10, a == 0)   ->   10 == 0   ->   false

            if (eqs.EliminateVariableEqLs(sym) == false)
            {
                return(false);
            }

            // (1/a != 0  &&  a != 0)   ->   a != 0

            if (eqs.Any(eq => eq.Operator == Equation.Operators.NotEqual && eq.a == sym && eq.b == 0)
                &&
                eqs.Any(eq => eq.Operator == Equation.Operators.NotEqual && eq.a == 1 / sym && eq.b == 0))
            {
                return(eqs
                       .Where(eq => (eq.Operator == Equation.Operators.NotEqual && eq.a == 1 / sym && eq.b == 0) == false)
                       .ToList()
                       .CheckVariableEqLs(sym));
            }

            // x + y == z && x / y == 0 && x != 0   -> false

            if (eqs.Any(eq => eq.Operator == Equation.Operators.Equal && eq.a.Numerator() == sym && eq.a.Denominator().FreeOf(sym) && eq.b == 0) &&
                eqs.Any(eq => eq == (sym != 0)))
            {
                return(false);
            }

            return(And.FromRange(eqs.Select(eq => eq as MathObject)));
        }
예제 #2
0
        public static MathObject IsolateVariable(this MathObject obj, Symbol sym)
        {
            if (obj is Or)
            {
                return(Or.FromRange((obj as Or).args.Select(elt => elt.IsolateVariable(sym))).Simplify());
            }

            if (obj is And)
            {
                return(And.FromRange((obj as And).args.Select(elt => elt.IsolateVariable(sym))).Simplify());
            }

            if (obj is Equation)
            {
                return((obj as Equation).IsolateVariableEq(sym));
            }

            throw new Exception();
        }
예제 #3
0
        public static MathObject LogicalExpand(this MathObject obj)
        {
            if (obj is Or)
            {
                return((obj as Or).Map(elt => elt.LogicalExpand()));
            }

            if (obj is And &&
                (obj as And).args.Any(elt => elt is Or) &&
                (obj as And).args.Count() > 1)
            {
                var before = new List <MathObject>();
                Or  or     = null;
                var after  = new List <MathObject>();

                foreach (var elt in (obj as And).args)
                {
                    if (elt is Or && or == null)
                    {
                        or = elt as Or;
                    }
                    else if (or == null)
                    {
                        before.Add(elt);
                    }
                    else
                    {
                        after.Add(elt);
                    }
                }

                return
                    (or.Map(or_elt =>
                            new And(
                                And.FromRange(before).Simplify().LogicalExpand(),
                                or_elt,
                                And.FromRange(after).Simplify().LogicalExpand()).Simplify()).LogicalExpand());
            }

            return(obj);
        }
예제 #4
0
        public static MathObject SimplifyLogical(this MathObject expr)
        {
            if (expr is And && (expr as And).args.HasDuplicates())
            {
                return(And.FromRange((expr as And).args.RemoveDuplicates()));
            }

            if (expr is Or && (expr as Or).args.HasDuplicates())
            {
                return
                    (Or.FromRange((expr as Or).args.RemoveDuplicates())
                     .SimplifyLogical());
            }

            if (expr is Or)
            {
                return((expr as Or).Map(elt => elt.SimplifyLogical()));
            }

            return(expr);
        }
예제 #5
0
        // EliminateVarAnd
        // EliminateVarOr
        // EliminateVarLs
        // EliminateVar

        // EliminateVars

        public static MathObject EliminateVariableEqLs(this List <Equation> eqs, Symbol sym)
        {
            if (eqs.Any(elt =>
                        elt.Operator == Equation.Operators.Equal &&
                        elt.Has(sym) &&
                        elt.AlgebraicExpand().Has(sym) &&
                        elt.IsolateVariableEq(sym).Has(obj => obj is Equation && (obj as Equation).a == sym && (obj as Equation).b.FreeOf(sym))
                        ) == false)
            {
                return(And.FromRange(eqs.Select(elt => elt as MathObject)));
            }

            var eq = eqs.First(elt =>
                               elt.Operator == Equation.Operators.Equal &&
                               elt.Has(sym) &&
                               elt.AlgebraicExpand().Has(sym) &&
                               elt.IsolateVariableEq(sym).Has(obj => obj is Equation && (obj as Equation).a == sym && (obj as Equation).b.FreeOf(sym)));

            var rest = eqs.Except(new List <Equation>()
            {
                eq
            });

            var result = eq.IsolateVariableEq(sym);

            // sym was not isolated

            if (result is Equation &&
                ((result as Equation).a != sym || (result as Equation).b.Has(sym)))
            {
                return(And.FromRange(eqs.Select(elt => elt as MathObject)));
            }

            if (result is Equation)
            {
                var eq_sym = result as Equation;

                return(And.FromRange(rest.Select(elt => elt.Substitute(sym, eq_sym.b))).Simplify());

                // return new And() { args = rest.Select(rest_eq => rest_eq.SubstituteEq(eq_sym)).ToList() };

                // rest.Map(rest_eq => rest_eq.Substitute(eq_sym)
            }

            // Or(
            //     And(eq0, eq1, eq2, ...)
            //     And(eq3, eq4, eq5, ...)
            // )

            if (result is Or && (result as Or).args.All(elt => elt is And))
            {
                return((result as Or).Map(elt => (elt as And).AddRange(rest).EliminateVariable(sym)));
            }

            if (result is Or)
            {
                var items = new List <MathObject>();

                foreach (Equation eq_sym in (result as Or).args)
                {
                    items.Add(new And(rest.Select(rest_eq => rest_eq.Substitute(sym, eq_sym.b)).ToArray()).Simplify());
                }

                return(Or.FromRange(items));
            }

            throw new Exception();
        }