@cortex-js/compute-engine 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/compute-engine.esm.js +1024 -355
  2. package/dist/compute-engine.js +1024 -355
  3. package/dist/compute-engine.min.esm.js +10 -9
  4. package/dist/compute-engine.min.js +10 -9
  5. package/dist/math-json.esm.js +2 -2
  6. package/dist/math-json.js +2 -2
  7. package/dist/math-json.min.esm.js +2 -2
  8. package/dist/math-json.min.js +2 -2
  9. package/dist/types/common/ansi-codes.d.ts +1 -1
  10. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  11. package/dist/types/common/signals.d.ts +4 -4
  12. package/dist/types/common/utils.d.ts +1 -1
  13. package/dist/types/compute-engine/assume.d.ts +1 -1
  14. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
  15. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  16. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  17. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +1 -1
  18. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +1 -1
  19. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  20. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  21. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  22. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  23. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +1 -1
  24. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  25. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  26. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  27. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  28. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -3
  29. package/dist/types/compute-engine/boxed-expression/validate.d.ts +7 -3
  30. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  31. package/dist/types/compute-engine/compile.d.ts +1 -1
  32. package/dist/types/compute-engine/compute-engine.d.ts +1 -1
  33. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  34. package/dist/types/compute-engine/domain-utils.d.ts +1 -1
  35. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  36. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  37. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  38. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  39. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  40. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +25 -1
  41. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +1 -1
  42. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  43. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  44. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  45. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  46. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  47. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  48. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  49. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  50. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +1 -1
  51. package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -23
  52. package/dist/types/compute-engine/latex-syntax/public.d.ts +11 -24
  53. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  54. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  55. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  56. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  57. package/dist/types/compute-engine/library/arithmetic-add.d.ts +1 -1
  58. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +1 -1
  59. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +1 -1
  60. package/dist/types/compute-engine/library/arithmetic-power.d.ts +1 -1
  61. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  62. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  63. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  64. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  65. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  66. package/dist/types/compute-engine/library/core.d.ts +1 -1
  67. package/dist/types/compute-engine/library/domains.d.ts +1 -1
  68. package/dist/types/compute-engine/library/library.d.ts +1 -1
  69. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  70. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  71. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  72. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  73. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  74. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  75. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  76. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  77. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  78. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  79. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  80. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  81. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  82. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  83. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  84. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  85. package/dist/types/compute-engine/public.d.ts +1 -1
  86. package/dist/types/compute-engine/rules.d.ts +1 -1
  87. package/dist/types/compute-engine/simplify-rules.d.ts +1 -1
  88. package/dist/types/compute-engine/solve.d.ts +1 -1
  89. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  90. package/dist/types/compute-engine/symbolic/expand.d.ts +1 -1
  91. package/dist/types/compute-engine/symbolic/flatten.d.ts +1 -3
  92. package/dist/types/compute-engine/symbolic/negate.d.ts +1 -1
  93. package/dist/types/compute-engine/symbolic/polynomials.d.ts +1 -1
  94. package/dist/types/compute-engine/symbolic/product.d.ts +1 -1
  95. package/dist/types/compute-engine/symbolic/sum.d.ts +1 -1
  96. package/dist/types/compute-engine/symbolic/utils.d.ts +1 -1
  97. package/dist/types/compute-engine.d.ts +2 -2
  98. package/dist/types/math-json/math-json-format.d.ts +1 -1
  99. package/dist/types/math-json/utils.d.ts +1 -4
  100. package/dist/types/math-json.d.ts +2 -2
  101. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** CortexJS Compute Engine 0.19.1 */
1
+ /** CortexJS Compute Engine 0.20.0 */
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -3964,14 +3964,6 @@ function symbol(expr) {
3964
3964
  return null;
3965
3965
  return s;
3966
3966
  }
