From 6f766ec8ec1e847be62edfb98cebb5c1abf11216 Mon Sep 17 00:00:00 2001 From: haykflexgrigoryan Date: Wed, 23 Oct 2019 01:01:37 +0300 Subject: [PATCH 1/3] Created some basic MathMl serialization and added Norm function --- Symbolism/Symbolism.cs | 297 +++++++++++++++++++++++++++++++++++------ Tests/Tests.cs | 84 ++++++++++++ Tests/Tests.csproj | 11 +- 3 files changed, 347 insertions(+), 45 deletions(-) diff --git a/Symbolism/Symbolism.cs b/Symbolism/Symbolism.cs index e83d385..51514c2 100644 --- a/Symbolism/Symbolism.cs +++ b/Symbolism/Symbolism.cs @@ -23,6 +23,8 @@ namespace Symbolism { public abstract class MathObject { + public const string MathmlDeclaration = "{0}"; + public const string EmptyMathmlDeclaration = "{}"; ////////////////////////////////////////////////////////////////////// public static implicit operator MathObject(int n) => new Integer(n); @@ -137,6 +139,10 @@ public override string ToString() throw new Exception(); } + public virtual MathObject Parent { get; set; } + + public virtual string ToMathml(bool useMathmlDeclaration = false) => string.Empty; + public virtual MathObject Numerator() => this; public virtual MathObject Denominator() => 1; @@ -171,6 +177,19 @@ public override string FullForm() throw new Exception(); } + public override string ToMathml(bool useMathmlDeclaration = false) + { + var equalsResult = a.ToMathml() + "=" + b.ToMathml(); + var notEqualsResult = a.ToMathml() + "" + b.ToMathml(); + var lessThenResult = a.ToMathml() + "<" + b.ToMathml(); + var greaterThenResult = a.ToMathml() + ">" + b.ToMathml(); + if (Operator == Operators.Equal) return useMathmlDeclaration ? string.Format(MathmlDeclaration, equalsResult) : equalsResult; + if (Operator == Operators.NotEqual) return useMathmlDeclaration ? string.Format(MathmlDeclaration, notEqualsResult) : notEqualsResult; + if (Operator == Operators.LessThan) return useMathmlDeclaration ? string.Format(MathmlDeclaration, lessThenResult) : lessThenResult; + if (Operator == Operators.GreaterThan) return useMathmlDeclaration ? string.Format(MathmlDeclaration, greaterThenResult) : greaterThenResult; + throw new Exception(); + } + public override bool Equals(object obj) => obj is Equation && a.Equals((obj as Equation).a) && @@ -272,7 +291,7 @@ public class Integer : Number public Integer(int n) { val = n; } public Integer(BigInteger n) { val = n; } - + public static implicit operator Integer(BigInteger n) => new Integer(n); // public static MathObject operator *(MathObject a, MathObject b) => new Product(a, b).Simplify(); @@ -288,6 +307,12 @@ public class Integer : Number public override int GetHashCode() => val.GetHashCode(); public override DoubleFloat ToDouble() => new DoubleFloat((double)val); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + var result = $"{val}"; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } } public class DoubleFloat : Number @@ -321,6 +346,14 @@ public override bool Equals(object obj) public override int GetHashCode() => val.GetHashCode(); public override DoubleFloat ToDouble() => this; + + public override string ToMathml(bool useMathmlDeclaration = false) + { + var arr = val.ToString().Split('.'); + var rest = arr.Length > 1 ? $".{arr[1]}" : string.Empty; + var result = $"{arr[0]}{rest}"; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } } public class Fraction : Number @@ -346,16 +379,124 @@ public override bool Equals(object obj) => public override MathObject Numerator() => numerator; public override MathObject Denominator() => denominator; + + public override string ToMathml(bool useMathmlDeclaration = false) + { + if (new Norm(numerator).Simplify() < denominator || numerator == denominator) + { + var result = $"{numerator.ToMathml()}{denominator.ToMathml()}"; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } + + BigInteger rem; + + var quot = BigInteger.DivRem(numerator.val, denominator.val, out rem); + return new MixedNumber(new Integer(quot), new Norm(rem).Simplify() as Integer, denominator).ToMathml(); + } + } + + public class MixedNumber : Number + { + public Integer quotient; + public Integer numerator; + public Integer denominator; + + public MixedNumber(Integer q, Integer a, Integer b) + { + quotient = q; + numerator = a; + denominator = b; + } + + public override string FullForm() => $"({quotient} + {numerator} / {denominator})"; + + public override string ToMathml(bool useMathmlDeclaration = false) + { + var result = $"{quotient.ToMathml()}{numerator.ToMathml()}{denominator.ToMathml()}"; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } + + public Fraction ToFraction() => new Fraction((quotient * denominator + numerator) as Integer, denominator); + public override DoubleFloat ToDouble() => this.ToFraction().ToDouble(); + ////////////////////////////////////////////////////////////////////// + + public override bool Equals(object obj) => + quotient == (obj as MixedNumber)?.quotient + && + numerator == (obj as Fraction)?.numerator + && + denominator == (obj as Fraction)?.denominator; + + public override int GetHashCode() => new { quotient, numerator, denominator }.GetHashCode(); + + public override MathObject Numerator() => numerator; + + public MathObject Quotient() => quotient; + + public override MathObject Denominator() => denominator; + } + + + public class Norm : Function + { + private MathObject _x; + + public Norm(MathObject x) : base(null, null, null) + { + name = "norm"; + _x = x; + args = ImmutableList.Create(_x); + proc = NormProc; + } + + MathObject NormProc(MathObject[] ls) + { + if (ls[0] == null) + { + return 0; + } + + if (ls[0] is Number) + { + if ((Number)ls[0] > new DoubleFloat(0) || (Number)ls[0] == new DoubleFloat(0)) + { + return ls[0]; + } + + return -1 * ls[0]; + } + + if (ls[0] is Product && ((Product)ls[0]).elts[0] == -1) + { + return new Norm(-1 * ls[0]); + } + + return new Norm(ls[0]); + } + + //public override bool Equals(object obj) => + // GetType() == obj.GetType() && + // name == (obj as Function).name && + // this.Simplify() == ((Norm)obj).Simplify(); + + public override int GetHashCode() => new { name, args }.GetHashCode(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + var result = $"{args[0].ToMathml()}"; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } } + public static class Rational { static BigInteger Div(BigInteger a, BigInteger b) { BigInteger rem; return BigInteger.DivRem(a, b, out rem); } - + static BigInteger Rem(BigInteger a, BigInteger b) { BigInteger rem; BigInteger.DivRem(a, b, out rem); return rem; } - + static BigInteger Gcd(BigInteger a, BigInteger b) { BigInteger r; @@ -377,13 +518,13 @@ public static MathObject SimplifyRationalNumber(MathObject u) var u_ = (Fraction)u; var n = u_.numerator.val; var d = u_.denominator.val; - + if (Rem(n, d) == 0) return Div(n, d); var g = Gcd(n, d); - + if (d > 0) return new Fraction(Div(n, g), Div(d, g)); - + if (d < 0) return new Fraction(Div(-n, g), Div(-d, g)); } @@ -437,7 +578,7 @@ public static Integer Denominator(MathObject u) throw new Exception(); } - public static Fraction EvaluateSum(MathObject v, MathObject w) => + public static Fraction EvaluateSum(MathObject v, MathObject w) => // a / b + c / d // a d / b d + c b / b d @@ -446,13 +587,13 @@ public static Fraction EvaluateSum(MathObject v, MathObject w) => new Fraction( Numerator(v) * Denominator(w) + Numerator(w) * Denominator(v), Denominator(v) * Denominator(w)); - + public static Fraction EvaluateDifference(MathObject v, MathObject w) => new Fraction( Numerator(v) * Denominator(w) - Numerator(w) * Denominator(v), Denominator(v) * Denominator(w)); - public static Fraction EvaluateProduct(MathObject v, MathObject w) => + public static Fraction EvaluateProduct(MathObject v, MathObject w) => new Fraction( Numerator(v) * Numerator(w), Denominator(v) * Denominator(w)); @@ -474,7 +615,7 @@ public static MathObject EvaluatePower(MathObject v, BigInteger n) if (n > 0) return EvaluateProduct(EvaluatePower(v, n - 1), v); if (n == 0) return 1; - + if (n == -1) return new Fraction(Denominator(v), Numerator(v)); if (n < -1) @@ -484,7 +625,7 @@ public static MathObject EvaluatePower(MathObject v, BigInteger n) return EvaluatePower(s, -n); } } - + if (n >= 1) return 0; if (n <= 0) return new Undefined(); @@ -507,7 +648,7 @@ public static MathObject SimplifyRNERec(MathObject u) var v = SimplifyRNERec(((Difference)u).elts[0]); if (v == new Undefined()) return v; - + return EvaluateProduct(-1, v); } @@ -591,6 +732,12 @@ public class Symbol : MathObject public override bool Equals(Object obj) => obj is Symbol ? name == (obj as Symbol).name : false; + + public override string ToMathml(bool useMathmlDeclaration = false) + { + var result = string.Format("{0}", name); + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } } public static class ListConstructor @@ -602,9 +749,9 @@ public static class ListConstructor public static class ListUtils { - public static ImmutableList Cons(this ImmutableList obj, MathObject elt) => + public static ImmutableList Cons(this ImmutableList obj, MathObject elt) => obj.Insert(0, elt); - + public static ImmutableList Cdr(this ImmutableList obj) => obj.RemoveAt(0); public static bool equal(ImmutableList a, ImmutableList b) @@ -625,11 +772,11 @@ public class Function : MathObject { public delegate MathObject Proc(params MathObject[] ls); - public readonly String name; + public String name { get; protected set; } + + public Proc proc { get; protected set; } - public readonly Proc proc; - - public readonly ImmutableList args; + public ImmutableList args { get; protected set; } public Function(string name, Proc proc, IEnumerable args) { @@ -637,7 +784,7 @@ public Function(string name, Proc proc, IEnumerable args) this.proc = proc; this.args = ImmutableList.CreateRange(args); } - + public override bool Equals(object obj) => GetType() == obj.GetType() && name == (obj as Function).name && @@ -659,7 +806,7 @@ public static class FunctionExtensions // // return new T() { args = obj.args.Select(proc).ToList() }.Simplify(); // // return - + //} } @@ -675,7 +822,7 @@ static MathObject AndProc(MathObject[] ls) if (ls.Any(elt => elt == true)) return new And(ls.Where(elt => elt != true).ToArray()).Simplify(); - + if (ls.Any(elt => elt is And)) { var items = new List(); @@ -692,7 +839,7 @@ static MathObject AndProc(MathObject[] ls) return new And(ls); } - + public And(params MathObject[] ls) : base("and", AndProc, ls) { } public And() : base("and", AndProc, new List()) { } @@ -704,9 +851,14 @@ public MathObject Add(MathObject obj) => public MathObject AddRange(IEnumerable ls) => And.FromRange(args.AddRange(ls)).Simplify(); - - public MathObject Map(Func proc) => + + public MathObject Map(Func proc) => And.FromRange(args.Select(proc)).Simplify(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + return $"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}"; + } } public class Or : Function @@ -723,7 +875,7 @@ static MathObject OrProc(params MathObject[] ls) if (ls.Any(elt => (elt is Bool) && (elt as Bool).val)) return new Bool(true); if (ls.All(elt => (elt is Bool) && (elt as Bool).val == false)) return new Bool(false); - + if (ls.Any(elt => elt is Or)) { var items = new List(); @@ -733,13 +885,13 @@ static MathObject OrProc(params MathObject[] ls) if (elt is Or) items.AddRange((elt as Or).args); else items.Add(elt); } - + return Or.FromRange(items).Simplify(); } return new Or(ls); } - + public Or(params MathObject[] ls) : base("or", OrProc, ls) { } public Or() : base("or", OrProc, new List()) { } @@ -747,6 +899,11 @@ public Or(params MathObject[] ls) : base("or", OrProc, ls) { } public static Or FromRange(IEnumerable ls) => new Or(ls.ToArray()); public MathObject Map(Func proc) => Or.FromRange(args.Select(proc)).Simplify(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + return $"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}"; + } } public static class OrderRelation @@ -759,7 +916,7 @@ public static MathObject Term(this MathObject u) { if (u is Product && ((Product)u).elts[0] is Number) return Product.FromRange((u as Product).elts.Cdr()); - // return (u as Product).Cdr() + // return (u as Product).Cdr() if (u is Product) return u; @@ -829,7 +986,7 @@ public static bool Compare(MathObject u, MathObject v) return O3( (u as Product).elts.Reverse(), (v as Product).elts.Reverse()); - + if (u is Sum && v is Sum) return O3( (u as Sum).elts.Reverse(), @@ -938,7 +1095,7 @@ public MathObject Simplify() return Rational.SimplifyRNE(new Power(v, n)); if (v is DoubleFloat && w is Integer) - return new DoubleFloat(Math.Pow(((DoubleFloat)v).val, (double) ((Integer)w).val)); + return new DoubleFloat(Math.Pow(((DoubleFloat)v).val, (double)((Integer)w).val)); if (v is DoubleFloat && w is Fraction) return new DoubleFloat(Math.Pow(((DoubleFloat)v).val, ((Fraction)w).ToDouble().val)); @@ -954,7 +1111,7 @@ public MathObject Simplify() if (v is Product && w is Integer) return (v as Product).Map(elt => elt ^ w); - + return new Power(v, w); } @@ -977,12 +1134,30 @@ public override MathObject Denominator() } public override int GetHashCode() => new { bas, exp }.GetHashCode(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + if (exp == new Integer(1) / new Integer(2)) + { + return $"{bas.ToMathml()}"; + } + + if (exp is Fraction && (exp as Fraction).numerator == 1) + { + return $"{bas.ToMathml()}{(exp as Fraction).denominator.ToMathml()}"; + } + + return string.Format("{0}{1}", + bas.Precedence() < Precedence() ? $"{bas.ToMathml()}" : $"{bas.ToMathml()}", + exp.Precedence() < Precedence() ? $"{exp.ToMathml()}" : $"{exp.ToMathml()}"); + + } } public class Product : MathObject { public readonly ImmutableList elts; - + public Product(params MathObject[] ls) => elts = ImmutableList.Create(ls); public static Product FromRange(IEnumerable ls) => new Product(ls.ToArray()); @@ -1050,7 +1225,7 @@ static ImmutableList SimplifyDoubleNumberProduct(DoubleFloat a, Numb if (b is Integer) val = a.val * (double)((Integer)b).val; if (b is Fraction) val = a.val * ((Fraction)b).ToDouble().val; - + if (val == 1.0) return ImmutableList.Create(); return ImList(new DoubleFloat(val)); @@ -1084,7 +1259,7 @@ public static ImmutableList RecursiveSimplify(ImmutableList(); return ImList(P); @@ -1099,7 +1274,7 @@ public static ImmutableList RecursiveSimplify(ImmutableList(); return ImList(res); @@ -1137,9 +1312,9 @@ public MathObject Simplify() // Without the below, the following throws an exception: // sqrt(a * b) * (sqrt(a * b) / a) / c - + if (res.Any(elt => elt is Product)) return Product.FromRange(res).Simplify(); - + return Product.FromRange(res); } @@ -1151,13 +1326,22 @@ public override MathObject Denominator() => public MathObject Map(Func proc) => Product.FromRange(elts.Select(proc)).Simplify(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + return string.Join("·", elts.ConvertAll(elt => elt.Precedence() < Precedence() ? $"{elt.ToMathml()}" : $"{elt.ToMathml()}")); + } } public class Sum : MathObject { public readonly ImmutableList elts; - public Sum(params MathObject[] ls) { elts = ImmutableList.Create(ls); } + public Sum(params MathObject[] ls) + { + elts = ImmutableList.Create(ls); + elts.ForEach(e => { e.Parent = this; }); + } public static Sum FromRange(IEnumerable ls) => new Sum(ls.ToArray()); @@ -1201,7 +1385,7 @@ static ImmutableList SimplifyDoubleNumberSum(DoubleFloat a, Number b if (b is Fraction) val = a.val + ((Fraction)b).ToDouble().val; if (val == 0.0) return ImmutableList.Create(); - + return ImmutableList.Create(new DoubleFloat(val)); } @@ -1239,7 +1423,7 @@ static ImmutableList RecursiveSimplify(ImmutableList elt (elts[1] is Integer || elts[1] is Fraction)) { var P = Rational.SimplifyRNE(new Sum(elts[0], elts[1])); - + if (P == 0) return ImmutableList.Create(); return ImList(P); @@ -1312,6 +1496,37 @@ public override string StandardForm() public MathObject Map(Func proc) => Sum.FromRange(elts.Select(proc)).Simplify(); + + public override string ToMathml(bool useMathmlDeclaration = false) + { + string mathmlResult = string.Empty; + int count = 0; + foreach (var item in elts) + { + if (item is Product && (item as Product).elts[0] is Number) + { + if (((item as Product).elts[0] as Number).ToDouble().val < 0) + { + mathmlResult = string.Concat(mathmlResult, "-", (-1 * item).ToMathml()); + } + else + { + mathmlResult = string.Concat(mathmlResult, count == 0 ? string.Empty : "+", item.ToMathml()); + } + } + else + { + mathmlResult = string.Concat(mathmlResult, count == 0 ? string.Empty : "+", item.ToMathml()); + } + + count++; + } + + var result = mathmlResult; + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + + //return String.Join("+", elts.ConvertAll(elt => elt.Precedence() < Precedence() ? $"{elt.ToMathml()})" : $"{elt.ToMathml()}")); + } } class Difference : MathObject @@ -1333,7 +1548,7 @@ public MathObject Simplify() class Quotient : MathObject { public readonly ImmutableList elts; - + public Quotient(params MathObject[] ls) => elts = ImmutableList.Create(ls); public MathObject Simplify() => elts[0] * (elts[1] ^ -1); diff --git a/Tests/Tests.cs b/Tests/Tests.cs index 842bea9..1714f7a 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -6776,5 +6776,89 @@ public void PSE_5E_Example_8_5() .AssertEqTo(ΔE == -302.0); } } + + [Fact] + public void SummeryTest() + { + var expected = "5+6"; + //var expected = "11"; + // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + var mo = new Sum(new Integer(5), 6); + var mathml = mo.ToMathml(true); + Assert.Equal(expected, mathml); + + } + //[Fact] + //public void SummeryTest() + //{ + // var mathml = "5+6"; + // var expected = "11"; + // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + // mathml = "5.64+7.83"; + // expected = "1347100"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + // mathml = "3.89-4.78"; + // expected = "-89100"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + // mathml = "5-6-7"; + // expected = "6"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + // mathml = "-2.2-3.4"; + // expected = "115"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + // mathml = "-3.4-2.2"; + // expected = "-115"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + + + // mathml = "12+45"; + // expected = "1310"; + + // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + //} + + //[TestMethod] + //public void ComplexExpressionsTest() + //{ + // var mathml = "1.88+2325·3160.625-1318:269+0.2160.15+0.56:0.57.7:2434+215·4.5"; + // var expected = "4"; + // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); + // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); + + // Assert.AreEqual(expected, mathResult); + //} } } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index afddea6..fb9dfa2 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.2 @@ -7,9 +7,12 @@ - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 8a90d19d1aec4c919d83b4eb434677798e34d69b Mon Sep 17 00:00:00 2001 From: Hakob Grigoryan Date: Wed, 23 Oct 2019 10:09:58 +0300 Subject: [PATCH 2/3] Refactoring after mathml serializer --- Symbolism/Symbolism.cs | 54 ++++++++++++-------------- Symbolism/Utils.cs | 50 +++++++----------------- Tests/Tests.cs | 88 ++++++++---------------------------------- 3 files changed, 55 insertions(+), 137 deletions(-) diff --git a/Symbolism/Symbolism.cs b/Symbolism/Symbolism.cs index 51514c2..bc23fb4 100644 --- a/Symbolism/Symbolism.cs +++ b/Symbolism/Symbolism.cs @@ -143,6 +143,11 @@ public override string ToString() public virtual string ToMathml(bool useMathmlDeclaration = false) => string.Empty; + protected static string ToMathml(string result, bool useMathmlDeclaration = false) + { + return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + } + public virtual MathObject Numerator() => this; public virtual MathObject Denominator() => 1; @@ -151,6 +156,7 @@ public override bool Equals(object obj) { throw new Exception("MathObject.Equals called - abstract class"); } public override int GetHashCode() => base.GetHashCode(); + } public class Equation : MathObject @@ -179,14 +185,10 @@ public override string FullForm() public override string ToMathml(bool useMathmlDeclaration = false) { - var equalsResult = a.ToMathml() + "=" + b.ToMathml(); - var notEqualsResult = a.ToMathml() + "" + b.ToMathml(); - var lessThenResult = a.ToMathml() + "<" + b.ToMathml(); - var greaterThenResult = a.ToMathml() + ">" + b.ToMathml(); - if (Operator == Operators.Equal) return useMathmlDeclaration ? string.Format(MathmlDeclaration, equalsResult) : equalsResult; - if (Operator == Operators.NotEqual) return useMathmlDeclaration ? string.Format(MathmlDeclaration, notEqualsResult) : notEqualsResult; - if (Operator == Operators.LessThan) return useMathmlDeclaration ? string.Format(MathmlDeclaration, lessThenResult) : lessThenResult; - if (Operator == Operators.GreaterThan) return useMathmlDeclaration ? string.Format(MathmlDeclaration, greaterThenResult) : greaterThenResult; + if (Operator == Operators.Equal) return ToMathml(a.ToMathml() + "=" + b.ToMathml(), useMathmlDeclaration); + if (Operator == Operators.NotEqual) return ToMathml(a.ToMathml() + "" + b.ToMathml(), useMathmlDeclaration); + if (Operator == Operators.LessThan) return ToMathml(a.ToMathml() + "<" + b.ToMathml(), useMathmlDeclaration); + if (Operator == Operators.GreaterThan) return ToMathml(a.ToMathml() + ">" + b.ToMathml(), useMathmlDeclaration); throw new Exception(); } @@ -310,8 +312,7 @@ public class Integer : Number public override string ToMathml(bool useMathmlDeclaration = false) { - var result = $"{val}"; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml($"{val}", useMathmlDeclaration); } } @@ -351,8 +352,7 @@ public override string ToMathml(bool useMathmlDeclaration = false) { var arr = val.ToString().Split('.'); var rest = arr.Length > 1 ? $".{arr[1]}" : string.Empty; - var result = $"{arr[0]}{rest}"; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml($"{arr[0]}{rest}", useMathmlDeclaration); } } @@ -384,14 +384,13 @@ public override string ToMathml(bool useMathmlDeclaration = false) { if (new Norm(numerator).Simplify() < denominator || numerator == denominator) { - var result = $"{numerator.ToMathml()}{denominator.ToMathml()}"; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml($"{numerator.ToMathml()}{denominator.ToMathml()}", useMathmlDeclaration); } BigInteger rem; var quot = BigInteger.DivRem(numerator.val, denominator.val, out rem); - return new MixedNumber(new Integer(quot), new Norm(rem).Simplify() as Integer, denominator).ToMathml(); + return new MixedNumber(new Integer(quot), new Norm(rem).Simplify() as Integer, denominator).ToMathml(useMathmlDeclaration); } } @@ -412,8 +411,7 @@ public MixedNumber(Integer q, Integer a, Integer b) public override string ToMathml(bool useMathmlDeclaration = false) { - var result = $"{quotient.ToMathml()}{numerator.ToMathml()}{denominator.ToMathml()}"; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml($"{quotient.ToMathml()}{numerator.ToMathml()}{denominator.ToMathml()}", useMathmlDeclaration); } public Fraction ToFraction() => new Fraction((quotient * denominator + numerator) as Integer, denominator); @@ -483,8 +481,7 @@ MathObject NormProc(MathObject[] ls) public override string ToMathml(bool useMathmlDeclaration = false) { - var result = $"{args[0].ToMathml()}"; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml($"{args[0].ToMathml()}", useMathmlDeclaration); } } @@ -735,8 +732,7 @@ public override bool Equals(Object obj) => public override string ToMathml(bool useMathmlDeclaration = false) { - var result = string.Format("{0}", name); - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml(string.Format("{0}", name), useMathmlDeclaration); } } @@ -857,7 +853,7 @@ public MathObject Map(Func proc) => public override string ToMathml(bool useMathmlDeclaration = false) { - return $"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}"; + return ToMathml($"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}", useMathmlDeclaration); } } @@ -902,7 +898,7 @@ public Or(params MathObject[] ls) : base("or", OrProc, ls) { } public override string ToMathml(bool useMathmlDeclaration = false) { - return $"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}"; + return ToMathml($"{string.Join(",", args.ConvertAll(arg => arg.ToMathml()))}", useMathmlDeclaration); } } @@ -1139,17 +1135,17 @@ public override string ToMathml(bool useMathmlDeclaration = false) { if (exp == new Integer(1) / new Integer(2)) { - return $"{bas.ToMathml()}"; + return ToMathml($"{bas.ToMathml()}", useMathmlDeclaration); } if (exp is Fraction && (exp as Fraction).numerator == 1) { - return $"{bas.ToMathml()}{(exp as Fraction).denominator.ToMathml()}"; + return ToMathml($"{bas.ToMathml()}{(exp as Fraction).denominator.ToMathml()}", useMathmlDeclaration); } - return string.Format("{0}{1}", + return ToMathml(string.Format("{0}{1}", bas.Precedence() < Precedence() ? $"{bas.ToMathml()}" : $"{bas.ToMathml()}", - exp.Precedence() < Precedence() ? $"{exp.ToMathml()}" : $"{exp.ToMathml()}"); + exp.Precedence() < Precedence() ? $"{exp.ToMathml()}" : $"{exp.ToMathml()}"), useMathmlDeclaration); } } @@ -1329,7 +1325,7 @@ public MathObject Map(Func proc) => public override string ToMathml(bool useMathmlDeclaration = false) { - return string.Join("·", elts.ConvertAll(elt => elt.Precedence() < Precedence() ? $"{elt.ToMathml()}" : $"{elt.ToMathml()}")); + return ToMathml(string.Join("·", elts.ConvertAll(elt => elt.Precedence() < Precedence() ? $"{elt.ToMathml()}" : $"{elt.ToMathml()}")), useMathmlDeclaration); } } @@ -1523,7 +1519,7 @@ public override string ToMathml(bool useMathmlDeclaration = false) } var result = mathmlResult; - return useMathmlDeclaration ? string.Format(MathmlDeclaration, result) : result; + return ToMathml(result, useMathmlDeclaration); //return String.Join("+", elts.ConvertAll(elt => elt.Precedence() < Precedence() ? $"{elt.ToMathml()})" : $"{elt.ToMathml()}")); } diff --git a/Symbolism/Utils.cs b/Symbolism/Utils.cs index 73d8d6a..ecaee28 100644 --- a/Symbolism/Utils.cs +++ b/Symbolism/Utils.cs @@ -6,42 +6,18 @@ namespace Symbolism.Utils { public static class Extensions { - public static T Disp(this T obj) - { - Console.WriteLine(obj); - return obj; - } - - public static T Disp(this T obj, string format) - { - Console.WriteLine(string.Format(format, obj)); - return obj; - } - - public static MathObject DispLong(this MathObject obj, int indent = 0, bool comma = false) - { - if (obj is Or || obj is And) - { - Console.WriteLine(new String(' ', indent) + (obj as Function).name + "("); - - var i = 0; - - foreach (var elt in (obj as Function).args) - { - if (i < (obj as Function).args.Count - 1) - elt.DispLong(indent + 2, comma: true); - else - elt.DispLong(indent + 2); - - i++; - } - - Console.WriteLine(new String(' ', indent) + ")" + (comma ? "," : "")); - } - - else Console.WriteLine(new String(' ', indent) + obj + (comma ? "," : "")); - - return obj; - } + //public static T Disp(this T obj) + //{ + // Console.WriteLine(obj); + // return obj; + //} + + //public static T Disp(this T obj, string format) + //{ + // Console.WriteLine(string.Format(format, obj)); + // return obj; + //} + + } } diff --git a/Tests/Tests.cs b/Tests/Tests.cs index 1714f7a..1e77204 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -6781,84 +6781,30 @@ public void PSE_5E_Example_8_5() public void SummeryTest() { var expected = "5+6"; - //var expected = "11"; - // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); - var mo = new Sum(new Integer(5), 6); var mathml = mo.ToMathml(true); Assert.Equal(expected, mathml); - } - //[Fact] - //public void SummeryTest() - //{ - // var mathml = "5+6"; - // var expected = "11"; - // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - // mathml = "5.64+7.83"; - // expected = "1347100"; - - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - // mathml = "3.89-4.78"; - // expected = "-89100"; - - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - // mathml = "5-6-7"; - // expected = "6"; - - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - // mathml = "-2.2-3.4"; - // expected = "115"; - - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - // mathml = "-3.4-2.2"; - // expected = "-115"; - - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); - - // Assert.AreEqual(expected, mathResult); - - - // mathml = "12+45"; - // expected = "1310"; + expected = "x+y"; + mo = new Sum(new Symbol("x"), new Symbol("y")); + mathml = mo.ToMathml(true); + Assert.Equal(expected, mathml); - // factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // mathResult = factory.GetGroup(null).Calculate().ToMathML(); + } - // Assert.AreEqual(expected, mathResult); - //} + [Fact] + public void DotTest() + { + var expected = "5·6"; + var mo = new Product(new Integer(5), 6); + var mathml = mo.ToMathml(true); + Assert.Equal(expected, mathml); - //[TestMethod] - //public void ComplexExpressionsTest() - //{ - // var mathml = "1.88+2325·3160.625-1318:269+0.2160.15+0.56:0.57.7:2434+215·4.5"; - // var expected = "4"; - // var factory = MathmlToAlgebraConverter.ToMathFactory(mathml); - // var mathResult = factory.GetGroup(null).Calculate().ToMathML(); + expected = "x·y·z"; + mo = new Product(new Symbol("x"), new Symbol("y"), new Symbol("z")); + mathml = mo.ToMathml(true); + Assert.Equal(expected, mathml); - // Assert.AreEqual(expected, mathResult); - //} + } } } From 43a6cc708919cb16054ee350bb4bd180ede72674 Mon Sep 17 00:00:00 2001 From: Hakob Grigoryan Date: Wed, 23 Oct 2019 10:23:49 +0300 Subject: [PATCH 3/3] got rid parent from mathobject and fixed Norm function --- Symbolism/Symbolism.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Symbolism/Symbolism.cs b/Symbolism/Symbolism.cs index bc23fb4..b038f36 100644 --- a/Symbolism/Symbolism.cs +++ b/Symbolism/Symbolism.cs @@ -139,8 +139,6 @@ public override string ToString() throw new Exception(); } - public virtual MathObject Parent { get; set; } - public virtual string ToMathml(bool useMathmlDeclaration = false) => string.Empty; protected static string ToMathml(string result, bool useMathmlDeclaration = false) @@ -437,14 +435,9 @@ public override bool Equals(object obj) => public class Norm : Function { - private MathObject _x; - - public Norm(MathObject x) : base(null, null, null) + public Norm(MathObject x) : base("norm", null, new List { x}) { - name = "norm"; - _x = x; - args = ImmutableList.Create(_x); - proc = NormProc; + this.proc = proc??NormProc; } MathObject NormProc(MathObject[] ls) @@ -1336,7 +1329,6 @@ public class Sum : MathObject public Sum(params MathObject[] ls) { elts = ImmutableList.Create(ls); - elts.ForEach(e => { e.Parent = this; }); } public static Sum FromRange(IEnumerable ls) => new Sum(ls.ToArray());