Skip to content

Commit 7982e72

Browse files
committed
Proper support for variable subscripts
1 parent c7de39b commit 7982e72

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

CSharpMath.Evaluation.Tests/EvaluationTests.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public void Numbers(string number, string output) =>
6262
@"\times \Pi \times \psi \times \Psi \times \rho \times \sigma \times \Sigma \times \tau " +
6363
@"\times \theta \times \Theta \times \upsilon \times \Upsilon \times \varepsilon \times \varkappa " +
6464
@"\times \varphi \times \varpi \times \varrho \times \varsigma \times \xi \times \Xi \times \zeta ")]
65+
[InlineData(@"a_2", @"a_2", @"a_2")]
66+
[InlineData(@"a_2+a_2", @"a_2+a_2", @"2\times a_2")]
67+
[InlineData(@"a_{23}", @"a_{23}", @"a_{23}")]
68+
[InlineData(@"\pi_a", @"\pi _a", @"\pi _a")]
6569
public void Variables(string input, string converted, string result) => Test(input, converted, result);
6670
[Theory]
6771
[InlineData("a + b", @"a+b", "a+b")]
@@ -265,7 +269,7 @@ public void Numbers(string number, string output) =>
265269
[InlineData(@"\sin^{--1} x", @"\sin \left( x\right) ^{--1}", @"\sin \left( x\right) ")]
266270
[InlineData(@"\sin^{-1^2} x", @"\sin \left( x\right) ^{-1^2}", @"\sin \left( x\right) ^{-1}")]
267271
[InlineData(@"\sin^{-1+3} xy+\cos^{-1+3} yx", @"\sin \left( x\times y\right) ^{-1+3}+\cos \left( y\times x\right) ^{-1+3}", @"1")]
268-
[InlineData(@"\log^{-1_2} x", @"\log \left( x\right) ^{-1}", @"\log \left( x\right) ^{-1}")]
272+
[InlineData(@"\log^{-a_2} x", @"\log \left( x\right) ^{-a_2}", @"\log \left( x\right) ^{-a_2}")]
269273
[InlineData(@"\ln^{3-1} x", @"\ln \left( x\right) ^{3-1}", @"\ln \left( x\right) ^2")]
270274
public void FunctionInverses(string latex, string converted, string result) => Test(latex, converted, result);
271275
[Theory]
@@ -359,6 +363,8 @@ public void Parentheses(string latex, string converted, string result) {
359363
[InlineData(@"1,2,3", @"1,2,3")]
360364
[InlineData(@"a,b,c,d", @"a,b,c,d")]
361365
[InlineData(@"\sqrt2,\sqrt[3]2,\frac34", @"\sqrt{2},2^{\frac{1}{3}},\frac{3}{4}")]
366+
[InlineData(@"\sin a,\cos b^2,\tan c_3,\cot de,\sec 12f,\csc g+h",
367+
@"\sin \left( a\right) ,\cos \left( b^2\right) ,\tan \left( c_3\right) ,\cot \left( d\times e\right) ,\frac{1}{\cos \left( 12\times f\right) },\frac{1}{\sin \left( g\right) }+h")]
362368
public void Comma(string latex, string converted) =>
363369
Test(latex, converted, null);
364370
[Theory(Skip = "https://github.com/asc-community/AngouriMath/pull/94")]
@@ -410,18 +416,39 @@ public void Intervals(string latex, string converted) {
410416
[InlineData(@"x\times", "Missing right operand for ×")]
411417
[InlineData(@"x\div", "Missing right operand for ÷")]
412418
[InlineData(@"x\dagger", "Unsupported Binary Operator †")]
419+
[InlineData(@"1+_21", "Subscripts are unsupported for Binary Operator +")]
420+
[InlineData(@"-_31", "Subscripts are unsupported for Unary Operator −")]
421+
[InlineData(@"1\times_41", "Subscripts are unsupported for Binary Operator ×")]
422+
[InlineData(@"\div_51", "Unsupported Unary Operator ÷")]
423+
[InlineData(@"1\%_6", "Subscripts are unsupported for Ordinary %")]
424+
[InlineData(@"1\degree_7", "Subscripts are unsupported for Ordinary °")]
425+
[InlineData(@"\dagger_8", "Unsupported Unary Operator †")]
413426
[InlineData(@".", "Invalid number: .")]
427+
[InlineData(@"1._2", "Subscripts are unsupported for Number 1.")]
414428
[InlineData(@"..", "Invalid number: ..")]
415429
[InlineData(@"1..", "Invalid number: 1..")]
416430
[InlineData(@"..1", "Invalid number: ..1")]
431+
[InlineData(@"a_+", "Unsupported Unary Operator + in subscript")]
432+
[InlineData(@"a_|", "Unsupported Ordinary | in subscript")]
433+
[InlineData(@"a_{1+1}", "Unsupported Binary Operator + in subscript")]
434+
[InlineData(@"a_{2^3}", "Unsupported exponentiation in subscript")]
435+
[InlineData(@"a_{a2^3}", "Unsupported exponentiation in subscript")]
436+
[InlineData(@"a_{a^32}", "Unsupported exponentiation in subscript")]
437+
[InlineData(@"a_{2_3}", "Unsupported subscript in subscript")]
438+
[InlineData(@"a_{a2_3}", "Unsupported subscript in subscript")]
439+
[InlineData(@"a_{a_32}", "Unsupported subscript in subscript")]
417440
[InlineData(@"\square", "Placeholders should be filled")]
418441
[InlineData(@"x^\square", "Placeholders should be filled")]
419442
[InlineData(@"\square^x", "Placeholders should be filled")]
443+
[InlineData(@"a_\square", "Placeholders should be filled")]
444+
[InlineData(@"\square_a", "Placeholders should be filled")]
420445
[InlineData(@"(", "Missing )")]
446+
[InlineData(@"(_21)", "Subscripts are unsupported for Open (")]
421447
[InlineData(@"(x", "Missing )")]
422448
[InlineData(@"((x)", "Missing )")]
423449
[InlineData(@"(+", "Missing right operand for +")]
424450
[InlineData(@")", "Missing (")]
451+
[InlineData(@"(1)_2", "Subscripts are unsupported for Close )")]
425452
[InlineData(@"x)", "Missing (")]
426453
[InlineData(@"(x))", "Missing (")]
427454
[InlineData(@"+)", "Missing right operand for +")]
@@ -430,6 +457,7 @@ public void Intervals(string latex, string converted) {
430457
[InlineData(@"\left(2,3\right)^\square", "Placeholders should be filled")]
431458
[InlineData(@"(2,3)^\square", "Placeholders should be filled")]
432459
[InlineData(@"[", "Missing ]")]
460+
[InlineData(@"[_21)", "Unrecognized bracket pair [ )")]
433461
[InlineData(@"[x", "Missing ]")]
434462
[InlineData(@"[x)", "Unrecognized bracket pair [ )")]
435463
[InlineData(@"[[x)", "Unrecognized bracket pair [ )")]
@@ -442,6 +470,7 @@ public void Intervals(string latex, string converted) {
442470
[InlineData(@"((x]", "Unrecognized bracket pair ( ]")]
443471
[InlineData(@"(x]", "Unrecognized bracket pair ( ]")]
444472
[InlineData(@"]", "Missing [")]
473+
[InlineData(@"]_2", "Subscripts are unsupported for Close ]")]
445474
[InlineData(@"x]", "Missing [")]
446475
[InlineData(@"(x]]", "Unrecognized bracket pair ( ]")]
447476
[InlineData(@"+]", "Missing right operand for +")]
@@ -458,10 +487,12 @@ public void Intervals(string latex, string converted) {
458487
[InlineData(@"\left[2,3\right]^\square", "Placeholders should be filled")]
459488
[InlineData(@"[2,3]^\square", "Placeholders should be filled")]
460489
[InlineData(@"\{", "Missing }")]
490+
[InlineData(@"\{_2\}", "Subscripts are unsupported for Open {")]
461491
[InlineData(@"\{x", "Missing }")]
462492
[InlineData(@"\{\{x\}", "Missing }")]
463493
[InlineData(@"\{+", "Missing right operand for +")]
464494
[InlineData(@"\}", "Missing {")]
495+
[InlineData(@"\}_2", "Subscripts are unsupported for Close }")]
465496
[InlineData(@"x\}", "Missing {")]
466497
[InlineData(@"\{x\}\}", "Missing {")]
467498
[InlineData(@"+\}", "Missing right operand for +")]
@@ -476,8 +507,10 @@ public void Intervals(string latex, string converted) {
476507
[InlineData(@"\tan\times", "Unsupported Unary Operator ×")]
477508
[InlineData(@"\cot^(-1)", "Missing )")]
478509
[InlineData(@"\sec\csc", "Missing argument for csc")]
510+
[InlineData(@"\arcsin_2x", "Subscripts are unsupported for Large Operator arcsin")]
479511
[InlineData(@"\operatorname{dab}", "Unsupported Large Operator dab")]
480512
[InlineData(@",", "Missing left operand for comma")]
513+
[InlineData(@"1,_22", "Subscripts are unsupported for Punctuation ,")]
481514
[InlineData(@"1,", "Missing right operand for comma")]
482515
[InlineData(@",1", "Missing left operand for comma")]
483516
[InlineData(@",1,2", "Missing left operand for comma")]

CSharpMath.Evaluation/Evaluation.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,36 @@ Result HandleSuperscript(ref MathItem? @this, MathList superscript) {
202202
goto handleThis;
203203
} else return "Invalid number: " + n.Nucleus;
204204
case Atoms.Variable v:
205-
@this = v.Nucleus switch
205+
var subscript = new System.Text.StringBuilder("_");
206+
foreach (var subAtom in v.Subscript)
207+
switch (subAtom) {
208+
case Atoms.Placeholder _:
209+
return "Placeholders should be filled";
210+
case { Superscript: { Count: var count } } when count > 0:
211+
return "Unsupported exponentiation in subscript";
212+
case { Subscript: { Count: var count } } when count > 0:
213+
return "Unsupported subscript in subscript";
214+
case Atoms.Number { Nucleus: var nucleus }:
215+
subscript.Append(nucleus);
216+
break;
217+
case Atoms.Variable { Nucleus: var nucleus }:
218+
subscript.Append(nucleus);
219+
break;
220+
default:
221+
return $"Unsupported {subAtom.TypeName} {subAtom.Nucleus} in subscript";
222+
}
223+
@this = (v.Nucleus, v.Subscript.Count) switch
206224
{
207-
"R" when v.FontStyle == FontStyle.Blackboard => MathS.Sets.R(),
208-
"C" when v.FontStyle == FontStyle.Blackboard => MathS.Sets.C(),
209-
"e" => MathS.e,
210-
"π" => MathS.pi,
211-
"i" => new NumberEntity(MathS.i),
225+
("R", 0) when v.FontStyle == FontStyle.Blackboard => MathS.Sets.R(),
226+
("C", 0) when v.FontStyle == FontStyle.Blackboard => MathS.Sets.C(),
227+
("e", 0) => MathS.e,
228+
("π", 0) => MathS.pi,
229+
("i", 0) => new NumberEntity(MathS.i),
212230
// Convert θ to theta
213-
_ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s),
214-
var name => new VariableEntity(name)
231+
_ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s + subscript.ToString()),
232+
(var name, _) => MathS.Var(name + subscript.ToString())
215233
};
234+
v.Subscript.Clear();
216235
goto handleThis;
217236
case Atoms.Ordinary { Nucleus: "∅" }:
218237
@this = MathS.Sets.Empty();
@@ -242,7 +261,8 @@ _ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s),
242261
if (error != null) return error;
243262
if (@this == null) return "Missing " + bracketInfo.InferredClosing;
244263
goto handleThis;
245-
case Atoms.Close { Nucleus: var rightBracket, Superscript: var super }:
264+
case Atoms.Close { Nucleus: var rightBracket, Superscript: var super, Subscript: var sub }:
265+
if (sub.Count > 0) return "Subscripts are unsupported for Close " + rightBracket;
246266
if (!ContextInfo.TryGetValue(prec, out var contextInfo))
247267
switch (prec) {
248268
case Precedence.DefaultContext:
@@ -342,6 +362,7 @@ _ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s),
342362
case Atoms.LargeOperator { Nucleus: "log", Subscript: var @base }:
343363
Entity? logBase;
344364
(logBase, error) = Transform(@base).ExpectEntityOrNull(nameof(logBase));
365+
@base.Clear();
345366
if (error != null) return error;
346367
logBase ??= new NumberEntity(10);
347368
handleFunction = arg => MathS.Log(arg, logBase);
@@ -572,6 +593,8 @@ _ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s),
572593
}
573594

574595
handleThis:
596+
if (atom.Subscript.Count > 0)
597+
return $"Subscripts are unsupported for {atom.TypeName} {atom.Nucleus}";
575598
error = HandleSuperscript(ref @this, atom.Superscript).Error;
576599
if (error != null) return error;
577600
Entity? prevEntity, thisEntity;

0 commit comments

Comments
 (0)