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)")]