From 9fc9ce56ccf9cb527d038666bdb623d2c4f55dd3 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 22 Jan 2026 23:08:10 +0800 Subject: [PATCH] Stringize provided as associative --- Sources/AngouriMath/Core/Antlr/AngouriMath.g | 4 +++- .../AngouriMath/Functions/Output/Latex/Latex.Omni.Classes.cs | 4 ++-- .../Functions/Output/ToString/ToString.Omni.Classes.cs | 2 +- Sources/Tests/UnitTests/Convenience/FromStringTest.cs | 1 + Sources/Tests/UnitTests/Convenience/LatexTest.cs | 2 +- Sources/Tests/UnitTests/Convenience/PriorityTest.cs | 1 - 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Sources/AngouriMath/Core/Antlr/AngouriMath.g b/Sources/AngouriMath/Core/Antlr/AngouriMath.g index 4416d022b..041799872 100644 --- a/Sources/AngouriMath/Core/Antlr/AngouriMath.g +++ b/Sources/AngouriMath/Core/Antlr/AngouriMath.g @@ -1,4 +1,4 @@ -/* +/* Remember to run the "antlr_rerun.bat" file located at "Sources/Utils/antlr_rerun.bat" (relative to the repository root) every time you modify this file so that the generated source files under the Antlr folder are updated and changes are @@ -219,6 +219,8 @@ Keyword nodes provided_expression returns[Entity value] : expr = implies_expression { $value = $expr.value; } ('provided' pred = provided_expression { $value = $value.Provided($pred.value); })? + // note: even though Provided is associative, we parse it right-to-left matching natural language + // "I'll go, provided you go, provided it's sunny" - Natural reading: I'll go ← (you go ← sunny) ; /* diff --git a/Sources/AngouriMath/Functions/Output/Latex/Latex.Omni.Classes.cs b/Sources/AngouriMath/Functions/Output/Latex/Latex.Omni.Classes.cs index 455ac77b4..f0acc2c82 100644 --- a/Sources/AngouriMath/Functions/Output/Latex/Latex.Omni.Classes.cs +++ b/Sources/AngouriMath/Functions/Output/Latex/Latex.Omni.Classes.cs @@ -79,13 +79,13 @@ public override string Latexise() partial record Providedf { /// - public override string Latexise() => $@"{Expression.Latexise(Expression.LatexPriority < LatexPriority)} \quad \text{{for}} \quad {Predicate.Latexise(Predicate.LatexPriority <= LatexPriority)}"; + public override string Latexise() => $@"{Expression.Latexise(Expression.LatexPriority < LatexPriority)} \quad \text{{for}} \quad {Predicate.Latexise(Predicate.LatexPriority < LatexPriority)}"; } partial record Piecewise { /// - public override string Latexise() => $@"\begin{{cases}}" + + public override string Latexise() => @"\begin{cases}" + string.Join(@"\\", Cases.Select(c => { diff --git a/Sources/AngouriMath/Functions/Output/ToString/ToString.Omni.Classes.cs b/Sources/AngouriMath/Functions/Output/ToString/ToString.Omni.Classes.cs index 00b04d43d..cac355347 100644 --- a/Sources/AngouriMath/Functions/Output/ToString/ToString.Omni.Classes.cs +++ b/Sources/AngouriMath/Functions/Output/ToString/ToString.Omni.Classes.cs @@ -127,7 +127,7 @@ public override string Stringize() partial record Providedf { /// - public override string Stringize() => $@"{Expression.Stringize(Expression.Priority <= Priority.Provided)} provided {Predicate.Stringize(Predicate.Priority < Priority.Provided)}"; + public override string Stringize() => $@"{Expression.Stringize(Expression.Priority < Priority.Provided)} provided {Predicate.Stringize(Predicate.Priority < Priority.Provided)}"; /// public override string ToString() => Stringize(); } diff --git a/Sources/Tests/UnitTests/Convenience/FromStringTest.cs b/Sources/Tests/UnitTests/Convenience/FromStringTest.cs index 163c9b022..49619299f 100644 --- a/Sources/Tests/UnitTests/Convenience/FromStringTest.cs +++ b/Sources/Tests/UnitTests/Convenience/FromStringTest.cs @@ -156,6 +156,7 @@ public void TestFormula8() [Fact] public void TestProvided1() => Assert.Equal(MathS.Provided("a", "b"), FromString("a provided b")); [Fact] public void TestProvided2() => Assert.Equal(MathS.Provided("a", MathS.Provided("b", "c")), FromString("a provided b provided c")); [Fact] public void TestProvided3() => Assert.Equal(MathS.Provided(MathS.Provided("a", "b"), "c"), FromString("(a provided b) provided c")); + [Fact] public void TestProvided4() => Assert.Equal(FromString("a provided (b provided c)").Stringize(), FromString("(a provided b) provided c").Stringize()); [Theory] [InlineData("sh", "Sinh")] diff --git a/Sources/Tests/UnitTests/Convenience/LatexTest.cs b/Sources/Tests/UnitTests/Convenience/LatexTest.cs index 5ae3ceddd..6f407a3c6 100644 --- a/Sources/Tests/UnitTests/Convenience/LatexTest.cs +++ b/Sources/Tests/UnitTests/Convenience/LatexTest.cs @@ -314,7 +314,7 @@ [Fact] public void Provided2() [Fact] public void Provided3() => Test(@"a \quad \text{for} \quad b \quad \text{for} \quad c", MathS.Provided(MathS.Provided("a", "b"), "c")); [Fact] public void Provided4() - => Test(@"\left(a \quad \text{for} \quad b \quad \text{for} \quad \left(c \quad \text{for} \quad d\right)\right) \to \top ", MathS.Provided(MathS.Provided("a", "b"), MathS.Provided("c", "d")).Implies(Entity.Boolean.True)); + => Test(@"\left(a \quad \text{for} \quad b \quad \text{for} \quad c \quad \text{for} \quad d\right) \to \top ", MathS.Provided(MathS.Provided("a", "b"), MathS.Provided("c", "d")).Implies(Entity.Boolean.True)); // Juxtaposition tests [Fact] public void M1InTheMiddle() => Test(@"x \left(-1\right) \cdot x", (x * (-1)) * x); [Fact] public void MultiplyNumberWithPower() => Test(@"2 \cdot {3}^{4}", 2 * ((Entity)3).Pow(4)); diff --git a/Sources/Tests/UnitTests/Convenience/PriorityTest.cs b/Sources/Tests/UnitTests/Convenience/PriorityTest.cs index 3a9c1fbdc..ff075acc7 100644 --- a/Sources/Tests/UnitTests/Convenience/PriorityTest.cs +++ b/Sources/Tests/UnitTests/Convenience/PriorityTest.cs @@ -40,7 +40,6 @@ public class PriorityTest [InlineData("not a or not b implies not c or not d", "((not a) or (not b)) implies ((not c) or (not d))")] [InlineData("a = b and b > c and d", "a = b > c and d")] [InlineData("a provided b", "a provided b")] - [InlineData("(a provided b) provided c", "(a provided b) provided c")] [InlineData("a provided b provided c", "a provided (b provided c)")] [InlineData("a provided b and c", "a provided (b and c)")] [InlineData("a provided b + c > 0", "a provided (b + c > 0)")]