@cortex-js/compute-engine 0.57.0 → 0.58.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.
- package/dist/compile.esm.js +690 -53
- package/dist/compile.min.esm.js +251 -51
- package/dist/compile.min.umd.cjs +251 -51
- package/dist/compile.umd.cjs +690 -53
- package/dist/compute-engine.esm.js +1079 -132
- package/dist/compute-engine.min.esm.js +271 -71
- package/dist/compute-engine.min.umd.cjs +270 -70
- package/dist/compute-engine.umd.cjs +1079 -132
- package/dist/core.esm.js +1078 -131
- package/dist/core.min.esm.js +269 -69
- package/dist/core.min.umd.cjs +269 -69
- package/dist/core.umd.cjs +1078 -131
- package/dist/interval.esm.js +132 -15
- package/dist/interval.min.esm.js +6 -6
- package/dist/interval.min.umd.cjs +6 -6
- package/dist/interval.umd.cjs +132 -15
- package/dist/latex-syntax.esm.js +132 -15
- package/dist/latex-syntax.min.esm.js +6 -6
- package/dist/latex-syntax.min.umd.cjs +6 -6
- package/dist/latex-syntax.umd.cjs +132 -15
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/numerics.esm.js +38 -3
- package/dist/numerics.min.esm.js +3 -3
- package/dist/numerics.min.umd.cjs +4 -4
- package/dist/numerics.umd.cjs +38 -3
- package/dist/types/big-decimal/big-decimal.d.ts +1 -1
- package/dist/types/big-decimal/index.d.ts +1 -1
- package/dist/types/big-decimal/transcendentals.d.ts +1 -1
- package/dist/types/big-decimal/utils.d.ts +1 -1
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +1 -1
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/ast-nodes.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +1 -1
- package/dist/types/common/type/lexer.d.ts +1 -1
- package/dist/types/common/type/parse.d.ts +1 -1
- package/dist/types/common/type/parser.d.ts +1 -1
- package/dist/types/common/type/primitive.d.ts +1 -1
- package/dist/types/common/type/reduce.d.ts +1 -1
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/type-builder.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +1 -1
- package/dist/types/common/type/utils.d.ts +1 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compile.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +3 -1
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +7 -1
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +22 -10
- package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
- package/dist/types/compute-engine/collection-utils.d.ts +1 -1
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +8 -1
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
- package/dist/types/compute-engine/compilation/constant-folding.d.ts +1 -1
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +44 -1
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +1 -1
- package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
- package/dist/types/compute-engine/engine-cache.d.ts +1 -1
- package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
- package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
- package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
- package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
- package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
- package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
- package/dist/types/compute-engine/engine-runtime-state.d.ts +4 -1
- package/dist/types/compute-engine/engine-scope.d.ts +1 -1
- package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
- package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
- package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
- package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
- package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/free-functions.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +1 -1
- package/dist/types/compute-engine/global-types.d.ts +1 -1
- package/dist/types/compute-engine/index.d.ts +17 -2
- package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
- package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
- package/dist/types/compute-engine/interval/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
- package/dist/types/compute-engine/interval/types.d.ts +1 -1
- package/dist/types/compute-engine/interval/util.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
- package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/calculus.d.ts +1 -1
- package/dist/types/compute-engine/library/collections.d.ts +1 -1
- package/dist/types/compute-engine/library/colors.d.ts +1 -1
- package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
- package/dist/types/compute-engine/library/complex.d.ts +1 -1
- package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
- package/dist/types/compute-engine/library/core.d.ts +1 -1
- package/dist/types/compute-engine/library/fractals.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +1 -1
- package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
- package/dist/types/compute-engine/library/logic.d.ts +1 -1
- package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
- package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/sets.d.ts +1 -1
- package/dist/types/compute-engine/library/statistics.d.ts +1 -1
- package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
- package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/library/units.d.ts +1 -1
- package/dist/types/compute-engine/library/utils.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/random.d.ts +23 -0
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +34 -1
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +69 -1
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types.d.ts +1 -1
- package/dist/types/compute-engine.d.ts +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/interval.d.ts +1 -1
- package/dist/types/latex-syntax.d.ts +2 -2
- package/dist/types/math-json/symbols.d.ts +1 -1
- package/dist/types/math-json/types.d.ts +1 -1
- package/dist/types/math-json/utils.d.ts +1 -1
- package/dist/types/math-json.d.ts +2 -2
- package/dist/types/numerics.d.ts +1 -1
- package/package.json +1 -1
package/dist/core.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.
|
|
1
|
+
/** Compute Engine 0.58.0 */
|
|
2
2
|
|
|
3
3
|
// node_modules/complex-esm/dist/src/complex.js
|
|
4
4
|
var cosh = Math.cosh || function(x) {
|
|
@@ -4268,7 +4268,42 @@ function widen2(a, b) {
|
|
|
4268
4268
|
if (b === "nothing") return a;
|
|
4269
4269
|
if (isSubtype(a, b)) return b;
|
|
4270
4270
|
if (isSubtype(b, a)) return a;
|
|
4271
|
-
|
|
4271
|
+
const sup = superType(a, b);
|
|
4272
|
+
if (LOSSY_SUPERTYPE.has(sup)) return unionTypes(a, b);
|
|
4273
|
+
return sup;
|
|
4274
|
+
}
|
|
4275
|
+
var LOSSY_SUPERTYPE = /* @__PURE__ */ new Set([
|
|
4276
|
+
"scalar",
|
|
4277
|
+
"value",
|
|
4278
|
+
"function",
|
|
4279
|
+
"expression",
|
|
4280
|
+
"collection",
|
|
4281
|
+
"indexed_collection",
|
|
4282
|
+
"list",
|
|
4283
|
+
"set",
|
|
4284
|
+
"tuple",
|
|
4285
|
+
"record",
|
|
4286
|
+
"dictionary",
|
|
4287
|
+
"map",
|
|
4288
|
+
"any"
|
|
4289
|
+
]);
|
|
4290
|
+
function unionTypes(a, b) {
|
|
4291
|
+
const members = [];
|
|
4292
|
+
const push = (t) => {
|
|
4293
|
+
if (typeof t === "object" && t.kind === "union") {
|
|
4294
|
+
for (const m of t.types) push(m);
|
|
4295
|
+
return;
|
|
4296
|
+
}
|
|
4297
|
+
const key = typeof t === "string" ? t : JSON.stringify(t);
|
|
4298
|
+
if (!members.some(
|
|
4299
|
+
(m) => (typeof m === "string" ? m : JSON.stringify(m)) === key
|
|
4300
|
+
))
|
|
4301
|
+
members.push(t);
|
|
4302
|
+
};
|
|
4303
|
+
push(a);
|
|
4304
|
+
push(b);
|
|
4305
|
+
if (members.length === 1) return members[0];
|
|
4306
|
+
return { kind: "union", types: members };
|
|
4272
4307
|
}
|
|
4273
4308
|
function narrow(...types) {
|
|
4274
4309
|
if (types.length === 0) return "nothing";
|
|
@@ -4346,7 +4381,7 @@ function collectionElementType(type2) {
|
|
|
4346
4381
|
if (type2.kind === "set") return type2.elements;
|
|
4347
4382
|
if (type2.kind === "tuple") return widen(...type2.elements.map((x) => x.type));
|
|
4348
4383
|
if (type2.kind === "dictionary")
|
|
4349
|
-
return parseType(`tuple<string, ${type2.values}>`);
|
|
4384
|
+
return parseType(`tuple<string, ${typeToString(type2.values)}>`);
|
|
4350
4385
|
if (type2.kind === "record") {
|
|
4351
4386
|
return parseType(
|
|
4352
4387
|
`tuple<string, ${typeToString(widen(...Object.values(type2.elements)))}>`
|
|
@@ -5892,6 +5927,84 @@ function sym(expr2) {
|
|
|
5892
5927
|
}
|
|
5893
5928
|
|
|
5894
5929
|
// src/compute-engine/boxed-expression/inequality-bounds.ts
|
|
5930
|
+
function extractIntervalBounds(expr2, symbol2) {
|
|
5931
|
+
if (isFunction2(expr2, "When")) {
|
|
5932
|
+
const cond = expr2.op2;
|
|
5933
|
+
if (!cond) return void 0;
|
|
5934
|
+
return extractIntervalBounds(cond, symbol2);
|
|
5935
|
+
}
|
|
5936
|
+
if (isFunction2(expr2, "Multiply")) {
|
|
5937
|
+
const ops = expr2.ops;
|
|
5938
|
+
if (!ops) return void 0;
|
|
5939
|
+
const merged = {};
|
|
5940
|
+
for (const sub2 of ops) {
|
|
5941
|
+
if (isFunction2(sub2, "When")) {
|
|
5942
|
+
const sub_ = extractIntervalBounds(sub2, symbol2);
|
|
5943
|
+
if (sub_ !== void 0) _mergeBounds(merged, sub_);
|
|
5944
|
+
}
|
|
5945
|
+
}
|
|
5946
|
+
return _hasAnyBound(merged) ? merged : void 0;
|
|
5947
|
+
}
|
|
5948
|
+
const result = {};
|
|
5949
|
+
if (isFunction2(expr2, "And")) {
|
|
5950
|
+
const ops = expr2.ops;
|
|
5951
|
+
if (!ops) return void 0;
|
|
5952
|
+
for (const sub2 of ops) {
|
|
5953
|
+
const subBounds = extractIntervalBounds(sub2, symbol2);
|
|
5954
|
+
if (subBounds === void 0) continue;
|
|
5955
|
+
_mergeBounds(result, subBounds);
|
|
5956
|
+
}
|
|
5957
|
+
return _hasAnyBound(result) ? result : void 0;
|
|
5958
|
+
}
|
|
5959
|
+
const op = expr2.operator;
|
|
5960
|
+
if ((op === "Less" || op === "LessEqual" || op === "Greater" || op === "GreaterEqual") && isFunction2(expr2)) {
|
|
5961
|
+
const isStrict = op === "Less" || op === "Greater";
|
|
5962
|
+
const ops = expr2.ops;
|
|
5963
|
+
if (!ops || ops.length < 2) return void 0;
|
|
5964
|
+
const flipped = op === "Greater" || op === "GreaterEqual" ? [...ops].reverse() : ops;
|
|
5965
|
+
for (let i = 0; i < flipped.length; i++) {
|
|
5966
|
+
if (isSymbol2(flipped[i], symbol2)) {
|
|
5967
|
+
if (i > 0) {
|
|
5968
|
+
const candidate = flipped[i - 1];
|
|
5969
|
+
if (result.lower === void 0 || candidate.isGreater(result.lower) === true) {
|
|
5970
|
+
result.lower = candidate;
|
|
5971
|
+
result.lowerStrict = isStrict;
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
if (i < flipped.length - 1) {
|
|
5975
|
+
const candidate = flipped[i + 1];
|
|
5976
|
+
if (result.upper === void 0 || candidate.isLess(result.upper) === true) {
|
|
5977
|
+
result.upper = candidate;
|
|
5978
|
+
result.upperStrict = isStrict;
|
|
5979
|
+
}
|
|
5980
|
+
}
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
return _hasAnyBound(result) ? result : void 0;
|
|
5984
|
+
}
|
|
5985
|
+
return void 0;
|
|
5986
|
+
}
|
|
5987
|
+
function _mergeBounds(into, from) {
|
|
5988
|
+
if (from.lower !== void 0) {
|
|
5989
|
+
if (into.lower === void 0 || from.lower.isGreater(into.lower) === true) {
|
|
5990
|
+
into.lower = from.lower;
|
|
5991
|
+
into.lowerStrict = from.lowerStrict;
|
|
5992
|
+
} else if (from.lower.isSame(into.lower)) {
|
|
5993
|
+
into.lowerStrict = into.lowerStrict || from.lowerStrict;
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
if (from.upper !== void 0) {
|
|
5997
|
+
if (into.upper === void 0 || from.upper.isLess(into.upper) === true) {
|
|
5998
|
+
into.upper = from.upper;
|
|
5999
|
+
into.upperStrict = from.upperStrict;
|
|
6000
|
+
} else if (from.upper.isSame(into.upper)) {
|
|
6001
|
+
into.upperStrict = into.upperStrict || from.upperStrict;
|
|
6002
|
+
}
|
|
6003
|
+
}
|
|
6004
|
+
}
|
|
6005
|
+
function _hasAnyBound(b) {
|
|
6006
|
+
return b.lower !== void 0 || b.upper !== void 0;
|
|
6007
|
+
}
|
|
5895
6008
|
function getInequalityBoundsFromAssumptions(ce, symbol2) {
|
|
5896
6009
|
const result = {};
|
|
5897
6010
|
const assumptions = ce.context?.assumptions;
|
|
@@ -5908,8 +6021,8 @@ function getInequalityBoundsFromAssumptions(ce, symbol2) {
|
|
|
5908
6021
|
const isStrict = op === "Less";
|
|
5909
6022
|
if (isFunction2(lhs, "Negate") && isSymbol2(lhs.op1, symbol2)) {
|
|
5910
6023
|
const bound = ce.Zero;
|
|
5911
|
-
if (result.
|
|
5912
|
-
result.
|
|
6024
|
+
if (result.lower === void 0 || bound.isGreater(result.lower) === true) {
|
|
6025
|
+
result.lower = bound;
|
|
5913
6026
|
result.lowerStrict = isStrict;
|
|
5914
6027
|
}
|
|
5915
6028
|
}
|
|
@@ -5928,16 +6041,16 @@ function getInequalityBoundsFromAssumptions(ce, symbol2) {
|
|
|
5928
6041
|
}
|
|
5929
6042
|
if (hasNegatedSymbol && constantSum !== 0) {
|
|
5930
6043
|
const bound = ce.expr(constantSum);
|
|
5931
|
-
if (result.
|
|
5932
|
-
result.
|
|
6044
|
+
if (result.lower === void 0 || bound.isGreater(result.lower) === true) {
|
|
6045
|
+
result.lower = bound;
|
|
5933
6046
|
result.lowerStrict = isStrict;
|
|
5934
6047
|
}
|
|
5935
6048
|
}
|
|
5936
6049
|
}
|
|
5937
6050
|
if (isSymbol2(lhs, symbol2)) {
|
|
5938
6051
|
const bound = ce.Zero;
|
|
5939
|
-
if (result.
|
|
5940
|
-
result.
|
|
6052
|
+
if (result.upper === void 0 || bound.isLess(result.upper) === true) {
|
|
6053
|
+
result.upper = bound;
|
|
5941
6054
|
result.upperStrict = isStrict;
|
|
5942
6055
|
}
|
|
5943
6056
|
}
|
|
@@ -5956,8 +6069,8 @@ function getInequalityBoundsFromAssumptions(ce, symbol2) {
|
|
|
5956
6069
|
}
|
|
5957
6070
|
if (hasSymbol && constantSum !== 0) {
|
|
5958
6071
|
const bound = ce.expr(-constantSum);
|
|
5959
|
-
if (result.
|
|
5960
|
-
result.
|
|
6072
|
+
if (result.upper === void 0 || bound.isLess(result.upper) === true) {
|
|
6073
|
+
result.upper = bound;
|
|
5961
6074
|
result.upperStrict = isStrict;
|
|
5962
6075
|
}
|
|
5963
6076
|
}
|
|
@@ -6177,8 +6290,8 @@ function cmp(a, b) {
|
|
|
6177
6290
|
const bounds = getInequalityBoundsFromAssumptions(a.engine, b.symbol);
|
|
6178
6291
|
const aNum = typeof a.numericValue === "number" ? a.numericValue : a.numericValue.re;
|
|
6179
6292
|
if (aNum !== void 0 && Number.isFinite(aNum)) {
|
|
6180
|
-
if (bounds.
|
|
6181
|
-
const lb = bounds.
|
|
6293
|
+
if (bounds.lower !== void 0) {
|
|
6294
|
+
const lb = bounds.lower;
|
|
6182
6295
|
const lowerNum = isNumber(lb) ? typeof lb.numericValue === "number" ? lb.numericValue : lb.numericValue.re : void 0;
|
|
6183
6296
|
if (lowerNum !== void 0 && Number.isFinite(lowerNum)) {
|
|
6184
6297
|
if (lowerNum > aNum) return "<";
|
|
@@ -6186,8 +6299,8 @@ function cmp(a, b) {
|
|
|
6186
6299
|
if (lowerNum === aNum && !bounds.lowerStrict) return "<=";
|
|
6187
6300
|
}
|
|
6188
6301
|
}
|
|
6189
|
-
if (bounds.
|
|
6190
|
-
const ub = bounds.
|
|
6302
|
+
if (bounds.upper !== void 0) {
|
|
6303
|
+
const ub = bounds.upper;
|
|
6191
6304
|
const upperNum = isNumber(ub) ? typeof ub.numericValue === "number" ? ub.numericValue : ub.numericValue.re : void 0;
|
|
6192
6305
|
if (upperNum !== void 0 && Number.isFinite(upperNum)) {
|
|
6193
6306
|
if (upperNum < aNum) return ">";
|
|
@@ -6217,8 +6330,8 @@ function cmp(a, b) {
|
|
|
6217
6330
|
if (typeof b === "number") {
|
|
6218
6331
|
if (isSymbol2(a)) {
|
|
6219
6332
|
const bounds = getInequalityBoundsFromAssumptions(a.engine, a.symbol);
|
|
6220
|
-
if (bounds.
|
|
6221
|
-
const lb = bounds.
|
|
6333
|
+
if (bounds.lower !== void 0) {
|
|
6334
|
+
const lb = bounds.lower;
|
|
6222
6335
|
const lowerNum = isNumber(lb) ? typeof lb.numericValue === "number" ? lb.numericValue : lb.numericValue.re : void 0;
|
|
6223
6336
|
if (lowerNum !== void 0 && Number.isFinite(lowerNum)) {
|
|
6224
6337
|
if (lowerNum > b) return ">";
|
|
@@ -6226,8 +6339,8 @@ function cmp(a, b) {
|
|
|
6226
6339
|
if (lowerNum === b && !bounds.lowerStrict) return ">=";
|
|
6227
6340
|
}
|
|
6228
6341
|
}
|
|
6229
|
-
if (bounds.
|
|
6230
|
-
const ub = bounds.
|
|
6342
|
+
if (bounds.upper !== void 0) {
|
|
6343
|
+
const ub = bounds.upper;
|
|
6231
6344
|
const upperNum = isNumber(ub) ? typeof ub.numericValue === "number" ? ub.numericValue : ub.numericValue.re : void 0;
|
|
6232
6345
|
if (upperNum !== void 0 && Number.isFinite(upperNum)) {
|
|
6233
6346
|
if (upperNum < b) return "<";
|
|
@@ -6283,8 +6396,8 @@ function cmp(a, b) {
|
|
|
6283
6396
|
const bounds = getInequalityBoundsFromAssumptions(a.engine, a.symbol);
|
|
6284
6397
|
const bNum = typeof b.numericValue === "number" ? b.numericValue : b.numericValue.re;
|
|
6285
6398
|
if (bNum !== void 0 && Number.isFinite(bNum)) {
|
|
6286
|
-
if (bounds.
|
|
6287
|
-
const lb = bounds.
|
|
6399
|
+
if (bounds.lower !== void 0) {
|
|
6400
|
+
const lb = bounds.lower;
|
|
6288
6401
|
const lowerNum = isNumber(lb) ? typeof lb.numericValue === "number" ? lb.numericValue : lb.numericValue.re : void 0;
|
|
6289
6402
|
if (lowerNum !== void 0 && Number.isFinite(lowerNum)) {
|
|
6290
6403
|
if (lowerNum > bNum) return ">";
|
|
@@ -6292,8 +6405,8 @@ function cmp(a, b) {
|
|
|
6292
6405
|
if (lowerNum === bNum && !bounds.lowerStrict) return ">=";
|
|
6293
6406
|
}
|
|
6294
6407
|
}
|
|
6295
|
-
if (bounds.
|
|
6296
|
-
const ub = bounds.
|
|
6408
|
+
if (bounds.upper !== void 0) {
|
|
6409
|
+
const ub = bounds.upper;
|
|
6297
6410
|
const upperNum = isNumber(ub) ? typeof ub.numericValue === "number" ? ub.numericValue : ub.numericValue.re : void 0;
|
|
6298
6411
|
if (upperNum !== void 0 && Number.isFinite(upperNum)) {
|
|
6299
6412
|
if (upperNum < bNum) return "<";
|
|
@@ -6831,6 +6944,12 @@ var _BoxedOperatorDefinition = class {
|
|
|
6831
6944
|
scoped = false;
|
|
6832
6945
|
signature;
|
|
6833
6946
|
inferredSignature = true;
|
|
6947
|
+
/** True if this operator definition was created from a user-defined
|
|
6948
|
+
* function literal (e.g. via `ce.assign('f', ce.parse('x \\mapsto x^2'))`).
|
|
6949
|
+
* Used to enable auto-broadcasting when applied to indexed collections.
|
|
6950
|
+
* @internal
|
|
6951
|
+
*/
|
|
6952
|
+
_isLambda = false;
|
|
6834
6953
|
type;
|
|
6835
6954
|
sgn;
|
|
6836
6955
|
eq;
|
|
@@ -6988,6 +7107,8 @@ var _BoxedOperatorDefinition = class {
|
|
|
6988
7107
|
this.engine._typeResolver
|
|
6989
7108
|
);
|
|
6990
7109
|
}
|
|
7110
|
+
if (isFunction2(boxedFn) && boxedFn.operator === "Function")
|
|
7111
|
+
this._isLambda = true;
|
|
6991
7112
|
const fn = applicable(boxedFn);
|
|
6992
7113
|
evaluate2 = (xs, _options) => fn(xs);
|
|
6993
7114
|
Object.defineProperty(evaluate2, "toString", {
|
|
@@ -8304,6 +8425,29 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
8304
8425
|
get isReal() {
|
|
8305
8426
|
return void 0;
|
|
8306
8427
|
}
|
|
8428
|
+
toSignedFunction() {
|
|
8429
|
+
const op = this.operator;
|
|
8430
|
+
if (op === void 0 || this.ops === void 0 || this.ops.length < 2) {
|
|
8431
|
+
return void 0;
|
|
8432
|
+
}
|
|
8433
|
+
const [lhs, rhs] = this.ops;
|
|
8434
|
+
const engine = this.engine;
|
|
8435
|
+
switch (op) {
|
|
8436
|
+
case "Equal":
|
|
8437
|
+
case "NotEqual":
|
|
8438
|
+
case "Less":
|
|
8439
|
+
case "LessEqual":
|
|
8440
|
+
return engine.function("Subtract", [lhs, rhs]);
|
|
8441
|
+
case "Greater":
|
|
8442
|
+
case "GreaterEqual":
|
|
8443
|
+
return engine.function("Subtract", [rhs, lhs]);
|
|
8444
|
+
default:
|
|
8445
|
+
return void 0;
|
|
8446
|
+
}
|
|
8447
|
+
}
|
|
8448
|
+
getInterval(symbol2) {
|
|
8449
|
+
return extractIntervalBounds(this, symbol2);
|
|
8450
|
+
}
|
|
8307
8451
|
simplify(_options) {
|
|
8308
8452
|
return this;
|
|
8309
8453
|
}
|
|
@@ -10322,15 +10466,16 @@ var DEFINITIONS_CORE = [
|
|
|
10322
10466
|
precedence: ASSIGNMENT_PRECEDENCE,
|
|
10323
10467
|
parse: parseAssign
|
|
10324
10468
|
},
|
|
10325
|
-
// General colon operator (type annotation, mapping notation)
|
|
10326
|
-
// Precedence below
|
|
10327
|
-
// and below arrows (270) so
|
|
10469
|
+
// General colon operator (type annotation, mapping notation, Desmos piecewise)
|
|
10470
|
+
// Precedence below comparisons (245) so `cond : val` (Desmos compact piecewise)
|
|
10471
|
+
// parses as `Colon(cond, val)`, and below arrows (270) so
|
|
10472
|
+
// `f: A \to B` parses as `Colon(f, To(A, B))`.
|
|
10328
10473
|
{
|
|
10329
10474
|
name: "Colon",
|
|
10330
10475
|
latexTrigger: ":",
|
|
10331
10476
|
kind: "infix",
|
|
10332
10477
|
associativity: "right",
|
|
10333
|
-
precedence:
|
|
10478
|
+
precedence: 240,
|
|
10334
10479
|
serialize: (serializer, expr2) => joinLatex([
|
|
10335
10480
|
serializer.serialize(operand(expr2, 1)),
|
|
10336
10481
|
"\\colon",
|
|
@@ -10341,7 +10486,7 @@ var DEFINITIONS_CORE = [
|
|
|
10341
10486
|
latexTrigger: "\\colon",
|
|
10342
10487
|
kind: "infix",
|
|
10343
10488
|
associativity: "right",
|
|
10344
|
-
precedence:
|
|
10489
|
+
precedence: 240,
|
|
10345
10490
|
parse: "Colon"
|
|
10346
10491
|
},
|
|
10347
10492
|
{
|
|
@@ -11911,7 +12056,10 @@ function parseForComprehension(parser, lhs, until) {
|
|
|
11911
12056
|
p.skipVisualSpace();
|
|
11912
12057
|
const isComma = p.peek === ",";
|
|
11913
12058
|
p.index = saved;
|
|
11914
|
-
return
|
|
12059
|
+
if (isComma) return true;
|
|
12060
|
+
if (peekKeyword(p, "where")) return true;
|
|
12061
|
+
if (peekKeyword(p, "with")) return true;
|
|
12062
|
+
return false;
|
|
11915
12063
|
}
|
|
11916
12064
|
};
|
|
11917
12065
|
const elements = [];
|
|
@@ -11952,6 +12100,25 @@ function parseWhereExpression(parser, lhs, until) {
|
|
|
11952
12100
|
parser.skipVisualSpace();
|
|
11953
12101
|
} while (parser.match(","));
|
|
11954
12102
|
if (bindings.length === 0) return null;
|
|
12103
|
+
const forStart = parser.index;
|
|
12104
|
+
if (matchKeyword(parser, "for")) {
|
|
12105
|
+
const loop = parseForComprehension(parser, lhs, until);
|
|
12106
|
+
if (loop) {
|
|
12107
|
+
const block2 = [];
|
|
12108
|
+
for (const b of bindings) {
|
|
12109
|
+
const normalized = normalizeLocalAssign(b);
|
|
12110
|
+
if (operator(normalized) === "Assign") {
|
|
12111
|
+
block2.push(["Declare", operand(normalized, 1)]);
|
|
12112
|
+
block2.push(normalized);
|
|
12113
|
+
} else {
|
|
12114
|
+
block2.push(normalized);
|
|
12115
|
+
}
|
|
12116
|
+
}
|
|
12117
|
+
block2.push(loop);
|
|
12118
|
+
return ["Block", ...block2];
|
|
12119
|
+
}
|
|
12120
|
+
parser.index = forStart;
|
|
12121
|
+
}
|
|
11955
12122
|
const block = [];
|
|
11956
12123
|
for (const b of bindings) {
|
|
11957
12124
|
const normalized = normalizeLocalAssign(b);
|
|
@@ -12165,6 +12332,17 @@ function parseIntervalBody(body, openLeft, openRight) {
|
|
|
12165
12332
|
const upperExpr = openRight ? ["Open", upper] : upper;
|
|
12166
12333
|
return ["Interval", lowerExpr, upperExpr];
|
|
12167
12334
|
}
|
|
12335
|
+
var COMPARISON_HEADS = /* @__PURE__ */ new Set([
|
|
12336
|
+
"Less",
|
|
12337
|
+
"LessEqual",
|
|
12338
|
+
"Greater",
|
|
12339
|
+
"GreaterEqual",
|
|
12340
|
+
"Equal",
|
|
12341
|
+
"NotEqual",
|
|
12342
|
+
"And",
|
|
12343
|
+
"Or",
|
|
12344
|
+
"Not"
|
|
12345
|
+
]);
|
|
12168
12346
|
var DEFINITIONS_SETS = [
|
|
12169
12347
|
//
|
|
12170
12348
|
// Constants
|
|
@@ -12423,18 +12601,58 @@ var DEFINITIONS_SETS = [
|
|
|
12423
12601
|
closeTrigger: "}",
|
|
12424
12602
|
parse: (_parser, body) => {
|
|
12425
12603
|
if (isEmptySequence(body)) return "EmptySet";
|
|
12604
|
+
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
12605
|
+
body = operand(body, 1);
|
|
12606
|
+
}
|
|
12426
12607
|
const h = operator(body);
|
|
12427
|
-
if (h === "Divides"
|
|
12608
|
+
if (h === "Divides") {
|
|
12428
12609
|
const expr2 = operand(body, 1);
|
|
12429
12610
|
const condition = operand(body, 2);
|
|
12430
12611
|
if (expr2 !== null && condition !== null)
|
|
12431
12612
|
return ["Set", expr2, ["Condition", condition]];
|
|
12432
12613
|
}
|
|
12433
|
-
if (
|
|
12434
|
-
|
|
12614
|
+
if (h === "Colon") {
|
|
12615
|
+
const lhs = operand(body, 1);
|
|
12616
|
+
const rhs = operand(body, 2);
|
|
12617
|
+
if (lhs !== null && rhs !== null) {
|
|
12618
|
+
const lhsOp = operator(lhs);
|
|
12619
|
+
if (lhsOp !== null && COMPARISON_HEADS.has(lhsOp)) {
|
|
12620
|
+
return ["Which", lhs, rhs];
|
|
12621
|
+
}
|
|
12622
|
+
return ["Set", lhs, ["Condition", rhs]];
|
|
12623
|
+
}
|
|
12624
|
+
}
|
|
12625
|
+
if (h === "Sequence") {
|
|
12626
|
+
const elements = operands(body);
|
|
12627
|
+
const colonElements = elements.filter((el) => operator(el) === "Colon");
|
|
12628
|
+
const allPiecewise = colonElements.length > 0 && colonElements.every((el) => {
|
|
12629
|
+
const lhs = operand(el, 1);
|
|
12630
|
+
const lhsOp = lhs !== null ? operator(lhs) : null;
|
|
12631
|
+
return lhsOp !== null && COMPARISON_HEADS.has(lhsOp);
|
|
12632
|
+
});
|
|
12633
|
+
if (allPiecewise) {
|
|
12634
|
+
const whichOps = [];
|
|
12635
|
+
for (let i = 0; i < elements.length; i++) {
|
|
12636
|
+
const el = elements[i];
|
|
12637
|
+
if (operator(el) === "Colon") {
|
|
12638
|
+
const cond = operand(el, 1);
|
|
12639
|
+
const val = operand(el, 2);
|
|
12640
|
+
if (cond === null || val === null) {
|
|
12641
|
+
return ["Set", ...elements];
|
|
12642
|
+
}
|
|
12643
|
+
whichOps.push(cond, val);
|
|
12644
|
+
} else {
|
|
12645
|
+
if (i !== elements.length - 1) {
|
|
12646
|
+
return ["Set", ...elements];
|
|
12647
|
+
}
|
|
12648
|
+
whichOps.push("True", el);
|
|
12649
|
+
}
|
|
12650
|
+
}
|
|
12651
|
+
return ["Which", ...whichOps];
|
|
12652
|
+
}
|
|
12653
|
+
return ["Set", ...elements];
|
|
12435
12654
|
}
|
|
12436
|
-
|
|
12437
|
-
return ["Set", ...operands(body)];
|
|
12655
|
+
return ["Set", body];
|
|
12438
12656
|
},
|
|
12439
12657
|
serialize: (serializer, expr2) => {
|
|
12440
12658
|
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
@@ -14438,7 +14656,8 @@ function parseTrig(op) {
|
|
|
14438
14656
|
minPrec: MULTIPLICATION_PRECEDENCE,
|
|
14439
14657
|
condition: (parser2) => trigCommands[parser2.peek] || (until?.condition?.(parser2) ?? false)
|
|
14440
14658
|
});
|
|
14441
|
-
const
|
|
14659
|
+
const head = fn === "Arctan" && args?.length === 2 ? "Arctan2" : fn;
|
|
14660
|
+
const appliedFn = args === null ? fn : typeof head === "string" ? [head, ...args] : ["Apply", head, ...args];
|
|
14442
14661
|
return sup === null ? appliedFn : ["Power", appliedFn, sup];
|
|
14443
14662
|
};
|
|
14444
14663
|
}
|
|
@@ -16654,10 +16873,17 @@ var DEFINITIONS_OTHERS = [
|
|
|
16654
16873
|
// The capitalized library entries already exist; these are pure parse
|
|
16655
16874
|
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
16656
16875
|
// ---------------------------------------------------------------------------
|
|
16876
|
+
{ latexTrigger: "\\operatorname{count}", parse: "Length" },
|
|
16657
16877
|
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
16658
16878
|
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
16659
16879
|
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
16660
16880
|
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
16881
|
+
{ latexTrigger: "\\operatorname{range}", parse: "Range" },
|
|
16882
|
+
// Note: `\operatorname{with}` (Desmos's local-binding clause) is intentionally
|
|
16883
|
+
// NOT registered here. Use the math-notation equivalent `\operatorname{where}`
|
|
16884
|
+
// (with `\coloneq` for bindings), or register `with` as a custom dictionary
|
|
16885
|
+
// entry at the integration layer — see the "Desmos-Specific Syntax — Prefer
|
|
16886
|
+
// Custom LaTeX Dictionary" section in COMPUTE_ENGINE.md for a worked example.
|
|
16661
16887
|
// ---------------------------------------------------------------------------
|
|
16662
16888
|
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
16663
16889
|
// can branch on the operator name; CE itself doesn't render them. The
|
|
@@ -22499,6 +22725,15 @@ function expressionTensorInfo(operator2, rows) {
|
|
|
22499
22725
|
}
|
|
22500
22726
|
} else {
|
|
22501
22727
|
for (const item of t) {
|
|
22728
|
+
const op = item.operator;
|
|
22729
|
+
if (op === "Tuple" || op === "Pair" || op === "Single" || op === "Triple" || op === "Quadruple" || op === "KeyValuePair" || op === "Dictionary" || op === "Set" || op === "Record") {
|
|
22730
|
+
valid = false;
|
|
22731
|
+
return;
|
|
22732
|
+
}
|
|
22733
|
+
if (item.type.type === "string") {
|
|
22734
|
+
valid = false;
|
|
22735
|
+
return;
|
|
22736
|
+
}
|
|
22502
22737
|
dtype = getSupertype(dtype, getExpressionDatatype(item));
|
|
22503
22738
|
}
|
|
22504
22739
|
}
|
|
@@ -27534,6 +27769,15 @@ function interval(expr2) {
|
|
|
27534
27769
|
return void 0;
|
|
27535
27770
|
}
|
|
27536
27771
|
|
|
27772
|
+
// src/compute-engine/numerics/random.ts
|
|
27773
|
+
function deterministicRandom(seed) {
|
|
27774
|
+
const v = Math.sin(seed * 12.9898) * 43758.5453;
|
|
27775
|
+
return v - Math.floor(v);
|
|
27776
|
+
}
|
|
27777
|
+
function nextSeed(seed) {
|
|
27778
|
+
return seed + 0.6180339887498949;
|
|
27779
|
+
}
|
|
27780
|
+
|
|
27537
27781
|
// src/compute-engine/boxed-expression/canonical-utils.ts
|
|
27538
27782
|
function canonical(ce, xs, scope) {
|
|
27539
27783
|
if (xs.every((x) => x.isCanonical)) return xs;
|
|
@@ -27583,6 +27827,19 @@ var COLLECTIONS_LIBRARY = {
|
|
|
27583
27827
|
indexWhere: void 0
|
|
27584
27828
|
}
|
|
27585
27829
|
},
|
|
27830
|
+
Length: {
|
|
27831
|
+
description: "Number of elements in a collection. Returns undefined for non-collections and for infinite collections.",
|
|
27832
|
+
complexity: 4e3,
|
|
27833
|
+
signature: "(any) -> integer",
|
|
27834
|
+
type: () => "integer",
|
|
27835
|
+
evaluate: ([xs], { engine }) => {
|
|
27836
|
+
if (!xs.isCollection) return void 0;
|
|
27837
|
+
if (xs.isEmptyCollection) return engine.Zero;
|
|
27838
|
+
const n = xs.count;
|
|
27839
|
+
if (n === void 0 || !isFinite(n)) return void 0;
|
|
27840
|
+
return engine.number(n);
|
|
27841
|
+
}
|
|
27842
|
+
},
|
|
27586
27843
|
Tuple: {
|
|
27587
27844
|
description: "A fixed number of heterogeneous elements",
|
|
27588
27845
|
complexity: 8200,
|
|
@@ -27836,10 +28093,12 @@ var COLLECTIONS_LIBRARY = {
|
|
|
27836
28093
|
const upper = expr2.op2.re;
|
|
27837
28094
|
let count = expr2.op3.re;
|
|
27838
28095
|
if (!isFinite(count)) count = DEFAULT_LINSPACE_COUNT;
|
|
28096
|
+
count = Math.floor(count);
|
|
27839
28097
|
if (!isFinite(lower) || !isFinite(upper)) return void 0;
|
|
27840
28098
|
if (index < 1 || index > count) return void 0;
|
|
28099
|
+
if (count === 1) return expr2.engine.number(lower);
|
|
27841
28100
|
return expr2.engine.number(
|
|
27842
|
-
lower + (upper - lower) * (index - 1) / count
|
|
28101
|
+
lower + (upper - lower) * (index - 1) / (count - 1)
|
|
27843
28102
|
);
|
|
27844
28103
|
},
|
|
27845
28104
|
iterator: (expr2) => {
|
|
@@ -27858,6 +28117,8 @@ var COLLECTIONS_LIBRARY = {
|
|
|
27858
28117
|
!isFinite(expr2.op3.re) ? DEFAULT_LINSPACE_COUNT : expr2.op3.re
|
|
27859
28118
|
);
|
|
27860
28119
|
}
|
|
28120
|
+
totalCount = Math.floor(totalCount);
|
|
28121
|
+
const denom = totalCount > 1 ? totalCount - 1 : 1;
|
|
27861
28122
|
let index = 1;
|
|
27862
28123
|
return {
|
|
27863
28124
|
next: () => {
|
|
@@ -27866,7 +28127,7 @@ var COLLECTIONS_LIBRARY = {
|
|
|
27866
28127
|
index += 1;
|
|
27867
28128
|
return {
|
|
27868
28129
|
value: expr2.engine.number(
|
|
27869
|
-
lower + (upper - lower) * (index - 1 - 1) /
|
|
28130
|
+
lower + (upper - lower) * (index - 1 - 1) / denom
|
|
27870
28131
|
),
|
|
27871
28132
|
done: false
|
|
27872
28133
|
};
|
|
@@ -27882,9 +28143,14 @@ var COLLECTIONS_LIBRARY = {
|
|
|
27882
28143
|
if (t < lower || t > upper) return false;
|
|
27883
28144
|
let count = expr2.op3.re;
|
|
27884
28145
|
if (!isFinite(count)) count = DEFAULT_LINSPACE_COUNT;
|
|
28146
|
+
count = Math.floor(count);
|
|
27885
28147
|
if (count === 0) return false;
|
|
27886
|
-
|
|
27887
|
-
|
|
28148
|
+
if (count === 1) return t === lower;
|
|
28149
|
+
const step = (upper - lower) / (count - 1);
|
|
28150
|
+
const k = (t - lower) / step;
|
|
28151
|
+
const tol = expr2.engine.tolerance;
|
|
28152
|
+
const kRounded = Math.round(k);
|
|
28153
|
+
return kRounded >= 0 && kRounded <= count - 1 && Math.abs(k - kRounded) < tol;
|
|
27888
28154
|
}
|
|
27889
28155
|
}
|
|
27890
28156
|
},
|
|
@@ -28209,10 +28475,12 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28209
28475
|
description: [
|
|
28210
28476
|
"Access an element of an indexed collection.",
|
|
28211
28477
|
"If the index is negative, it is counted from the end.",
|
|
28212
|
-
"Multiple indices can be provided to access nested collections (e.g., matrices)."
|
|
28478
|
+
"Multiple indices can be provided to access nested collections (e.g., matrices).",
|
|
28479
|
+
"If the index is a finite collection of booleans, returns the elements where the mask is True.",
|
|
28480
|
+
"If the index is a finite collection of integers, returns the elements at those indices."
|
|
28213
28481
|
],
|
|
28214
28482
|
complexity: 8200,
|
|
28215
|
-
signature: "(value: indexed_collection, index: (number|string)+) -> unknown",
|
|
28483
|
+
signature: "(value: indexed_collection, index: (number|string|indexed_collection)+) -> unknown",
|
|
28216
28484
|
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? collectionElementType(xs.type.type) ?? "any",
|
|
28217
28485
|
evaluate: (ops, { engine: ce }) => {
|
|
28218
28486
|
let expr2 = ops[0];
|
|
@@ -28223,12 +28491,39 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28223
28491
|
if (!at) return void 0;
|
|
28224
28492
|
const opAtIndex = ops[index];
|
|
28225
28493
|
const s = isString(opAtIndex) ? opAtIndex.string : void 0;
|
|
28226
|
-
if (s !== void 0)
|
|
28227
|
-
|
|
28228
|
-
|
|
28229
|
-
|
|
28230
|
-
expr2 = at(expr2, i) ?? ce.Nothing;
|
|
28494
|
+
if (s !== void 0) {
|
|
28495
|
+
expr2 = at(expr2, s) ?? ce.Nothing;
|
|
28496
|
+
index += 1;
|
|
28497
|
+
continue;
|
|
28231
28498
|
}
|
|
28499
|
+
if (opAtIndex.isCollection && opAtIndex.isFiniteCollection) {
|
|
28500
|
+
const indices = Array.from(opAtIndex.each());
|
|
28501
|
+
const isMask = indices.every((m) => {
|
|
28502
|
+
const name = sym(m);
|
|
28503
|
+
return name === "True" || name === "False";
|
|
28504
|
+
});
|
|
28505
|
+
const picked = [];
|
|
28506
|
+
if (isMask) {
|
|
28507
|
+
indices.forEach((m, i2) => {
|
|
28508
|
+
if (sym(m) !== "True") return;
|
|
28509
|
+
const v = at(expr2, i2 + 1);
|
|
28510
|
+
if (v !== void 0) picked.push(v);
|
|
28511
|
+
});
|
|
28512
|
+
} else {
|
|
28513
|
+
for (const m of indices) {
|
|
28514
|
+
const k = m.re;
|
|
28515
|
+
if (!Number.isInteger(k)) return void 0;
|
|
28516
|
+
const v = at(expr2, k);
|
|
28517
|
+
if (v !== void 0) picked.push(v);
|
|
28518
|
+
}
|
|
28519
|
+
}
|
|
28520
|
+
expr2 = ce._fn("List", picked);
|
|
28521
|
+
index += 1;
|
|
28522
|
+
continue;
|
|
28523
|
+
}
|
|
28524
|
+
const i = opAtIndex.re;
|
|
28525
|
+
if (!Number.isInteger(i)) return void 0;
|
|
28526
|
+
expr2 = at(expr2, i) ?? ce.Nothing;
|
|
28232
28527
|
index += 1;
|
|
28233
28528
|
}
|
|
28234
28529
|
return expr2;
|
|
@@ -28239,7 +28534,7 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28239
28534
|
description: ["Return `n` elements from a collection."],
|
|
28240
28535
|
complexity: 8200,
|
|
28241
28536
|
signature: "(xs: indexed_collection, count: number) -> indexed_collection",
|
|
28242
|
-
type: ([xs]) => `list<${collectionElementType(xs.type.type)}>`,
|
|
28537
|
+
type: ([xs]) => `list<${typeToString(collectionElementType(xs.type.type) ?? "any")}>`,
|
|
28243
28538
|
evaluate: (ops, { engine, materialization: eager }) => {
|
|
28244
28539
|
if (!eager) return void 0;
|
|
28245
28540
|
const takeExpr = engine._fn("Take", ops);
|
|
@@ -28286,7 +28581,7 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28286
28581
|
description: ["Return the collection without the first n elements."],
|
|
28287
28582
|
complexity: 8200,
|
|
28288
28583
|
signature: "(xs: indexed_collection, count: number) -> indexed_collection",
|
|
28289
|
-
type: ([xs]) => `list<${collectionElementType(xs.type.type)}>`,
|
|
28584
|
+
type: ([xs]) => `list<${typeToString(collectionElementType(xs.type.type) ?? "any")}>`,
|
|
28290
28585
|
collection: {
|
|
28291
28586
|
isLazy: (_expr) => true,
|
|
28292
28587
|
count: (expr2) => {
|
|
@@ -28482,7 +28777,9 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28482
28777
|
],
|
|
28483
28778
|
complexity: 8200,
|
|
28484
28779
|
signature: "(value: indexed_collection, start: number, end: number) -> list",
|
|
28485
|
-
type: ([xs]) => parseType(
|
|
28780
|
+
type: ([xs]) => parseType(
|
|
28781
|
+
`list<${typeToString(collectionElementType(xs.type.type) ?? "any")}>`
|
|
28782
|
+
),
|
|
28486
28783
|
collection: {
|
|
28487
28784
|
isLazy: (_expr) => true,
|
|
28488
28785
|
count: (expr2) => {
|
|
@@ -28814,16 +29111,26 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28814
29111
|
},
|
|
28815
29112
|
// Randomize the order of the elements in the collection.
|
|
28816
29113
|
Shuffle: {
|
|
28817
|
-
description: "Randomize the order of the elements in the collection.",
|
|
29114
|
+
description: "Randomize the order of the elements in the collection. With an optional `seed` argument, the shuffle is deterministic.",
|
|
28818
29115
|
complexity: 8200,
|
|
28819
|
-
signature: "(indexed_collection) -> indexed_collection",
|
|
29116
|
+
signature: "(indexed_collection, real?) -> indexed_collection",
|
|
28820
29117
|
type: (ops) => ops[0].type,
|
|
28821
|
-
evaluate: ([xs], { engine: ce }) => {
|
|
29118
|
+
evaluate: ([xs, seedOp], { engine: ce }) => {
|
|
28822
29119
|
if (!xs.isFiniteCollection) return void 0;
|
|
28823
29120
|
const data = Array.from(xs.each());
|
|
28824
|
-
|
|
28825
|
-
|
|
28826
|
-
|
|
29121
|
+
const seed = seedOp?.re;
|
|
29122
|
+
if (seed !== void 0 && !Number.isNaN(seed)) {
|
|
29123
|
+
let s = seed;
|
|
29124
|
+
for (let i = data.length - 1; i > 0; i--) {
|
|
29125
|
+
const j = Math.floor(deterministicRandom(s) * (i + 1));
|
|
29126
|
+
[data[i], data[j]] = [data[j], data[i]];
|
|
29127
|
+
s = nextSeed(s);
|
|
29128
|
+
}
|
|
29129
|
+
} else {
|
|
29130
|
+
for (let i = data.length - 1; i > 0; i--) {
|
|
29131
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
29132
|
+
[data[i], data[j]] = [data[j], data[i]];
|
|
29133
|
+
}
|
|
28827
29134
|
}
|
|
28828
29135
|
return ce.function(xs.operator, data);
|
|
28829
29136
|
}
|
|
@@ -28890,7 +29197,9 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28890
29197
|
if (t === "string")
|
|
28891
29198
|
return parseType(`tuple<list<string>, list<integer>>`);
|
|
28892
29199
|
return parseType(
|
|
28893
|
-
`tuple<list<${
|
|
29200
|
+
`tuple<list<${typeToString(
|
|
29201
|
+
collectionElementType(t) ?? "any"
|
|
29202
|
+
)}>, list<integer>>`
|
|
28894
29203
|
);
|
|
28895
29204
|
},
|
|
28896
29205
|
evaluate: (ops, { engine: ce }) => {
|
|
@@ -28906,7 +29215,7 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28906
29215
|
description: "Return a list of the unique elements of the collection.",
|
|
28907
29216
|
complexity: 8200,
|
|
28908
29217
|
signature: "(collection) -> list",
|
|
28909
|
-
type: ([xs]) => `list<${collectionElementType(xs.type.type)}>`,
|
|
29218
|
+
type: ([xs]) => `list<${typeToString(collectionElementType(xs.type.type) ?? "any")}>`,
|
|
28910
29219
|
evaluate: (ops, { engine: ce }) => {
|
|
28911
29220
|
if (!ops[0].isFiniteCollection) return void 0;
|
|
28912
29221
|
const [values, _counts] = tally(ops[0]);
|
|
@@ -28918,7 +29227,7 @@ var COLLECTIONS_LIBRARY = {
|
|
|
28918
29227
|
wikidata: "Q381060",
|
|
28919
29228
|
complexity: 8200,
|
|
28920
29229
|
signature: "(collection, integer | function) -> list",
|
|
28921
|
-
type: ([xs]) => `list<${collectionElementType(xs.type.type)}>`,
|
|
29230
|
+
type: ([xs]) => `list<${typeToString(collectionElementType(xs.type.type) ?? "any")}>`,
|
|
28922
29231
|
evaluate: ([xs, arg], { engine: ce }) => {
|
|
28923
29232
|
if (!xs.isFiniteCollection) return void 0;
|
|
28924
29233
|
const k = toInteger(arg);
|
|
@@ -29092,32 +29401,74 @@ var COLLECTIONS_LIBRARY = {
|
|
|
29092
29401
|
}
|
|
29093
29402
|
}
|
|
29094
29403
|
},
|
|
29095
|
-
// Repeat(x) -> [x, x, ...]
|
|
29096
|
-
//
|
|
29097
|
-
// x is evaluated once. Although could use Hold()?
|
|
29098
|
-
// So that First(Repeat(Hold(Random(5))), 10) would return 10 random numbers...
|
|
29404
|
+
// Repeat(x) -> [x, x, ...] — infinite sequence
|
|
29405
|
+
// Repeat(x, n) -> [x, x, ..., x] — finite list of n copies
|
|
29099
29406
|
Repeat: {
|
|
29100
|
-
description: "Produce
|
|
29407
|
+
description: "Produce a sequence by repeating a single value. With 1 argument, returns an infinite sequence; with 2 arguments (value, count), returns a finite list of `count` copies.",
|
|
29101
29408
|
complexity: 8200,
|
|
29102
|
-
signature: "(value: any) -> list",
|
|
29409
|
+
signature: "(value: any, count: integer?) -> list",
|
|
29410
|
+
evaluate: (ops, { engine }) => {
|
|
29411
|
+
if (ops.length !== 2) return void 0;
|
|
29412
|
+
const raw = toInteger(ops[1]);
|
|
29413
|
+
if (raw === null) return void 0;
|
|
29414
|
+
const n = Math.max(0, raw);
|
|
29415
|
+
if (n > engine.maxCollectionSize) return void 0;
|
|
29416
|
+
return engine._fn("List", Array(n).fill(ops[0]));
|
|
29417
|
+
},
|
|
29103
29418
|
collection: {
|
|
29104
|
-
isLazy: (
|
|
29105
|
-
count: () =>
|
|
29106
|
-
|
|
29107
|
-
|
|
29108
|
-
|
|
29109
|
-
|
|
29419
|
+
isLazy: (expr2) => isFunction2(expr2) && expr2.ops?.length === 1,
|
|
29420
|
+
count: (expr2) => {
|
|
29421
|
+
if (!isFunction2(expr2)) return void 0;
|
|
29422
|
+
if (expr2.ops?.length === 2) {
|
|
29423
|
+
const n = toInteger(expr2.op2);
|
|
29424
|
+
return n !== null ? Math.max(0, n) : void 0;
|
|
29425
|
+
}
|
|
29426
|
+
return Infinity;
|
|
29427
|
+
},
|
|
29428
|
+
isEmpty: (expr2) => {
|
|
29429
|
+
if (!isFunction2(expr2)) return void 0;
|
|
29430
|
+
if (expr2.ops?.length === 2) {
|
|
29431
|
+
const n = toInteger(expr2.op2);
|
|
29432
|
+
return n !== null ? n <= 0 : void 0;
|
|
29433
|
+
}
|
|
29434
|
+
return false;
|
|
29435
|
+
},
|
|
29436
|
+
isFinite: (expr2) => isFunction2(expr2) && expr2.ops?.length === 2,
|
|
29110
29437
|
contains: (expr2, target) => {
|
|
29111
29438
|
if (!isFunction2(expr2)) return false;
|
|
29439
|
+
if (expr2.ops?.length === 2) {
|
|
29440
|
+
const n = toInteger(expr2.op2);
|
|
29441
|
+
if (n !== null && n <= 0) return false;
|
|
29442
|
+
}
|
|
29112
29443
|
return expr2.op1.isSame(target);
|
|
29113
29444
|
},
|
|
29114
29445
|
iterator: (expr2) => {
|
|
29115
29446
|
if (!isFunction2(expr2))
|
|
29116
29447
|
return { next: () => ({ value: void 0, done: true }) };
|
|
29448
|
+
if (expr2.ops?.length === 2) {
|
|
29449
|
+
const n = toInteger(expr2.op2);
|
|
29450
|
+
if (n === null) {
|
|
29451
|
+
return { next: () => ({ value: void 0, done: true }) };
|
|
29452
|
+
}
|
|
29453
|
+
const count = Math.max(0, n);
|
|
29454
|
+
let i = 0;
|
|
29455
|
+
return {
|
|
29456
|
+
next: () => i++ < count ? { value: expr2.op1, done: false } : { value: void 0, done: true }
|
|
29457
|
+
};
|
|
29458
|
+
}
|
|
29117
29459
|
return { next: () => ({ value: expr2.op1, done: false }) };
|
|
29118
29460
|
},
|
|
29119
|
-
at
|
|
29461
|
+
// at is 1-based (consistent with Range, Take, and other collection handlers)
|
|
29462
|
+
at: (expr2, index) => {
|
|
29120
29463
|
if (!isFunction2(expr2)) return void 0;
|
|
29464
|
+
if (typeof index !== "number") return void 0;
|
|
29465
|
+
if (expr2.ops?.length === 2) {
|
|
29466
|
+
const n = toInteger(expr2.op2);
|
|
29467
|
+
const count = n !== null ? Math.max(0, n) : 0;
|
|
29468
|
+
if (index < 1 || index > count) return void 0;
|
|
29469
|
+
} else {
|
|
29470
|
+
if (index < 1) return void 0;
|
|
29471
|
+
}
|
|
29121
29472
|
return expr2.op1;
|
|
29122
29473
|
}
|
|
29123
29474
|
}
|
|
@@ -31403,11 +31754,12 @@ var ARITHMETIC_LIBRARY = [
|
|
|
31403
31754
|
);
|
|
31404
31755
|
}
|
|
31405
31756
|
},
|
|
31406
|
-
|
|
31407
|
-
|
|
31408
|
-
|
|
31409
|
-
|
|
31410
|
-
|
|
31757
|
+
Complex: {
|
|
31758
|
+
description: 'Construct a complex number from real and imaginary parts. Converted directly to a BoxedNumber during boxing; this entry exists so `operatorInfo("Complex")` returns a signature.',
|
|
31759
|
+
wikidata: "Q11567",
|
|
31760
|
+
complexity: 500,
|
|
31761
|
+
signature: "(real: number, imaginary: number) -> complex"
|
|
31762
|
+
},
|
|
31411
31763
|
Divide: {
|
|
31412
31764
|
description: "Quotient of a numerator and one or more denominators.",
|
|
31413
31765
|
wikidata: "Q1226939",
|
|
@@ -32757,48 +33109,83 @@ var ARITHMETIC_LIBRARY = [
|
|
|
32757
33109
|
}
|
|
32758
33110
|
},
|
|
32759
33111
|
Sum: {
|
|
32760
|
-
description: "`Sum(f, [a, b])` computes the sum of `f` from `a` to `b`",
|
|
33112
|
+
description: "`Sum(f, [a, b])` computes the sum of `f` from `a` to `b`; `Sum(L)` sums the elements of a collection `L`",
|
|
32761
33113
|
wikidata: "Q218005",
|
|
32762
33114
|
complexity: 1e3,
|
|
32763
33115
|
broadcastable: false,
|
|
32764
33116
|
scoped: true,
|
|
32765
33117
|
lazy: true,
|
|
32766
|
-
signature: "(
|
|
32767
|
-
canonical: ([body, ...bounds], { scope }) =>
|
|
32768
|
-
|
|
33118
|
+
signature: "(any, tuple*) -> number",
|
|
33119
|
+
canonical: ([body, ...bounds], { scope, engine: ce }) => {
|
|
33120
|
+
if (bounds.length === 0) {
|
|
33121
|
+
const canon = body?.canonical;
|
|
33122
|
+
if (canon?.isCollection) return ce._fn("Sum", [canon]);
|
|
33123
|
+
}
|
|
33124
|
+
return canonicalBigop("Sum", body, bounds, scope);
|
|
33125
|
+
},
|
|
33126
|
+
evaluate: ([first, ...rest], { engine, numericApproximation: numericApproximation2 }) => {
|
|
33127
|
+
if (rest.length === 0 && first?.isCollection) {
|
|
33128
|
+
if (first.isFiniteCollection !== true) return void 0;
|
|
33129
|
+
const result2 = run(
|
|
33130
|
+
reduceCollection2(
|
|
33131
|
+
first,
|
|
33132
|
+
engine.Zero,
|
|
33133
|
+
(acc, x) => acc.add(x.evaluate({ numericApproximation: numericApproximation2 }))
|
|
33134
|
+
),
|
|
33135
|
+
engine._timeRemaining
|
|
33136
|
+
);
|
|
33137
|
+
return result2?.evaluate({ numericApproximation: numericApproximation2 }) ?? engine.NaN;
|
|
33138
|
+
}
|
|
32769
33139
|
const result = run(
|
|
32770
33140
|
reduceBigOp(
|
|
32771
|
-
|
|
32772
|
-
|
|
33141
|
+
first,
|
|
33142
|
+
rest,
|
|
32773
33143
|
(acc, x) => acc.add(x.evaluate({ numericApproximation: numericApproximation2 })),
|
|
32774
33144
|
engine.Zero
|
|
32775
33145
|
),
|
|
32776
33146
|
engine._timeRemaining
|
|
32777
33147
|
);
|
|
32778
|
-
if (result === NON_ENUMERABLE_DOMAIN)
|
|
32779
|
-
return void 0;
|
|
32780
|
-
}
|
|
33148
|
+
if (result === NON_ENUMERABLE_DOMAIN) return void 0;
|
|
32781
33149
|
return result?.evaluate({ numericApproximation: numericApproximation2 }) ?? engine.NaN;
|
|
32782
33150
|
},
|
|
32783
|
-
evaluateAsync: async (
|
|
33151
|
+
evaluateAsync: async ([first, ...rest], { engine, signal, numericApproximation: numericApproximation2 }) => {
|
|
33152
|
+
if (rest.length === 0 && first?.isCollection) {
|
|
33153
|
+
if (first.isFiniteCollection !== true) return void 0;
|
|
33154
|
+
const result2 = await runAsync(
|
|
33155
|
+
reduceCollection2(
|
|
33156
|
+
first,
|
|
33157
|
+
engine.Zero,
|
|
33158
|
+
(acc, x) => acc.add(x.evaluate({ numericApproximation: numericApproximation2 }))
|
|
33159
|
+
),
|
|
33160
|
+
engine._timeRemaining,
|
|
33161
|
+
signal
|
|
33162
|
+
);
|
|
33163
|
+
return result2?.evaluate({ numericApproximation: numericApproximation2 }) ?? engine.NaN;
|
|
33164
|
+
}
|
|
32784
33165
|
const result = await runAsync(
|
|
32785
33166
|
reduceBigOp(
|
|
32786
|
-
|
|
32787
|
-
|
|
33167
|
+
first,
|
|
33168
|
+
rest,
|
|
32788
33169
|
(acc, x) => acc.add(x.evaluate({ numericApproximation: numericApproximation2 })),
|
|
32789
33170
|
engine.Zero
|
|
32790
33171
|
),
|
|
32791
33172
|
engine._timeRemaining,
|
|
32792
33173
|
signal
|
|
32793
33174
|
);
|
|
32794
|
-
if (result === NON_ENUMERABLE_DOMAIN)
|
|
32795
|
-
return void 0;
|
|
32796
|
-
}
|
|
33175
|
+
if (result === NON_ENUMERABLE_DOMAIN) return void 0;
|
|
32797
33176
|
return result?.evaluate({ numericApproximation: numericApproximation2 }) ?? engine.NaN;
|
|
32798
33177
|
}
|
|
32799
33178
|
}
|
|
32800
33179
|
}
|
|
32801
33180
|
];
|
|
33181
|
+
function* reduceCollection2(collection, init, combine) {
|
|
33182
|
+
let acc = init;
|
|
33183
|
+
for (const x of collection.each()) {
|
|
33184
|
+
acc = combine(acc, x);
|
|
33185
|
+
yield acc;
|
|
33186
|
+
}
|
|
33187
|
+
return acc;
|
|
33188
|
+
}
|
|
32802
33189
|
function evaluateAbs(arg) {
|
|
32803
33190
|
const ce = arg.engine;
|
|
32804
33191
|
if (isNumber(arg)) {
|
|
@@ -43035,7 +43422,7 @@ var COLORS_LIBRARY = {
|
|
|
43035
43422
|
var CONTROL_STRUCTURES_LIBRARY = [
|
|
43036
43423
|
{
|
|
43037
43424
|
Block: {
|
|
43038
|
-
description: "Evaluate a sequence of expressions in a local scope.",
|
|
43425
|
+
description: "Evaluate a sequence of expressions in a local scope, **sequentially**. Each operand is evaluated in order; later operands observe side effects (`Assign`, `Declare`) of earlier operands. The block's value is the value of the last expression. Short-circuiting heads (`Return`, `Break`, `Continue`) terminate the sequence early.\n\nIMPORTANT \u2014 consumers translating *simultaneous* action tuples (e.g. Desmos `(a \u2192 1, b \u2192 a + 1)` where `b` reads the *pre-action* `a`) must rewrite to a snapshot-then-commit Block: bind each RHS to a fresh temp first, then assign the temps to the LHS symbols. See `docs/architecture/actions-and-randomness.md` for the canonical recipe.",
|
|
43039
43426
|
lazy: true,
|
|
43040
43427
|
scoped: true,
|
|
43041
43428
|
signature: "(unknown*) -> unknown",
|
|
@@ -43097,7 +43484,7 @@ var CONTROL_STRUCTURES_LIBRARY = [
|
|
|
43097
43484
|
evaluateAsync: async (ops, { engine: ce, signal }) => runAsync(runLoop(ops[0], ops.slice(1), ce), ce._timeRemaining, signal)
|
|
43098
43485
|
},
|
|
43099
43486
|
When: {
|
|
43100
|
-
description:
|
|
43487
|
+
description: 'Conditional/restriction value. `When(e, cond)` evaluates to:\n - `e` when `cond` evaluates to `True`\n - `Undefined` when `cond` evaluates to `False` (the "masking rule"; consumers like 2D plotters skip masked points)\n - `When(e, cond_simplified)` when `cond` is indeterminate (holds)\nStacked restrictions canonicalize: `When(When(e, c1), c2)` \u2192 `When(e, And(c1, c2))`.\nCompiles to ternary `(cond) ? (e) : NaN` in JS and GLSL.',
|
|
43101
43488
|
lazy: true,
|
|
43102
43489
|
signature: "(expression, boolean) -> any",
|
|
43103
43490
|
type: ([expr2]) => expr2.type,
|
|
@@ -44956,7 +45343,7 @@ var CORE_LIBRARY = [
|
|
|
44956
45343
|
evaluate: (ops) => apply(ops[0], ops.slice(1))
|
|
44957
45344
|
},
|
|
44958
45345
|
Assign: {
|
|
44959
|
-
description: "Assign a value to a symbol or define a sequence",
|
|
45346
|
+
description: "Assign a value to a symbol or define a sequence. The RHS is evaluated immediately and `ce.assign(name, val)` mutates the binding in the current scope chain. When used inside a `Block`, the assignment is visible to subsequent statements in the block (sequential semantics).",
|
|
44960
45347
|
lazy: true,
|
|
44961
45348
|
pure: false,
|
|
44962
45349
|
signature: "(symbol | expression, any) -> any",
|
|
@@ -45087,7 +45474,12 @@ var CORE_LIBRARY = [
|
|
|
45087
45474
|
evaluate: (ops, { engine: ce }) => {
|
|
45088
45475
|
const symbolName2 = sym(ops[0].evaluate());
|
|
45089
45476
|
if (!symbolName2) return void 0;
|
|
45477
|
+
const currentScope = ce.context.lexicalScope;
|
|
45478
|
+
const existing = currentScope.bindings.get(symbolName2);
|
|
45479
|
+
const existingValueDef = existing && isValueDef(existing) ? existing : void 0;
|
|
45480
|
+
const isAutoDeclareHere = !!existingValueDef && existingValueDef.value.inferredType && existingValueDef.value.value === void 0;
|
|
45090
45481
|
if (!ops[1]) {
|
|
45482
|
+
if (isAutoDeclareHere) return ce.Nothing;
|
|
45091
45483
|
ce.declare(symbolName2, { inferred: true, type: "unknown" });
|
|
45092
45484
|
return ce.Nothing;
|
|
45093
45485
|
}
|
|
@@ -45096,6 +45488,11 @@ var CORE_LIBRARY = [
|
|
|
45096
45488
|
(isString(t) ? t.string : void 0) ?? sym(t) ?? void 0
|
|
45097
45489
|
);
|
|
45098
45490
|
if (!isValidType(type2)) return void 0;
|
|
45491
|
+
if (isAutoDeclareHere && existingValueDef) {
|
|
45492
|
+
existingValueDef.value.type = ce.type(type2);
|
|
45493
|
+
existingValueDef.value.inferredType = false;
|
|
45494
|
+
return ce.Nothing;
|
|
45495
|
+
}
|
|
45099
45496
|
ce.declare(symbolName2, type2);
|
|
45100
45497
|
return ce.Nothing;
|
|
45101
45498
|
}
|
|
@@ -45213,33 +45610,41 @@ var CORE_LIBRARY = [
|
|
|
45213
45610
|
},
|
|
45214
45611
|
Random: {
|
|
45215
45612
|
description: [
|
|
45216
|
-
"Random():
|
|
45217
|
-
"Random(
|
|
45218
|
-
"Random(
|
|
45613
|
+
"Random(): non-deterministic float in [0, 1)",
|
|
45614
|
+
"Random(seed: real): deterministic float in [0, 1) from a real seed",
|
|
45615
|
+
"Random(n: integer): non-deterministic integer in [0, n)",
|
|
45616
|
+
"Random(m: integer, n: integer): non-deterministic integer in [m, n)"
|
|
45219
45617
|
],
|
|
45220
45618
|
pure: false,
|
|
45221
|
-
|
|
45222
|
-
|
|
45223
|
-
|
|
45224
|
-
|
|
45619
|
+
// Signature accepts: nothing, one number, or two integers.
|
|
45620
|
+
// Use `number` (not `integer`) for the single-arg case so float seeds
|
|
45621
|
+
// type-check; runtime dispatch differentiates integer vs real.
|
|
45622
|
+
signature: "(number?, integer?) -> finite_number",
|
|
45623
|
+
type: ([first, second]) => {
|
|
45624
|
+
if (first === void 0) return "finite_number";
|
|
45625
|
+
if (second !== void 0) return "finite_integer";
|
|
45626
|
+
if (first.type.matches("integer")) return "finite_integer";
|
|
45627
|
+
return "finite_number";
|
|
45225
45628
|
},
|
|
45226
45629
|
sgn: () => "non-negative",
|
|
45227
45630
|
evaluate: (ops, { engine: ce }) => {
|
|
45228
45631
|
if (ops.length === 0) return ce.number(Math.random());
|
|
45229
|
-
const [
|
|
45230
|
-
|
|
45231
|
-
|
|
45232
|
-
|
|
45233
|
-
lower = 0;
|
|
45234
|
-
upper = Math.floor(lowerOp.re - 1);
|
|
45235
|
-
if (isNaN(upper)) upper = 0;
|
|
45236
|
-
} else {
|
|
45237
|
-
lower = Math.floor(lowerOp.re);
|
|
45238
|
-
upper = Math.floor(upperOp.re);
|
|
45632
|
+
const [firstOp, secondOp] = ops;
|
|
45633
|
+
if (secondOp !== void 0) {
|
|
45634
|
+
let lower = Math.floor(firstOp.re);
|
|
45635
|
+
let upper = Math.floor(secondOp.re);
|
|
45239
45636
|
if (isNaN(lower)) lower = 0;
|
|
45240
45637
|
if (isNaN(upper)) upper = 0;
|
|
45638
|
+
return ce.number(lower + Math.floor(Math.random() * (upper - lower)));
|
|
45241
45639
|
}
|
|
45242
|
-
|
|
45640
|
+
if (firstOp.type.matches("integer")) {
|
|
45641
|
+
let n = Math.floor(firstOp.re);
|
|
45642
|
+
if (isNaN(n)) n = 0;
|
|
45643
|
+
return ce.number(Math.floor(Math.random() * n));
|
|
45644
|
+
}
|
|
45645
|
+
const seed = firstOp.re;
|
|
45646
|
+
if (isNaN(seed)) return ce.number(0);
|
|
45647
|
+
return ce.number(deterministicRandom(seed));
|
|
45243
45648
|
}
|
|
45244
45649
|
},
|
|
45245
45650
|
// @todo: need review
|
|
@@ -45695,6 +46100,14 @@ var CORE_LIBRARY = [
|
|
|
45695
46100
|
To: {
|
|
45696
46101
|
description: "Action arrow / mapping (`a \\to b`) \u2014 opaque typed head.",
|
|
45697
46102
|
signature: "(any, any) -> nothing"
|
|
46103
|
+
},
|
|
46104
|
+
Colon: {
|
|
46105
|
+
description: "Type annotation (`a : b`) \u2014 opaque typed head.",
|
|
46106
|
+
signature: "(any, any) -> expression"
|
|
46107
|
+
},
|
|
46108
|
+
Prime: {
|
|
46109
|
+
description: "Derivative or prime notation (`f'`, `f^{(n)}`) \u2014 opaque typed head until a derivative library handler runs.",
|
|
46110
|
+
signature: "(any, integer?) -> expression"
|
|
45698
46111
|
}
|
|
45699
46112
|
}
|
|
45700
46113
|
];
|
|
@@ -50735,18 +51148,28 @@ var STATISTICS_LIBRARY = [
|
|
|
50735
51148
|
},
|
|
50736
51149
|
{
|
|
50737
51150
|
Sample: {
|
|
50738
|
-
description: "Return a random sample of k elements from the collection, without replacement.",
|
|
51151
|
+
description: "Return a random sample of k elements from the collection, without replacement. With an optional `seed` argument, the sample is deterministic.",
|
|
50739
51152
|
complexity: 8200,
|
|
50740
|
-
signature: "(collection, integer) -> list",
|
|
50741
|
-
evaluate: ([xs, nArg], { engine: ce }) => {
|
|
51153
|
+
signature: "(collection, integer, real?) -> list",
|
|
51154
|
+
evaluate: ([xs, nArg, seedArg], { engine: ce }) => {
|
|
50742
51155
|
if (!xs.isFiniteCollection) return void 0;
|
|
50743
51156
|
const k = toInteger(nArg);
|
|
50744
51157
|
if (k === null || k < 0) return void 0;
|
|
50745
51158
|
const data = Array.from(xs.each());
|
|
50746
51159
|
if (k > data.length) return void 0;
|
|
50747
|
-
|
|
50748
|
-
|
|
50749
|
-
|
|
51160
|
+
const seed = seedArg?.re;
|
|
51161
|
+
if (seed !== void 0 && !Number.isNaN(seed)) {
|
|
51162
|
+
let s = seed;
|
|
51163
|
+
for (let i = data.length - 1; i > 0; i--) {
|
|
51164
|
+
const j = Math.floor(deterministicRandom(s) * (i + 1));
|
|
51165
|
+
[data[i], data[j]] = [data[j], data[i]];
|
|
51166
|
+
s = nextSeed(s);
|
|
51167
|
+
}
|
|
51168
|
+
} else {
|
|
51169
|
+
for (let i = data.length - 1; i > 0; i--) {
|
|
51170
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
51171
|
+
[data[i], data[j]] = [data[j], data[i]];
|
|
51172
|
+
}
|
|
50750
51173
|
}
|
|
50751
51174
|
const sample = data.slice(0, k);
|
|
50752
51175
|
return ce.function("List", sample);
|
|
@@ -53567,6 +53990,20 @@ var BoxedFunction = class extends _BoxedExpression {
|
|
|
53567
53990
|
if (results.length === 1) return results[0];
|
|
53568
53991
|
return this.engine._fn("List", results);
|
|
53569
53992
|
}
|
|
53993
|
+
if (def instanceof _BoxedOperatorDefinition && def._isLambda && this.ops.some((x) => isFiniteIndexedCollection(x)) && paramsAreScalar(def)) {
|
|
53994
|
+
const items = zip(this._ops);
|
|
53995
|
+
if (items) {
|
|
53996
|
+
const results = [];
|
|
53997
|
+
while (true) {
|
|
53998
|
+
const { done, value } = items.next();
|
|
53999
|
+
if (done) break;
|
|
54000
|
+
results.push(
|
|
54001
|
+
this.engine._fn(this.operator, value).evaluate(options)
|
|
54002
|
+
);
|
|
54003
|
+
}
|
|
54004
|
+
return this.engine._fn("List", results);
|
|
54005
|
+
}
|
|
54006
|
+
}
|
|
53570
54007
|
if (materialization !== false && !def.evaluate && this.isLazyCollection)
|
|
53571
54008
|
return materialize(this, def, options);
|
|
53572
54009
|
const tail = holdMap(this, (x) => x.evaluate(options));
|
|
@@ -53613,6 +54050,22 @@ var BoxedFunction = class extends _BoxedExpression {
|
|
|
53613
54050
|
(resolved) => this.engine._fn("List", resolved)
|
|
53614
54051
|
);
|
|
53615
54052
|
}
|
|
54053
|
+
if (def instanceof _BoxedOperatorDefinition && def._isLambda && this.ops.some((x) => isFiniteIndexedCollection(x)) && paramsAreScalar(def)) {
|
|
54054
|
+
const items = zip(this._ops);
|
|
54055
|
+
if (items) {
|
|
54056
|
+
const results = [];
|
|
54057
|
+
while (true) {
|
|
54058
|
+
const { done, value } = items.next();
|
|
54059
|
+
if (done) break;
|
|
54060
|
+
results.push(
|
|
54061
|
+
this.engine._fn(this.operator, value).evaluateAsync(options)
|
|
54062
|
+
);
|
|
54063
|
+
}
|
|
54064
|
+
return Promise.all(results).then(
|
|
54065
|
+
(resolved) => this.engine._fn("List", resolved)
|
|
54066
|
+
);
|
|
54067
|
+
}
|
|
54068
|
+
}
|
|
53616
54069
|
const tail = await holdMapAsync(
|
|
53617
54070
|
this,
|
|
53618
54071
|
async (x) => await x.evaluateAsync(options)
|
|
@@ -53827,8 +54280,47 @@ function applyFunctionLiteral(expr2, def, options) {
|
|
|
53827
54280
|
const ops = expr2.ops.map((x) => x.evaluate(options));
|
|
53828
54281
|
if (!value || value.type.isUnknown)
|
|
53829
54282
|
return expr2.engine.function(expr2.operator, ops);
|
|
54283
|
+
if (ops.some((x) => isFiniteIndexedCollection(x)) && paramsAreScalar(value.type.type)) {
|
|
54284
|
+
const items = zip(ops);
|
|
54285
|
+
if (items) {
|
|
54286
|
+
const results = [];
|
|
54287
|
+
while (true) {
|
|
54288
|
+
const { done, value: zipped } = items.next();
|
|
54289
|
+
if (done) break;
|
|
54290
|
+
results.push(apply(value, zipped).evaluate(options));
|
|
54291
|
+
}
|
|
54292
|
+
return expr2.engine._fn("List", results);
|
|
54293
|
+
}
|
|
54294
|
+
}
|
|
53830
54295
|
return apply(value, ops);
|
|
53831
54296
|
}
|
|
54297
|
+
function paramsAreScalar(source) {
|
|
54298
|
+
const sigType = isOperatorDefinition(source) ? source.signature?.type : source;
|
|
54299
|
+
if (!sigType || typeof sigType === "string") return true;
|
|
54300
|
+
if (sigType.kind !== "signature") return true;
|
|
54301
|
+
const args = [
|
|
54302
|
+
...sigType.args ?? [],
|
|
54303
|
+
...sigType.optArgs ?? [],
|
|
54304
|
+
...sigType.variadicArg ? [sigType.variadicArg] : []
|
|
54305
|
+
];
|
|
54306
|
+
return args.every((arg) => isScalarType(arg.type));
|
|
54307
|
+
}
|
|
54308
|
+
function isOperatorDefinition(source) {
|
|
54309
|
+
return typeof source === "object" && source !== null && "signature" in source;
|
|
54310
|
+
}
|
|
54311
|
+
function isScalarType(t) {
|
|
54312
|
+
if (typeof t === "string") {
|
|
54313
|
+
if (t === "collection" || t === "indexed_collection" || t === "list" || t === "tuple" || t === "set" || t === "dictionary" || t === "record" || t === "function")
|
|
54314
|
+
return false;
|
|
54315
|
+
return true;
|
|
54316
|
+
}
|
|
54317
|
+
if (t.kind === "collection" || t.kind === "indexed_collection" || t.kind === "list" || t.kind === "tuple" || t.kind === "set" || t.kind === "dictionary" || t.kind === "record" || t.kind === "signature")
|
|
54318
|
+
return false;
|
|
54319
|
+
if (t.kind === "union" || t.kind === "intersection")
|
|
54320
|
+
return t.types.every((x) => isScalarType(x));
|
|
54321
|
+
if (t.kind === "negation") return isScalarType(t.type);
|
|
54322
|
+
return true;
|
|
54323
|
+
}
|
|
53832
54324
|
function materialize(expr2, def, options) {
|
|
53833
54325
|
if (!expr2.isValid || options?.materialization === false) return expr2;
|
|
53834
54326
|
let materialization = options?.materialization ?? false;
|
|
@@ -53836,6 +54328,11 @@ function materialize(expr2, def, options) {
|
|
|
53836
54328
|
materialization = DEFAULT_MATERIALIZATION;
|
|
53837
54329
|
const isIndexed = expr2.isIndexedCollection;
|
|
53838
54330
|
const isFinite2 = expr2.isFiniteCollection;
|
|
54331
|
+
if (isIndexed && isFinite2) {
|
|
54332
|
+
const count = expr2.count;
|
|
54333
|
+
if (count !== void 0 && count > expr2.engine.maxCollectionSize)
|
|
54334
|
+
return expr2;
|
|
54335
|
+
}
|
|
53839
54336
|
const xs = [];
|
|
53840
54337
|
if (!expr2.isEmptyCollection) {
|
|
53841
54338
|
if (!isIndexed || !isFinite2) {
|
|
@@ -54063,7 +54560,7 @@ var BoxedDictionary = class _BoxedDictionary extends _BoxedExpression {
|
|
|
54063
54560
|
const eltType = widen(
|
|
54064
54561
|
...Object.values(this._keyValues).map((op) => op.type.type)
|
|
54065
54562
|
);
|
|
54066
|
-
this._type =
|
|
54563
|
+
this._type = new BoxedType({ kind: "dictionary", values: eltType });
|
|
54067
54564
|
return this._type;
|
|
54068
54565
|
}
|
|
54069
54566
|
get isPure() {
|
|
@@ -54341,6 +54838,7 @@ function box(ce, expr2, options) {
|
|
|
54341
54838
|
}
|
|
54342
54839
|
if (typeof expr2 === "number" || expr2 instanceof BigDecimal || expr2 instanceof Complex)
|
|
54343
54840
|
return ce.number(expr2);
|
|
54841
|
+
if (typeof expr2 === "boolean") return ce.symbol(expr2 ? "True" : "False");
|
|
54344
54842
|
if (typeof expr2 === "string") {
|
|
54345
54843
|
if (matchesSymbol(expr2)) {
|
|
54346
54844
|
const sym2 = symbol(expr2);
|
|
@@ -55519,6 +56017,13 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
55519
56017
|
* GLSL (no dynamic arrays, no push). A compile-time error is thrown.
|
|
55520
56018
|
* TODO(E3-GLSL): support GLSL multi-Element via a pre-declared fixed-size
|
|
55521
56019
|
* array or by unrolling when bounds are known at compile time.
|
|
56020
|
+
*
|
|
56021
|
+
* Known issue (imperative form): the IIFE generated by form (1) has no
|
|
56022
|
+
* `return` statement, so `Loop(body, Element(i, Range(lo, hi)))` compiled
|
|
56023
|
+
* to JS evaluates to `undefined` at runtime, while CE evaluation returns a
|
|
56024
|
+
* `List` of body values. See `test/compute-engine/a1-c1-compile-parity.test.ts`
|
|
56025
|
+
* ("Loop compiles in JS") for the verify-only test that locks in the
|
|
56026
|
+
* current behavior.
|
|
55522
56027
|
*/
|
|
55523
56028
|
static compileForLoop(args, target) {
|
|
55524
56029
|
if (!args[0]) throw new Error("Loop: no body");
|
|
@@ -60155,8 +60660,8 @@ function assumeInequality(proposition) {
|
|
|
60155
60660
|
}
|
|
60156
60661
|
if (effectiveOp === "greater" || effectiveOp === "greaterEqual") {
|
|
60157
60662
|
const isStrict = effectiveOp === "greater";
|
|
60158
|
-
if (bounds.
|
|
60159
|
-
const lowerVal = isNumber(bounds.
|
|
60663
|
+
if (bounds.lower !== void 0) {
|
|
60664
|
+
const lowerVal = isNumber(bounds.lower) ? bounds.lower.numericValue : void 0;
|
|
60160
60665
|
if (typeof lowerVal === "number" && isFinite(lowerVal)) {
|
|
60161
60666
|
if (isStrict) {
|
|
60162
60667
|
if (lowerVal > k) return "tautology";
|
|
@@ -60168,8 +60673,8 @@ function assumeInequality(proposition) {
|
|
|
60168
60673
|
}
|
|
60169
60674
|
}
|
|
60170
60675
|
}
|
|
60171
|
-
if (bounds.
|
|
60172
|
-
const upperVal = isNumber(bounds.
|
|
60676
|
+
if (bounds.upper !== void 0) {
|
|
60677
|
+
const upperVal = isNumber(bounds.upper) ? bounds.upper.numericValue : void 0;
|
|
60173
60678
|
if (typeof upperVal === "number" && isFinite(upperVal)) {
|
|
60174
60679
|
if (isStrict) {
|
|
60175
60680
|
if (upperVal < k) return "contradiction";
|
|
@@ -60184,8 +60689,8 @@ function assumeInequality(proposition) {
|
|
|
60184
60689
|
}
|
|
60185
60690
|
} else {
|
|
60186
60691
|
const isStrict = effectiveOp === "less";
|
|
60187
|
-
if (bounds.
|
|
60188
|
-
const upperVal = isNumber(bounds.
|
|
60692
|
+
if (bounds.upper !== void 0) {
|
|
60693
|
+
const upperVal = isNumber(bounds.upper) ? bounds.upper.numericValue : void 0;
|
|
60189
60694
|
if (typeof upperVal === "number" && isFinite(upperVal)) {
|
|
60190
60695
|
if (isStrict) {
|
|
60191
60696
|
if (upperVal < k) return "tautology";
|
|
@@ -60196,8 +60701,8 @@ function assumeInequality(proposition) {
|
|
|
60196
60701
|
}
|
|
60197
60702
|
}
|
|
60198
60703
|
}
|
|
60199
|
-
if (bounds.
|
|
60200
|
-
const lowerVal = isNumber(bounds.
|
|
60704
|
+
if (bounds.lower !== void 0) {
|
|
60705
|
+
const lowerVal = isNumber(bounds.lower) ? bounds.lower.numericValue : void 0;
|
|
60201
60706
|
if (typeof lowerVal === "number" && isFinite(lowerVal)) {
|
|
60202
60707
|
if (isStrict) {
|
|
60203
60708
|
if (lowerVal > k) return "contradiction";
|
|
@@ -60425,7 +60930,7 @@ function ask(ce, pattern) {
|
|
|
60425
60930
|
const patOp1B2 = pat.op1;
|
|
60426
60931
|
if (isSymbol2(patOp1B2)) {
|
|
60427
60932
|
const bounds = getInequalityBoundsFromAssumptions(ce, patOp1B2.symbol);
|
|
60428
|
-
const bound = isLower ? bounds.
|
|
60933
|
+
const bound = isLower ? bounds.lower : bounds.upper;
|
|
60429
60934
|
const strictOk = isLower ? bounds.lowerStrict : bounds.upperStrict;
|
|
60430
60935
|
if (bound !== void 0 && (!isStrict || strictOk === true))
|
|
60431
60936
|
pushResult({ [boundWildcard]: bound });
|
|
@@ -60435,7 +60940,7 @@ function ask(ce, pattern) {
|
|
|
60435
60940
|
if (symbolWildcard && !symbolWildcard.startsWith("__")) {
|
|
60436
60941
|
for (const s of candidatesFromAssumptions()) {
|
|
60437
60942
|
const bounds = getInequalityBoundsFromAssumptions(ce, s);
|
|
60438
|
-
const bound = isLower ? bounds.
|
|
60943
|
+
const bound = isLower ? bounds.lower : bounds.upper;
|
|
60439
60944
|
const strictOk = isLower ? bounds.lowerStrict : bounds.upperStrict;
|
|
60440
60945
|
if (bound === void 0 || isStrict && strictOk !== true)
|
|
60441
60946
|
continue;
|
|
@@ -61467,6 +61972,7 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
61467
61972
|
return `_SYS.cexp(${compile3(args[0])})`;
|
|
61468
61973
|
return `Math.exp(${compile3(args[0])})`;
|
|
61469
61974
|
},
|
|
61975
|
+
First: (args, compile3) => `${compile3(args[0])}[0]`,
|
|
61470
61976
|
Floor: (args, compile3) => {
|
|
61471
61977
|
if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
|
|
61472
61978
|
return `Math.floor(${compile3(args[0])})`;
|
|
@@ -61625,7 +62131,20 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
61625
62131
|
if (nConst !== void 0) return `Math.pow(${compile3(arg)}, ${1 / nConst})`;
|
|
61626
62132
|
return `Math.pow(${compile3(arg)}, 1 / (${compile3(exp3)}))`;
|
|
61627
62133
|
},
|
|
61628
|
-
Random:
|
|
62134
|
+
Random: (args, compile3) => {
|
|
62135
|
+
if (args.length === 0) return "Math.random()";
|
|
62136
|
+
if (args.length === 2) {
|
|
62137
|
+
const m = compile3(args[0]);
|
|
62138
|
+
const n = compile3(args[1]);
|
|
62139
|
+
return `((${m}) + Math.floor(Math.random() * ((${n}) - (${m}))))`;
|
|
62140
|
+
}
|
|
62141
|
+
const arg = args[0];
|
|
62142
|
+
if (BaseCompiler.isIntegerValued(arg)) {
|
|
62143
|
+
return `Math.floor(Math.random() * (${compile3(arg)}))`;
|
|
62144
|
+
}
|
|
62145
|
+
const a = compile3(arg);
|
|
62146
|
+
return `(() => { const _s = (${a}) * 12.9898; const _v = Math.sin(_s) * 43758.5453; return _v - Math.floor(_v); })()`;
|
|
62147
|
+
},
|
|
61629
62148
|
Round: (args, compile3) => {
|
|
61630
62149
|
if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
|
|
61631
62150
|
return `Math.round(${compile3(args[0])})`;
|
|
@@ -61653,6 +62172,7 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
61653
62172
|
if (BaseCompiler.isComplexValued(arg)) return `_SYS.csech(${compile3(arg)})`;
|
|
61654
62173
|
return `1 / Math.cosh(${compile3(arg)})`;
|
|
61655
62174
|
},
|
|
62175
|
+
Second: (args, compile3) => `${compile3(args[0])}[1]`,
|
|
61656
62176
|
Heaviside: "_SYS.heaviside",
|
|
61657
62177
|
Sign: "Math.sign",
|
|
61658
62178
|
Sinc: "_SYS.sinc",
|
|
@@ -61685,6 +62205,7 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
61685
62205
|
return `_SYS.ctanh(${compile3(args[0])})`;
|
|
61686
62206
|
return `Math.tanh(${compile3(args[0])})`;
|
|
61687
62207
|
},
|
|
62208
|
+
Third: (args, compile3) => `${compile3(args[0])}[2]`,
|
|
61688
62209
|
Mod: ([a, b], compile3) => {
|
|
61689
62210
|
if (a === null || b === null) throw new Error("Mod: missing argument");
|
|
61690
62211
|
const ca = compile3(a);
|
|
@@ -62964,6 +63485,14 @@ var GPU_FUNCTIONS = {
|
|
|
62964
63485
|
return `exp(${compile3(args[0])})`;
|
|
62965
63486
|
},
|
|
62966
63487
|
Exp2: "exp2",
|
|
63488
|
+
// Component access — assumes the argument compiles to a vec2/vec3/vec4
|
|
63489
|
+
// (the common case for 2D/3D points). For 5+-element tuples that compile
|
|
63490
|
+
// to `float[N]` arrays, swizzle access is invalid GLSL and the shader
|
|
63491
|
+
// will fail to compile; that's an edge case `First`/`Second`/`Third`
|
|
63492
|
+
// aren't designed for. Vec swizzles are identical between GLSL and WGSL.
|
|
63493
|
+
First: (args, compile3) => `${compile3(args[0])}.x`,
|
|
63494
|
+
Second: (args, compile3) => `${compile3(args[0])}.y`,
|
|
63495
|
+
Third: (args, compile3) => `${compile3(args[0])}.z`,
|
|
62967
63496
|
Floor: (args, compile3) => {
|
|
62968
63497
|
if (BaseCompiler.isIntegerValued(args[0])) return compile3(args[0]);
|
|
62969
63498
|
return `floor(${compile3(args[0])})`;
|
|
@@ -63441,6 +63970,39 @@ var GPU_FUNCTIONS = {
|
|
|
63441
63970
|
// Sum/Product — unrolled or for-loop
|
|
63442
63971
|
Sum: (args, compile3, target) => compileGPUSumProduct("Sum", args, compile3, target),
|
|
63443
63972
|
Product: (args, compile3, target) => compileGPUSumProduct("Product", args, compile3, target),
|
|
63973
|
+
// Range — inline constant array literal (bounds must be compile-time constants)
|
|
63974
|
+
Range: (args, _compile2, target) => {
|
|
63975
|
+
if (args.length < 2 || args.length > 3) {
|
|
63976
|
+
throw new Error(
|
|
63977
|
+
"Range: GPU compile expects 2 or 3 arguments (lo, hi, step?)"
|
|
63978
|
+
);
|
|
63979
|
+
}
|
|
63980
|
+
const lo = args[0].re;
|
|
63981
|
+
const hi = args[1].re;
|
|
63982
|
+
const step = args.length === 3 ? args[2].re : 1;
|
|
63983
|
+
if (!Number.isFinite(lo) || !Number.isFinite(hi) || !Number.isFinite(step)) {
|
|
63984
|
+
throw new Error(
|
|
63985
|
+
"Range: GPU compile requires constant numeric bounds (non-constant ranges must be materialized at JS host then uploaded as a uniform)"
|
|
63986
|
+
);
|
|
63987
|
+
}
|
|
63988
|
+
if (step === 0) throw new Error("Range: step cannot be zero");
|
|
63989
|
+
const count = Math.max(0, Math.floor((hi - lo) / step) + 1);
|
|
63990
|
+
if (count === 0) {
|
|
63991
|
+
throw new Error(
|
|
63992
|
+
"Range: empty range (lo > hi for positive step, or lo < hi for negative step)"
|
|
63993
|
+
);
|
|
63994
|
+
}
|
|
63995
|
+
if (count > 256) {
|
|
63996
|
+
throw new Error(
|
|
63997
|
+
`Range: GPU compile inlines ranges up to 256 elements (got ${count})`
|
|
63998
|
+
);
|
|
63999
|
+
}
|
|
64000
|
+
const values = [];
|
|
64001
|
+
for (let i = 0; i < count; i++) values.push(lo + i * step);
|
|
64002
|
+
const isWGSL = target.language === "wgsl";
|
|
64003
|
+
const arrayType = isWGSL ? `array<f32, ${count}>` : `float[${count}]`;
|
|
64004
|
+
return `${arrayType}(${values.map(formatGPUNumber).join(", ")})`;
|
|
64005
|
+
},
|
|
63444
64006
|
// Loop — GPU for-loop (no IIFE, no let)
|
|
63445
64007
|
Loop: (args, _compile2, target) => {
|
|
63446
64008
|
if (!args[0]) throw new Error("Loop: no body");
|
|
@@ -63469,6 +64031,134 @@ var GPU_FUNCTIONS = {
|
|
|
63469
64031
|
${bodyCode};
|
|
63470
64032
|
}`;
|
|
63471
64033
|
},
|
|
64034
|
+
// Statistical functions
|
|
64035
|
+
/**
|
|
64036
|
+
* GCD of two scalar arguments.
|
|
64037
|
+
*
|
|
64038
|
+
* Uses a preamble helper `_gpu_gcd` (Euclidean algorithm via `mod`).
|
|
64039
|
+
* Only two-argument form is supported in GPU targets.
|
|
64040
|
+
*/
|
|
64041
|
+
GCD: (args, compile3) => {
|
|
64042
|
+
if (args.length < 2) throw new Error("GCD: need at least two arguments");
|
|
64043
|
+
if (args.length > 2)
|
|
64044
|
+
throw new Error("GCD: GPU target supports only two-argument GCD");
|
|
64045
|
+
const a = args[0];
|
|
64046
|
+
const b = args[1];
|
|
64047
|
+
if (a === null || b === null) throw new Error("GCD: missing argument");
|
|
64048
|
+
return `_gpu_gcd(${compile3(a)}, ${compile3(b)})`;
|
|
64049
|
+
},
|
|
64050
|
+
/**
|
|
64051
|
+
* Variance of a compile-time-known list.
|
|
64052
|
+
*
|
|
64053
|
+
* Accepts either a single `List(...)` argument or N scalar arguments.
|
|
64054
|
+
* Generates fully inline code: computes mean then sum of squared deviations,
|
|
64055
|
+
* divided by (N-1) for sample variance (matches JS `_SYS.variance`).
|
|
64056
|
+
*/
|
|
64057
|
+
Variance: (args, compile3) => {
|
|
64058
|
+
let elems;
|
|
64059
|
+
if (args.length === 1 && isFunction2(args[0], "List")) {
|
|
64060
|
+
elems = args[0].ops;
|
|
64061
|
+
} else if (args.length >= 2) {
|
|
64062
|
+
elems = args;
|
|
64063
|
+
} else {
|
|
64064
|
+
throw new Error(
|
|
64065
|
+
"Variance: GPU target requires a List argument or at least 2 scalar arguments"
|
|
64066
|
+
);
|
|
64067
|
+
}
|
|
64068
|
+
const n = elems.length;
|
|
64069
|
+
if (n < 2) throw new Error("Variance: need at least 2 elements");
|
|
64070
|
+
const compiled = elems.map((e) => compile3(e));
|
|
64071
|
+
const sum = compiled.join(" + ");
|
|
64072
|
+
const mean2 = `((${sum}) / ${formatGPUNumber(n)})`;
|
|
64073
|
+
const sqDiffs = compiled.map((c) => `(${c} - ${mean2}) * (${c} - ${mean2})`).join(" + ");
|
|
64074
|
+
return `((${sqDiffs}) / ${formatGPUNumber(n - 1)})`;
|
|
64075
|
+
},
|
|
64076
|
+
/**
|
|
64077
|
+
* Median of a compile-time-known list.
|
|
64078
|
+
*
|
|
64079
|
+
* Accepts either a single `List(...)` argument or N scalar arguments.
|
|
64080
|
+
* For N ≤ 8: generates a fully unrolled inline sorting network followed by
|
|
64081
|
+
* a middle-element pick. For larger N, throws (too large to inline cleanly).
|
|
64082
|
+
*
|
|
64083
|
+
* The sorting network uses the "odd-even merge sort" comparator pattern
|
|
64084
|
+
* inlined as `min`/`max` calls — no GPU statements required.
|
|
64085
|
+
*/
|
|
64086
|
+
Median: (args, compile3) => {
|
|
64087
|
+
let elems;
|
|
64088
|
+
if (args.length === 1 && isFunction2(args[0], "List")) {
|
|
64089
|
+
elems = args[0].ops;
|
|
64090
|
+
} else if (args.length >= 1) {
|
|
64091
|
+
elems = args;
|
|
64092
|
+
} else {
|
|
64093
|
+
throw new Error(
|
|
64094
|
+
"Median: GPU target requires a List argument or at least 1 scalar argument"
|
|
64095
|
+
);
|
|
64096
|
+
}
|
|
64097
|
+
const n = elems.length;
|
|
64098
|
+
if (n === 0) throw new Error("Median: empty list");
|
|
64099
|
+
if (n > 8) {
|
|
64100
|
+
throw new Error(
|
|
64101
|
+
`Median: GPU target supports up to 8 elements via inline sorting network (got ${n}). For larger lists, compute on the CPU and pass the result as a uniform.`
|
|
64102
|
+
);
|
|
64103
|
+
}
|
|
64104
|
+
const compiled = elems.map((e) => compile3(e));
|
|
64105
|
+
if (n === 1) return compiled[0];
|
|
64106
|
+
return `_gpu_median_${n}(${compiled.join(", ")})`;
|
|
64107
|
+
},
|
|
64108
|
+
/**
|
|
64109
|
+
* Deterministic pseudorandom for GPU.
|
|
64110
|
+
*
|
|
64111
|
+
* All emitted forms return a GLSL `float` (or WGSL `f32`) so the result
|
|
64112
|
+
* composes with surrounding float arithmetic without explicit casts. The
|
|
64113
|
+
* "integer-bound" forms return an integer-valued float (the result of
|
|
64114
|
+
* `floor`), matching the convention used by `Floor` and other ostensibly
|
|
64115
|
+
* integer-returning operators in this target.
|
|
64116
|
+
*
|
|
64117
|
+
* - 0 args (GLSL only): fall back to a fragment-coord-derived seed.
|
|
64118
|
+
* Only meaningful in fragment shaders (gl_FragCoord is FS-only).
|
|
64119
|
+
* - 0 args (WGSL): throws — WGSL has no built-in fragment coordinate;
|
|
64120
|
+
* caller must provide an explicit seed.
|
|
64121
|
+
* - 1 arg, real-typed: `_gpu_random(seed)` — deterministic float in [0, 1)
|
|
64122
|
+
* - 1 arg, integer-typed: `floor(_gpu_random(float(n)) * float(n))` —
|
|
64123
|
+
* integer-valued float in {0, 1, ..., n-1}. The seed is derived from
|
|
64124
|
+
* `n` itself, so the result is per-pixel-and-n deterministic in GLSL.
|
|
64125
|
+
* - 2 args (integer m, n): float in [m, n), seeded from gl_FragCoord.
|
|
64126
|
+
*
|
|
64127
|
+
* JS-side `Random` has matching semantics (see `library/core.ts`'s
|
|
64128
|
+
* polymorphic dispatch). JS↔GLSL parity is approximate — same seed yields
|
|
64129
|
+
* a similar value, not bit-identical, due to fp64 vs fp32 and platform
|
|
64130
|
+
* `sin` differences.
|
|
64131
|
+
*/
|
|
64132
|
+
Random: (args, compile3, target) => {
|
|
64133
|
+
if (args.length === 0) {
|
|
64134
|
+
if (target.language === "wgsl") {
|
|
64135
|
+
throw new Error(
|
|
64136
|
+
"Random(): WGSL compile requires an explicit seed argument. WGSL has no gl_FragCoord built-in outside fragment entry points, so the no-arg fallback used in GLSL is unavailable. Use Random(seed) where seed is a deterministic per-invocation value."
|
|
64137
|
+
);
|
|
64138
|
+
}
|
|
64139
|
+
return "_gpu_random(gl_FragCoord.x + gl_FragCoord.y * 1024.0)";
|
|
64140
|
+
}
|
|
64141
|
+
if (args.length === 1) {
|
|
64142
|
+
const arg = args[0];
|
|
64143
|
+
if (BaseCompiler.isIntegerValued(arg)) {
|
|
64144
|
+
const compiled = compile3(arg);
|
|
64145
|
+
return `floor(_gpu_random(float(${compiled})) * float(${compiled}))`;
|
|
64146
|
+
}
|
|
64147
|
+
return `_gpu_random(${compile3(arg)})`;
|
|
64148
|
+
}
|
|
64149
|
+
if (args.length === 2) {
|
|
64150
|
+
if (target.language === "wgsl") {
|
|
64151
|
+
throw new Error(
|
|
64152
|
+
"Random(m, n): WGSL compile requires explicit seeding. Use a seeded variant or compute the integer range manually."
|
|
64153
|
+
);
|
|
64154
|
+
}
|
|
64155
|
+
const m = compile3(args[0]);
|
|
64156
|
+
const n = compile3(args[1]);
|
|
64157
|
+
const seed = "_gpu_random(gl_FragCoord.x + gl_FragCoord.y * 1024.0)";
|
|
64158
|
+
return `(float(${m}) + floor(${seed} * float((${n}) - (${m}))))`;
|
|
64159
|
+
}
|
|
64160
|
+
throw new Error("Random: GPU compile expects 0, 1, or 2 arguments");
|
|
64161
|
+
},
|
|
63472
64162
|
// Function (lambda) — not supported in GPU
|
|
63473
64163
|
Function: () => {
|
|
63474
64164
|
throw new Error(
|
|
@@ -64068,6 +64758,212 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
64068
64758
|
return 1.0;
|
|
64069
64759
|
}
|
|
64070
64760
|
`;
|
|
64761
|
+
var GPU_GCD_PREAMBLE_GLSL = `
|
|
64762
|
+
float _gpu_gcd(float a, float b) {
|
|
64763
|
+
a = abs(a); b = abs(b);
|
|
64764
|
+
for (int i = 0; i < 32; i++) {
|
|
64765
|
+
if (b < 0.5) break;
|
|
64766
|
+
float t = mod(a, b);
|
|
64767
|
+
a = b;
|
|
64768
|
+
b = t;
|
|
64769
|
+
}
|
|
64770
|
+
return a;
|
|
64771
|
+
}
|
|
64772
|
+
`;
|
|
64773
|
+
var GPU_GCD_PREAMBLE_WGSL = `
|
|
64774
|
+
fn _gpu_gcd(a_in: f32, b_in: f32) -> f32 {
|
|
64775
|
+
var a = abs(a_in); var b = abs(b_in);
|
|
64776
|
+
for (var i: i32 = 0; i < 32; i++) {
|
|
64777
|
+
if (b < 0.5) { break; }
|
|
64778
|
+
let t = a % b;
|
|
64779
|
+
a = b;
|
|
64780
|
+
b = t;
|
|
64781
|
+
}
|
|
64782
|
+
return a;
|
|
64783
|
+
}
|
|
64784
|
+
`;
|
|
64785
|
+
var GPU_RANDOM_PREAMBLE_GLSL = `
|
|
64786
|
+
// Deterministic pseudorandom in [0, 1) from a float seed.
|
|
64787
|
+
// Standard fract-sin hash; reproducible across runs for the same seed.
|
|
64788
|
+
// Note: this hash exhibits visible banding near seed \u2248 k\u03C0 for integer k.
|
|
64789
|
+
// For high-quality shader random, callers should use a more robust hash
|
|
64790
|
+
// (e.g. PCG or xxHash) and pre-seed it appropriately.
|
|
64791
|
+
float _gpu_random(float seed) {
|
|
64792
|
+
return fract(sin(seed * 12.9898) * 43758.5453);
|
|
64793
|
+
}
|
|
64794
|
+
`;
|
|
64795
|
+
var GPU_RANDOM_PREAMBLE_WGSL = `
|
|
64796
|
+
// Deterministic pseudorandom in [0, 1) from a float seed.
|
|
64797
|
+
// Standard fract-sin hash; reproducible across runs for the same seed.
|
|
64798
|
+
// Note: this hash exhibits visible banding near seed \u2248 k\u03C0 for integer k.
|
|
64799
|
+
// For high-quality shader random, callers should use a more robust hash
|
|
64800
|
+
// (e.g. PCG or xxHash) and pre-seed it appropriately.
|
|
64801
|
+
fn _gpu_random(seed: f32) -> f32 {
|
|
64802
|
+
return fract(sin(seed * 12.9898) * 43758.5453);
|
|
64803
|
+
}
|
|
64804
|
+
`;
|
|
64805
|
+
var GPU_MEDIAN_PREAMBLE_GLSL = `
|
|
64806
|
+
float _gpu_median_2(float a, float b) {
|
|
64807
|
+
return (a + b) * 0.5;
|
|
64808
|
+
}
|
|
64809
|
+
float _gpu_median_3(float a, float b, float c) {
|
|
64810
|
+
return max(min(a, b), min(max(a, b), c));
|
|
64811
|
+
}
|
|
64812
|
+
float _gpu_median_4(float a, float b, float c, float d) {
|
|
64813
|
+
float lo = max(min(a, b), min(c, d));
|
|
64814
|
+
float hi = min(max(a, b), max(c, d));
|
|
64815
|
+
return (lo + hi) * 0.5;
|
|
64816
|
+
}
|
|
64817
|
+
float _gpu_median_5(float a, float b, float c, float d, float e) {
|
|
64818
|
+
// 9-comparator Bose-Nelson sort; v2 holds the median.
|
|
64819
|
+
float t; float v0=a,v1=b,v2=c,v3=d,v4=e;
|
|
64820
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64821
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64822
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64823
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64824
|
+
t=min(v0,v3); v3=max(v0,v3); v0=t;
|
|
64825
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64826
|
+
t=min(v1,v4); v4=max(v1,v4); v1=t;
|
|
64827
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64828
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64829
|
+
return v2;
|
|
64830
|
+
}
|
|
64831
|
+
float _gpu_median_6(float a, float b, float c, float d, float e, float f) {
|
|
64832
|
+
float t; float v0=a,v1=b,v2=c,v3=d,v4=e,v5=f;
|
|
64833
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64834
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64835
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64836
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64837
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64838
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64839
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64840
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64841
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64842
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64843
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64844
|
+
return (v2 + v3) * 0.5;
|
|
64845
|
+
}
|
|
64846
|
+
float _gpu_median_7(float a, float b, float c, float d, float e, float f, float g) {
|
|
64847
|
+
float t; float v0=a,v1=b,v2=c,v3=d,v4=e,v5=f,v6=g;
|
|
64848
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64849
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64850
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64851
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64852
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64853
|
+
t=min(v4,v6); v6=max(v4,v6); v4=t;
|
|
64854
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64855
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64856
|
+
t=min(v2,v6); v6=max(v2,v6); v2=t;
|
|
64857
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64858
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64859
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64860
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64861
|
+
return v3;
|
|
64862
|
+
}
|
|
64863
|
+
float _gpu_median_8(float a, float b, float c, float d, float e, float f, float g, float h) {
|
|
64864
|
+
float t; float v0=a,v1=b,v2=c,v3=d,v4=e,v5=f,v6=g,v7=h;
|
|
64865
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64866
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64867
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64868
|
+
t=min(v6,v7); v7=max(v6,v7); v6=t;
|
|
64869
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64870
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64871
|
+
t=min(v4,v6); v6=max(v4,v6); v4=t;
|
|
64872
|
+
t=min(v5,v7); v7=max(v5,v7); v5=t;
|
|
64873
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64874
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64875
|
+
t=min(v2,v6); v6=max(v2,v6); v2=t;
|
|
64876
|
+
t=min(v3,v7); v7=max(v3,v7); v3=t;
|
|
64877
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64878
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64879
|
+
t=min(v5,v6); v6=max(v5,v6); v5=t;
|
|
64880
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64881
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64882
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64883
|
+
return (v3 + v4) * 0.5;
|
|
64884
|
+
}
|
|
64885
|
+
`;
|
|
64886
|
+
var GPU_MEDIAN_PREAMBLE_WGSL = `
|
|
64887
|
+
fn _gpu_median_2(a: f32, b: f32) -> f32 {
|
|
64888
|
+
return (a + b) * 0.5;
|
|
64889
|
+
}
|
|
64890
|
+
fn _gpu_median_3(a: f32, b: f32, c: f32) -> f32 {
|
|
64891
|
+
return max(min(a, b), min(max(a, b), c));
|
|
64892
|
+
}
|
|
64893
|
+
fn _gpu_median_4(a: f32, b: f32, c: f32, d: f32) -> f32 {
|
|
64894
|
+
let lo = max(min(a, b), min(c, d));
|
|
64895
|
+
let hi = min(max(a, b), max(c, d));
|
|
64896
|
+
return (lo + hi) * 0.5;
|
|
64897
|
+
}
|
|
64898
|
+
fn _gpu_median_5(a: f32, b: f32, c: f32, d: f32, e: f32) -> f32 {
|
|
64899
|
+
// 9-comparator Bose-Nelson sort; v2 holds the median.
|
|
64900
|
+
var v0=a; var v1=b; var v2=c; var v3=d; var v4=e; var t: f32;
|
|
64901
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64902
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64903
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64904
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64905
|
+
t=min(v0,v3); v3=max(v0,v3); v0=t;
|
|
64906
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64907
|
+
t=min(v1,v4); v4=max(v1,v4); v1=t;
|
|
64908
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64909
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64910
|
+
return v2;
|
|
64911
|
+
}
|
|
64912
|
+
fn _gpu_median_6(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) -> f32 {
|
|
64913
|
+
var v0=a; var v1=b; var v2=c; var v3=d; var v4=e; var v5=f; var t: f32;
|
|
64914
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64915
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64916
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64917
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64918
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64919
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64920
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64921
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64922
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64923
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64924
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64925
|
+
return (v2 + v3) * 0.5;
|
|
64926
|
+
}
|
|
64927
|
+
fn _gpu_median_7(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32) -> f32 {
|
|
64928
|
+
var v0=a; var v1=b; var v2=c; var v3=d; var v4=e; var v5=f; var v6=g; var t: f32;
|
|
64929
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64930
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64931
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64932
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64933
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64934
|
+
t=min(v4,v6); v6=max(v4,v6); v4=t;
|
|
64935
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64936
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64937
|
+
t=min(v2,v6); v6=max(v2,v6); v2=t;
|
|
64938
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64939
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64940
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64941
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64942
|
+
return v3;
|
|
64943
|
+
}
|
|
64944
|
+
fn _gpu_median_8(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: f32) -> f32 {
|
|
64945
|
+
var v0=a; var v1=b; var v2=c; var v3=d; var v4=e; var v5=f; var v6=g; var v7=h; var t: f32;
|
|
64946
|
+
t=min(v0,v1); v1=max(v0,v1); v0=t;
|
|
64947
|
+
t=min(v2,v3); v3=max(v2,v3); v2=t;
|
|
64948
|
+
t=min(v4,v5); v5=max(v4,v5); v4=t;
|
|
64949
|
+
t=min(v6,v7); v7=max(v6,v7); v6=t;
|
|
64950
|
+
t=min(v0,v2); v2=max(v0,v2); v0=t;
|
|
64951
|
+
t=min(v1,v3); v3=max(v1,v3); v1=t;
|
|
64952
|
+
t=min(v4,v6); v6=max(v4,v6); v4=t;
|
|
64953
|
+
t=min(v5,v7); v7=max(v5,v7); v5=t;
|
|
64954
|
+
t=min(v0,v4); v4=max(v0,v4); v0=t;
|
|
64955
|
+
t=min(v1,v5); v5=max(v1,v5); v1=t;
|
|
64956
|
+
t=min(v2,v6); v6=max(v2,v6); v2=t;
|
|
64957
|
+
t=min(v3,v7); v7=max(v3,v7); v3=t;
|
|
64958
|
+
t=min(v1,v2); v2=max(v1,v2); v1=t;
|
|
64959
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64960
|
+
t=min(v5,v6); v6=max(v5,v6); v5=t;
|
|
64961
|
+
t=min(v3,v5); v5=max(v3,v5); v3=t;
|
|
64962
|
+
t=min(v2,v4); v4=max(v2,v4); v2=t;
|
|
64963
|
+
t=min(v3,v4); v4=max(v3,v4); v3=t;
|
|
64964
|
+
return (v3 + v4) * 0.5;
|
|
64965
|
+
}
|
|
64966
|
+
`;
|
|
64071
64967
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
64072
64968
|
float _gpu_srgb_to_linear(float c) {
|
|
64073
64969
|
if (c <= 0.04045) return c / 12.92;
|
|
@@ -64745,6 +65641,12 @@ var GPUShaderTarget = class {
|
|
|
64745
65641
|
if (code.includes("_fractal_")) {
|
|
64746
65642
|
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
64747
65643
|
}
|
|
65644
|
+
if (code.includes("_gpu_random"))
|
|
65645
|
+
preamble += this.languageId === "wgsl" ? GPU_RANDOM_PREAMBLE_WGSL : GPU_RANDOM_PREAMBLE_GLSL;
|
|
65646
|
+
if (code.includes("_gpu_gcd"))
|
|
65647
|
+
preamble += this.languageId === "wgsl" ? GPU_GCD_PREAMBLE_WGSL : GPU_GCD_PREAMBLE_GLSL;
|
|
65648
|
+
if (code.includes("_gpu_median_"))
|
|
65649
|
+
preamble += this.languageId === "wgsl" ? GPU_MEDIAN_PREAMBLE_WGSL : GPU_MEDIAN_PREAMBLE_GLSL;
|
|
64748
65650
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
64749
65651
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
64750
65652
|
}
|
|
@@ -66970,6 +67872,7 @@ var EngineRuntimeState = class {
|
|
|
66970
67872
|
_timeLimit = 2e3;
|
|
66971
67873
|
_iterationLimit = 1024;
|
|
66972
67874
|
_recursionLimit = 1024;
|
|
67875
|
+
_maxCollectionSize = 1e4;
|
|
66973
67876
|
_deadline = void 0;
|
|
66974
67877
|
_isVerifying = false;
|
|
66975
67878
|
get timeLimit() {
|
|
@@ -66990,6 +67893,12 @@ var EngineRuntimeState = class {
|
|
|
66990
67893
|
set recursionLimit(value) {
|
|
66991
67894
|
this._recursionLimit = value <= 0 ? Number.POSITIVE_INFINITY : value;
|
|
66992
67895
|
}
|
|
67896
|
+
get maxCollectionSize() {
|
|
67897
|
+
return this._maxCollectionSize;
|
|
67898
|
+
}
|
|
67899
|
+
set maxCollectionSize(value) {
|
|
67900
|
+
this._maxCollectionSize = value <= 0 ? Number.POSITIVE_INFINITY : value;
|
|
67901
|
+
}
|
|
66993
67902
|
get deadline() {
|
|
66994
67903
|
return this._deadline;
|
|
66995
67904
|
}
|
|
@@ -69028,6 +69937,23 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
69028
69937
|
set recursionLimit(t) {
|
|
69029
69938
|
this._runtimeState.recursionLimit = t;
|
|
69030
69939
|
}
|
|
69940
|
+
/** Maximum number of elements a collection may have when materialized
|
|
69941
|
+
* (converted from a lazy form to a `List`). Default: 10,000.
|
|
69942
|
+
*
|
|
69943
|
+
* When a materialization would exceed this size, the operation leaves
|
|
69944
|
+
* the expression in its lazy form. Consumers can detect oversize
|
|
69945
|
+
* collections via the symbolic form's `count`.
|
|
69946
|
+
*
|
|
69947
|
+
* Set to `Infinity` (or `0` / a negative number) to disable the cap.
|
|
69948
|
+
*
|
|
69949
|
+
* @experimental
|
|
69950
|
+
*/
|
|
69951
|
+
get maxCollectionSize() {
|
|
69952
|
+
return this._runtimeState.maxCollectionSize;
|
|
69953
|
+
}
|
|
69954
|
+
set maxCollectionSize(t) {
|
|
69955
|
+
this._runtimeState.maxCollectionSize = t;
|
|
69956
|
+
}
|
|
69031
69957
|
/**
|
|
69032
69958
|
* Flag to prevent infinite recursion in the verify/ask/equality checking cycle.
|
|
69033
69959
|
*
|
|
@@ -69304,6 +70230,18 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
69304
70230
|
lookupDefinition(id) {
|
|
69305
70231
|
return lookupDefinition(this, id);
|
|
69306
70232
|
}
|
|
70233
|
+
normalizeIdentifier(latex) {
|
|
70234
|
+
if (!latex) return "";
|
|
70235
|
+
if (isValidSymbol(latex)) return latex;
|
|
70236
|
+
this.pushScope();
|
|
70237
|
+
try {
|
|
70238
|
+
const expr2 = this.parse(latex);
|
|
70239
|
+
if (isSymbol2(expr2)) return expr2.symbol;
|
|
70240
|
+
} finally {
|
|
70241
|
+
this.popScope();
|
|
70242
|
+
}
|
|
70243
|
+
return "";
|
|
70244
|
+
}
|
|
69307
70245
|
operatorInfo(head) {
|
|
69308
70246
|
const def = this.lookupDefinition(head);
|
|
69309
70247
|
if (!def || !isOperatorDef(def)) return void 0;
|
|
@@ -69313,6 +70251,15 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
69313
70251
|
signature: op.signature
|
|
69314
70252
|
};
|
|
69315
70253
|
}
|
|
70254
|
+
symbolInfo(name) {
|
|
70255
|
+
const def = this.lookupDefinition(name);
|
|
70256
|
+
if (!def || !isValueDef(def)) return void 0;
|
|
70257
|
+
const v = def.value;
|
|
70258
|
+
return {
|
|
70259
|
+
kind: v.isConstant ? "constant" : "variable",
|
|
70260
|
+
type: v.type
|
|
70261
|
+
};
|
|
70262
|
+
}
|
|
69316
70263
|
/**
|
|
69317
70264
|
* Associate a new definition to a symbol in the current context.
|
|
69318
70265
|
*
|
|
@@ -69765,7 +70712,7 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
69765
70712
|
_setDefaultEngineFactory(() => new ComputeEngine());
|
|
69766
70713
|
|
|
69767
70714
|
// src/core.ts
|
|
69768
|
-
var version = "0.
|
|
70715
|
+
var version = "0.58.0";
|
|
69769
70716
|
export {
|
|
69770
70717
|
ComputeEngine,
|
|
69771
70718
|
N,
|