nerdamer 1.1.13 → 2.0.0-rc.1
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/LICENSE.md +184 -0
- package/README.md +293 -312
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +7 -0
- package/dist/parser.js +2 -0
- package/dist/parser.js.LICENSE.txt +7 -0
- package/docs-data/parser-functions.json +1960 -0
- package/index.d.ts +10 -426
- package/output/algebra/adapters.d.ts +33 -0
- package/output/algebra/adapters.js +109 -0
- package/output/algebra/algorithms/arith.d.ts +84 -0
- package/output/algebra/algorithms/arith.js +323 -0
- package/output/algebra/algorithms/factor.d.ts +3 -0
- package/output/algebra/algorithms/factor.js +5 -0
- package/output/algebra/algorithms/factorMultivariate.d.ts +23 -0
- package/output/algebra/algorithms/factorMultivariate.js +2393 -0
- package/output/algebra/algorithms/factorUnivariate.d.ts +72 -0
- package/output/algebra/algorithms/factorUnivariate.js +1072 -0
- package/output/algebra/algorithms/gcd.d.ts +22 -0
- package/output/algebra/algorithms/gcd.js +690 -0
- package/output/algebra/algorithms/groebnerBase.d.ts +157 -0
- package/output/algebra/algorithms/groebnerBase.js +1166 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +137 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.js +346 -0
- package/output/algebra/algorithms/poly.d.ts +228 -0
- package/output/algebra/algorithms/poly.js +1299 -0
- package/output/algebra/algorithms/rational.d.ts +17 -0
- package/output/algebra/algorithms/rational.js +115 -0
- package/output/algebra/factor/factor.d.ts +62 -0
- package/output/algebra/factor/factor.js +158 -0
- package/output/algebra/gcd/gcd.d.ts +29 -0
- package/output/algebra/gcd/gcd.js +141 -0
- package/output/algebra/groebner.d.ts +21 -0
- package/output/algebra/groebner.js +42 -0
- package/output/algebra/partfrac.d.ts +19 -0
- package/output/algebra/partfrac.js +398 -0
- package/output/algebra/polynomialize.d.ts +20 -0
- package/output/algebra/polynomialize.js +24 -0
- package/output/algebra/simplify/complexsimp.d.ts +7 -0
- package/output/algebra/simplify/complexsimp.js +24 -0
- package/output/algebra/simplify/factorCommon.d.ts +13 -0
- package/output/algebra/simplify/factorCommon.js +136 -0
- package/output/algebra/simplify/funcsimp.d.ts +26 -0
- package/output/algebra/simplify/funcsimp.js +633 -0
- package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
- package/output/algebra/simplify/invtrigrewrite.js +96 -0
- package/output/algebra/simplify/ratsimp.d.ts +21 -0
- package/output/algebra/simplify/ratsimp.js +140 -0
- package/output/algebra/simplify/simplify.d.ts +25 -0
- package/output/algebra/simplify/simplify.js +228 -0
- package/output/algebra/simplify/trigreduce.d.ts +38 -0
- package/output/algebra/simplify/trigreduce.js +424 -0
- package/output/algebra/simplify/trigrewrite.d.ts +17 -0
- package/output/algebra/simplify/trigrewrite.js +156 -0
- package/output/algebra/simplify/trigsimp.d.ts +11 -0
- package/output/algebra/simplify/trigsimp.js +369 -0
- package/output/algebra/simplify/utils.d.ts +32 -0
- package/output/algebra/simplify/utils.js +56 -0
- package/output/algebra/utils.d.ts +32 -0
- package/output/algebra/utils.js +48 -0
- package/output/api/advanced.d.ts +7 -0
- package/output/api/advanced.js +18 -0
- package/output/api/algebra.d.ts +17 -0
- package/output/api/algebra.js +32 -0
- package/output/api/assumptions.d.ts +4 -0
- package/output/api/assumptions.js +11 -0
- package/output/api/calculus.d.ts +9 -0
- package/output/api/calculus.js +21 -0
- package/output/api/core.d.ts +17 -0
- package/output/api/core.js +41 -0
- package/output/api/debug.d.ts +16 -0
- package/output/api/debug.js +23 -0
- package/output/api/parser.d.ts +85 -0
- package/output/api/parser.js +16 -0
- package/output/api/solve.d.ts +10 -0
- package/output/api/solve.js +16 -0
- package/output/api/structures.d.ts +10 -0
- package/output/api/structures.js +22 -0
- package/output/calculus/derivative/diff.d.ts +30 -0
- package/output/calculus/derivative/diff.js +238 -0
- package/output/calculus/fresnel.d.ts +16 -0
- package/output/calculus/fresnel.js +39 -0
- package/output/calculus/integrate/byParts.d.ts +18 -0
- package/output/calculus/integrate/byParts.js +339 -0
- package/output/calculus/integrate/bySubstitution.d.ts +135 -0
- package/output/calculus/integrate/bySubstitution.js +411 -0
- package/output/calculus/integrate/integrate.d.ts +38 -0
- package/output/calculus/integrate/integrate.js +652 -0
- package/output/calculus/integrate/integrationTable.d.ts +2 -0
- package/output/calculus/integrate/integrationTable.js +914 -0
- package/output/calculus/integrate/utils.d.ts +28 -0
- package/output/calculus/integrate/utils.js +96 -0
- package/output/calculus/laplace/ilaplace.d.ts +31 -0
- package/output/calculus/laplace/ilaplace.js +192 -0
- package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
- package/output/calculus/laplace/ilaplaceTable.js +200 -0
- package/output/calculus/laplace/laplace.d.ts +22 -0
- package/output/calculus/laplace/laplace.js +109 -0
- package/output/calculus/laplace/laplaceTable.d.ts +2 -0
- package/output/calculus/laplace/laplaceTable.js +187 -0
- package/output/calculus/limit/limit.d.ts +35 -0
- package/output/calculus/limit/limit.js +1183 -0
- package/output/calculus/limit/limitsTable.d.ts +2 -0
- package/output/calculus/limit/limitsTable.js +7 -0
- package/output/core/Settings.d.ts +32 -0
- package/output/core/Settings.js +68 -0
- package/output/core/adapters.d.ts +18 -0
- package/output/core/adapters.js +40 -0
- package/output/core/classes/assumption/Assumption.d.ts +218 -0
- package/output/core/classes/assumption/Assumption.js +605 -0
- package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
- package/output/core/classes/assumption/assertiveFunctions.js +64 -0
- package/output/core/classes/assumption/assume.d.ts +90 -0
- package/output/core/classes/assumption/assume.js +145 -0
- package/output/core/classes/collection/Collection.d.ts +107 -0
- package/output/core/classes/collection/Collection.js +231 -0
- package/output/core/classes/complex/Complex.d.ts +99 -0
- package/output/core/classes/complex/Complex.js +135 -0
- package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
- package/output/core/classes/decimalSet/DecimalSet.js +453 -0
- package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
- package/output/core/classes/dictionary/Dictionary.js +213 -0
- package/output/core/classes/equation/Equation.d.ts +256 -0
- package/output/core/classes/equation/Equation.js +350 -0
- package/output/core/classes/expression/CoeffObject.d.ts +100 -0
- package/output/core/classes/expression/CoeffObject.js +198 -0
- package/output/core/classes/expression/Expression.d.ts +1674 -0
- package/output/core/classes/expression/Expression.js +2332 -0
- package/output/core/classes/expression/analysis.d.ts +25 -0
- package/output/core/classes/expression/analysis.js +218 -0
- package/output/core/classes/expression/collect.d.ts +9 -0
- package/output/core/classes/expression/collect.js +49 -0
- package/output/core/classes/expression/format.d.ts +45 -0
- package/output/core/classes/expression/format.js +217 -0
- package/output/core/classes/expression/products.d.ts +23 -0
- package/output/core/classes/expression/products.js +115 -0
- package/output/core/classes/expression/shortcuts.d.ts +35 -0
- package/output/core/classes/expression/shortcuts.js +129 -0
- package/output/core/classes/expression/traversal.d.ts +31 -0
- package/output/core/classes/expression/traversal.js +216 -0
- package/output/core/classes/expression/trig.d.ts +25 -0
- package/output/core/classes/expression/trig.js +40 -0
- package/output/core/classes/expression/utils.d.ts +52 -0
- package/output/core/classes/expression/utils.js +189 -0
- package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
- package/output/core/classes/lookupTable/LookupTable.js +55 -0
- package/output/core/classes/matrix/Matrix.d.ts +227 -0
- package/output/core/classes/matrix/Matrix.js +889 -0
- package/output/core/classes/matrix/Sylvester.d.ts +11 -0
- package/output/core/classes/matrix/Sylvester.js +54 -0
- package/output/core/classes/matrix/functions.d.ts +26 -0
- package/output/core/classes/matrix/functions.js +52 -0
- package/output/core/classes/matrix/utils.d.ts +9 -0
- package/output/core/classes/matrix/utils.js +22 -0
- package/output/core/classes/parser/Parser.d.ts +480 -0
- package/output/core/classes/parser/Parser.js +1812 -0
- package/output/core/classes/parser/Token.d.ts +58 -0
- package/output/core/classes/parser/Token.js +137 -0
- package/output/core/classes/parser/constants.d.ts +160 -0
- package/output/core/classes/parser/constants.js +227 -0
- package/output/core/classes/parser/helpers.d.ts +21 -0
- package/output/core/classes/parser/helpers.js +42 -0
- package/output/core/classes/parser/operations/add.d.ts +15 -0
- package/output/core/classes/parser/operations/add.js +238 -0
- package/output/core/classes/parser/operations/comma.d.ts +7 -0
- package/output/core/classes/parser/operations/comma.js +11 -0
- package/output/core/classes/parser/operations/compare.d.ts +21 -0
- package/output/core/classes/parser/operations/compare.js +461 -0
- package/output/core/classes/parser/operations/divide.d.ts +2 -0
- package/output/core/classes/parser/operations/divide.js +72 -0
- package/output/core/classes/parser/operations/functions.d.ts +46 -0
- package/output/core/classes/parser/operations/functions.js +430 -0
- package/output/core/classes/parser/operations/multiply.d.ts +11 -0
- package/output/core/classes/parser/operations/multiply.js +321 -0
- package/output/core/classes/parser/operations/power.d.ts +48 -0
- package/output/core/classes/parser/operations/power.js +673 -0
- package/output/core/classes/parser/operations/subtract.d.ts +3 -0
- package/output/core/classes/parser/operations/subtract.js +35 -0
- package/output/core/classes/parser/preprocess.d.ts +14 -0
- package/output/core/classes/parser/preprocess.js +259 -0
- package/output/core/classes/parser/scripting/controlFlow.d.ts +121 -0
- package/output/core/classes/parser/scripting/controlFlow.js +355 -0
- package/output/core/classes/parser/scripting/evaluate.d.ts +10 -0
- package/output/core/classes/parser/scripting/evaluate.js +112 -0
- package/output/core/classes/parser/scripting/functions.d.ts +14 -0
- package/output/core/classes/parser/scripting/functions.js +59 -0
- package/output/core/classes/parser/scripting/scope.d.ts +35 -0
- package/output/core/classes/parser/scripting/scope.js +155 -0
- package/output/core/classes/parser/types.d.ts +125 -0
- package/output/core/classes/parser/types.js +2 -0
- package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
- package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
- package/output/core/classes/polynomial/Polynomial.d.ts +500 -0
- package/output/core/classes/polynomial/Polynomial.js +1149 -0
- package/output/core/classes/polynomial/Term.d.ts +222 -0
- package/output/core/classes/polynomial/Term.js +430 -0
- package/output/core/classes/polynomial/functions.d.ts +69 -0
- package/output/core/classes/polynomial/functions.js +126 -0
- package/output/core/classes/polynomial/utils.d.ts +62 -0
- package/output/core/classes/polynomial/utils.js +206 -0
- package/output/core/classes/rational/Rational.d.ts +504 -0
- package/output/core/classes/rational/Rational.js +779 -0
- package/output/core/classes/seq/SEQ.d.ts +13 -0
- package/output/core/classes/seq/SEQ.js +137 -0
- package/output/core/classes/valuesSet/ValuesSet.d.ts +179 -0
- package/output/core/classes/valuesSet/ValuesSet.js +381 -0
- package/output/core/classes/vector/Vector.d.ts +222 -0
- package/output/core/classes/vector/Vector.js +497 -0
- package/output/core/classes/vector/functions.d.ts +28 -0
- package/output/core/classes/vector/functions.js +47 -0
- package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
- package/output/core/common/classes/MathematicalAggregate.js +140 -0
- package/output/core/common/classes/Scope.d.ts +62 -0
- package/output/core/common/classes/Scope.js +122 -0
- package/output/core/common/classes/StructuredEntity.d.ts +55 -0
- package/output/core/common/classes/StructuredEntity.js +151 -0
- package/output/core/common/common.d.ts +63 -0
- package/output/core/common/common.js +279 -0
- package/output/core/common/functions/functions.d.ts +14 -0
- package/output/core/common/functions/functions.js +33 -0
- package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
- package/output/core/common/functions/structuredEntityUtils.js +40 -0
- package/output/core/converters/BaseConverter.d.ts +97 -0
- package/output/core/converters/BaseConverter.js +405 -0
- package/output/core/converters/Converter.d.ts +111 -0
- package/output/core/converters/Converter.js +802 -0
- package/output/core/converters/Pattern.d.ts +71 -0
- package/output/core/converters/Pattern.js +302 -0
- package/output/core/dispatch.d.ts +34 -0
- package/output/core/dispatch.js +304 -0
- package/output/core/errors.d.ts +531 -0
- package/output/core/errors.js +621 -0
- package/output/core/functions/bigint/bigint.d.ts +121 -0
- package/output/core/functions/bigint/bigint.js +392 -0
- package/output/core/functions/bigint/primeFactor.d.ts +49 -0
- package/output/core/functions/bigint/primeFactor.js +267 -0
- package/output/core/functions/bigint/primes.d.ts +1 -0
- package/output/core/functions/bigint/primes.js +11 -0
- package/output/core/functions/build/definitions.d.ts +12 -0
- package/output/core/functions/build/definitions.js +133 -0
- package/output/core/functions/build/index.d.ts +32 -0
- package/output/core/functions/build/index.js +136 -0
- package/output/core/functions/complex.d.ts +90 -0
- package/output/core/functions/complex.js +482 -0
- package/output/core/functions/decimal.d.ts +24 -0
- package/output/core/functions/decimal.js +664 -0
- package/output/core/functions/expand/expand.d.ts +42 -0
- package/output/core/functions/expand/expand.js +376 -0
- package/output/core/functions/fresnelNumeric.d.ts +12 -0
- package/output/core/functions/fresnelNumeric.js +123 -0
- package/output/core/functions/numeric.d.ts +140 -0
- package/output/core/functions/numeric.js +790 -0
- package/output/core/functions/rationalNormalization.d.ts +11 -0
- package/output/core/functions/rationalNormalization.js +117 -0
- package/output/core/functions/setFunction.d.ts +19 -0
- package/output/core/functions/setFunction.js +75 -0
- package/output/core/functions/string.d.ts +26 -0
- package/output/core/functions/string.js +101 -0
- package/output/core/functions/subst.d.ts +90 -0
- package/output/core/functions/subst.js +498 -0
- package/output/core/functions/utils.d.ts +24 -0
- package/output/core/functions/utils.js +51 -0
- package/output/core/types.d.ts +48 -0
- package/output/core/types.js +2 -0
- package/output/index.d.ts +339 -0
- package/output/index.js +715 -0
- package/output/math/defint/defintDecimal.d.ts +37 -0
- package/output/math/defint/defintDecimal.js +320 -0
- package/output/math/defint/defintNative.d.ts +57 -0
- package/output/math/defint/defintNative.js +292 -0
- package/output/math/geometry.d.ts +8 -0
- package/output/math/geometry.js +32 -0
- package/output/math/math.d.ts +655 -0
- package/output/math/math.js +1811 -0
- package/output/math/trig.d.ts +518 -0
- package/output/math/trig.js +1444 -0
- package/output/math/trunc.d.ts +19 -0
- package/output/math/trunc.js +36 -0
- package/output/math/utils.d.ts +60 -0
- package/output/math/utils.js +180 -0
- package/output/solve/classes/DecimalMatrix.d.ts +17 -0
- package/output/solve/classes/DecimalMatrix.js +86 -0
- package/output/solve/classes/FunctionSolver.d.ts +135 -0
- package/output/solve/classes/FunctionSolver.js +433 -0
- package/output/solve/classes/MultivariateSolver.d.ts +84 -0
- package/output/solve/classes/MultivariateSolver.js +240 -0
- package/output/solve/classes/PolynomialSolver.d.ts +85 -0
- package/output/solve/classes/PolynomialSolver.js +292 -0
- package/output/solve/classes/SolutionSet.d.ts +153 -0
- package/output/solve/classes/SolutionSet.js +357 -0
- package/output/solve/classes/Solver.d.ts +17 -0
- package/output/solve/classes/Solver.js +132 -0
- package/output/solve/classes/SymbolicSolver.d.ts +74 -0
- package/output/solve/classes/SymbolicSolver.js +601 -0
- package/output/solve/linsolve.d.ts +51 -0
- package/output/solve/linsolve.js +225 -0
- package/output/solve/solve.d.ts +34 -0
- package/output/solve/solve.js +260 -0
- package/output/solve/solveSystem.d.ts +31 -0
- package/output/solve/solveSystem.js +290 -0
- package/output/solve/utils.d.ts +9 -0
- package/output/solve/utils.js +62 -0
- package/output/utils/array.d.ts +42 -0
- package/output/utils/array.js +98 -0
- package/output/utils/debug.d.ts +131 -0
- package/output/utils/debug.js +295 -0
- package/output/utils/decimal.d.ts +3 -0
- package/output/utils/decimal.js +16 -0
- package/output/utils/numeric.d.ts +14 -0
- package/output/utils/numeric.js +51 -0
- package/output/utils/object.d.ts +26 -0
- package/output/utils/object.js +56 -0
- package/package.json +213 -57
- package/.travis.yml +0 -3
- package/Algebra.js +0 -4568
- package/BREAKING_CHANGES.md +0 -5
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -14
- package/Calculus.js +0 -2675
- package/Extra.js +0 -622
- package/Solve.js +0 -1783
- package/all.js +0 -16
- package/all.min.js +0 -1
- package/gulpfile.js +0 -16
- package/index.html +0 -158
- package/license.txt +0 -19
- package/nerdamer.core.js +0 -12510
- package/spec/LaTeX.spec.js +0 -302
- package/spec/TeXConvert.spec.js +0 -8
- package/spec/algebra.spec.js +0 -287
- package/spec/basic_parser.spec.js +0 -134
- package/spec/build.spec.js +0 -131
- package/spec/calculus.spec.js +0 -183
- package/spec/core.spec.js +0 -2970
- package/spec/extra.spec.js +0 -54
- package/spec/solve.spec.js +0 -126
- package/spec/support/jasmine.json +0 -11
- package/spec/support/utils.js +0 -42
- package/spec/text.spec.js +0 -132
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Assumption = void 0;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const common_1 = require("../../common/common");
|
|
9
|
+
const Expression_1 = require("../expression/Expression");
|
|
10
|
+
const constants_1 = require("../parser/constants");
|
|
11
|
+
const Rational_1 = require("../rational/Rational");
|
|
12
|
+
function isIdentStart(ch) {
|
|
13
|
+
return /[A-Za-z_]/.test(ch);
|
|
14
|
+
}
|
|
15
|
+
function isIdentChar(ch) {
|
|
16
|
+
return /[A-Za-z0-9_]/.test(ch);
|
|
17
|
+
}
|
|
18
|
+
function normalizeAssumptionValue(value) {
|
|
19
|
+
let decimal;
|
|
20
|
+
let exact;
|
|
21
|
+
if (Rational_1.Rational.isRational(value)) {
|
|
22
|
+
exact = Rational_1.Rational.makeCopy(value);
|
|
23
|
+
decimal = exact.toDecimal();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
decimal = typeof value === 'number' || typeof value === 'string' ? new decimal_js_1.default(value) : value;
|
|
27
|
+
if (decimal.isFinite()) {
|
|
28
|
+
exact = Rational_1.Rational.create(decimal.toString());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { value: decimal, exact };
|
|
32
|
+
}
|
|
33
|
+
function compareBoundValues(a, aExact, b, bExact) {
|
|
34
|
+
let retval;
|
|
35
|
+
if (a.isFinite() && b.isFinite()) {
|
|
36
|
+
const left = aExact ?? Rational_1.Rational.create(a.toString());
|
|
37
|
+
const right = bExact ?? Rational_1.Rational.create(b.toString());
|
|
38
|
+
if (left.lt(right)) {
|
|
39
|
+
retval = -1;
|
|
40
|
+
}
|
|
41
|
+
else if (left.gt(right)) {
|
|
42
|
+
retval = 1;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
retval = 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (a.eq(b)) {
|
|
49
|
+
retval = 0;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
retval = a.lt(b) ? -1 : 1;
|
|
53
|
+
}
|
|
54
|
+
return retval;
|
|
55
|
+
}
|
|
56
|
+
function parseNumber(value) {
|
|
57
|
+
const v = String(value).toLowerCase();
|
|
58
|
+
if (v === 'inf' || v === 'infinity' || v === '+inf' || v === '+infinity') {
|
|
59
|
+
return new decimal_js_1.default(Infinity);
|
|
60
|
+
}
|
|
61
|
+
if (v === '-inf' || v === '-infinity') {
|
|
62
|
+
return new decimal_js_1.default(-Infinity);
|
|
63
|
+
}
|
|
64
|
+
const n = new decimal_js_1.default(v);
|
|
65
|
+
if (n.isNaN()) {
|
|
66
|
+
throw new Error(`Invalid Decimal: "${value}"`);
|
|
67
|
+
}
|
|
68
|
+
return n;
|
|
69
|
+
}
|
|
70
|
+
function compareNumericExpressionToBound(x, bound, boundExact) {
|
|
71
|
+
let retval = undefined;
|
|
72
|
+
if (x.isNegInf()) {
|
|
73
|
+
retval = bound.eq(-Infinity) ? 0 : -1;
|
|
74
|
+
}
|
|
75
|
+
else if (x.isPosInf()) {
|
|
76
|
+
retval = bound.eq(Infinity) ? 0 : 1;
|
|
77
|
+
}
|
|
78
|
+
else if (x.isNUM()) {
|
|
79
|
+
if (bound.isFinite()) {
|
|
80
|
+
const boundValue = boundExact ?? Rational_1.Rational.create(bound.toString());
|
|
81
|
+
const numericValue = x.getMultiplier();
|
|
82
|
+
if (numericValue.lt(boundValue)) {
|
|
83
|
+
retval = -1;
|
|
84
|
+
}
|
|
85
|
+
else if (numericValue.gt(boundValue)) {
|
|
86
|
+
retval = 1;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
retval = 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
retval = bound.lt(0) ? 1 : -1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return retval;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Describes the admissible real values of a symbolic variable as one numeric interval.
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* An `Assumption` is an interval constraint, not a symbolic theorem. It can prove
|
|
103
|
+
* relations when the interval bounds force an answer, disprove them when the bounds
|
|
104
|
+
* force the opposite answer, and otherwise reports an unknown result as `undefined`.
|
|
105
|
+
* Two variables having the same admissible interval therefore does not prove that the
|
|
106
|
+
* variables are equal.
|
|
107
|
+
*
|
|
108
|
+
* Instances are immutable. Repeated assumptions for a variable are intersected by
|
|
109
|
+
* the global assumption registry rather than modifying an existing interval.
|
|
110
|
+
*
|
|
111
|
+
* Finite bounds preserve an exact rational value internally. Decimal inputs therefore
|
|
112
|
+
* retain the exact value represented by their decimal text, while Rational inputs such
|
|
113
|
+
* as `1/3` are not rounded through Decimal precision before comparisons are made.
|
|
114
|
+
*
|
|
115
|
+
* The 2.0 assumption vocabulary covers a single real interval with numeric bounds.
|
|
116
|
+
* Integer, parity, complex-domain, relational (`x > y`), union, and general predicate
|
|
117
|
+
* assumptions are not represented by this class.
|
|
118
|
+
*/
|
|
119
|
+
class Assumption {
|
|
120
|
+
endExact;
|
|
121
|
+
startExact;
|
|
122
|
+
/** Runtime tag used by Nerdamer's assumption type guard. */
|
|
123
|
+
dataType = constants_1.ASSUMPTION;
|
|
124
|
+
/** Upper endpoint of the admissible interval. */
|
|
125
|
+
end;
|
|
126
|
+
/** Whether the interval contains exactly one finite value. */
|
|
127
|
+
isSingleton;
|
|
128
|
+
/** Lower endpoint of the admissible interval. */
|
|
129
|
+
start;
|
|
130
|
+
/**
|
|
131
|
+
* Creates a non-empty real interval.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* Infinite endpoints are normalized to open bounds. A zero-width interval is valid
|
|
135
|
+
* only when both endpoints are inclusive, in which case it represents one exact
|
|
136
|
+
* value. Rational inputs retain their exact value even when their Decimal projection
|
|
137
|
+
* is necessarily finite precision.
|
|
138
|
+
*
|
|
139
|
+
* @param start - Lower numeric endpoint.
|
|
140
|
+
* @param end - Upper numeric endpoint.
|
|
141
|
+
* @param startInclusive - Include the lower endpoint when it is finite.
|
|
142
|
+
* @param endInclusive - Include the upper endpoint when it is finite.
|
|
143
|
+
* @throws Error
|
|
144
|
+
* Thrown when a bound is `NaN`, the bounds are reversed, or the interval is empty.
|
|
145
|
+
*/
|
|
146
|
+
constructor(start, end, startInclusive = true, endInclusive = true) {
|
|
147
|
+
const normalizedStart = normalizeAssumptionValue(start);
|
|
148
|
+
const normalizedEnd = normalizeAssumptionValue(end);
|
|
149
|
+
const startValue = normalizedStart.value;
|
|
150
|
+
const endValue = normalizedEnd.value;
|
|
151
|
+
const normalizedStartInclusive = startValue.isFinite() && !!startInclusive;
|
|
152
|
+
const normalizedEndInclusive = endValue.isFinite() && !!endInclusive;
|
|
153
|
+
const boundComparison = startValue.isNaN() || endValue.isNaN()
|
|
154
|
+
? undefined
|
|
155
|
+
: compareBoundValues(startValue, normalizedStart.exact, endValue, normalizedEnd.exact);
|
|
156
|
+
// NaN cannot define an ordered interval, and equal endpoints describe a value
|
|
157
|
+
// only when that point belongs to both sides.
|
|
158
|
+
if (boundComparison === undefined ||
|
|
159
|
+
boundComparison > 0 ||
|
|
160
|
+
(boundComparison === 0 && !(normalizedStartInclusive && normalizedEndInclusive))) {
|
|
161
|
+
throw new Error(`Invalid interval: (${startValue}, ${endValue})`);
|
|
162
|
+
}
|
|
163
|
+
this.start = Object.freeze({
|
|
164
|
+
value: startValue,
|
|
165
|
+
inclusive: normalizedStartInclusive,
|
|
166
|
+
});
|
|
167
|
+
this.end = Object.freeze({
|
|
168
|
+
value: endValue,
|
|
169
|
+
inclusive: normalizedEndInclusive,
|
|
170
|
+
});
|
|
171
|
+
this.startExact = normalizedStart.exact;
|
|
172
|
+
this.endExact = normalizedEnd.exact;
|
|
173
|
+
this.isSingleton =
|
|
174
|
+
boundComparison === 0 && this.start.inclusive && this.end.inclusive;
|
|
175
|
+
Object.freeze(this);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Creates an interval extending upward from `x`.
|
|
179
|
+
*
|
|
180
|
+
* @param x - Lower endpoint.
|
|
181
|
+
* @param inclusive - Whether a finite lower endpoint belongs to the interval.
|
|
182
|
+
* @returns The interval `[x, +∞)` when inclusive, otherwise `(x, +∞)`.
|
|
183
|
+
*/
|
|
184
|
+
static atLeast(x, inclusive = true) {
|
|
185
|
+
return new Assumption(x, Infinity, !!inclusive, false);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Creates an interval extending downward from `x`.
|
|
189
|
+
*
|
|
190
|
+
* @param x - Upper endpoint.
|
|
191
|
+
* @param inclusive - Whether a finite upper endpoint belongs to the interval.
|
|
192
|
+
* @returns The interval `(-∞, x]` when inclusive, otherwise `(-∞, x)`.
|
|
193
|
+
*/
|
|
194
|
+
static atMost(x, inclusive = true) {
|
|
195
|
+
return new Assumption(-Infinity, x, false, !!inclusive);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates the singleton interval containing exactly `x`.
|
|
199
|
+
*
|
|
200
|
+
* @param x - The one admissible value.
|
|
201
|
+
* @returns The closed singleton interval `[x, x]`.
|
|
202
|
+
*/
|
|
203
|
+
static exactly(x) {
|
|
204
|
+
return new Assumption(x, x, true, true);
|
|
205
|
+
}
|
|
206
|
+
static isAssumption(obj) {
|
|
207
|
+
return (0, common_1.isNerdamerNativeType)(obj, constants_1.ASSUMPTION);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Parses one numeric interval constraint such as `x >= 0` or `n < 10`.
|
|
211
|
+
*
|
|
212
|
+
* @remarks
|
|
213
|
+
* Whitespace is ignored. Variable names use the ASCII identifier form
|
|
214
|
+
* `[A-Za-z_][A-Za-z0-9_]*`. Supported operators are `=`, `==`, `>`, `>=`, `<`,
|
|
215
|
+
* and `<=`. Bounds are Decimal-compatible numeric literals; `inf`, `infinity`,
|
|
216
|
+
* `+inf`, `+infinity`, `-inf`, and `-infinity` are also accepted.
|
|
217
|
+
*
|
|
218
|
+
* Expressions such as `x > y`, `x = 1/2`, and property predicates such as
|
|
219
|
+
* `integer(x)` are outside the string assumption grammar. Parser assertive calls may
|
|
220
|
+
* still provide already-evaluated Rational bounds directly.
|
|
221
|
+
*
|
|
222
|
+
* @param expr - Constraint to parse.
|
|
223
|
+
* @returns The parsed symbol and its interval assumption.
|
|
224
|
+
* @throws Error
|
|
225
|
+
* Thrown when the constraint has an invalid identifier, operator, or numeric bound.
|
|
226
|
+
*/
|
|
227
|
+
static parse(expr) {
|
|
228
|
+
if (typeof expr !== 'string') {
|
|
229
|
+
throw new Error(`Invalid assumption: "${String(expr)}"`);
|
|
230
|
+
}
|
|
231
|
+
const s = expr.replace(/\s+/g, '');
|
|
232
|
+
if (!s) {
|
|
233
|
+
throw new Error(`Invalid assumption: "${expr}"`);
|
|
234
|
+
}
|
|
235
|
+
// Must have at least a one-character identifier, operator, and value.
|
|
236
|
+
if (s.length < 3) {
|
|
237
|
+
throw new Error(`Invalid assumption: "${expr}"`);
|
|
238
|
+
}
|
|
239
|
+
let i = 0;
|
|
240
|
+
// Parse the variable identifier first. Assumptions are attached to plain
|
|
241
|
+
// variables rather than arbitrary symbolic expressions.
|
|
242
|
+
if (!isIdentStart(s[i])) {
|
|
243
|
+
throw new Error(`Expected identifier`);
|
|
244
|
+
}
|
|
245
|
+
let j = i + 1;
|
|
246
|
+
while (j < s.length && isIdentChar(s[j])) {
|
|
247
|
+
j++;
|
|
248
|
+
}
|
|
249
|
+
const symbol = s.slice(i, j);
|
|
250
|
+
i = j;
|
|
251
|
+
// Read the comparison operator separately so malformed combinations fail with
|
|
252
|
+
// an unsupported-operator error instead of being misread as part of the value.
|
|
253
|
+
let op = '';
|
|
254
|
+
while (i < s.length) {
|
|
255
|
+
const ch = s[i];
|
|
256
|
+
if (ch === '<' || ch === '>' || ch === '=') {
|
|
257
|
+
op += ch;
|
|
258
|
+
i++;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (!op) {
|
|
265
|
+
throw new Error(`Missing operator`);
|
|
266
|
+
}
|
|
267
|
+
const valueStr = s.slice(i);
|
|
268
|
+
if (!valueStr) {
|
|
269
|
+
throw new Error(`Missing value`);
|
|
270
|
+
}
|
|
271
|
+
const value = parseNumber(valueStr);
|
|
272
|
+
let retval;
|
|
273
|
+
switch (op) {
|
|
274
|
+
case '>':
|
|
275
|
+
retval = { symbol, assumption: Assumption.atLeast(value, false) };
|
|
276
|
+
break;
|
|
277
|
+
case '>=':
|
|
278
|
+
retval = { symbol, assumption: Assumption.atLeast(value, true) };
|
|
279
|
+
break;
|
|
280
|
+
case '<':
|
|
281
|
+
retval = { symbol, assumption: Assumption.atMost(value, false) };
|
|
282
|
+
break;
|
|
283
|
+
case '<=':
|
|
284
|
+
retval = { symbol, assumption: Assumption.atMost(value, true) };
|
|
285
|
+
break;
|
|
286
|
+
case '=':
|
|
287
|
+
case '==':
|
|
288
|
+
retval = { symbol, assumption: Assumption.exactly(value) };
|
|
289
|
+
break;
|
|
290
|
+
default:
|
|
291
|
+
throw new Error(`Unsupported operator "${op}"`);
|
|
292
|
+
}
|
|
293
|
+
return retval;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Tests whether a numeric value belongs to this interval.
|
|
297
|
+
*
|
|
298
|
+
* @param x - Numeric value to test.
|
|
299
|
+
* @returns `true` when `x` satisfies both interval bounds.
|
|
300
|
+
*/
|
|
301
|
+
contains(x) {
|
|
302
|
+
const value = normalizeAssumptionValue(x);
|
|
303
|
+
let retval = !value.value.isNaN();
|
|
304
|
+
if (retval &&
|
|
305
|
+
(compareBoundValues(value.value, value.exact, this.start.value, this.startExact) < 0 ||
|
|
306
|
+
compareBoundValues(value.value, value.exact, this.end.value, this.endExact) > 0)) {
|
|
307
|
+
retval = false;
|
|
308
|
+
}
|
|
309
|
+
else if (retval &&
|
|
310
|
+
compareBoundValues(value.value, value.exact, this.start.value, this.startExact) === 0 &&
|
|
311
|
+
!this.start.inclusive) {
|
|
312
|
+
retval = false;
|
|
313
|
+
}
|
|
314
|
+
else if (retval &&
|
|
315
|
+
compareBoundValues(value.value, value.exact, this.end.value, this.endExact) === 0 &&
|
|
316
|
+
!this.end.inclusive) {
|
|
317
|
+
retval = false;
|
|
318
|
+
}
|
|
319
|
+
return retval;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Determines whether values constrained by this interval are equal to `x`.
|
|
323
|
+
*
|
|
324
|
+
* @remarks
|
|
325
|
+
* Equality is proved only when both sides identify the same single value. It is
|
|
326
|
+
* disproved when the admissible values are disjoint. Overlapping ranges, including
|
|
327
|
+
* identical non-singleton ranges, return `undefined` because equality depends on the
|
|
328
|
+
* actual values chosen from those ranges.
|
|
329
|
+
*
|
|
330
|
+
* @param x - Another interval-constrained value or a numeric expression.
|
|
331
|
+
* @returns `true` when equality is forced, `false` when inequality is forced, or
|
|
332
|
+
* `undefined` when the available information permits either outcome.
|
|
333
|
+
*/
|
|
334
|
+
eq(x) {
|
|
335
|
+
let retval = undefined;
|
|
336
|
+
if (Expression_1.Expression.isExpression(x)) {
|
|
337
|
+
const startComparison = compareNumericExpressionToBound(x, this.start.value, this.startExact);
|
|
338
|
+
const endComparison = compareNumericExpressionToBound(x, this.end.value, this.endExact);
|
|
339
|
+
if (startComparison !== undefined && endComparison !== undefined) {
|
|
340
|
+
if (startComparison < 0 ||
|
|
341
|
+
endComparison > 0 ||
|
|
342
|
+
(startComparison === 0 && !this.start.inclusive) ||
|
|
343
|
+
(endComparison === 0 && !this.end.inclusive)) {
|
|
344
|
+
retval = false;
|
|
345
|
+
}
|
|
346
|
+
else if (this.isSingleton) {
|
|
347
|
+
retval = true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else if (this.isSingleton && x.isSingleton) {
|
|
352
|
+
retval =
|
|
353
|
+
compareBoundValues(this.start.value, this.startExact, x.start.value, x.startExact) === 0;
|
|
354
|
+
}
|
|
355
|
+
else if (!this.overlaps(x)) {
|
|
356
|
+
retval = false;
|
|
357
|
+
}
|
|
358
|
+
return retval;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Returns the exact value represented by a singleton interval.
|
|
362
|
+
*
|
|
363
|
+
* @returns A numeric Expression when this interval is a singleton, otherwise
|
|
364
|
+
* `undefined`.
|
|
365
|
+
*/
|
|
366
|
+
getSingletonValue() {
|
|
367
|
+
let retval;
|
|
368
|
+
if (this.isSingleton && this.startExact) {
|
|
369
|
+
retval = Expression_1.Expression.fromRational(this.startExact);
|
|
370
|
+
}
|
|
371
|
+
return retval;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Determines whether every value in this interval is strictly greater than `x`.
|
|
375
|
+
*
|
|
376
|
+
* @param x - Another interval-constrained value or a numeric expression.
|
|
377
|
+
* @returns `true` when `>` is forced, `false` when `<=` is forced, or `undefined`
|
|
378
|
+
* when the interval information permits both outcomes.
|
|
379
|
+
*/
|
|
380
|
+
gt(x) {
|
|
381
|
+
let retval = undefined;
|
|
382
|
+
if (Expression_1.Expression.isExpression(x)) {
|
|
383
|
+
const startComparison = compareNumericExpressionToBound(x, this.start.value, this.startExact);
|
|
384
|
+
const endComparison = compareNumericExpressionToBound(x, this.end.value, this.endExact);
|
|
385
|
+
if (startComparison !== undefined && endComparison !== undefined) {
|
|
386
|
+
if (startComparison < 0 || (startComparison === 0 && !this.start.inclusive)) {
|
|
387
|
+
retval = true;
|
|
388
|
+
}
|
|
389
|
+
else if (endComparison >= 0) {
|
|
390
|
+
retval = false;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
const startVsEnd = compareBoundValues(this.start.value, this.startExact, x.end.value, x.endExact);
|
|
396
|
+
const endVsStart = compareBoundValues(this.end.value, this.endExact, x.start.value, x.startExact);
|
|
397
|
+
if (startVsEnd > 0 || (startVsEnd === 0 && (!this.start.inclusive || !x.end.inclusive))) {
|
|
398
|
+
retval = true;
|
|
399
|
+
}
|
|
400
|
+
else if (endVsStart <= 0) {
|
|
401
|
+
retval = false;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return retval;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Determines whether every value in this interval is greater than or equal to `x`.
|
|
408
|
+
*
|
|
409
|
+
* @param x - Another interval-constrained value or a numeric expression.
|
|
410
|
+
* @returns `true` when `>=` is forced, `false` when `<` is forced, or `undefined`
|
|
411
|
+
* when the interval information permits both outcomes.
|
|
412
|
+
*/
|
|
413
|
+
gte(x) {
|
|
414
|
+
let retval = undefined;
|
|
415
|
+
if (Expression_1.Expression.isExpression(x)) {
|
|
416
|
+
const startComparison = compareNumericExpressionToBound(x, this.start.value, this.startExact);
|
|
417
|
+
const endComparison = compareNumericExpressionToBound(x, this.end.value, this.endExact);
|
|
418
|
+
if (startComparison !== undefined && endComparison !== undefined) {
|
|
419
|
+
if (startComparison <= 0) {
|
|
420
|
+
retval = true;
|
|
421
|
+
}
|
|
422
|
+
else if (endComparison > 0 || (endComparison === 0 && !this.end.inclusive)) {
|
|
423
|
+
retval = false;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
const startVsEnd = compareBoundValues(this.start.value, this.startExact, x.end.value, x.endExact);
|
|
429
|
+
const endVsStart = compareBoundValues(this.end.value, this.endExact, x.start.value, x.startExact);
|
|
430
|
+
if (startVsEnd >= 0) {
|
|
431
|
+
retval = true;
|
|
432
|
+
}
|
|
433
|
+
else if (endVsStart < 0 ||
|
|
434
|
+
(endVsStart === 0 && (!this.end.inclusive || !x.start.inclusive))) {
|
|
435
|
+
retval = false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return retval;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Intersects this interval with another interval.
|
|
442
|
+
*
|
|
443
|
+
* Endpoint selection uses the exact finite representation retained by each interval,
|
|
444
|
+
* so repeated constraints do not lose rational precision while narrowing the range.
|
|
445
|
+
*
|
|
446
|
+
* @param x - Interval to intersect with this one.
|
|
447
|
+
* @returns The non-empty intersection, or `undefined` when the intervals are disjoint.
|
|
448
|
+
*/
|
|
449
|
+
intersect(x) {
|
|
450
|
+
const startComparison = compareBoundValues(this.start.value, this.startExact, x.start.value, x.startExact);
|
|
451
|
+
const endComparison = compareBoundValues(this.end.value, this.endExact, x.end.value, x.endExact);
|
|
452
|
+
let startValue;
|
|
453
|
+
let startInclusive;
|
|
454
|
+
if (startComparison > 0) {
|
|
455
|
+
startValue = this.startExact ?? this.start.value;
|
|
456
|
+
startInclusive = this.start.inclusive;
|
|
457
|
+
}
|
|
458
|
+
else if (startComparison < 0) {
|
|
459
|
+
startValue = x.startExact ?? x.start.value;
|
|
460
|
+
startInclusive = x.start.inclusive;
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
startValue = this.startExact ?? this.start.value;
|
|
464
|
+
startInclusive = this.start.inclusive && x.start.inclusive;
|
|
465
|
+
}
|
|
466
|
+
let endValue;
|
|
467
|
+
let endInclusive;
|
|
468
|
+
if (endComparison < 0) {
|
|
469
|
+
endValue = this.endExact ?? this.end.value;
|
|
470
|
+
endInclusive = this.end.inclusive;
|
|
471
|
+
}
|
|
472
|
+
else if (endComparison > 0) {
|
|
473
|
+
endValue = x.endExact ?? x.end.value;
|
|
474
|
+
endInclusive = x.end.inclusive;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
endValue = this.endExact ?? this.end.value;
|
|
478
|
+
endInclusive = this.end.inclusive && x.end.inclusive;
|
|
479
|
+
}
|
|
480
|
+
const normalizedStart = normalizeAssumptionValue(startValue);
|
|
481
|
+
const normalizedEnd = normalizeAssumptionValue(endValue);
|
|
482
|
+
const intersectionComparison = compareBoundValues(normalizedStart.value, normalizedStart.exact, normalizedEnd.value, normalizedEnd.exact);
|
|
483
|
+
let retval;
|
|
484
|
+
if (intersectionComparison < 0 ||
|
|
485
|
+
(intersectionComparison === 0 && startInclusive && endInclusive)) {
|
|
486
|
+
retval = new Assumption(startValue, endValue, startInclusive, endInclusive);
|
|
487
|
+
}
|
|
488
|
+
return retval;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Determines whether every value in this interval is strictly less than `x`.
|
|
492
|
+
*
|
|
493
|
+
* @param x - Another interval-constrained value or a numeric expression.
|
|
494
|
+
* @returns `true` when `<` is forced, `false` when `>=` is forced, or `undefined`
|
|
495
|
+
* when the interval information permits both outcomes.
|
|
496
|
+
*/
|
|
497
|
+
lt(x) {
|
|
498
|
+
let retval = undefined;
|
|
499
|
+
if (Expression_1.Expression.isExpression(x)) {
|
|
500
|
+
const startComparison = compareNumericExpressionToBound(x, this.start.value, this.startExact);
|
|
501
|
+
const endComparison = compareNumericExpressionToBound(x, this.end.value, this.endExact);
|
|
502
|
+
if (startComparison !== undefined && endComparison !== undefined) {
|
|
503
|
+
if (endComparison > 0 || (endComparison === 0 && !this.end.inclusive)) {
|
|
504
|
+
retval = true;
|
|
505
|
+
}
|
|
506
|
+
else if (startComparison <= 0) {
|
|
507
|
+
retval = false;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
const endVsStart = compareBoundValues(this.end.value, this.endExact, x.start.value, x.startExact);
|
|
513
|
+
const startVsEnd = compareBoundValues(this.start.value, this.startExact, x.end.value, x.endExact);
|
|
514
|
+
if (endVsStart < 0 || (endVsStart === 0 && (!this.end.inclusive || !x.start.inclusive))) {
|
|
515
|
+
retval = true;
|
|
516
|
+
}
|
|
517
|
+
else if (startVsEnd >= 0) {
|
|
518
|
+
retval = false;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return retval;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Determines whether every value in this interval is less than or equal to `x`.
|
|
525
|
+
*
|
|
526
|
+
* @param x - Another interval-constrained value or a numeric expression.
|
|
527
|
+
* @returns `true` when `<=` is forced, `false` when `>` is forced, or `undefined`
|
|
528
|
+
* when the interval information permits both outcomes.
|
|
529
|
+
*/
|
|
530
|
+
lte(x) {
|
|
531
|
+
let retval = undefined;
|
|
532
|
+
if (Expression_1.Expression.isExpression(x)) {
|
|
533
|
+
const startComparison = compareNumericExpressionToBound(x, this.start.value, this.startExact);
|
|
534
|
+
const endComparison = compareNumericExpressionToBound(x, this.end.value, this.endExact);
|
|
535
|
+
if (startComparison !== undefined && endComparison !== undefined) {
|
|
536
|
+
if (endComparison >= 0) {
|
|
537
|
+
retval = true;
|
|
538
|
+
}
|
|
539
|
+
else if (startComparison < 0 || (startComparison === 0 && !this.start.inclusive)) {
|
|
540
|
+
retval = false;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
const endVsStart = compareBoundValues(this.end.value, this.endExact, x.start.value, x.startExact);
|
|
546
|
+
const startVsEnd = compareBoundValues(this.start.value, this.startExact, x.end.value, x.endExact);
|
|
547
|
+
if (endVsStart <= 0) {
|
|
548
|
+
retval = true;
|
|
549
|
+
}
|
|
550
|
+
else if (startVsEnd > 0 ||
|
|
551
|
+
(startVsEnd === 0 && (!this.start.inclusive || !x.end.inclusive))) {
|
|
552
|
+
retval = false;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return retval;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Tests whether this interval and `x` share at least one admissible value.
|
|
559
|
+
*
|
|
560
|
+
* @param x - Interval to test for overlap.
|
|
561
|
+
* @returns `true` when the intersection is non-empty.
|
|
562
|
+
*/
|
|
563
|
+
overlaps(x) {
|
|
564
|
+
const endVsStart = compareBoundValues(this.end.value, this.endExact, x.start.value, x.startExact);
|
|
565
|
+
const startVsEnd = compareBoundValues(this.start.value, this.startExact, x.end.value, x.endExact);
|
|
566
|
+
let retval = true;
|
|
567
|
+
if (endVsStart < 0 || startVsEnd > 0) {
|
|
568
|
+
retval = false;
|
|
569
|
+
}
|
|
570
|
+
else if (endVsStart === 0) {
|
|
571
|
+
retval = this.end.inclusive && x.start.inclusive;
|
|
572
|
+
}
|
|
573
|
+
else if (startVsEnd === 0) {
|
|
574
|
+
retval = this.start.inclusive && x.end.inclusive;
|
|
575
|
+
}
|
|
576
|
+
return retval;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Tests whether two objects describe the same interval constraint.
|
|
580
|
+
*
|
|
581
|
+
* @remarks
|
|
582
|
+
* This is structural interval equality and is separate from {@link eq}: two different
|
|
583
|
+
* variables may have identical intervals without being known to have the same value.
|
|
584
|
+
*
|
|
585
|
+
* @param x - Interval constraint to compare with this one.
|
|
586
|
+
* @returns `true` when both endpoints and their inclusivity are identical.
|
|
587
|
+
*/
|
|
588
|
+
sameInterval(x) {
|
|
589
|
+
return (compareBoundValues(this.start.value, this.startExact, x.start.value, x.startExact) === 0 &&
|
|
590
|
+
compareBoundValues(this.end.value, this.endExact, x.end.value, x.endExact) === 0 &&
|
|
591
|
+
this.start.inclusive === x.start.inclusive &&
|
|
592
|
+
this.end.inclusive === x.end.inclusive);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Formats the interval using mathematical bracket notation.
|
|
596
|
+
*
|
|
597
|
+
* @returns A representation such as `[0, 10)` or `(-Infinity, Infinity)`.
|
|
598
|
+
*/
|
|
599
|
+
toString() {
|
|
600
|
+
const l = this.start.inclusive ? '[' : '(';
|
|
601
|
+
const r = this.end.inclusive ? ']' : ')';
|
|
602
|
+
return `${l}${this.start.value}, ${this.end.value}${r}`;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
exports.Assumption = Assumption;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ParserEntity } from '../../types';
|
|
2
|
+
export declare function assertEQ(a: ParserEntity, b: ParserEntity): ParserEntity;
|
|
3
|
+
export declare function assertGT(a: ParserEntity, b: ParserEntity): ParserEntity;
|
|
4
|
+
export declare function assertGTE(a: ParserEntity, b: ParserEntity): ParserEntity;
|
|
5
|
+
export declare function assertLT(a: ParserEntity, b: ParserEntity): ParserEntity;
|
|
6
|
+
export declare function assertLTE(a: ParserEntity, b: ParserEntity): ParserEntity;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertEQ = assertEQ;
|
|
4
|
+
exports.assertGT = assertGT;
|
|
5
|
+
exports.assertGTE = assertGTE;
|
|
6
|
+
exports.assertLT = assertLT;
|
|
7
|
+
exports.assertLTE = assertLTE;
|
|
8
|
+
const errors_1 = require("../../errors");
|
|
9
|
+
const Expression_1 = require("../expression/Expression");
|
|
10
|
+
const assume_1 = require("./assume");
|
|
11
|
+
const Assumption_1 = require("./Assumption");
|
|
12
|
+
function assertRelation(a, b, operator) {
|
|
13
|
+
let bound;
|
|
14
|
+
// Assertive parser calls receive evaluated operands. Keep exact numeric values typed
|
|
15
|
+
// all the way into Assumption instead of converting Rational values through Decimal.
|
|
16
|
+
if (Expression_1.Expression.isExpression(b) && b.isNUM()) {
|
|
17
|
+
bound = b.getMultiplier();
|
|
18
|
+
}
|
|
19
|
+
else if (Expression_1.Expression.isExpression(b) && b.isPosInf()) {
|
|
20
|
+
bound = Infinity;
|
|
21
|
+
}
|
|
22
|
+
else if (Expression_1.Expression.isExpression(b) && b.isNegInf()) {
|
|
23
|
+
bound = -Infinity;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new errors_1.UnexpectedInputError((0, errors_1.message)('wrongInput', {
|
|
27
|
+
expected: 'a real numeric value',
|
|
28
|
+
received: String(b),
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
let assumption;
|
|
32
|
+
if (operator === '=') {
|
|
33
|
+
assumption = Assumption_1.Assumption.exactly(bound);
|
|
34
|
+
}
|
|
35
|
+
else if (operator === '>') {
|
|
36
|
+
assumption = Assumption_1.Assumption.atLeast(bound, false);
|
|
37
|
+
}
|
|
38
|
+
else if (operator === '>=') {
|
|
39
|
+
assumption = Assumption_1.Assumption.atLeast(bound, true);
|
|
40
|
+
}
|
|
41
|
+
else if (operator === '<') {
|
|
42
|
+
assumption = Assumption_1.Assumption.atMost(bound, false);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
assumption = Assumption_1.Assumption.atMost(bound, true);
|
|
46
|
+
}
|
|
47
|
+
(0, assume_1.assume)(String(a), assumption);
|
|
48
|
+
return a;
|
|
49
|
+
}
|
|
50
|
+
function assertEQ(a, b) {
|
|
51
|
+
return assertRelation(a, b, '=');
|
|
52
|
+
}
|
|
53
|
+
function assertGT(a, b) {
|
|
54
|
+
return assertRelation(a, b, '>');
|
|
55
|
+
}
|
|
56
|
+
function assertGTE(a, b) {
|
|
57
|
+
return assertRelation(a, b, '>=');
|
|
58
|
+
}
|
|
59
|
+
function assertLT(a, b) {
|
|
60
|
+
return assertRelation(a, b, '<');
|
|
61
|
+
}
|
|
62
|
+
function assertLTE(a, b) {
|
|
63
|
+
return assertRelation(a, b, '<=');
|
|
64
|
+
}
|