3967
- function isListLike(expr) {
3968
- if (expr === null)
3969
- return false;
3970
- const h = head(expr);
3971
- if (!h || typeof h !== "string")
3972
- return false;
3973
- return /^(List|Sequence|Tuple|Single|Pair|Triple)$/.test(h);
3974
- }
3975
3967
  function keyValuePair(expr) {
3976
3968
  const h = head(expr);
3977
3969
  if (h === "KeyValuePair" || h === "Tuple" || h === "Pair") {
@@ -4131,21 +4123,21 @@ function getSequence(expr) {
4131
4123
  expr = op(expr, 1);
4132
4124
  if (expr === null)
4133
4125
  return [];
4134
- if (head(expr) !== "Sequence")
4126
+ h = head(expr);
4127
+ if (h !== "Sequence")
4135
4128
  return [expr];
4136
4129
  }
4137
- h = head(expr);
4138
4130
  if (h !== "Sequence")
4139
4131
  return null;
4140
4132
  return ops(expr) ?? [];
4141
4133
  }
4142
4134
  function isEmptySequence(expr) {
4143
- return expr !== null && head(expr) === "Sequence" && nops(expr) === 0;
4135
+ return head(expr) === "Sequence" && nops(expr) === 0;
4144
4136
  }
4145
4137
  function missingIfEmpty(expr) {
4146
- if (expr === null || isEmptySequence(expr))
4138
+ if (isEmptySequence(expr))
4147
4139
  return MISSING;
4148
- return expr;
4140
+ return expr ?? MISSING;
4149
4141
  }
4150
4142
  function countFunctionLeaves(xs) {
4151
4143
  if (xs[0] === "Square") {
@@ -4315,9 +4307,9 @@ function serializeAdd(serializer, expr) {
4315
4307
  if (val < 0) {
4316
4308
  result += serializer.serialize(arg);
4317
4309
  } else if (head(arg) === "Negate") {
4318
- result += serializer.wrap(arg, 275);
4310
+ result += serializer.wrap(arg, ADDITION_PRECEDENCE);
4319
4311
  } else {
4320
- const term = serializer.wrap(arg, 275);
4312
+ const term = serializer.wrap(arg, ADDITION_PRECEDENCE);
4321
4313
  if (term[0] === "-" || term[0] === "+")
4322
4314
  result += term;
4323
4315
  else
@@ -4325,10 +4317,10 @@ function serializeAdd(serializer, expr) {
4325
4317
  }
4326
4318
  }
4327
4319
  } else if (name === "Subtract") {
4328
- result = serializer.wrap(arg, 275);
4320
+ result = serializer.wrap(arg, ADDITION_PRECEDENCE);
4329
4321
  const arg2 = op(expr, 2);
4330
4322
  if (arg2 !== null) {
4331
- const term = serializer.wrap(arg2, 275);
4323
+ const term = serializer.wrap(arg2, ADDITION_PRECEDENCE);
4332
4324
  if (term[0] === "-")
4333
4325
  result += "+" + term.slice(1);
4334
4326
  else if (term[0] === "+")
@@ -4418,7 +4410,7 @@ function serializeMultiply(serializer, expr) {
4418
4410
  arg = op(arg, 1);
4419
4411
  isNegative = !isNegative;
4420
4412
  }
4421
- term = serializer.wrap(arg, 390);
4413
+ term = serializer.wrap(arg, MULTIPLICATION_PRECEDENCE);
4422
4414
  if (!result) {
4423
4415
  result = term;
4424
4416
  } else {
@@ -4667,11 +4659,14 @@ var DEFINITIONS_ARITHMETIC = [
4667
4659
  latexTrigger: ["+"],
4668
4660
  kind: "infix",
4669
4661
  associativity: "both",
4670
- precedence: 275,
4662
+ precedence: ADDITION_PRECEDENCE,
4671
4663
  parse: (parser, lhs, until) => {
4672
- if (until && 275 < until.minPrec)
4664
+ if (until && ADDITION_PRECEDENCE < until.minPrec)
4673
4665
  return null;
4674
- const rhs = parser.parseExpression({ ...until, minPrec: 275 });
4666
+ const rhs = parser.parseExpression({
4667
+ ...until,
4668
+ minPrec: ADDITION_PRECEDENCE
4669
+ });
4675
4670
  if (rhs === null)
4676
4671
  return null;
4677
4672
  return applyAssociativeOperator("Add", lhs, rhs);
@@ -4681,9 +4676,9 @@ var DEFINITIONS_ARITHMETIC = [
4681
4676
  {
4682
4677
  kind: "prefix",
4683
4678
  latexTrigger: ["+"],
4684
- precedence: 275,
4679
+ precedence: ADDITION_PRECEDENCE,
4685
4680
  parse: (parser, until) => {
4686
- if (until && 275 < until.minPrec)
4681
+ if (until && ADDITION_PRECEDENCE < until.minPrec)
4687
4682
  return null;
4688
4683
  return parser.parseExpression({ ...until, minPrec: 400 });
4689
4684
  }
@@ -4711,7 +4706,7 @@ var DEFINITIONS_ARITHMETIC = [
4711
4706
  { name: "Chop", identifierTrigger: "chop", kind: "function", parse: "Chop" },
4712
4707
  {
4713
4708
  name: "Complex",
4714
- precedence: 274,
4709
+ precedence: ADDITION_PRECEDENCE - 1,
4715
4710
  // One less than precedence of `Add`: used for correct wrapping
4716
4711
  serialize: (serializer, expr) => {
4717
4712
  const re = machineValue(op(expr, 1));
@@ -4729,7 +4724,7 @@ var DEFINITIONS_ARITHMETIC = [
4729
4724
  {
4730
4725
  name: "Divide",
4731
4726
  latexTrigger: "\\frac",
4732
- precedence: 660,
4727
+ precedence: DIVISION_PRECEDENCE,
4733
4728
  // For \frac specifically, not for \div, etc..
4734
4729
  // handles Leibnitz notation for partial derivatives
4735
4730
  parse: parseFraction,
@@ -4738,14 +4733,14 @@ var DEFINITIONS_ARITHMETIC = [
4738
4733
  {
4739
4734
  kind: "infix",
4740
4735
  latexTrigger: "\\over",
4741
- precedence: 660,
4736
+ precedence: DIVISION_PRECEDENCE,
4742
4737
  parse: "Divide"
4743
4738
  },
4744
4739
  {
4745
4740
  latexTrigger: ["\\/"],
4746
4741
  kind: "infix",
4747
4742
  associativity: "non",
4748
- precedence: 660,
4743
+ precedence: DIVISION_PRECEDENCE,
4749
4744
  // ??? MathML has 265, but it's wrong.
4750
4745
  // It has to be at least higher than multiply
4751
4746
  // e.g. `1/2+3*x` -> `1/2 + 3*x` , not `1/(2+3*x)`
@@ -4755,14 +4750,14 @@ var DEFINITIONS_ARITHMETIC = [
4755
4750
  latexTrigger: ["/"],
4756
4751
  kind: "infix",
4757
4752
  associativity: "non",
4758
- precedence: 660,
4753
+ precedence: DIVISION_PRECEDENCE,
4759
4754
  parse: "Divide"
4760
4755
  },
4761
4756
  {
4762
4757
  latexTrigger: ["\\div"],
4763
4758
  kind: "infix",
4764
4759
  associativity: "non",
4765
- precedence: 660,
4760
+ precedence: DIVISION_PRECEDENCE,
4766
4761
  // ??? according to MathML
4767
4762
  parse: "Divide"
4768
4763
  },
@@ -4779,13 +4774,13 @@ var DEFINITIONS_ARITHMETIC = [
4779
4774
  name: "Factorial",
4780
4775
  latexTrigger: ["!"],
4781
4776
  kind: "postfix",
4782
- precedence: 810
4777
+ precedence: POSTFIX_PRECEDENCE
4783
4778
  },
4784
4779
  {
4785
4780
  name: "Factorial2",
4786
4781
  latexTrigger: ["!", "!"],
4787
4782
  kind: "postfix",
4788
- precedence: 810
4783
+ precedence: POSTFIX_PRECEDENCE
4789
4784
  },
4790
4785
  {
4791
4786
  name: "Floor",
@@ -4918,23 +4913,26 @@ var DEFINITIONS_ARITHMETIC = [
4918
4913
  latexTrigger: ["\\mp"],
4919
4914
  kind: "infix",
4920
4915
  associativity: "both",
4921
- precedence: 270
4916
+ precedence: ARROW_PRECEDENCE
4922
4917
  },
4923
4918
  {
4924
4919
  name: "Multiply",
4925
4920
  latexTrigger: ["\\times"],
4926
4921
  kind: "infix",
4927
4922
  associativity: "both",
4928
- precedence: 390,
4923
+ precedence: MULTIPLICATION_PRECEDENCE,
4929
4924
  serialize: serializeMultiply
4930
4925
  },
4931
4926
  {
4932
4927
  latexTrigger: ["\\cdot"],
4933
4928
  kind: "infix",
4934
4929
  associativity: "both",
4935
- precedence: 390,
4930
+ precedence: MULTIPLICATION_PRECEDENCE,
4936
4931
  parse: (parser, lhs, terminator) => {
4937
- const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4932
+ const rhs = parser.parseExpression({
4933
+ ...terminator,
4934
+ minPrec: MULTIPLICATION_PRECEDENCE + 2
4935
+ });
4938
4936
  if (rhs === null)
4939
4937
  return ["Multiply", lhs, MISSING];
4940
4938
  return applyAssociativeOperator("Multiply", lhs, rhs);
@@ -4944,23 +4942,77 @@ var DEFINITIONS_ARITHMETIC = [
4944
4942
  latexTrigger: ["*"],
4945
4943
  kind: "infix",
4946
4944
  associativity: "both",
4947
- precedence: 390,
4945
+ precedence: MULTIPLICATION_PRECEDENCE,
4948
4946
  parse: (parser, lhs, terminator) => {
4949
- const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4947
+ const rhs = parser.parseExpression({
4948
+ ...terminator,
4949
+ minPrec: MULTIPLICATION_PRECEDENCE + 2
4950
+ });
4950
4951
  if (rhs === null)
4951
4952
  return ["Multiply", lhs, MISSING];
4952
4953
  return applyAssociativeOperator("Multiply", lhs, rhs);
4953
4954
  }
4954
4955
  },
4956
+ // Infix modulo, as in `26 \bmod 5`
4957
+ {
4958
+ name: "Mod",
4959
+ latexTrigger: "\\bmod",
4960
+ kind: "infix",
4961
+ precedence: DIVISION_PRECEDENCE,
4962
+ serialize: (serializer, expr) => {
4963
+ if (nops(expr) !== 2)
4964
+ return "";
4965
+ const lhs = serializer.serialize(op(expr, 1));
4966
+ const rhs = serializer.serialize(op(expr, 2));
4967
+ return joinLatex([lhs, "\\bmod", rhs]);
4968
+ }
4969
+ },
4970
+ // Synonym to \\bmod
4971
+ {
4972
+ latexTrigger: "\\mod",
4973
+ kind: "infix",
4974
+ precedence: DIVISION_PRECEDENCE,
4975
+ parse: "Mod"
4976
+ },
4977
+ {
4978
+ latexTrigger: "\\pmod",
4979
+ kind: "prefix",
4980
+ precedence: COMPARISON_PRECEDENCE,
4981
+ parse: (parser) => {
4982
+ const rhs = parser.parseGroup() ?? parser.parseToken();
4983
+ return ["Mod", missingIfEmpty(rhs)];
4984
+ }
4985
+ },
4986
+ {
4987
+ name: "Congruent",
4988
+ serialize: (serializer, expr) => {
4989
+ const lhs = serializer.serialize(op(expr, 1));
4990
+ const rhs = serializer.serialize(op(expr, 2));
4991
+ if (op(expr, 3) === null)
4992
+ return joinLatex([lhs, "\\equiv", rhs]);
4993
+ const modulus = serializer.serialize(op(expr, 3));
4994
+ return joinLatex([lhs, "\\equiv", rhs, "\\pmod{", modulus, "}"]);
4995
+ }
4996
+ },
4955
4997
  {
4956
4998
  name: "Negate",
4957
4999
  latexTrigger: ["-"],
4958
5000
  kind: "prefix",
5001
+ precedence: ADDITION_PRECEDENCE,
4959
5002
  parse: (parser, terminator) => {
4960
- const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5003
+ if (/\d/.test(parser.peek))
5004
+ return null;
5005
+ const index = parser.index;
5006
+ if (parser.parseNumber() !== null) {
5007
+ parser.index = index;
5008
+ return null;
5009
+ }
5010
+ const rhs = parser.parseExpression({
5011
+ ...terminator,
5012
+ minPrec: ADDITION_PRECEDENCE + 1
5013
+ });
4961
5014
  return ["Negate", missingIfEmpty(rhs)];
4962
- },
4963
- precedence: 275
5015
+ }
4964
5016
  },
4965
5017
  // {
4966
5018
  // /** If the argument is a vector */
@@ -5000,7 +5052,7 @@ var DEFINITIONS_ARITHMETIC = [
5000
5052
  latexTrigger: ["\\pm"],
5001
5053
  kind: "infix",
5002
5054
  associativity: "both",
5003
- precedence: 270,
5055
+ precedence: ARROW_PRECEDENCE,
5004
5056
  serialize: (serializer, expr) => {
5005
5057
  const op12 = op(expr, 1);
5006
5058
  if (op12 === null)
@@ -5018,7 +5070,7 @@ var DEFINITIONS_ARITHMETIC = [
5018
5070
  {
5019
5071
  latexTrigger: ["\\pm"],
5020
5072
  kind: "prefix",
5021
- precedence: 270,
5073
+ precedence: ARROW_PRECEDENCE,
5022
5074
  parse: (parser, terminator) => {
5023
5075
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5024
5076
  return ["PlusMinus", missingIfEmpty(rhs)];
@@ -5028,7 +5080,7 @@ var DEFINITIONS_ARITHMETIC = [
5028
5080
  latexTrigger: ["\\plusmn"],
5029
5081
  kind: "infix",
5030
5082
  associativity: "both",
5031
- precedence: 270,
5083
+ precedence: ARROW_PRECEDENCE,
5032
5084
  parse: (parser, lhs, terminator) => {
5033
5085
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5034
5086
  return ["PlusMinus", lhs, missingIfEmpty(rhs)];
@@ -5037,7 +5089,7 @@ var DEFINITIONS_ARITHMETIC = [
5037
5089
  {
5038
5090
  latexTrigger: ["\\plusmn"],
5039
5091
  kind: "prefix",
5040
- precedence: 270,
5092
+ precedence: ARROW_PRECEDENCE,
5041
5093
  parse: (parser, terminator) => {
5042
5094
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5043
5095
  return ["PlusMinus", missingIfEmpty(rhs)];
@@ -5052,9 +5104,9 @@ var DEFINITIONS_ARITHMETIC = [
5052
5104
  },
5053
5105
  {
5054
5106
  latexTrigger: "\\prod",
5055
- precedence: 390,
5107
+ precedence: MULTIPLICATION_PRECEDENCE,
5056
5108
  name: "Product",
5057
- parse: parseBigOp("Product", 390),
5109
+ parse: parseBigOp("Product", MULTIPLICATION_PRECEDENCE),
5058
5110
  serialize: serializeBigOp("\\prod")
5059
5111
  },
5060
5112
  // {
@@ -5065,7 +5117,7 @@ var DEFINITIONS_ARITHMETIC = [
5065
5117
  // },
5066
5118
  {
5067
5119
  name: "Rational",
5068
- precedence: 660,
5120
+ precedence: DIVISION_PRECEDENCE,
5069
5121
  serialize: (serializer, expr) => {
5070
5122
  if (expr && nops(expr) === 1)
5071
5123
  return "\\operatorname{Rational}" + serializer.wrapArguments(expr);
@@ -5088,9 +5140,9 @@ var DEFINITIONS_ARITHMETIC = [
5088
5140
  },
5089
5141
  {
5090
5142
  latexTrigger: ["\\sum"],
5091
- precedence: 275,
5143
+ precedence: ADDITION_PRECEDENCE,
5092
5144
  name: "Sum",
5093
- parse: parseBigOp("Sum", 275),
5145
+ parse: parseBigOp("Sum", ADDITION_PRECEDENCE),
5094
5146
  serialize: serializeBigOp("\\sum")
5095
5147
  },
5096
5148
  {
@@ -5110,9 +5162,12 @@ var DEFINITIONS_ARITHMETIC = [
5110
5162
  latexTrigger: ["-"],
5111
5163
  kind: "infix",
5112
5164
  associativity: "both",
5113
- precedence: 275,
5165
+ precedence: ADDITION_PRECEDENCE,
5114
5166
  parse: (parser, lhs, terminator) => {
5115
- const rhs = parser.parseExpression({ ...terminator, minPrec: 277 });
5167
+ const rhs = parser.parseExpression({
5168
+ ...terminator,
5169
+ minPrec: ADDITION_PRECEDENCE + 2
5170
+ });
5116
5171
  return ["Subtract", lhs, missingIfEmpty(rhs)];
5117
5172
  }
5118
5173
  }
@@ -5213,10 +5268,9 @@ function parseLog(command, parser) {
5213
5268
 
5214
5269
  // src/compute-engine/latex-syntax/dictionary/definitions-core.ts
5215
5270
  function parseSequence(parser, terminator, lhs, prec, sep) {
5216
- console.assert(lhs !== null);
5217
5271
  if (terminator.minPrec >= prec)
5218
5272
  return null;
5219
- const result = [lhs];
5273
+ const result = lhs ? [lhs] : ["Nothing"];
5220
5274
  let done = false;
5221
5275
  while (!done) {
5222
5276
  done = true;
@@ -5240,7 +5294,40 @@ function parseSequence(parser, terminator, lhs, prec, sep) {
5240
5294
  return result;
5241
5295
  }
5242
5296
  function serializeOps(sep = "") {
5243
- return (serializer, expr) => (ops(expr) ?? []).map((x) => serializer.serialize(x)).join(sep);
5297
+ return (serializer, expr) => {
5298
+ if (!expr)
5299
+ return "";
5300
+ const xs = ops(expr) ?? [];
5301
+ if (xs.length === 0)
5302
+ return "";
5303
+ if (xs.length === 1)
5304
+ return serializer.serialize(xs[0]);
5305
+ sep = {
5306
+ "&": "\\&",
5307
+ ":": "\\colon",
5308
+ "|": "\\mvert",
5309
+ "-": "-",
5310
+ "\xB7": "\\cdot",
5311
+ // U+00B7 MIDDLE DOT
5312
+ "\u2012": "-",
5313
+ // U+2012 FIGURE DASH
5314
+ "\u2013": "--",
5315
+ // U+2013 EN DASH
5316
+ "\u2014": "---",
5317
+ // U+2014 EM DASH
5318
+ "\u2015": "-",
5319
+ // U+2015 HORIZONTAL BAR
5320
+ "\u2022": "\\bullet",
5321
+ // U+2022 BULLET
5322
+ "\u2026": "\\ldots"
5323
+ }[sep] ?? sep;
5324
+ const ys = xs.reduce((acc, item) => {
5325
+ acc.push(serializer.serialize(item), sep);
5326
+ return acc;
5327
+ }, []);
5328
+ ys.pop();
5329
+ return joinLatex(ys);
5330
+ };
5244
5331
  }
5245
5332
  var DEFINITIONS_CORE = [
5246
5333
  //
@@ -5271,7 +5358,7 @@ var DEFINITIONS_CORE = [
5271
5358
  name: "Function",
5272
5359
  latexTrigger: ["\\mapsto"],
5273
5360
  kind: "infix",
5274
- precedence: 270,
5361
+ precedence: ARROW_PRECEDENCE,
5275
5362
  // MathML rightwards arrow
5276
5363
  parse: (parser, lhs) => {
5277
5364
  let params = [];
@@ -5290,7 +5377,7 @@ var DEFINITIONS_CORE = [
5290
5377
  else
5291
5378
  return null;
5292
5379
  }
5293
- let rhs = parser.parseExpression({ minPrec: 270 }) ?? "Nothing";
5380
+ let rhs = parser.parseExpression({ minPrec: ARROW_PRECEDENCE }) ?? "Nothing";
5294
5381
  if (head(rhs) === "Delimiter")
5295
5382
  rhs = op(rhs, 1) ?? "Nothing";
5296
5383
  if (head(rhs) === "Sequence")
@@ -5348,12 +5435,14 @@ var DEFINITIONS_CORE = [
5348
5435
  return ["Apply", rhs, lhs];
5349
5436
  }
5350
5437
  },
5438
+ // The mathtools package includes several synonmyms for \colonequals. The
5439
+ // current preferred one is `\coloneq`
5351
5440
  {
5352
5441
  name: "Assign",
5353
- latexTrigger: "\\coloneqq",
5442
+ latexTrigger: "\\coloneq",
5354
5443
  kind: "infix",
5355
5444
  associativity: "right",
5356
- precedence: 260,
5445
+ precedence: ASSIGNMENT_PRECEDENCE,
5357
5446
  // parse: (parser: Parser, lhs: Expression) => {
5358
5447
  // const rhs = parser.parseExpression({ minPrec: 260 }) ?? 'Nothing';
5359
5448
  // return ['Assign', lhs, rhs];
@@ -5361,37 +5450,32 @@ var DEFINITIONS_CORE = [
5361
5450
  serialize: (serializer, expr) => {
5362
5451
  return joinLatex([
5363
5452
  serializer.serialize(op(expr, 1)),
5364
- "\\coloneqq",
5453
+ "\\coloneq",
5365
5454
  serializer.serialize(op(expr, 2))
5366
5455
  ]);
5367
- }
5456
+ },
5457
+ parse: parseAssign
5368
5458
  },
5369
5459
  {
5370
5460
  latexTrigger: [":", "="],
5371
5461
  kind: "infix",
5372
5462
  associativity: "right",
5373
- precedence: 260,
5374
- parse: "Assign"
5463
+ precedence: ASSIGNMENT_PRECEDENCE,
5464
+ parse: parseAssign
5375
5465
  },
5376
- // {
5377
- // kind: 'function',
5378
- // latexTrigger: ':=', // \coloneqq
5379
- // parse: (parser: Parser, lhs: Expression) => {
5380
- // const rhs = parser.parseExpression({ minPrec: 270 }) ?? 'Nothing';
5381
- // return ['Assign', lhs, rhs];
5382
- // },
5383
- // },
5384
5466
  {
5385
5467
  latexTrigger: "\\colonequals",
5386
- // \coloneqq
5387
5468
  kind: "infix",
5388
5469
  associativity: "right",
5389
- precedence: 260,
5390
- parse: "Assign"
5391
- // parse: (parser: Parser, lhs: Expression) => {
5392
- // const rhs = parser.parseExpression({ minPrec: 270 }) ?? 'Nothing';
5393
- // return ['Assign', lhs, rhs];
5394
- // },
5470
+ precedence: ASSIGNMENT_PRECEDENCE,
5471
+ parse: parseAssign
5472
+ },
5473
+ {
5474
+ latexTrigger: "\\coloneqq",
5475
+ kind: "infix",
5476
+ associativity: "right",
5477
+ precedence: ASSIGNMENT_PRECEDENCE,
5478
+ parse: parseAssign
5395
5479
  },
5396
5480
  {
5397
5481
  name: "BaseForm",
@@ -5427,28 +5511,151 @@ var DEFINITIONS_CORE = [
5427
5511
  }
5428
5512
  },
5429
5513
  {
5514
+ name: "Sequence",
5515
+ // Use a space as a separator, otherwise a sequence of numbers
5516
+ // could be interpreted as a single number.
5517
+ serialize: serializeOps(" ")
5518
+ },
5519
+ {
5520
+ name: "InvisibleOperator",
5521
+ serialize: serializeOps("")
5522
+ },
5523
+ {
5524
+ // The first argument is a function expression.
5525
+ // The second (optional) argument is a string specifying the
5526
+ // delimiters and separator.
5430
5527
  name: "Delimiter",
5431
5528
  serialize: (serializer, expr) => {
5432
- const argCount = nops(expr);
5433
- if (argCount === 0)
5434
- return "";
5435
- const style = serializer.options.groupStyle(expr, serializer.level + 1);
5436
5529
  const arg1 = op(expr, 1);
5530
+ const style = serializer.options.groupStyle(expr, serializer.level + 1);
5437
5531
  const h1 = head(arg1);
5438
- const defaultFence = { List: "[],", Sequence: "" }[typeof h1 === "string" ? h1 : ""] ?? "(),";
5439
- let open = defaultFence[0] ?? "";
5440
- let close = defaultFence[1] ?? "";
5441
- let sep = defaultFence[2] ?? "";
5442
- if (argCount > 1) {
5443
- const op22 = stringValue(op(expr, 2)) ?? "";
5444
- open = op22[0] ?? defaultFence[0];
5445
- close = op22[1] ?? defaultFence[1];
5446
- sep = op22[2] ?? defaultFence[2];
5447
- }
5448
- const body = isListLike(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1);
5532
+ let delims = {
5533
+ Set: "{,}",
5534
+ List: "[,]",
5535
+ Tuple: "(,)",
5536
+ Single: "(,)",
5537
+ Pair: "(,)",
5538
+ Triple: "(,)",
5539
+ Sequence: "(,)",
5540
+ String: '""'
5541
+ }[typeof h1 === "string" ? h1 : ""] ?? "(,)";
5542
+ if (nops(expr) > 1) {
5543
+ const op22 = stringValue(op(expr, 2));
5544
+ if (typeof op22 === "string" && op22.length <= 3)
5545
+ delims = op22;
5546
+ }
5547
+ let [open, sep, close] = ["", "", ""];
5548
+ if (delims.length === 3)
5549
+ [open, sep, close] = delims;
5550
+ else if (delims.length === 2)
5551
+ [open, close] = delims;
5552
+ else if (delims.length === 1)
5553
+ sep = delims;
5554
+ const body = arg1 ? ops(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1) : "";
5449
5555
  return serializer.wrapString(body, style, open + close);
5450
5556
  }
5451
5557
  },
5558
+ // The first argument is the matrix data.
5559
+ // The second, optional, argument are the delimiters.
5560
+ // The third, optional, argument is the column specification.
5561
+ {
5562
+ name: "Matrix",
5563
+ // https://ctan.math.illinois.edu/macros/latex/required/tools/array.pdf
5564
+ serialize: (serializer, expr) => {
5565
+ const body = op(expr, 1);
5566
+ const delims = op(expr, 2) ?? "()";
5567
+ let columns = "";
5568
+ if (op(expr, 3) !== null) {
5569
+ const colsSpec = stringValue(op(expr, 3)) ?? "";
5570
+ for (const c of colsSpec) {
5571
+ if (c === "<")
5572
+ columns += "l";
5573
+ else if (c === ">")
5574
+ columns += "r";
5575
+ else if (c === "=")
5576
+ columns += "c";
5577
+ else if (c === "|")
5578
+ columns += "|";
5579
+ else if (c === ":")
5580
+ columns += ":";
5581
+ }
5582
+ }
5583
+ let [open, close] = ["", ""];
5584
+ if (typeof delims === "string" && delims.length === 2)
5585
+ [open, close] = delims;
5586
+ const rows = [];
5587
+ for (const row of ops(body) ?? []) {
5588
+ const cells = [];
5589
+ for (const cell of ops(row) ?? [])
5590
+ cells.push(serializer.serialize(cell));
5591
+ rows.push(cells.join(" & "));
5592
+ }
5593
+ const tabular = rows.join("\\\\\n");
5594
+ const optColumns = columns.length > 0 ? `[${columns}]` : "";
5595
+ if (open === "(" && close === ")")
5596
+ return joinLatex([
5597
+ "\\begin{pmatrix}",
5598
+ optColumns,
5599
+ tabular,
5600
+ "\\end{pmatrix}"
5601
+ ]);
5602
+ if (open === "[" && close === "]")
5603
+ return joinLatex([
5604
+ "\\begin{bmatrix}",
5605
+ optColumns,
5606
+ tabular,
5607
+ "\\end{bmatrix}"
5608
+ ]);
5609
+ if (open === "{" && close === "}")
5610
+ return joinLatex([
5611
+ "\\begin{Bmatrix}",
5612
+ optColumns,
5613
+ tabular,
5614
+ "\\end{Bmatrix}"
5615
+ ]);
5616
+ if (open === "|" && close === "|")
5617
+ return joinLatex([
5618
+ "\\begin{vmatrix}",
5619
+ optColumns,
5620
+ tabular,
5621
+ "\\end{vmatrix}"
5622
+ ]);
5623
+ if (open === "\u2016" && close === "\u2016")
5624
+ return joinLatex([
5625
+ "\\begin{Vmatrix}",
5626
+ optColumns,
5627
+ tabular,
5628
+ "\\end{Vmatrix}"
5629
+ ]);
5630
+ if (open === "{" && close === ".")
5631
+ return joinLatex([
5632
+ "\\begin{dcases}",
5633
+ optColumns,
5634
+ tabular,
5635
+ "\\end{dcases}"
5636
+ ]);
5637
+ if (open === "." && close === "}")
5638
+ return joinLatex([
5639
+ "\\begin{rcases}",
5640
+ optColumns,
5641
+ tabular,
5642
+ "\\end{rcases}"
5643
+ ]);
5644
+ if (columns || open !== "." || close !== ".") {
5645
+ return joinLatex([
5646
+ "\\left",
5647
+ DELIMITERS_SHORTHAND[open] ?? open,
5648
+ "\\begin{array}",
5649
+ `{${columns}}`,
5650
+ tabular,
5651
+ "\\end{array}",
5652
+ "\\right",
5653
+ DELIMITERS_SHORTHAND[close] ?? close
5654
+ ]);
5655
+ }
5656
+ return joinLatex(["\\begin{matrix}", tabular, "\\end{matrix}"]);
5657
+ }
5658
+ },
5452
5659
  {
5453
5660
  name: "Domain",
5454
5661
  serialize: (serializer, expr) => {
@@ -5554,7 +5761,7 @@ var DEFINITIONS_CORE = [
5554
5761
  kind: "matchfix",
5555
5762
  openTrigger: "(",
5556
5763
  closeTrigger: ")",
5557
- parse: parseDelimiter
5764
+ parse: parseParenDelimiter
5558
5765
  },
5559
5766
  {
5560
5767
  latexTrigger: [","],
@@ -5569,7 +5776,20 @@ var DEFINITIONS_CORE = [
5569
5776
  const seq = parseSequence(parser, terminator, lhs, 20, ",");
5570
5777
  if (seq === null)
5571
5778
  return null;
5572
- return ["Sequence", ...seq];
5779
+ return ["Delimiter", ["Sequence", ...seq], { str: "," }];
5780
+ }
5781
+ },
5782
+ // Entry to handle the case of a single comma
5783
+ // with a missing lhs.
5784
+ {
5785
+ latexTrigger: [","],
5786
+ kind: "prefix",
5787
+ precedence: 20,
5788
+ parse: (parser, terminator) => {
5789
+ const seq = parseSequence(parser, terminator, null, 20, ",");
5790
+ if (seq === null)
5791
+ return null;
5792
+ return ["Delimiter", ["Sequence", ...seq], { str: "," }];
5573
5793
  }
5574
5794
  },
5575
5795
  {
@@ -5597,10 +5817,6 @@ var DEFINITIONS_CORE = [
5597
5817
  return "";
5598
5818
  }
5599
5819
  },
5600
- {
5601
- name: "Sequence",
5602
- serialize: serializeOps("")
5603
- },
5604
5820
  {
5605
5821
  latexTrigger: [";"],
5606
5822
  kind: "infix",
@@ -5609,12 +5825,7 @@ var DEFINITIONS_CORE = [
5609
5825
  const seq = parseSequence(parser, terminator, lhs, 19, ";");
5610
5826
  if (seq === null)
5611
5827
  return null;
5612
- return [
5613
- "Sequence",
5614
- ...seq.map(
5615
- (x) => head(x) === "Sequence" ? ["List", ...ops(x) ?? []] : x
5616
- )
5617
- ];
5828
+ return ["Delimiter", ["Sequence", ...seq], "';'"];
5618
5829
  }
5619
5830
  },
5620
5831
  {
@@ -5881,8 +6092,66 @@ function parseTextRun(parser, style) {
5881
6092
  text += "$$";
5882
6093
  parser.index = index;
5883
6094
  }
5884
- } else
5885
- text += parser.matchChar() ?? parser.nextToken();
6095
+ } else {
6096
+ const c = parser.matchChar() ?? parser.nextToken();
6097
+ text += {
6098
+ "\\enskip": "\u2002",
6099
+ // en space
6100
+ "\\enspace": "\u2002",
6101
+ // en space
6102
+ "\\quad": "\u2003",
6103
+ // em space
6104
+ "\\qquad": "\u2003\u2003",
6105
+ // 2 em space
6106
+ "\\space": "\u2003",
6107
+ // em space
6108
+ "\\ ": "\u2003",
6109
+ // em space
6110
+ "\\;": "\u2004",
6111
+ // three per em space
6112
+ "\\,": "\u2009",
6113
+ // thin space
6114
+ "\\:": "\u205F",
6115
+ // medium mathematical space
6116
+ "\\!": "",
6117
+ // negative thin space
6118
+ "\\{": "{",
6119
+ "\\}": "}",
6120
+ "\\$": "$",
6121
+ "\\&": "&",
6122
+ "\\#": "#",
6123
+ "\\%": "%",
6124
+ "\\_": "_",
6125
+ "\\textbackslash": "\\",
6126
+ "\\textasciitilde": "~",
6127
+ "\\textasciicircum": "^",
6128
+ "\\textless": "<",
6129
+ "\\textgreater": ">",
6130
+ "\\textbar": "|",
6131
+ "\\textunderscore": "_",
6132
+ "\\textbraceleft": "{",
6133
+ "\\textbraceright": "}",
6134
+ "\\textasciigrave": "`",
6135
+ "\\textquotesingle": "'",
6136
+ "\\textquotedblleft": "\u201C",
6137
+ "\\textquotedblright": "\u201D",
6138
+ "\\textquotedbl": '"',
6139
+ "\\textquoteleft": "\u2018",
6140
+ "\\textquoteright": "\u2019",
6141
+ "\\textbullet": "\u2022",
6142
+ "\\textdagger": "\u2020",
6143
+ "\\textdaggerdbl": "\u2021",
6144
+ "\\textsection": "\xA7",
6145
+ "\\textparagraph": "\xB6",
6146
+ "\\textperiodcentered": "\xB7",
6147
+ "\\textellipsis": "\u2026",
6148
+ "\\textemdash": "\u2014",
6149
+ "\\textendash": "\u2013",
6150
+ "\\textregistered": "\xAE",
6151
+ "\\texttrademark": "\u2122",
6152
+ "\\textdegree": "\xB0"
6153
+ }[c] ?? c;
6154
+ }
5886
6155
  }
5887
6156
  if (runinStyle !== null && text) {
5888
6157
  runs.push(["Style", `'${text}'`, { dict: runinStyle }]);
@@ -5962,19 +6231,27 @@ function parsePrime(parser, lhs, order2) {
5962
6231
  return ["Prime", missingIfEmpty(lhs)];
5963
6232
  return ["Prime", missingIfEmpty(lhs), order2];
5964
6233
  }
5965
- function parseDelimiter(_parser, body) {
6234
+ function parseParenDelimiter(_parser, body) {
5966
6235
  if (body === null || isEmptySequence(body))
5967
- return ["Sequence"];
6236
+ return ["Delimiter"];
6237
+ if (head(body) === "Delimiter" && op(body, 2)) {
6238
+ const delims = stringValue(op(body, 2));
6239
+ if (delims?.length === 1) {
6240
+ return ["Delimiter", op(body, 1) ?? ["Sequence"], { str: `(${delims})` }];
6241
+ }
6242
+ }
5968
6243
  if (head(body) === "Sequence") {
5969
6244
  if (nops(body) === 0)
5970
6245
  return ["Delimiter"];
5971
- return ["Delimiter", ["Sequence", ...ops(body) ?? []]];
6246
+ return ["Delimiter", body];
5972
6247
  }
5973
- return ["Delimiter", body];
6248
+ return ["Delimiter", ["Sequence", body]];
5974
6249
  }
5975
6250
  function parseList(_parser, body) {
5976
6251
  if (body === null || isEmptySequence(body))
5977
6252
  return ["List"];
6253
+ if (head(body) === "Delimiter")
6254
+ return parseList(_parser, op(body, 1));
5978
6255
  if (head(body) === "Range")
5979
6256
  return body;
5980
6257
  if (head(body) !== "Sequence" && head(body) !== "List")
@@ -6015,6 +6292,70 @@ function parseRange(parser, lhs) {
6015
6292
  }
6016
6293
  return ["Range", start, end];
6017
6294
  }
6295
+ var DELIMITERS_SHORTHAND = {
6296
+ "(": "(",
6297
+ ")": ")",
6298
+ "[": "\\lbrack",
6299
+ "\u27E6": "\\llbrack",
6300
+ // U+27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET
6301
+ "\u27E7": "\\rrbrack",
6302
+ // U+27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET
6303
+ "]": "\\rbrack",
6304
+ "{": "\\lbrace",
6305
+ "}": "\\rbrace",
6306
+ "<": "\\langle",
6307
+ ">": "\\rangle",
6308
+ // '|': '\\vert',
6309
+ "\u2016": "\\Vert",
6310
+ // U+2016 DOUBLE VERTICAL LINE
6311
+ "\\": "\\backslash",
6312
+ "\u2308": "\\lceil",
6313
+ // ⌈ U+2308 LEFT CEILING
6314
+ "\u2309": "\\rceil",
6315
+ // U+2309 RIGHT CEILING
6316
+ "\u230A": "\\lfloor",
6317
+ // ⌊ U+230A LEFT FLOOR
6318
+ "\u230B": "\\rfloor",
6319
+ // ⌋ U+230B RIGHT FLOOR
6320
+ "\u231C": "\\ulcorner",
6321
+ // ⌜ U+231C TOP LEFT CORNER
6322
+ "\u231D": "\\urcorner",
6323
+ // ⌝ U+231D TOP RIGHT CORNER
6324
+ "\u231E": "\\llcorner",
6325
+ // ⌞ U+231E BOTTOM LEFT CORNER
6326
+ "\u231F": "\\lrcorner",
6327
+ // ⌟ U+231F BOTTOM RIGHT CORNER
6328
+ "\u23B0": "\\lmoustache",
6329
+ // U+23B0 UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
6330
+ "\u23B1": "\\rmoustache"
6331
+ // U+23B1 UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
6332
+ // '⎹': '', // U+23B9 DIVIDES
6333
+ // '⎾': '', // U+23BE RIGHT PARENTHESIS UPPER HOOK
6334
+ // '⎿': '', // U+23BF RIGHT PARENTHESIS LOWER HOOK
6335
+ };
6336
+ function parseAssign(parser, lhs) {
6337
+ const index = parser.index;
6338
+ if (head(lhs) === "InvisibleOperator" && nops(lhs) === 2 && head(op(lhs, 2)) === "Delimiter" && head(op(op(lhs, 2), 1)) === "Sequence") {
6339
+ const fn = symbol(op(lhs, 1));
6340
+ if (!fn)
6341
+ return null;
6342
+ const args = ops(op(op(lhs, 2), 1));
6343
+ const rhs2 = parser.parseExpression({ minPrec: 0 });
6344
+ if (rhs2 === null) {
6345
+ parser.index = index;
6346
+ return null;
6347
+ }
6348
+ return ["Assign", fn, ["Function", rhs2, ...args ?? []]];
6349
+ }
6350
+ if (!symbol(lhs))
6351
+ return null;
6352
+ const rhs = parser.parseExpression({ minPrec: 0 });
6353
+ if (rhs === null) {
6354
+ parser.index = index;
6355
+ return null;
6356
+ }
6357
+ return ["Assign", lhs, rhs];
6358
+ }
6018
6359
 
6019
6360
  // src/compute-engine/latex-syntax/dictionary/definitions-inequalities.ts
6020
6361
  var DEFINITIONS_INEQUALITIES = [
@@ -6071,7 +6412,7 @@ var DEFINITIONS_INEQUALITIES = [
6071
6412
  latexTrigger: ["\\leqslant"],
6072
6413
  kind: "infix",
6073
6414
  associativity: "right",
6074
- precedence: 265,
6415
+ precedence: COMPARISON_PRECEDENCE + 5,
6075
6416
  // Note different precedence than `<=` as per MathML
6076
6417
  parse: "LessEqual"
6077
6418
  },
@@ -6080,28 +6421,28 @@ var DEFINITIONS_INEQUALITIES = [
6080
6421
  latexTrigger: ["\\lneqq"],
6081
6422
  kind: "infix",
6082
6423
  associativity: "right",
6083
- precedence: 260
6424
+ precedence: COMPARISON_PRECEDENCE
6084
6425
  },
6085
6426
  {
6086
6427
  name: "NotLessNotEqual",
6087
6428
  latexTrigger: ["\\nleqq"],
6088
6429
  kind: "infix",
6089
6430
  associativity: "right",
6090
- precedence: 260
6431
+ precedence: COMPARISON_PRECEDENCE
6091
6432
  },
6092
6433
  {
6093
6434
  name: "LessOverEqual",
6094
6435
  latexTrigger: ["\\leqq"],
6095
6436
  kind: "infix",
6096
6437
  associativity: "right",
6097
- precedence: 265
6438
+ precedence: COMPARISON_PRECEDENCE + 5
6098
6439
  },
6099
6440
  {
6100
6441
  name: "GreaterOverEqual",
6101
6442
  latexTrigger: ["\\geqq"],
6102
6443
  kind: "infix",
6103
6444
  associativity: "right",
6104
- precedence: 265,
6445
+ precedence: COMPARISON_PRECEDENCE + 5,
6105
6446
  parse: "GreaterEqual"
6106
6447
  },
6107
6448
  {
@@ -6109,13 +6450,13 @@ var DEFINITIONS_INEQUALITIES = [
6109
6450
  latexTrigger: ["="],
6110
6451
  kind: "infix",
6111
6452
  associativity: "right",
6112
- precedence: 260
6453
+ precedence: COMPARISON_PRECEDENCE
6113
6454
  },
6114
6455
  {
6115
6456
  latexTrigger: ["*", "="],
6116
6457
  kind: "infix",
6117
6458
  associativity: "right",
6118
- precedence: 260,
6459
+ precedence: COMPARISON_PRECEDENCE,
6119
6460
  parse: "StarEqual"
6120
6461
  },
6121
6462
  {
@@ -6123,42 +6464,42 @@ var DEFINITIONS_INEQUALITIES = [
6123
6464
  latexTrigger: ["\\star", "="],
6124
6465
  kind: "infix",
6125
6466
  associativity: "right",
6126
- precedence: 260
6467
+ precedence: COMPARISON_PRECEDENCE
6127
6468
  },
6128
6469
  {
6129
6470
  name: "PlusEqual",
6130
6471
  latexTrigger: ["+", "="],
6131
6472
  kind: "infix",
6132
6473
  associativity: "right",
6133
- precedence: 260
6474
+ precedence: COMPARISON_PRECEDENCE
6134
6475
  },
6135
6476
  {
6136
6477
  name: "MinusEqual",
6137
6478
  latexTrigger: ["-", "="],
6138
6479
  kind: "infix",
6139
6480
  associativity: "right",
6140
- precedence: 260
6481
+ precedence: COMPARISON_PRECEDENCE
6141
6482
  },
6142
6483
  {
6143
6484
  name: "SlashEqual",
6144
6485
  latexTrigger: ["/", "="],
6145
6486
  kind: "infix",
6146
6487
  associativity: "right",
6147
- precedence: 260
6488
+ precedence: COMPARISON_PRECEDENCE
6148
6489
  },
6149
6490
  {
6150
6491
  name: "EqualEqual",
6151
6492
  latexTrigger: ["=", "="],
6152
6493
  kind: "infix",
6153
6494
  associativity: "right",
6154
- precedence: 260
6495
+ precedence: COMPARISON_PRECEDENCE
6155
6496
  },
6156
6497
  {
6157
6498
  name: "EqualEqualEqual",
6158
6499
  latexTrigger: ["=", "=", "="],
6159
6500
  kind: "infix",
6160
6501
  associativity: "right",
6161
- precedence: 265
6502
+ precedence: COMPARISON_PRECEDENCE + 5
6162
6503
  },
6163
6504
  {
6164
6505
  name: "TildeFullEqual",
@@ -6166,7 +6507,7 @@ var DEFINITIONS_INEQUALITIES = [
6166
6507
  latexTrigger: ["\\cong"],
6167
6508
  kind: "infix",
6168
6509
  associativity: "right",
6169
- precedence: 260
6510
+ precedence: COMPARISON_PRECEDENCE
6170
6511
  },
6171
6512
  {
6172
6513
  name: "NotTildeFullEqual",
@@ -6174,7 +6515,7 @@ var DEFINITIONS_INEQUALITIES = [
6174
6515
  latexTrigger: ["\\ncong"],
6175
6516
  kind: "infix",
6176
6517
  associativity: "right",
6177
- precedence: 260
6518
+ precedence: COMPARISON_PRECEDENCE
6178
6519
  },
6179
6520
  {
6180
6521
  name: "Approx",
@@ -6198,7 +6539,7 @@ var DEFINITIONS_INEQUALITIES = [
6198
6539
  latexTrigger: ["\\approxeq"],
6199
6540
  kind: "infix",
6200
6541
  associativity: "right",
6201
- precedence: 260
6542
+ precedence: COMPARISON_PRECEDENCE
6202
6543
  },
6203
6544
  {
6204
6545
  name: "NotApproxEqual",
@@ -6221,7 +6562,7 @@ var DEFINITIONS_INEQUALITIES = [
6221
6562
  latexTrigger: ["!", "="],
6222
6563
  kind: "infix",
6223
6564
  associativity: "right",
6224
- precedence: 260
6565
+ precedence: COMPARISON_PRECEDENCE
6225
6566
  // Note different precedence than \\ne per MathML
6226
6567
  },
6227
6568
  {
@@ -6251,7 +6592,7 @@ var DEFINITIONS_INEQUALITIES = [
6251
6592
  latexTrigger: ["\\geqslant"],
6252
6593
  kind: "infix",
6253
6594
  associativity: "right",
6254
- precedence: 265,
6595
+ precedence: COMPARISON_PRECEDENCE + 5,
6255
6596
  // Note: different precedence than `>=` as per MathML
6256
6597
  parse: "GreaterEqual"
6257
6598
  },
@@ -6260,14 +6601,14 @@ var DEFINITIONS_INEQUALITIES = [
6260
6601
  latexTrigger: ["\\gneqq"],
6261
6602
  kind: "infix",
6262
6603
  associativity: "right",
6263
- precedence: 260
6604
+ precedence: COMPARISON_PRECEDENCE
6264
6605
  },
6265
6606
  {
6266
6607
  name: "NotGreaterNotEqual",
6267
6608
  latexTrigger: ["\\ngeqq"],
6268
6609
  kind: "infix",
6269
6610
  associativity: "right",
6270
- precedence: 260
6611
+ precedence: COMPARISON_PRECEDENCE
6271
6612
  },
6272
6613
  {
6273
6614
  latexTrigger: [">"],
@@ -6302,7 +6643,7 @@ var DEFINITIONS_INEQUALITIES = [
6302
6643
  latexTrigger: ["\\circeq"],
6303
6644
  kind: "infix",
6304
6645
  associativity: "right",
6305
- precedence: 260
6646
+ precedence: COMPARISON_PRECEDENCE
6306
6647
  },
6307
6648
  {
6308
6649
  name: "TriangleEqual",
@@ -6310,7 +6651,7 @@ var DEFINITIONS_INEQUALITIES = [
6310
6651
  latexTrigger: ["\\triangleq"],
6311
6652
  kind: "infix",
6312
6653
  associativity: "right",
6313
- precedence: 260
6654
+ precedence: COMPARISON_PRECEDENCE
6314
6655
  },
6315
6656
  {
6316
6657
  name: "DotEqual",
@@ -6318,7 +6659,7 @@ var DEFINITIONS_INEQUALITIES = [
6318
6659
  latexTrigger: ["\\doteq"],
6319
6660
  kind: "infix",
6320
6661
  associativity: "right",
6321
- precedence: 265
6662
+ precedence: COMPARISON_PRECEDENCE + 5
6322
6663
  },
6323
6664
  {
6324
6665
  name: "DotEqualDot",
@@ -6326,7 +6667,7 @@ var DEFINITIONS_INEQUALITIES = [
6326
6667
  latexTrigger: ["\\doteqdot"],
6327
6668
  kind: "infix",
6328
6669
  associativity: "right",
6329
- precedence: 265
6670
+ precedence: COMPARISON_PRECEDENCE + 5
6330
6671
  },
6331
6672
  {
6332
6673
  name: "FallingDotEqual",
@@ -6334,7 +6675,7 @@ var DEFINITIONS_INEQUALITIES = [
6334
6675
  latexTrigger: ["\\fallingdotseq"],
6335
6676
  kind: "infix",
6336
6677
  associativity: "right",
6337
- precedence: 265
6678
+ precedence: COMPARISON_PRECEDENCE + 5
6338
6679
  },
6339
6680
  {
6340
6681
  name: "RisingDotEqual",
@@ -6342,77 +6683,77 @@ var DEFINITIONS_INEQUALITIES = [
6342
6683
  latexTrigger: ["\\fallingdotseq"],
6343
6684
  kind: "infix",
6344
6685
  associativity: "right",
6345
- precedence: 265
6686
+ precedence: COMPARISON_PRECEDENCE + 5
6346
6687
  },
6347
6688
  {
6348
6689
  name: "QuestionEqual",
6349
6690
  latexTrigger: ["\\questeq"],
6350
6691
  kind: "infix",
6351
6692
  associativity: "right",
6352
- precedence: 260
6693
+ precedence: COMPARISON_PRECEDENCE
6353
6694
  },
6354
6695
  {
6355
6696
  name: "MuchLess",
6356
6697
  latexTrigger: ["\\ll"],
6357
6698
  kind: "infix",
6358
6699
  associativity: "right",
6359
- precedence: 260
6700
+ precedence: COMPARISON_PRECEDENCE
6360
6701
  },
6361
6702
  {
6362
6703
  name: "MuchGreater",
6363
6704
  latexTrigger: ["\\gg"],
6364
6705
  kind: "infix",
6365
6706
  associativity: "right",
6366
- precedence: 260
6707
+ precedence: COMPARISON_PRECEDENCE
6367
6708
  },
6368
6709
  {
6369
6710
  name: "Precedes",
6370
6711
  latexTrigger: ["\\prec"],
6371
6712
  kind: "infix",
6372
6713
  associativity: "right",
6373
- precedence: 260
6714
+ precedence: COMPARISON_PRECEDENCE
6374
6715
  },
6375
6716
  {
6376
6717
  name: "Succeeds",
6377
6718
  latexTrigger: ["\\succ"],
6378
6719
  kind: "infix",
6379
6720
  associativity: "right",
6380
- precedence: 260
6721
+ precedence: COMPARISON_PRECEDENCE
6381
6722
  },
6382
6723
  {
6383
6724
  name: "PrecedesEqual",
6384
6725
  latexTrigger: ["\\preccurlyeq"],
6385
6726
  kind: "infix",
6386
6727
  associativity: "right",
6387
- precedence: 260
6728
+ precedence: COMPARISON_PRECEDENCE
6388
6729
  },
6389
6730
  {
6390
6731
  name: "SucceedsEqual",
6391
6732
  latexTrigger: ["\\curlyeqprec"],
6392
6733
  kind: "infix",
6393
6734
  associativity: "right",
6394
- precedence: 260
6735
+ precedence: COMPARISON_PRECEDENCE
6395
6736
  },
6396
6737
  {
6397
6738
  name: "NotPrecedes",
6398
6739
  latexTrigger: ["\\nprec"],
6399
6740
  kind: "infix",
6400
6741
  associativity: "right",
6401
- precedence: 260
6742
+ precedence: COMPARISON_PRECEDENCE
6402
6743
  },
6403
6744
  {
6404
6745
  name: "NotSucceeds",
6405
6746
  latexTrigger: ["\\nsucc"],
6406
6747
  kind: "infix",
6407
6748
  associativity: "right",
6408
- precedence: 260
6749
+ precedence: COMPARISON_PRECEDENCE
6409
6750
  },
6410
6751
  {
6411
6752
  name: "Between",
6412
6753
  latexTrigger: ["\\between"],
6413
6754
  kind: "infix",
6414
6755
  associativity: "right",
6415
- precedence: 265
6756
+ precedence: COMPARISON_PRECEDENCE + 5
6416
6757
  }
6417
6758
  ];
6418
6759
 
@@ -6566,7 +6907,15 @@ var DEFINITIONS_LOGIC = [
6566
6907
  kind: "infix",
6567
6908
  associativity: "right",
6568
6909
  precedence: 219,
6569
- parse: "Equivalent"
6910
+ parse: (parser, lhs, terminator) => {
6911
+ const rhs = parser.parseExpression({ ...terminator, minPrec: 219 });
6912
+ const index = parser.index;
6913
+ const modulus = parser.parseExpression({ ...terminator, minPrec: 219 });
6914
+ if (modulus && head(modulus) === "Mod")
6915
+ return ["Congruent", lhs, rhs, missingIfEmpty(op(modulus, 1))];
6916
+ parser.index = index;
6917
+ return ["Equivalent", lhs, missingIfEmpty(rhs)];
6918
+ }
6570
6919
  },
6571
6920
  {
6572
6921
  name: "Proves",
@@ -7319,6 +7668,9 @@ var DEFINITIONS_SETS = [
7319
7668
  parse: (_parser, body) => {
7320
7669
  if (body === null || isEmptySequence(body))
7321
7670
  return "EmptySet";
7671
+ if (head(body) == "Delimiter" && stringValue(op(body, 2)) === ",") {
7672
+ body = op(body, 1);
7673
+ }
7322
7674
  if (head(body) !== "Sequence")
7323
7675
  return ["Set", body];
7324
7676
  return ["Set", ...ops(body) ?? []];
@@ -7343,7 +7695,7 @@ var DEFINITIONS_SETS = [
7343
7695
  // or \\ominus
7344
7696
  kind: "infix",
7345
7697
  // @todo: parser could check that lhs and rhs are sets
7346
- precedence: 260
7698
+ precedence: COMPARISON_PRECEDENCE
7347
7699
  },
7348
7700
  // Predicates/Relations
7349
7701
  {
@@ -7677,7 +8029,10 @@ function parseIntegralBodyExpression(expr) {
7677
8029
  const op12 = op(expr, 1);
7678
8030
  if (!op12)
7679
8031
  return [expr, null];
7680
- if (h === "Multiply") {
8032
+ if (h === "Sequence" && nops(expr) === 1) {
8033
+ return parseIntegralBodyExpression(op12);
8034
+ }
8035
+ if (h === "Multiply" || h === "InvisibleOperator") {
7681
8036
  const args = ops(expr);
7682
8037
  if (args && args.length > 1) {
7683
8038
  const sym = symbol(args[args.length - 2]);
@@ -7700,7 +8055,7 @@ function parseIntegralBodyExpression(expr) {
7700
8055
  if (index) {
7701
8056
  if (!fn2)
7702
8057
  return [null, index];
7703
- return [["Delimiter", fn2, ...ops(expr).slice(1)], index];
8058
+ return [["Delimiter", ["Sequence", fn2], ...ops(expr).slice(1)], index];
7704
8059
  }
7705
8060
  } else if (h === "Add") {
7706
8061
  const args = ops(expr);
@@ -8775,7 +9130,6 @@ var DEFAULT_LATEX_NUMBER_OPTIONS = {
8775
9130
  avoidExponentsInRange: [-7, 20]
8776
9131
  };
8777
9132
  var DEFAULT_PARSE_LATEX_OPTIONS = {
8778
- applyInvisibleOperator: "auto",
8779
9133
  skipSpace: true,
8780
9134
  parseArgumentsOfUnknownLatexCommands: true,
8781
9135
  parseNumbers: "auto",
@@ -9179,11 +9533,12 @@ var _Parser = class {
9179
9533
  this.skipSpace();
9180
9534
  if (this.matchBoundary())
9181
9535
  return expr ?? ["Sequence"];
9182
- const from = this.index;
9183
9536
  while (!this.matchBoundary() && !this.atEnd)
9184
9537
  this.nextToken();
9185
- const err = this.error("syntax-error", from);
9186
- return expr ? ["Sequence", expr, err] : err;
9538
+ if (head(expr) === "Error")
9539
+ return expr;
9540
+ const err = this.error("expected-closing-delimiter", start);
9541
+ return expr ? ["InvisibleOperator", expr, err] : err;
9187
9542
  }
9188
9543
  this.index = start;
9189
9544
  return null;
@@ -9330,7 +9685,7 @@ var _Parser = class {
9330
9685
  }
9331
9686
  parseDecimalDigits(options) {
9332
9687
  options ?? (options = {});
9333
- options.withGrouping ?? (options.withGrouping = false);
9688
+ options.withGrouping ?? (options.withGrouping = true);
9334
9689
  const result = [];
9335
9690
  let done = false;
9336
9691
  while (!done) {
@@ -9355,7 +9710,7 @@ var _Parser = class {
9355
9710
  }
9356
9711
  parseSignedInteger(options) {
9357
9712
  options ?? (options = {});
9358
- options.withGrouping ?? (options.withGrouping = false);
9713
+ options.withGrouping ?? (options.withGrouping = true);
9359
9714
  const start = this.index;
9360
9715
  const sign2 = this.parseOptionalSign();
9361
9716
  const result = this.parseDecimalDigits(options);
@@ -9395,7 +9750,7 @@ var _Parser = class {
9395
9750
  this.skipSpaceTokens();
9396
9751
  if (this.matchAll(this._beginExponentMarkerTokens)) {
9397
9752
  this.skipSpaceTokens();
9398
- const exponent = this.parseSignedInteger();
9753
+ const exponent = this.parseSignedInteger({ withGrouping: false });
9399
9754
  this.skipSpaceTokens();
9400
9755
  if (this.matchAll(this._endExponentMarkerTokens) && exponent)
9401
9756
  return exponent;
@@ -9450,7 +9805,14 @@ var _Parser = class {
9450
9805
  return null;
9451
9806
  const start = this.index;
9452
9807
  this.skipVisualSpace();
9453
- this.match("+");
9808
+ let sign2 = 1;
9809
+ while (this.peek === "-" || this.peek === "+") {
9810
+ if (this.match("-"))
9811
+ sign2 *= -1;
9812
+ else
9813
+ this.match("+");
9814
+ this.skipVisualSpace();
9815
+ }
9454
9816
  let wholePart = "";
9455
9817
  let fractionalPart = "";
9456
9818
  let startsWithDecimalMarker = false;
@@ -9461,21 +9823,17 @@ var _Parser = class {
9461
9823
  wholePart = "0";
9462
9824
  }
9463
9825
  } else
9464
- wholePart = this.parseDecimalDigits({ withGrouping: true });
9826
+ wholePart = this.parseDecimalDigits();
9465
9827
  if (!wholePart) {
9466
9828
  this.index = start;
9467
9829
  return null;
9468
9830
  }
9469
9831
  const fractionalIndex = this.index;
9470
- let hasFractionalPart = true;
9832
+ let hasFractionalPart = false;
9471
9833
  if (startsWithDecimalMarker || this.match(".") || this.matchAll(this._decimalMarkerTokens)) {
9472
- fractionalPart = this.parseDecimalDigits({ withGrouping: true });
9473
- if (!fractionalPart) {
9474
- this.index = fractionalIndex;
9475
- return { num: wholePart };
9476
- }
9477
- } else
9478
- hasFractionalPart = false;
9834
+ fractionalPart = this.parseDecimalDigits();
9835
+ hasFractionalPart = true;
9836
+ }
9479
9837
  let hasRepeatingPart = false;
9480
9838
  if (hasFractionalPart) {
9481
9839
  const repeat = this.parseRepeatingDecimal();
@@ -9485,14 +9843,18 @@ var _Parser = class {
9485
9843
  } else if (this.match("\\ldots") || this.matchAll(this._truncationMarkerTokens)) {
9486
9844
  }
9487
9845
  }
9846
+ if (hasFractionalPart && !fractionalPart) {
9847
+ this.index = fractionalIndex;
9848
+ return { num: sign2 < 0 ? "-" + wholePart : wholePart };
9849
+ }
9488
9850
  this.skipVisualSpace();
9489
9851
  const exponent = this.parseExponent();
9490
9852
  if (!hasRepeatingPart && this.options.parseNumbers === "rational") {
9491
9853
  const whole = parseInt(wholePart, 10);
9492
9854
  if (!fractionalPart) {
9493
9855
  if (exponent)
9494
- return ["Multiply", whole, ["Power", 10, exponent]];
9495
- return whole;
9856
+ return ["Multiply", sign2 * whole, ["Power", 10, exponent]];
9857
+ return sign2 * whole;
9496
9858
  }
9497
9859
  const fraction = parseInt(fractionalPart, 10);
9498
9860
  const n = fractionalPart.length;
@@ -9501,14 +9863,14 @@ var _Parser = class {
9501
9863
  if (exponent) {
9502
9864
  return [
9503
9865
  "Multiply",
9504
- ["Rational", numerator, denominator],
9866
+ ["Rational", sign2 * numerator, denominator],
9505
9867
  ["Power", 10, exponent]
9506
9868
  ];
9507
9869
  }
9508
- return ["Rational", numerator, denominator];
9870
+ return ["Rational", sign2 * numerator, denominator];
9509
9871
  }
9510
9872
  return {
9511
- num: wholePart + (hasFractionalPart ? "." + fractionalPart : "") + (exponent ? "e" + exponent : "")
9873
+ num: (sign2 < 0 ? "-" : "") + wholePart + (hasFractionalPart ? "." + fractionalPart : "") + (exponent ? "e" + exponent : "")
9512
9874
  };
9513
9875
  }
9514
9876
  /**
@@ -9636,8 +9998,13 @@ var _Parser = class {
9636
9998
  return getSequence(group) ?? [];
9637
9999
  }
9638
10000
  if (kind === "implicit") {
9639
- if (head(group) === "Delimiter")
9640
- return getSequence(group) ?? [];
10001
+ if (head(group) === "Delimiter") {
10002
+ if (head(op1(group)) === "Sequence") {
10003
+ const seq = op1(op1(group));
10004
+ return seq ? [seq] : [];
10005
+ }
10006
+ return op1(group) ? [op1(group)] : [];
10007
+ }
9641
10008
  if (group !== null)
9642
10009
  return [group];
9643
10010
  const primary = this.parseExpression({ ...until, minPrec: 390 });
@@ -9896,7 +10263,7 @@ var _Parser = class {
9896
10263
  );
9897
10264
  if (defs) {
9898
10265
  const nonEmptySuperscripts = superscripts.filter(
9899
- (x) => head(x) !== "Sequence"
10266
+ (x) => !(head(x) === "Sequence" && nops(x) === 0)
9900
10267
  );
9901
10268
  if (nonEmptySuperscripts.length !== 0) {
9902
10269
  const superscriptExpression = nonEmptySuperscripts.length === 1 ? nonEmptySuperscripts[0] : ["List", ...nonEmptySuperscripts];
@@ -9965,75 +10332,6 @@ var _Parser = class {
9965
10332
  }
9966
10333
  return result;
9967
10334
  }
9968
- /**
9969
- * Apply an invisible operator between two expressions.
9970
- *
9971
- * If the `lhs` is an literal integer and the `rhs` is a literal rational
9972
- * -> 'invisible plus'
9973
- *
9974
- * That is '2 3/4' -> ['Add', 2, ['Rational', 3, 4]]
9975
- *
9976
- * If `lhs` is a number and `rhs` is a number but not a literal -> 'invisible multiply'.
9977
- * - 2x
9978
- * - 2(x+1)
9979
- * - x(x+1)
9980
- * - f(x)g(y)
9981
- * - 2 sin(x)
9982
- * - 2 f(x)
9983
- * - x f(x)
9984
- * - (x-1)(x+1)
9985
- * - (x+1)2 -> no
9986
- * - x2 -> no
9987
- * => lhs is a number, rhs is a number, but not a literal
9988
- */
9989
- applyInvisibleOperator(until, lhs) {
9990
- if (lhs === null || this.options.applyInvisibleOperator === null || head(lhs) === "Error" || symbol(lhs) === "Nothing" || isEmptySequence(lhs) || this.atTerminator(until))
9991
- return null;
9992
- if (this.peekDefinitions("operator").length > 0)
9993
- return null;
9994
- if (this.isFunctionHead(lhs)) {
9995
- const args = this.parseArguments("enclosure", { ...until, minPrec: 0 });
9996
- if (args === null)
9997
- return null;
9998
- return [lhs, ...args];
9999
- }
10000
- const start = this.index;
10001
- const rhs = this.parseExpression({ ...until, minPrec: 390 });
10002
- if (rhs === null || symbol(rhs) === "Nothing" || isEmptySequence(rhs)) {
10003
- this.index = start;
10004
- return null;
10005
- }
10006
- if (head(rhs) === "Error")
10007
- return applyAssociativeOperator("Sequence", lhs, rhs);
10008
- if (typeof this.options.applyInvisibleOperator === "function")
10009
- return this.options.applyInvisibleOperator(this, lhs, rhs);
10010
- if (this.isFunctionHead(lhs)) {
10011
- const seq = getSequence(rhs);
10012
- return seq ? [lhs, ...seq] : lhs;
10013
- }
10014
- const lhsNumber = machineValue(lhs);
10015
- if (lhsNumber !== null && Number.isInteger(lhsNumber)) {
10016
- const rhsHead = head(rhs);
10017
- if (rhsHead === "Divide" || rhsHead === "Rational") {
10018
- const [n, d] = [machineValue(op(rhs, 1)), machineValue(op(rhs, 2))];
10019
- if (n !== null && d !== null && n > 0 && n <= 1e3 && d > 1 && d <= 1e3 && Number.isInteger(n) && Number.isInteger(d))
10020
- return ["Add", lhs, rhs];
10021
- }
10022
- }
10023
- if (head(rhs) === "Delimiter") {
10024
- if (head(op(rhs, 1)) === "Sequence")
10025
- return [lhs, ...ops(op(rhs, 1)) ?? []];
10026
- if (!op(rhs, 1) || symbol(op(rhs, 1)) === "Nothing")
10027
- return applyAssociativeOperator(
10028
- "Sequence",
10029
- lhs,
10030
- this.error("expected-expression", start)
10031
- );
10032
- }
10033
- if (head(rhs) === "Sequence" || head(lhs) === "Sequence" || stringValue(lhs) !== null || stringValue(rhs) !== null || dictionary(lhs) !== null || dictionary(rhs) !== null)
10034
- return applyAssociativeOperator("Sequence", lhs, rhs);
10035
- return applyAssociativeOperator("Multiply", lhs, rhs);
10036
- }
10037
10335
  /**
10038
10336
  * This method can be invoked when we know we're in an error situation.
10039
10337
  *
@@ -10239,7 +10537,23 @@ var _Parser = class {
10239
10537
  this.skipSpace();
10240
10538
  let result = this.parseInfixOperator(lhs, until);
10241
10539
  if (result === null) {
10242
- result = this.applyInvisibleOperator(until, lhs);
10540
+ if (this.peekDefinitions("operator").length === 0) {
10541
+ const rhs = this.parseExpression({
10542
+ ...until,
10543
+ minPrec: MULTIPLICATION_PRECEDENCE
10544
+ });
10545
+ if (rhs !== null) {
10546
+ if (head(lhs) === "InvisibleOperator") {
10547
+ if (head(rhs) === "InvisibleOperator")
10548
+ result = ["InvisibleOperator", ...ops(lhs), ...ops(rhs)];
10549
+ else
10550
+ result = ["InvisibleOperator", ...ops(lhs), rhs];
10551
+ } else if (head(rhs) === "InvisibleOperator") {
10552
+ result = ["InvisibleOperator", lhs, ...ops(rhs)];
10553
+ } else
10554
+ result = ["InvisibleOperator", lhs, rhs];
10555
+ }
10556
+ }
10243
10557
  }
10244
10558
  if (result !== null) {
10245
10559
  lhs = result;
@@ -10248,11 +10562,6 @@ var _Parser = class {
10248
10562
  }
10249
10563
  }
10250
10564
  }
10251
- if (!lhs) {
10252
- lhs = this.parseSyntaxError();
10253
- while (!this.atTerminator(until))
10254
- this.nextToken();
10255
- }
10256
10565
  return this.decorate(lhs, start);
10257
10566
  }
10258
10567
  /**
@@ -10578,7 +10887,7 @@ var STYLE_MODIFIERS = {
10578
10887
  sansserif: (s) => `\\mathsf{${s}}`,
10579
10888
  monospace: (s) => `\\mathtt{${s}}`
10580
10889
  };
10581
- var Serializer2 = class {
10890
+ var Serializer4 = class {
10582
10891
  constructor(options, dictionary2, onError) {
10583
10892
  this.level = -1;
10584
10893
  this.options = options;
@@ -10660,10 +10969,24 @@ var Serializer2 = class {
10660
10969
  return s;
10661
10970
  if (fence === void 0)
10662
10971
  fence = "()";
10663
- const openFence = fence?.[0] ?? ".";
10664
- const closeFence = fence?.[1] ?? ".";
10972
+ let openFence = fence?.[0] ?? ".";
10973
+ let closeFence = fence?.[1] ?? ".";
10665
10974
  if ((openFence === "." || closeFence === ".") && style === "paren")
10666
10975
  style = "leftright";
10976
+ if (openFence === '"')
10977
+ openFence = "``";
10978
+ else if (openFence === "|")
10979
+ openFence = "\\lvert";
10980
+ else
10981
+ openFence = DELIMITERS_SHORTHAND[openFence] ?? openFence;
10982
+ if (closeFence === '"')
10983
+ closeFence = "''";
10984
+ else if (closeFence === "|")
10985
+ closeFence = "\\rvert";
10986
+ else
10987
+ closeFence = DELIMITERS_SHORTHAND[closeFence] ?? closeFence;
10988
+ if (openFence === "." && closeFence === ".")
10989
+ return s;
10667
10990
  if (style === "leftright")
10668
10991
  return `\\left${openFence}${s}\\right${closeFence}}`;
10669
10992
  if (style === "big")
@@ -11056,7 +11379,7 @@ var LatexSyntax = class _LatexSyntax {
11056
11379
  get serializer() {
11057
11380
  if (this._serializer)
11058
11381
  return this._serializer;
11059
- this._serializer = new Serializer2(
11382
+ this._serializer = new Serializer4(
11060
11383
  this.options,
11061
11384
  this._dictionary,
11062
11385
  this.onError
@@ -13520,11 +13843,19 @@ function flattenOps(ops2, head2) {
13520
13843
  return result;
13521
13844
  }
13522
13845
  function flattenSequence(xs) {
13523
- if (xs.every((x) => x.head !== "Sequence"))
13846
+ if (xs.every((x) => x.head !== "Sequence" && x.head !== "Delimiter"))
13524
13847
  return xs;
13525
13848
  const ys = [];
13526
13849
  for (const x of xs) {
13527
- if (x.isValid && x.head === "Sequence") {
13850
+ if (!x.isValid)
13851
+ ys.push(x);
13852
+ else if (x.head === "Delimiter") {
13853
+ const seq = x.op1.ops ?? [];
13854
+ if (seq.length === 0)
13855
+ ys.push(x.engine.box(["Tupple"]));
13856
+ else
13857
+ ys.push(...flattenSequence(seq));
13858
+ } else if (x.head === "Sequence") {
13528
13859
  if (x.ops)
13529
13860
  ys.push(...x.ops);
13530
13861
  } else
@@ -13870,7 +14201,7 @@ var DOMAIN_ALIAS = {
13870
14201
  LogicOperators: [
13871
14202
  "FunctionOf",
13872
14203
  "Booleans",
13873
- ["OptArg", "Booleans"],
14204
+ ["VarArg", "Booleans"],
13874
14205
  "Booleans"
13875
14206
  ],
13876
14207
  Predicates: ["FunctionOf", "Anything", ["VarArg", "Anything"], "Booleans"],
@@ -14190,7 +14521,7 @@ function checkArity(ce, ops2, count) {
14190
14521
  }
14191
14522
  function checkNumericArgs(ce, ops2, options) {
14192
14523
  let count = typeof options === "number" ? options : options?.count;
14193
- const flatten = typeof options === "number" ? true : options?.flatten ?? true;
14524
+ const flatten = typeof options === "number" || (options?.flatten ?? true);
14194
14525
  ops2 = canonical(ops2);
14195
14526
  if (flatten)
14196
14527
  ops2 = flattenSequence(ops2);
@@ -14251,7 +14582,7 @@ function checkNumericArgs(ce, ops2, options) {
14251
14582
  x.infer(ce.Numbers);
14252
14583
  return xs;
14253
14584
  }
14254
- function checkArg(ce, arg, dom) {
14585
+ function checkDomain(ce, arg, dom) {
14255
14586
  if (arg === void 0 || arg === null)
14256
14587
  return ce.error("missing");
14257
14588
  if (dom === void 0)
@@ -14265,12 +14596,22 @@ function checkArg(ce, arg, dom) {
14265
14596
  return arg;
14266
14597
  return ce.domainError(dom, arg.domain, arg);
14267
14598
  }
14268
- function checkArgs(ce, args, doms) {
14599
+ function checkPure(ce, arg) {
14600
+ if (arg === void 0 || arg === null)
14601
+ return ce.error("missing");
14602
+ arg = arg.canonical;
14603
+ if (!arg.isValid)
14604
+ return arg;
14605
+ if (arg.isPure)
14606
+ return arg;
14607
+ return ce.error("expected-pure-expression", arg);
14608
+ }
14609
+ function checkDomains(ce, args, doms) {
14269
14610
  if (args.length === doms.length && args.every((x, i) => !x.domain || x.domain.isCompatible(doms[i])))
14270
14611
  return args;
14271
14612
  const xs = [];
14272
14613
  for (let i = 0; i <= doms.length - 1; i++)
14273
- xs.push(checkArg(ce, args[i], doms[i]));
14614
+ xs.push(checkDomain(ce, args[i], doms[i]));
14274
14615
  for (let i = doms.length; i <= args.length - 1; i++)
14275
14616
  xs.push(ce.error("unexpected-argument", args[i]));
14276
14617
  return xs;
@@ -14446,9 +14787,9 @@ function canonicalLimits(limits) {
14446
14787
  } else
14447
14788
  index = ce.domainError("Symbols", index.domain, index);
14448
14789
  if (lower && lower.isFinite)
14449
- lower = checkArg(ce, lower, "Integers");
14790
+ lower = checkDomain(ce, lower, "Integers");
14450
14791
  if (upper && upper.isFinite)
14451
- upper = checkArg(ce, upper, "Integers");
14792
+ upper = checkDomain(ce, upper, "Integers");
14452
14793
  if (lower && upper)
14453
14794
  return ce.tuple([index, lower, upper]);
14454
14795
  if (upper)
@@ -14537,7 +14878,11 @@ var NATIVE_JS_FUNCTIONS = {
14537
14878
  Limit: (args, compile2) => `_SYS.limit(${compile2(args[0])}, ${compile2(args[1])})`,
14538
14879
  Ln: "Math.log",
14539
14880
  List: (args, compile2) => `[${args.map((x) => compile2(x)).join(", ")}]`,
14540
- Log: "Math.log10",
14881
+ Log: (args, compile2) => {
14882
+ if (args.length === 1)
14883
+ return `Math.log(${compile2(args[0])})`;
14884
+ return `(Math.log(${compile2(args[0])}) / Math.log(${compile2(args[1])}))`;
14885
+ },
14541
14886
  LogGamma: "_SYS.lngamma",
14542
14887
  Lb: "Math.log2",
14543
14888
  Max: "Math.max",
@@ -14773,6 +15118,12 @@ function compileExpr(h, args, prec, target) {
14773
15118
  return compileLoop(h, args, target);
14774
15119
  if (args.every((x) => !isCollection(x))) {
14775
15120
  const op3 = target.operators?.(h);
15121
+ if ((h === "NotEqual" || h === "Equal" || h === "Less" || h === "Greater" || h === "LessEqual" || h === "GreaterEqual") && args.length > 2 && op3) {
15122
+ const result = [];
15123
+ for (let i = 0; i < args.length - 1; i++)
15124
+ result.push(compileExpr(h, [args[i], args[i + 1]], op3[1], target));
15125
+ return `(${result.join(") && (")})`;
15126
+ }
14776
15127
  if (op3 !== void 0) {
14777
15128
  if (args === null)
14778
15129
  return "";
@@ -19866,6 +20217,12 @@ var ARITHMETIC_LIBRARY = [
19866
20217
  complexity: 9e3,
19867
20218
  signature: {
19868
20219
  domain: ["FunctionOf", "Numbers", "Numbers"],
20220
+ canonical: (ce, args) => {
20221
+ const base = args[0];
20222
+ if (base instanceof BoxedNumber && base.isNegative)
20223
+ return ce.neg(ce._fn("Factorial", [ce.neg(base)]));
20224
+ return ce._fn("Factorial", [base]);
20225
+ },
19869
20226
  evaluate: (ce, ops2) => {
19870
20227
  const n = asSmallInteger(ops2[0]);
19871
20228
  if (n !== null && n >= 0) {
@@ -19964,7 +20321,7 @@ var ARITHMETIC_LIBRARY = [
19964
20321
  domain: ["FunctionOf", "Numbers", ["OptArg", "Numbers"], "Numbers"],
19965
20322
  canonical: (ce, ops2) => {
19966
20323
  if (ops2.length === 1)
19967
- return ce._fn("Log", [checkArg(ce, ops2[0], "Numbers")]);
20324
+ return ce._fn("Log", [checkDomain(ce, ops2[0], "Numbers")]);
19968
20325
  ops2 = checkNumericArgs(ce, ops2, 2);
19969
20326
  if (ops2.length !== 2)
19970
20327
  return ce._fn("Log", ops2);
@@ -20021,6 +20378,27 @@ var ARITHMETIC_LIBRARY = [
20021
20378
  )
20022
20379
  }
20023
20380
  },
20381
+ Mod: {
20382
+ description: "Modulo",
20383
+ wikidata: "Q1799665",
20384
+ complexity: 2500,
20385
+ threadable: true,
20386
+ signature: {
20387
+ domain: ["FunctionOf", "Numbers", "Numbers", "Numbers"],
20388
+ evaluate: (ce, ops2) => {
20389
+ if (ops2.length !== 2)
20390
+ return void 0;
20391
+ const [lhs, rhs] = ops2;
20392
+ const nLhs = lhs.value;
20393
+ const nRhs = rhs.value;
20394
+ if (typeof nLhs !== "number")
20395
+ return void 0;
20396
+ if (typeof nRhs !== "number")
20397
+ return void 0;
20398
+ return ce.number((nLhs % nRhs + nRhs) % nRhs);
20399
+ }
20400
+ }
20401
+ },
20024
20402
  Multiply: {
20025
20403
  wikidata: "Q40276",
20026
20404
  associative: true,
@@ -20098,7 +20476,10 @@ var ARITHMETIC_LIBRARY = [
20098
20476
  args = checkNumericArgs(ce, args, 2);
20099
20477
  if (args.length !== 2)
20100
20478
  return ce._fn("Power", args);
20101
- return ce.pow(args[0], args[1]);
20479
+ const [base, exp2] = args;
20480
+ if (base instanceof BoxedNumber && base.isNegative)
20481
+ return ce.neg(ce.pow(base, exp2));
20482
+ return ce.pow(base, exp2);
20102
20483
  },
20103
20484
  simplify: (ce, ops2) => processPower(ce, ops2[0], ops2[1], "simplify"),
20104
20485
  evaluate: (ce, ops2) => processPower(ce, ops2[0], ops2[1], "evaluate"),
@@ -20132,9 +20513,9 @@ var ARITHMETIC_LIBRARY = [
20132
20513
  return ce._fn("Rational", [ce.error("missing")]);
20133
20514
  if (args.length === 1)
20134
20515
  return ce._fn("Rational", [
20135
- checkArg(ce, args[0], "ExtendedRealNumbers")
20516
+ checkDomain(ce, args[0], "ExtendedRealNumbers")
20136
20517
  ]);
20137
- args = checkArgs(ce, args, ["Integers", "Integers"]);
20518
+ args = checkDomains(ce, args, ["Integers", "Integers"]);
20138
20519
  if (args.length !== 2 || !args[0].isValid || !args[1].isValid)
20139
20520
  return ce._fn("Rational", args);
20140
20521
  return ce.div(args[0], args[1]);
@@ -20295,7 +20676,7 @@ var ARITHMETIC_LIBRARY = [
20295
20676
  domain: ["FunctionOf", "Numbers", ["OptArg", "Numbers"], "Numbers"],
20296
20677
  canonical: (ce, args) => {
20297
20678
  if (args.length === 1) {
20298
- const x = checkArg(ce, args[0], "Numbers");
20679
+ const x = checkDomain(ce, args[0], "Numbers");
20299
20680
  if (x.isValid)
20300
20681
  return ce.neg(x);
20301
20682
  }
@@ -21346,7 +21727,6 @@ var CALCULUS_LIBRARY = [
21346
21727
  "Numbers"
21347
21728
  ],
21348
21729
  canonical: (ce, ops2) => {
21349
- const body = ops2[0] ?? ce.error("missing");
21350
21730
  let range = ops2[1];
21351
21731
  let index = null;
21352
21732
  let lower = null;
@@ -21366,9 +21746,9 @@ var CALCULUS_LIBRARY = [
21366
21746
  if (!index.symbol)
21367
21747
  index = ce.domainError("Symbols", index.domain, index);
21368
21748
  if (lower)
21369
- lower = checkArg(ce, lower, ce.Numbers);
21749
+ lower = checkDomain(ce, lower, ce.Numbers);
21370
21750
  if (upper)
21371
- upper = checkArg(ce, upper, ce.Numbers);
21751
+ upper = checkDomain(ce, upper, ce.Numbers);
21372
21752
  if (lower && upper)
21373
21753
  range = ce.tuple([index, lower, upper]);
21374
21754
  else if (upper)
@@ -21377,7 +21757,11 @@ var CALCULUS_LIBRARY = [
21377
21757
  range = ce.tuple([index, lower]);
21378
21758
  else
21379
21759
  range = index;
21380
- return ce._fn("Integrate", [body.canonical, range]);
21760
+ let body = ops2[0] ?? ce.error("missing");
21761
+ body = body.canonical;
21762
+ if (body.head === "Delimiter" && body.op1.head === "Sequence")
21763
+ body = body.op1.op1;
21764
+ return ce._fn("Integrate", [body, range]);
21381
21765
  }
21382
21766
  }
21383
21767
  },
@@ -21410,15 +21794,12 @@ var COLLECTIONS_LIBRARY = {
21410
21794
  //
21411
21795
  // Data Structures
21412
21796
  //
21413
- Sequence: {
21414
- signature: {
21415
- domain: "Functions"
21416
- }
21417
- },
21418
21797
  List: {
21419
21798
  complexity: 8200,
21799
+ hold: "all",
21420
21800
  signature: {
21421
- domain: ["FunctionOf", ["VarArg", "Anything"], "Lists"]
21801
+ domain: ["FunctionOf", ["VarArg", "Anything"], "Lists"],
21802
+ canonical: canonicalList
21422
21803
  },
21423
21804
  size: (expr) => expr.nops,
21424
21805
  iterator: (expr, start, count) => {
@@ -21573,7 +21954,7 @@ var COLLECTIONS_LIBRARY = {
21573
21954
  signature: {
21574
21955
  domain: ["FunctionOf", "Strings", "Anything", "Tuples"],
21575
21956
  canonical: (ce, args) => {
21576
- const [key, value] = checkArgs(ce, args, [ce.Strings, "Values"]);
21957
+ const [key, value] = checkDomains(ce, args, [ce.Strings, "Values"]);
21577
21958
  if (!key.isValid || !value.isValid)
21578
21959
  return ce._fn("KeyValuePair", [key, value]);
21579
21960
  return ce.tuple([key, value]);
@@ -22159,6 +22540,17 @@ function indexes(ranges) {
22159
22540
  }
22160
22541
  return result;
22161
22542
  }
22543
+ function canonicalList(ce, ops2) {
22544
+ ops2 = ops2.map((op3) => {
22545
+ if (op3.head === "Delimiter") {
22546
+ if (op3.op1.head === "Sequence")
22547
+ return ce._fn("List", canonical(op3.op1.ops));
22548
+ return ce._fn("List", [op3.op1?.canonical ?? ce.Nothing]);
22549
+ }
22550
+ return op3.canonical;
22551
+ });
22552
+ return ce._fn("List", ops2);
22553
+ }
22162
22554
 
22163
22555
  // src/compute-engine/library/control-structures.ts
22164
22556
  var CONTROL_STRUCTURES_LIBRARY = [
@@ -22594,19 +22986,172 @@ var CORE_LIBRARY = [
22594
22986
  // Inert functions
22595
22987
  //
22596
22988
  {
22989
+ /**
22990
+ * ## THEORY OF OPERATIONS: SEQUENCES
22991
+ *
22992
+ * There are two similar functions used to represent sequences of
22993
+ * expressions:
22994
+ *
22995
+ * - `InvisibleOperator` represent a sequence of expressions
22996
+ * that are syntactically juxtaposed without any separator or
22997
+ * operators combining them. For example, `2x` is represented as
22998
+ * `["InvisibleOperator", 2, "x"]`. `InvisibleOperator` gets
22999
+ * transformed into `Multiply` (or some other semantic operation)
23000
+ * during canonicalization.
23001
+ *
23002
+ * - `Sequence` is used to represent a sequence of expressions
23003
+ * at a semantic level. It is a collection, but it is handled
23004
+ * specially when canonicalizing expressions, for example it
23005
+ * is automatically flattened and hoisted to the top level of the
23006
+ * argument list.
23007
+ * For example:
23008
+ * `["Add", "a", ["Sequence", "b", "c"]]` is canonicalized
23009
+ * to `["Add", "a", "b", "c"]`.
23010
+ *
23011
+ * The empty `Sequence` expression (i.e. `["Sequence"]`) is ignored
23012
+ * but it can be used to represent an "empty" expression.
23013
+ *
23014
+ * - `Delimiter` is used to represent a group of expressions
23015
+ * with an open and close delimiter and separator. They capture the
23016
+ * input syntax, and can get transformed into other expressions
23017
+ * during boxing and canonicalization.
23018
+ * The first argument is a function expression, such as `List`
23019
+ * or `Sequence`. The arguments of that expression are represented
23020
+ * with a separator between them and delimiters around the whole
23021
+ * group.
23022
+ * The second argument specify the separator and delimiters. If not
23023
+ * specified, the default is the string `"(,)"`
23024
+ *
23025
+ * Examples:
23026
+ * - `f(x)` ->
23027
+ * `["InvisibleOperator",
23028
+ * "f",
23029
+ * ["Delimiter", ["Sequence", "x"], "'(,)'"]
23030
+ * ]`
23031
+ *
23032
+ * - `1, 2; 3, 4` ->
23033
+ * `["Delimiter",
23034
+ * ["Sequence",
23035
+ * ["Delimiter", ["Sequence", 1, 2], "','"],
23036
+ * ["Delimiter", ["Sequence", 3, 4], "','"],
23037
+ * ],
23038
+ * "';'"
23039
+ * ]`
23040
+ *
23041
+ * - `2x` -> `["InvisibleOperator", 2, "x"]`
23042
+ *
23043
+ * - `2+` -> `["InvisibleOperator", 2, ["Error", "'unexpected-operator'", "+"]]`
23044
+ *
23045
+ *
23046
+ *
23047
+ *
23048
+ */
23049
+ InvisibleOperator: {
23050
+ complexity: 9e3,
23051
+ hold: "all",
23052
+ signature: {
23053
+ restParam: "Anything",
23054
+ result: (ce, args) => {
23055
+ if (args.length === 0)
23056
+ return ce.domain("NothingDomain");
23057
+ if (args.length === 1)
23058
+ return args[0].domain;
23059
+ return ce.Anything;
23060
+ },
23061
+ canonical: canonicalInvisibleOperator
23062
+ }
23063
+ },
23064
+ /** See above for a theory of operations */
23065
+ Sequence: {
23066
+ hold: "all",
23067
+ signature: {
23068
+ restParam: "Anything",
23069
+ result: (ce, args) => {
23070
+ if (args.length === 0)
23071
+ return ce.domain("NothingDomain");
23072
+ if (args.length === 1)
23073
+ return args[0].domain;
23074
+ return ce.Anything;
23075
+ },
23076
+ canonical: (ce, args) => {
23077
+ const xs = canonical(flattenSequence(args));
23078
+ if (xs.length === 0)
23079
+ return ce._fn("Sequence", []);
23080
+ if (xs.length === 1)
23081
+ return xs[0];
23082
+ return ce._fn("Sequence", xs);
23083
+ }
23084
+ }
23085
+ },
23086
+ /** See above for a theory of operations */
22597
23087
  Delimiter: {
22598
- // Use to represent groups of expressions. Named after https://en.wikipedia.org/wiki/Delimiter
23088
+ // Use to represent groups of expressions.
23089
+ // Named after https://en.wikipedia.org/wiki/Delimiter
22599
23090
  complexity: 9e3,
22600
- hold: "first",
23091
+ hold: "all",
22601
23092
  signature: {
22602
- domain: [
22603
- "FunctionOf",
22604
- "Anything",
22605
- ["OptArg", "Strings", "Strings"],
22606
- "Anything"
22607
- ],
23093
+ params: ["Anything"],
23094
+ optParams: ["Strings"],
22608
23095
  result: (_ce, args) => args[0].domain,
22609
- canonical: (ce, args) => args[0]?.canonical ?? ce.box(["Sequence"])
23096
+ // During canonicalization, Delimiters get replaced by their first
23097
+ // argument, which is a function expression (e.g. `List` or `Sequence`)
23098
+ canonical: (ce, args) => {
23099
+ if (args.length === 0)
23100
+ return ce._fn("Tuple", []);
23101
+ let body = args[0];
23102
+ console.assert(body.ops !== null);
23103
+ if (body.head === "Sequence")
23104
+ body = ce._fn("Sequence", ce.canonical(body.ops));
23105
+ args = [body, ...args.slice(1)];
23106
+ if (args.length === 1)
23107
+ return ce._fn("Delimiter", args);
23108
+ if (args.length > 2)
23109
+ return ce._fn("Delimiter", checkArity(ce, args, 2));
23110
+ if ((args[1].string?.length ?? 0) > 3) {
23111
+ return ce._fn("Delimiter", [
23112
+ args[0],
23113
+ ce.error("invalid-delimiter", args[1])
23114
+ ]);
23115
+ }
23116
+ return ce._fn("Delimiter", [
23117
+ args[0],
23118
+ checkDomain(ce, args[1], "Strings")
23119
+ ]);
23120
+ },
23121
+ evaluate: (ce, ops2) => {
23122
+ if (ops2.length === 0)
23123
+ return ce.Nothing;
23124
+ const op12 = ops2[0];
23125
+ if (op12.head === "Sequence" || op12.head === "Delimiter")
23126
+ ops2 = flattenSequence(ops2[0].ops);
23127
+ return ce._fn(
23128
+ "Tuple",
23129
+ ops2.map((x) => x.evaluate())
23130
+ );
23131
+ },
23132
+ N: (ce, ops2) => {
23133
+ if (ops2.length === 0)
23134
+ return ce.Nothing;
23135
+ const op12 = ops2[0];
23136
+ if (op12.head === "Sequence" || op12.head === "Delimiter")
23137
+ ops2 = flattenSequence(ops2[0].ops);
23138
+ return ce._fn(
23139
+ "Tuple",
23140
+ ops2.map((x) => x.N())
23141
+ );
23142
+ }
23143
+ }
23144
+ },
23145
+ Matrix: {
23146
+ complexity: 9e3,
23147
+ hold: "all",
23148
+ signature: {
23149
+ params: ["Lists"],
23150
+ optParams: ["Strings", "Strings"],
23151
+ result: "Lists",
23152
+ canonical: canonicalMatrix,
23153
+ evaluate: (_ce, ops2) => ops2[0].evaluate(),
23154
+ N: (_ce, ops2) => ops2[0].N()
22610
23155
  }
22611
23156
  },
22612
23157
  Error: {
@@ -22631,7 +23176,7 @@ var CORE_LIBRARY = [
22631
23176
  signature: {
22632
23177
  domain: ["FunctionOf", "Strings", ["VarArg", "Anything"], "Anything"],
22633
23178
  canonical: (ce, args) => {
22634
- const code = checkArg(ce, args[0], ce.Strings).string;
23179
+ const code = checkDomain(ce, args[0], ce.Strings).string;
22635
23180
  if (code === "incompatible-domain") {
22636
23181
  return ce._fn("ErrorCode", [ce.string(code), args[1], args[2]]);
22637
23182
  }
@@ -22651,11 +23196,11 @@ var CORE_LIBRARY = [
22651
23196
  return ce.domain("Strings");
22652
23197
  if (op12.head === "Numbers")
22653
23198
  return ce.domain("Numbers");
22654
- return void 0;
23199
+ return op12.domain;
22655
23200
  },
22656
23201
  // By definition, for arguments of the canonical expression of
22657
23202
  // `Hold` are not canonicalized.
22658
- canonical: (ce, args) => args.length !== 1 ? null : ce._fn("Hold", args),
23203
+ canonical: (ce, args) => args.length !== 1 ? null : ce.hold(args[0]),
22659
23204
  evaluate: (ce, ops2) => ops2[0]
22660
23205
  }
22661
23206
  },
@@ -22750,18 +23295,17 @@ var CORE_LIBRARY = [
22750
23295
  },
22751
23296
  Assign: {
22752
23297
  hold: "all",
23298
+ pure: false,
22753
23299
  signature: {
22754
- domain: ["FunctionOf", "Symbols", "Anything", "Anything"],
23300
+ domain: ["FunctionOf", "Anything", "Anything", "Anything"],
22755
23301
  canonical: (ce, args) => {
22756
23302
  if (args.length !== 2)
22757
23303
  return null;
22758
23304
  const op12 = args[0];
22759
- const op22 = args[1];
22760
23305
  if (!op12.symbol)
22761
23306
  return null;
22762
- if (op22.symbol)
22763
- return ce._fn("Assign", args);
22764
- return ce._fn("Assign", [op12, ce._fn("Hold", [op22])]);
23307
+ const op22 = args[1];
23308
+ return ce._fn("Assign", [ce.hold(op12), ce.hold(op22)]);
22765
23309
  },
22766
23310
  evaluate: (ce, ops2) => {
22767
23311
  const op12 = ops2[0];
@@ -22776,6 +23320,7 @@ var CORE_LIBRARY = [
22776
23320
  },
22777
23321
  Assume: {
22778
23322
  hold: "all",
23323
+ pure: false,
22779
23324
  signature: {
22780
23325
  domain: ["FunctionOf", "Anything", "Anything"],
22781
23326
  evaluate: (ce, ops2) => ce.string(ce.assume(ops2[0]))
@@ -22783,6 +23328,7 @@ var CORE_LIBRARY = [
22783
23328
  },
22784
23329
  Declare: {
22785
23330
  hold: "all",
23331
+ pure: false,
22786
23332
  signature: {
22787
23333
  domain: ["FunctionOf", "Symbols", "Anything"],
22788
23334
  canonical: (ce, args) => {
@@ -22936,17 +23482,15 @@ var CORE_LIBRARY = [
22936
23482
  const op22 = args[1];
22937
23483
  if (op12.string) {
22938
23484
  const base = asSmallInteger(op22);
22939
- if (base !== null) {
22940
- if (base > 1 && base <= 36) {
22941
- const [value, rest] = fromDigits(op12.string, base);
22942
- if (rest) {
22943
- return ce.error(
22944
- ["unexpected-digit", { str: rest[0] }],
22945
- ["LatexString", ce.string(op12.string)]
22946
- );
22947
- }
22948
- return ce.number(value);
23485
+ if (base !== null && base > 1 && base <= 36) {
23486
+ const [value, rest] = fromDigits(op12.string, base);
23487
+ if (rest) {
23488
+ return ce.error(
23489
+ ["unexpected-digit", { str: rest[0] }],
23490
+ ["LatexString", ce.string(op12.string)]
23491
+ );
22949
23492
  }
23493
+ return ce.number(value);
22950
23494
  }
22951
23495
  }
22952
23496
  if (op12.symbol) {
@@ -23064,6 +23608,56 @@ var CORE_LIBRARY = [
23064
23608
  }
23065
23609
  }
23066
23610
  ];
23611
+ function canonicalInvisibleOperator(ce, ops2) {
23612
+ if (ops2.length === 0)
23613
+ return null;
23614
+ const lhs = ops2[0];
23615
+ if (ops2.length === 1)
23616
+ return canonicalInvisibleOperator(ce, [lhs.canonical]);
23617
+ if (ops2.length === 2) {
23618
+ const lhsNumber = asFloat(lhs);
23619
+ if (lhsNumber !== null && Number.isInteger(lhsNumber)) {
23620
+ const rhs2 = ops2[1];
23621
+ if (rhs2.head === "Divide" || rhs2.head === "Rational") {
23622
+ const [n, d] = [asFloat(rhs2.op1), asFloat(rhs2.op2)];
23623
+ if (n !== null && d !== null && n > 0 && n <= 1e3 && d > 1 && d <= 1e3 && Number.isInteger(n) && Number.isInteger(d))
23624
+ return ce.add([lhs.canonical, rhs2.canonical]);
23625
+ }
23626
+ }
23627
+ let rhs = ops2[1];
23628
+ if (lhs.symbol && rhs.head === "Delimiter" && !ce.lookupSymbol(lhs.symbol)) {
23629
+ if (!ce.lookupFunction(lhs.symbol)) {
23630
+ ce.declare(lhs.symbol, "Functions");
23631
+ }
23632
+ if (rhs.nops === 0)
23633
+ return ce.box([lhs.symbol]);
23634
+ rhs = rhs.op1;
23635
+ if (rhs.head === "Sequence")
23636
+ return ce.box([lhs.symbol, ...ce.canonical(rhs.ops)]);
23637
+ return ce.box([lhs.symbol, rhs.canonical]);
23638
+ }
23639
+ }
23640
+ ops2 = canonical(flattenSequence(ops2));
23641
+ if (ops2.every(
23642
+ (x) => x.isValid && (!x.domain || x.domain.isNumeric || isIndexableCollection(x) && !x.string)
23643
+ ))
23644
+ return ce._fn("Multiply", flattenOps(ops2, "Multiply"));
23645
+ return ce._fn("Tuple", ops2);
23646
+ }
23647
+ function canonicalMatrix(ce, ops2) {
23648
+ if (ops2.length === 0)
23649
+ return ce._fn("Matrix", []);
23650
+ const body = ops2[0].canonical;
23651
+ const delims = ops2[1]?.canonical;
23652
+ const columns = ops2[2]?.canonical;
23653
+ if (ops2.length > 3)
23654
+ return ce._fn("Matrix", checkArity(ce, ops2, 3));
23655
+ if (columns)
23656
+ return ce._fn("Matrix", [body, delims, columns]);
23657
+ if (delims)
23658
+ return ce._fn("Matrix", [body, delims]);
23659
+ return ce._fn("Matrix", [body]);
23660
+ }
23067
23661
 
23068
23662
  // src/compute-engine/library/linear-algebra.ts
23069
23663
  var LINEAR_ALGEBRA_LIBRARY = [];
@@ -23131,6 +23725,15 @@ var LOGIC_LIBRARY = {
23131
23725
  complexity: 10200,
23132
23726
  signature: {
23133
23727
  domain: "LogicOperators",
23728
+ canonical: (ce, args) => {
23729
+ const lhs = args[0].symbol;
23730
+ const rhs = args[1].symbol;
23731
+ if (lhs === "True" && rhs === "True" || lhs === "False" && rhs === "False")
23732
+ return ce.True;
23733
+ if (lhs === "True" && rhs === "False" || lhs === "False" && rhs === "True")
23734
+ return ce.False;
23735
+ return ce._fn("Equivalent", args);
23736
+ },
23134
23737
  simplify: processEquivalent,
23135
23738
  evaluate: processEquivalent
23136
23739
  }
@@ -23200,7 +23803,7 @@ function processOr(ce, args) {
23200
23803
  return ce._fn("Or", ops2);
23201
23804
  }
23202
23805
  function processNot(ce, args) {
23203
- const op12 = args[0].symbol;
23806
+ const op12 = args[0]?.symbol;
23204
23807
  if (op12 === "True")
23205
23808
  return ce.False;
23206
23809
  if (op12 === "False")
@@ -23264,17 +23867,42 @@ var POLYNOMIALS_LIBRARY = [
23264
23867
 
23265
23868
  // src/compute-engine/library/relational-operator.ts
23266
23869
  var RELOP_LIBRARY = {
23870
+ Congruent: {
23871
+ commutative: false,
23872
+ complexity: 11e3,
23873
+ numeric: true,
23874
+ signature: {
23875
+ simplify: (ce, ops2) => {
23876
+ if (ops2.length < 3)
23877
+ return void 0;
23878
+ return ce._fn("Equal", [
23879
+ ce.box(["Mod", ops2[0], ops2[2]]).simplify(),
23880
+ ce.box(["Mod", ops2[1], ops2[2]]).simplify()
23881
+ ]).simplify();
23882
+ },
23883
+ evaluate: (ce, ops2) => {
23884
+ if (ops2.length < 3)
23885
+ return void 0;
23886
+ const [lhs, rhs, modulo] = ops2;
23887
+ const nLhs = lhs.value;
23888
+ const nRhs = rhs.value;
23889
+ const nModulo = modulo.value;
23890
+ if (typeof nLhs !== "number")
23891
+ return void 0;
23892
+ if (typeof nRhs !== "number")
23893
+ return void 0;
23894
+ if (typeof nModulo !== "number")
23895
+ return void 0;
23896
+ return nLhs % nModulo === nRhs % nModulo ? ce.True : ce.False;
23897
+ }
23898
+ }
23899
+ },
23267
23900
  Equal: {
23268
23901
  commutative: true,
23269
23902
  complexity: 11e3,
23270
23903
  signature: {
23271
23904
  domain: "RelationalOperators",
23272
- canonical: (ce, ops2) => {
23273
- return ce._fn(
23274
- "Equal",
23275
- flattenOps(flattenSequence(canonical(ops2)), "Equal")
23276
- );
23277
- },
23905
+ canonical: (ce, args) => canonicalRelational(ce, "Equal", args),
23278
23906
  evaluate: (ce, ops2) => {
23279
23907
  if (ops2.length < 2)
23280
23908
  return ce.True;
@@ -23298,6 +23926,7 @@ var RELOP_LIBRARY = {
23298
23926
  complexity: 11e3,
23299
23927
  signature: {
23300
23928
  domain: "RelationalOperators",
23929
+ canonical: (ce, args) => canonicalRelational(ce, "NotEqual", args),
23301
23930
  evaluate: (ce, ops2) => {
23302
23931
  if (ops2.length < 2)
23303
23932
  return ce.False;
@@ -23319,7 +23948,7 @@ var RELOP_LIBRARY = {
23319
23948
  complexity: 11e3,
23320
23949
  signature: {
23321
23950
  domain: "RelationalOperators",
23322
- canonical: (ce, ops2) => ce._fn("Less", flattenOps(flattenSequence(canonical(ops2)), "Less")),
23951
+ canonical: (ce, ops2) => canonicalRelational(ce, "Less", ops2),
23323
23952
  evaluate: (ce, ops2) => {
23324
23953
  if (ops2.length < 2)
23325
23954
  return ce.True;
@@ -23346,14 +23975,14 @@ var RELOP_LIBRARY = {
23346
23975
  complexity: 11e3,
23347
23976
  signature: {
23348
23977
  domain: "RelationalOperators",
23349
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Less", args)])
23978
+ canonical: (ce, ops2) => ce._fn("Not", [canonicalRelational(ce, "Less", ops2)])
23350
23979
  }
23351
23980
  },
23352
23981
  Greater: {
23353
23982
  complexity: 11e3,
23354
23983
  signature: {
23355
23984
  domain: "RelationalOperators",
23356
- canonical: (ce, args) => ce._fn("Less", args.reverse()),
23985
+ canonical: (ce, ops2) => canonicalRelational(ce, "Less", ops2.reverse()),
23357
23986
  evaluate: (ce, ops2) => {
23358
23987
  if (ops2.length < 2)
23359
23988
  return ce.True;
@@ -23387,6 +24016,7 @@ var RELOP_LIBRARY = {
23387
24016
  complexity: 11e3,
23388
24017
  signature: {
23389
24018
  domain: "RelationalOperators",
24019
+ canonical: (ce, ops2) => canonicalRelational(ce, "LessEqual", ops2),
23390
24020
  evaluate: (ce, ops2) => {
23391
24021
  if (ops2.length < 2)
23392
24022
  return ce.True;
@@ -23413,14 +24043,14 @@ var RELOP_LIBRARY = {
23413
24043
  complexity: 11e3,
23414
24044
  signature: {
23415
24045
  domain: "RelationalOperators",
23416
- canonical: (ce, args) => ce._fn("Not", [ce._fn("LessEqual", args)])
24046
+ canonical: (ce, ops2) => ce._fn("Not", [canonicalRelational(ce, "LessEqual", ops2)])
23417
24047
  }
23418
24048
  },
23419
24049
  GreaterEqual: {
23420
24050
  complexity: 11e3,
23421
24051
  signature: {
23422
24052
  domain: "RelationalOperators",
23423
- canonical: (ce, args) => ce._fn("LessEqual", args.reverse()),
24053
+ canonical: (ce, args) => canonicalRelational(ce, "LessEqual", args.reverse()),
23424
24054
  evaluate: (ce, ops2) => {
23425
24055
  if (ops2.length < 2)
23426
24056
  return ce.True;
@@ -23447,94 +24077,136 @@ var RELOP_LIBRARY = {
23447
24077
  complexity: 11e3,
23448
24078
  signature: {
23449
24079
  domain: "RelationalOperators",
23450
- canonical: (ce, args) => ce._fn("Not", [ce._fn("GreaterEqual", args)])
24080
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "GreaterEqual", args)])
23451
24081
  }
23452
24082
  },
23453
24083
  TildeFullEqual: {
23454
24084
  description: "Indicate isomorphism, congruence and homotopic equivalence",
23455
- signature: { domain: "RelationalOperators" }
24085
+ signature: {
24086
+ domain: "RelationalOperators",
24087
+ canonical: (ce, args) => canonicalRelational(ce, "TildeFullEqual", args)
24088
+ }
23456
24089
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23457
24090
  },
23458
24091
  NotTildeFullEqual: {
23459
24092
  complexity: 11100,
23460
24093
  signature: {
23461
24094
  domain: "RelationalOperators",
23462
- canonical: (ce, args) => ce._fn("Not", [ce._fn("TildeFullEqual", args)])
24095
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "TildeFullEqual", args)])
23463
24096
  }
23464
24097
  },
23465
24098
  TildeEqual: {
23466
24099
  description: "Approximately or asymptotically equal",
23467
24100
  complexity: 11e3,
23468
- signature: { domain: "RelationalOperators" }
24101
+ signature: {
24102
+ domain: "RelationalOperators",
24103
+ canonical: (ce, args) => canonicalRelational(ce, "TildeEqual", args)
24104
+ }
23469
24105
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23470
24106
  },
23471
24107
  NotTildeEqual: {
23472
24108
  complexity: 11100,
23473
24109
  signature: {
23474
24110
  domain: "RelationalOperators",
23475
- canonical: (ce, args) => ce._fn("Not", [ce._fn("TildeEqual", args)])
24111
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "TildeEqual", args)])
23476
24112
  }
23477
24113
  },
23478
24114
  Approx: {
23479
24115
  complexity: 11100,
23480
- signature: { domain: "RelationalOperators" }
24116
+ signature: {
24117
+ domain: "RelationalOperators",
24118
+ canonical: (ce, args) => canonicalRelational(ce, "Approx", args)
24119
+ }
23481
24120
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23482
24121
  },
23483
24122
  NotApprox: {
23484
24123
  complexity: 11100,
23485
24124
  signature: {
23486
24125
  domain: "RelationalOperators",
23487
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Approx", args)])
24126
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Approx", args)])
23488
24127
  }
23489
24128
  },
23490
24129
  ApproxEqual: {
23491
24130
  complexity: 11100,
23492
- signature: { domain: "RelationalOperators" }
24131
+ signature: {
24132
+ domain: "RelationalOperators",
24133
+ canonical: (ce, args) => canonicalRelational(ce, "ApproxEqual", args)
24134
+ }
23493
24135
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23494
24136
  },
23495
24137
  NotApproxEqual: {
23496
24138
  complexity: 11100,
23497
24139
  signature: {
23498
24140
  domain: "RelationalOperators",
23499
- canonical: (ce, args) => ce._fn("Not", [ce._fn("ApproxEqual", args)])
24141
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "ApproxEqual", args)])
23500
24142
  }
23501
24143
  },
23502
24144
  ApproxNotEqual: {
23503
24145
  complexity: 11100,
23504
- signature: { domain: "RelationalOperators" }
24146
+ signature: {
24147
+ domain: "RelationalOperators",
24148
+ canonical: (ce, args) => canonicalRelational(ce, "ApproxNotEqual", args)
24149
+ }
23505
24150
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23506
24151
  },
23507
24152
  NotApproxNotEqual: {
23508
24153
  complexity: 11100,
23509
24154
  signature: {
23510
24155
  domain: "RelationalOperators",
23511
- canonical: (ce, args) => ce._fn("Not", [ce._fn("ApproxNotEqual", args)])
24156
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "ApproxNotEqual", args)])
23512
24157
  }
23513
24158
  },
23514
24159
  Precedes: {
23515
24160
  complexity: 11100,
23516
- signature: { domain: "RelationalOperators" }
24161
+ signature: {
24162
+ domain: "RelationalOperators",
24163
+ canonical: (ce, args) => canonicalRelational(ce, "Precedes", args)
24164
+ }
23517
24165
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23518
24166
  },
23519
24167
  NotPrecedes: {
23520
24168
  complexity: 11100,
23521
24169
  signature: {
23522
24170
  domain: "RelationalOperators",
23523
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Precedes", args)])
24171
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Precedes", args)])
23524
24172
  }
23525
24173
  },
23526
24174
  Succeeds: {
23527
- signature: { domain: "RelationalOperators" }
24175
+ signature: {
24176
+ domain: "RelationalOperators",
24177
+ canonical: (ce, args) => canonicalRelational(ce, "Succeeds", args)
24178
+ }
23528
24179
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23529
24180
  },
23530
24181
  NotSucceeds: {
23531
24182
  complexity: 11100,
23532
24183
  signature: {
23533
24184
  domain: "RelationalOperators",
23534
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Succeeds", args)])
24185
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Succeeds", args)])
23535
24186
  }
23536
24187
  }
23537
24188
  };
24189
+ function canonicalRelational(ce, head2, ops2) {
24190
+ ops2 = flattenOps(flattenSequence(canonical(ops2)), head2);
24191
+ const nestedRelational = [];
24192
+ let newOps = [];
24193
+ for (const op3 of ops2) {
24194
+ if (isRelationalOperator(op3)) {
24195
+ nestedRelational.push(op3);
24196
+ newOps.push(op3.ops[op3.ops.length - 1]);
24197
+ } else
24198
+ newOps.push(op3);
24199
+ }
24200
+ newOps = newOps.map((op3) => checkPure(ce, op3));
24201
+ if (nestedRelational.length === 0)
24202
+ return ce._fn(head2, newOps);
24203
+ return ce._fn("And", [ce._fn(head2, newOps), ...nestedRelational]);
24204
+ }
24205
+ function isRelationalOperator(op3) {
24206
+ return typeof op3.head === "string" && /Equal|NotEqual|Less|NotLess|Greater|NotGreater|LessEqual|NotLessNotEqual|GreaterEqual|NotGreater|NotEqual|TildeFullEqual|NotTildeFullEqual|TildeEqual|NotTildeEqual|Approx|NotApprox|ApproxEqual|NotApproxEqual|ApproxNotEqual|NotApproxNotEqual|Precedes|NotPrecedes|Succeeds|NotSucceeds/.test(
24207
+ op3.head
24208
+ );
24209
+ }
23538
24210
 
23539
24211
  // src/compute-engine/library/sets.ts
23540
24212
  var SETS_LIBRARY = {
@@ -26332,14 +27004,7 @@ var BoxedSymbol = class _BoxedSymbol extends _BoxedExpression {
26332
27004
  return this._hash;
26333
27005
  }
26334
27006
  get isPure() {
26335
- const def = this._def ?? this.engine.lookupSymbol(this._id, this.wikidata);
26336
- if (!def)
26337
- return false;
26338
- if (def instanceof _BoxedSymbolDefinition)
26339
- return (def?.constant && def.value?.isPure) ?? false;
26340
- if (def instanceof _BoxedFunctionDefinition)
26341
- return def?.pure ?? false;
26342
- return false;
27007
+ return true;
26343
27008
  }
26344
27009
  get json() {
26345
27010
  const wikidata = this._scope ? this.wikidata : void 0;
@@ -26848,15 +27513,15 @@ var ComputeEngine = class _ComputeEngine {
26848
27513
  TranscendentalNumbers: null,
26849
27514
  PositiveNumbers: null,
26850
27515
  Functions: null,
26851
- // (Anything^n) -> Anything
27516
+ // (Anything*) -> Anything
26852
27517
  NumericFunctions: null,
26853
- // (Numbers^n) -> Numbers
27518
+ // (Numbers+) -> Numbers
26854
27519
  RealFunctions: null,
26855
- // (ExtendedRealNumbers^n) -> ExtendRealNumbers
27520
+ // (ExtendedRealNumbers+) -> ExtendRealNumbers
26856
27521
  LogicOperators: null,
26857
- // (Booleans, Booleans) -> Boolean
27522
+ // (Booleans+) -> Boolean
26858
27523
  Predicates: null
26859
- // (Anything^n) -> Booleans
27524
+ // (Anything+) -> Booleans
26860
27525
  };
26861
27526
  if (options !== void 0 && typeof options !== "object")
26862
27527
  throw Error("Unexpected argument");
@@ -27128,7 +27793,12 @@ var ComputeEngine = class _ComputeEngine {
27128
27793
  bignum(a) {
27129
27794
  if (typeof a === "bigint")
27130
27795
  return new this._bignum(a.toString());
27131
- return new this._bignum(a);
27796
+ try {
27797
+ return new this._bignum(a);
27798
+ } catch (e) {
27799
+ console.error(e);
27800
+ }
27801
+ return this._BIGNUM_NAN;
27132
27802
  }
27133
27803
  complex(a, b) {
27134
27804
  if (a instanceof Decimal)
@@ -27477,11 +28147,10 @@ var ComputeEngine = class _ComputeEngine {
27477
28147
  const scope = symDef.scope;
27478
28148
  scope?.ids?.delete(symDef.name);
27479
28149
  if (!args && !isFunctionValue(value)) {
27480
- if (value === void 0 || value === null) {
28150
+ if (value === void 0 || value === null)
27481
28151
  symDef.value = void 0;
27482
- return this;
27483
- }
27484
- symDef.value = this.box(value);
28152
+ else
28153
+ symDef.value = this.box(value);
27485
28154
  scope?.ids?.set(symDef.name, symDef);
27486
28155
  return this;
27487
28156
  }
@@ -28114,10 +28783,10 @@ function isFunctionValue(value) {
28114
28783
  }
28115
28784
 
28116
28785
  // src/compute-engine.ts
28117
- var version = "0.19.1";
28786
+ var version = "0.20.0";
28118
28787
  globalThis[Symbol.for("io.cortexjs.compute-engine")] = {
28119
28788
  ComputeEngine: ComputeEngine.prototype.constructor,
28120
- version: "0.19.1"
28789
+ version: "0.20.0"
28121
28790
  };
28122
28791
  export {
28123
28792
  ADDITION_PRECEDENCE,