stemcmicro
Version:
Computer Algebra System in TypeScript
1,145 lines (1,116 loc) • 2.72 MB
JavaScript
/**
* stemcmicro 0.9.41
* (c) David Geo Holmes david.geo.holmes@gmail.com
* Released under the MIT License.
*/
System.register(['math-expression-native', 'math-expression-atoms', 'math-expression-tree', 'math-expression-context'], (function (exports) {
'use strict';
var native_sym, Native, is_native, code_from_native_sym, log$1, multiply$2, real$2, exp$1, Err, is_rat, is_flt$1, is_str$2, create_sym, is_boo$1, Flt, negOne$1, BigInteger, create_int, create_rat, Rat, Boo, is_sym$1, is_num$1, is_tensor, imu, one$2, is_uom, zero$2, Tensor, Sym, is_err, is_blade, is_hyp$1, is_keyword, is_imu, Str$1, create_keyword_ns, assert_sym$1, create_tensor, Map$1, assert_tensor, booT, booF, create_algebra, create_flt$1, assert_num, QQ, is_lambda, Uom, Cell, Lambda$1, create_str$1, et, epsilon, Hyp, is_map, is_tag, is_jsobject, create_boo, JsObject, assert_jsobject, is_cell, assert_str, assert_map, assert_cell, assert_rat, assert_flt, create_hyp, Keyword$1, booU, bigInt$1, Char, Set, create_sym_ns, Tag, Timestamp, Uuid, is_nil, items_to_cons, is_atom, nil, is_cons, car, cdr, cons$2, assert_cons_or_nil$1, pos_end_items_to_cons, assert_cons$2, is_singleton, SIGN_GT$1, SIGN_LT$1, SIGN_EQ$1;
return {
setters: [function (module) {
native_sym = module.native_sym;
Native = module.Native;
is_native = module.is_native;
code_from_native_sym = module.code_from_native_sym;
log$1 = module.log;
multiply$2 = module.multiply;
real$2 = module.real;
exp$1 = module.exp;
exports({ NATIVE_MAX: module.NATIVE_MAX, NATIVE_MIN: module.NATIVE_MIN, Native: module.Native, code_from_native_sym: module.code_from_native_sym, is_native_sym: module.is_native_sym, native_sym: module.native_sym });
}, function (module) {
Err = module.Err;
is_rat = module.is_rat;
is_flt$1 = module.is_flt;
is_str$2 = module.is_str;
create_sym = module.create_sym;
is_boo$1 = module.is_boo;
Flt = module.Flt;
negOne$1 = module.negOne;
BigInteger = module.BigInteger;
create_int = module.create_int;
create_rat = module.create_rat;
Rat = module.Rat;
Boo = module.Boo;
is_sym$1 = module.is_sym;
is_num$1 = module.is_num;
is_tensor = module.is_tensor;
imu = module.imu;
one$2 = module.one;
is_uom = module.is_uom;
zero$2 = module.zero;
Tensor = module.Tensor;
Sym = module.Sym;
is_err = module.is_err;
is_blade = module.is_blade;
is_hyp$1 = module.is_hyp;
is_keyword = module.is_keyword;
is_imu = module.is_imu;
Str$1 = module.Str;
create_keyword_ns = module.create_keyword_ns;
assert_sym$1 = module.assert_sym;
create_tensor = module.create_tensor;
Map$1 = module.Map;
assert_tensor = module.assert_tensor;
booT = module.booT;
booF = module.booF;
create_algebra = module.create_algebra;
create_flt$1 = module.create_flt;
assert_num = module.assert_num;
QQ = module.QQ;
is_lambda = module.is_lambda;
Uom = module.Uom;
Cell = module.Cell;
Lambda$1 = module.Lambda;
create_str$1 = module.create_str;
et = module.et;
epsilon = module.epsilon;
Hyp = module.Hyp;
is_map = module.is_map;
is_tag = module.is_tag;
is_jsobject = module.is_jsobject;
create_boo = module.create_boo;
JsObject = module.JsObject;
assert_jsobject = module.assert_jsobject;
is_cell = module.is_cell;
assert_str = module.assert_str;
assert_map = module.assert_map;
assert_cell = module.assert_cell;
assert_rat = module.assert_rat;
assert_flt = module.assert_flt;
create_hyp = module.create_hyp;
Keyword$1 = module.Keyword;
booU = module.booU;
bigInt$1 = module.bigInt;
Char = module.Char;
Set = module.Set;
create_sym_ns = module.create_sym_ns;
Tag = module.Tag;
Timestamp = module.Timestamp;
Uuid = module.Uuid;
}, function (module) {
is_nil = module.is_nil;
items_to_cons = module.items_to_cons;
is_atom = module.is_atom;
nil = module.nil;
is_cons = module.is_cons;
car = module.car;
cdr = module.cdr;
cons$2 = module.cons;
assert_cons_or_nil$1 = module.assert_cons_or_nil;
pos_end_items_to_cons = module.pos_end_items_to_cons;
assert_cons$2 = module.assert_cons;
is_singleton = module.is_singleton;
}, function (module) {
SIGN_GT$1 = module.SIGN_GT;
SIGN_LT$1 = module.SIGN_LT;
SIGN_EQ$1 = module.SIGN_EQ;
}],
execute: (function () {
exports({
create_engine: create_engine,
create_script_context: create_script_context,
human_readable_syntax_kind: human_readable_syntax_kind,
roots: roots
});
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* A hook to allow the inspection of errors as they are created.
*/
function hook_create_err(message, pos, end, cause) {
// nil is used typicsall for determining the type property of an Err dynamically, so we'll ignore these.
if (!is_nil(message)) ;
return new Err(message, cause, pos, end);
}
var _Localizable_refCount;
class Localizable {
constructor(message, argList) {
this.message = message;
this.argList = argList;
this.name = "Localizable";
this.type = "localizable";
_Localizable_refCount.set(this, 1);
argList.addRef();
}
addRef() {
var _a;
__classPrivateFieldSet(this, _Localizable_refCount, (_a = __classPrivateFieldGet(this, _Localizable_refCount, "f"), _a++, _a), "f");
}
release() {
var _a;
__classPrivateFieldSet(this, _Localizable_refCount, (_a = __classPrivateFieldGet(this, _Localizable_refCount, "f"), _a--, _a), "f");
if (__classPrivateFieldGet(this, _Localizable_refCount, "f") === 0) {
this.argList.release();
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
contains(needle) {
throw new Error("Method not implemented.");
}
equals(other) {
if (this === other) {
return true;
}
else if (is_localizable(other)) {
if (this.message.key === other.message.key) {
return this.argList.equals(other.argList);
}
else {
return false;
}
}
else {
return false;
}
}
get iscons() {
return false;
}
get isnil() {
return false;
}
toString() {
return `Localizable(${JSON.stringify(this.message)}, ${this.argList})`;
}
}
_Localizable_refCount = new WeakMap();
function is_localizable(expr) {
return expr instanceof Localizable;
}
function diagnostic(message, ...args) {
const argList = items_to_cons(...args);
try {
const msg = new Localizable(message, argList);
try {
return hook_create_err(msg);
}
finally {
msg.release();
}
}
finally {
argList.release();
}
}
const Diagnostics = {
Hello_World: diag(0, "", ""),
Operator_0_cannot_be_applied_to_types_1_and_2: diag(1000, "Operator_0_cannot_be_applied_to_types_1_and_2_1000", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
Property_0_does_not_exist_on_type_1: diag(1001, "Property_0_does_not_exist_on_type_1_1001", "Property '{0}' does not exist on type '{1}'."),
Division_by_zero: diag(1002, "Division_by_zero_1002", "Division by zero.")
};
function diag(code, key, text) {
return { code, key, text };
}
function in_safe_integer_range(a) {
return a.geq(Number.MIN_SAFE_INTEGER) && a.leq(Number.MAX_SAFE_INTEGER);
}
/**
* is_rat(expr) && expr.isInteger
*/
function is_rat_and_integer(expr) {
return is_rat(expr) && expr.isInteger();
}
class ProgrammingError extends Error {
constructor(message) {
super();
this.name = "ProgrammingError";
if (typeof message === "string") {
this.message = message;
}
}
}
/**
* If the expr is not a Rat or Flt then the result is NaN.
* If the expr is a Rat and an integer and in safe range for EcmaScript number then a number is returned.
* If the expr is a Flt and an integer then the number is returned.
*/
function nativeInt(expr) {
if (is_rat(expr)) {
if (expr.isInteger() && in_safe_integer_range(expr.a)) {
return expr.a.toJSNumber();
}
else {
return NaN;
}
}
else if (is_flt$1(expr)) {
if (Math.floor(expr.d) === expr.d) {
return expr.d;
}
else {
return NaN;
}
}
else {
return NaN;
}
}
function nativeStr(expr) {
if (is_atom(expr)) {
if (is_str$2(expr)) {
return expr.str;
}
else {
// The problem here is that expr is Err, it is not propagated.
throw new ProgrammingError(`${expr}: ${expr.type}`);
}
}
else {
throw new ProgrammingError(`${expr}`);
}
}
function is_integer_and_in_safe_number_range(num) {
if (is_rat(num)) {
if (is_rat_and_integer(num) && in_safe_integer_range(num.a)) {
return true;
}
else {
return false;
}
}
else if (is_flt$1(num)) {
if (Math.floor(num.d) === num.d) {
return true;
}
else {
return false;
}
}
else {
throw new Error();
}
}
const SIGN_LT = -1;
const SIGN_EQ = 0;
const SIGN_GT = 1;
/**
* The expression was ignored by the transformer, usually because it did not match the transformer.
*/
const TFLAG_NONE = 0;
/**
* The expression changed as a result of the transformation.
*/
const TFLAG_DIFF = 1 << 0;
/**
* The expression did not change as a result of the transformation because it is stable.
*/
const TFLAG_HALT = 1 << 1;
/**
* Returns true if flags has the "diff" bit set.
*/
function diffFlag(flags) {
return (flags & TFLAG_DIFF) === TFLAG_DIFF;
}
const ALL_FEATURES = ["Blade", "Boo", "Cell", "Flt", "Imu", "Map", "Rat", "Sym", "Tensor", "Uom"];
/**
* Determines how an expression is evaluated.
*/
var Directive$1;
(function (Directive) {
/**
* Convert familiar expressions to canonical form. Mutually exclusive with familiarize.
*/
Directive[Directive["canonicalize"] = 0] = "canonicalize";
/**
* Replace sin with cos. Mutually exclusive with convertCosToSim.
*/
Directive[Directive["convertSinToCos"] = 1] = "convertSinToCos";
/**
* Replace cos with sin. Mutually exclusive with convertSinToCos.
*/
Directive[Directive["convertCosToSin"] = 2] = "convertCosToSin";
/**
* Convert canonical expressions to familiar form. Mutually exclusive with canonicalize.
*/
Directive[Directive["familiarize"] = 3] = "familiarize";
/**
* Is not the same as the expand function.
* Mutually exclusive with factoring.
*/
Directive[Directive["expanding"] = 4] = "expanding";
/**
* Determines whether abs(a + b + c ...) is expanded.
*/
Directive[Directive["expandAbsSum"] = 5] = "expandAbsSum";
/**
* Determines whether cos(a + b + c ...) is expanded.
*/
Directive[Directive["expandCosSum"] = 6] = "expandCosSum";
/**
* Determines whether (a + b + c ...) raised to a positive integer exponent is expanded.
* The default is true.
*/
Directive[Directive["expandPowSum"] = 7] = "expandPowSum";
/**
* Determines whether cos(a + b + c ...) is expanded.
*/
Directive[Directive["expandSinSum"] = 8] = "expandSinSum";
/**
* Determines whether numeric types are converted to floating point numbers for numeric evaluation.
*
* The default value as false.
*/
Directive[Directive["evaluatingAsFloat"] = 9] = "evaluatingAsFloat";
/**
* Determines whether complex numbers are driven towards clock form.
* The other possibilities are polar and rectanglular.
*
* The default value is false.
*/
Directive[Directive["complexAsClock"] = 10] = "complexAsClock";
/**
* Determines whether complex numbers are driven towards polar form.
* The other possibilities are clock and rectanglular.
*
* The default value is false.
*/
Directive[Directive["complexAsPolar"] = 11] = "complexAsPolar";
/**
* Determines whether complex numbers are driven towards rectangular form.
* The other possibilities are clock and polar.
*
* The default value is false.
*/
Directive[Directive["complexAsRectangular"] = 12] = "complexAsRectangular";
/**
* Determines whether exponential functions are converted ti exponential form.
*/
Directive[Directive["convertExpToTrig"] = 13] = "convertExpToTrig";
/**
* Determines whether trigonometric functions are converted to exponential form.
*
* The default is false.
*/
Directive[Directive["convertTrigToExp"] = 14] = "convertTrigToExp";
/**
* Determines whether zero terms are kept in sums in attempt to preserve the dynamic type.
* The alternative is to use a canonical zero value, usually that for rational numbers.
*
* The default value is false.
*/
Directive[Directive["keepZeroTermsInSums"] = 15] = "keepZeroTermsInSums";
/**
* Is not the same as the factor function.
* Mutually exclusive with expanding.
*/
Directive[Directive["factoring"] = 16] = "factoring";
/**
* Determines whether floating point numbers are rendered as EcmaScript numbers.
* If not, floating point numbers are rendered in a proprietary format.
*
* The default value is false.
*/
Directive[Directive["renderFloatAsEcmaScript"] = 17] = "renderFloatAsEcmaScript";
/**
* Determines whether caret token '^' will be used for exponentiation or for the exterior product.
* Using the caret token for exponetitation is common in mathematical tools but not in programming languages.
*
* The default value is false.
*/
Directive[Directive["useCaretForExponentiation"] = 18] = "useCaretForExponentiation";
/**
* Determines whether test funtions will return Boo or Rat values.
*
* The default value is false.
*/
Directive[Directive["useIntegersForPredicates"] = 19] = "useIntegersForPredicates";
Directive[Directive["useParenForTensors"] = 20] = "useParenForTensors";
Directive[Directive["depth"] = 21] = "depth";
Directive[Directive["drawing"] = 22] = "drawing";
Directive[Directive["nonstop"] = 23] = "nonstop";
Directive[Directive["forceFixedPrintout"] = 24] = "forceFixedPrintout";
Directive[Directive["maxFixedPrintoutDigits"] = 25] = "maxFixedPrintoutDigits";
Directive[Directive["printMode"] = 26] = "printMode";
Directive[Directive["codeGen"] = 27] = "codeGen";
})(Directive$1 || (Directive$1 = {}));
function flag_from_directive(value) {
return value > 0;
}
function directive_from_flag(value) {
if (typeof value === "boolean") {
return value ? 1 : 0;
}
else {
return 0;
}
}
const MODE_EXPANDING = 1;
const MODE_FACTORING = 2;
const MODE_SEQUENCE = [MODE_EXPANDING, MODE_FACTORING];
const MODE_FLAGS_ALL = MODE_EXPANDING | MODE_FACTORING;
const PHASE_FLAGS_EXPANDING_UNION_FACTORING = MODE_EXPANDING | MODE_FACTORING;
let Builder$l = class Builder {
constructor(extension) {
this.extension = extension;
}
create(config) {
return new this.extension(config);
}
};
function mkbuilder(extension) {
return new Builder$l(extension);
}
/**
* A convenience function for constructing transform results and peforming correct reference counting.
* If the expressions are the same then we return the oldExpr (it may have better positional metadata), and TFLAG_NONE.
* If the expressions differ, we return newExpr and TFLAG_DIFF.
*
*/
function wrap_as_transform(newExpr, oldExpr) {
if (newExpr.equals(oldExpr)) {
// If the expressions have the same value, we return the oldExpr because it may have better meta information
// such as pos and end properties.
oldExpr.addRef();
return [TFLAG_NONE, oldExpr];
}
else {
newExpr.addRef();
return [TFLAG_DIFF, newExpr];
}
}
var _AtomExtensionFromExprHandler_type, _AtomExtensionFromExprHandler_guard;
class AtomExtensionFromExprHandler {
constructor(handler, type, guard) {
this.handler = handler;
_AtomExtensionFromExprHandler_type.set(this, void 0);
_AtomExtensionFromExprHandler_guard.set(this, void 0);
__classPrivateFieldSet(this, _AtomExtensionFromExprHandler_type, type, "f");
__classPrivateFieldSet(this, _AtomExtensionFromExprHandler_guard, guard, "f");
}
get hash() {
return __classPrivateFieldGet(this, _AtomExtensionFromExprHandler_type, "f");
}
get name() {
return __classPrivateFieldGet(this, _AtomExtensionFromExprHandler_type, "f");
}
iscons() {
return false;
}
operator() {
throw new ProgrammingError();
}
isKind(expr) {
if (is_atom(expr)) {
return __classPrivateFieldGet(this, _AtomExtensionFromExprHandler_guard, "f").call(this, expr);
}
else {
return false;
}
}
toHumanString(expr, $) {
return nativeStr(this.handler.dispatch(expr, native_sym(Native.human), nil, $));
}
toInfixString(expr, $) {
return nativeStr(this.handler.dispatch(expr, native_sym(Native.infix), nil, $));
}
toLatexString(expr, $) {
return nativeStr(this.handler.dispatch(expr, native_sym(Native.latex), nil, $));
}
toListString(expr, $) {
return nativeStr(this.handler.dispatch(expr, native_sym(Native.sexpr), nil, $));
}
evaluate(opr, argList, $) {
throw new Error("evaluate method not implemented.");
}
transform(expr, env) {
const newExpr = this.valueOf(expr, env);
try {
return wrap_as_transform(newExpr, expr);
}
finally {
newExpr.release();
}
}
valueOf(expr, env) {
return this.dispatch(expr, create_sym("valueof"), nil, env);
}
binL(lhs, opr, rhs, env) {
return this.handler.binL(lhs, opr, rhs, env);
}
binR(rhs, opr, lhs, env) {
return this.handler.binR(rhs, opr, lhs, env);
}
dispatch(target, opr, argList, env) {
const response = this.handler.dispatch(target, opr, argList, env);
if (is_nil(response)) {
return diagnostic(Diagnostics.Property_0_does_not_exist_on_type_1, opr, create_sym(target.type));
}
else {
return response;
}
}
subst(expr, oldExpr, newExpr, env) {
throw new Error("subst method not implemented.");
}
test(expr, opr, env) {
const response = this.handler.dispatch(expr, opr, nil, env);
if (is_boo$1(response)) {
return response.isTrue();
}
else {
throw diagnostic(Diagnostics.Property_0_does_not_exist_on_type_1, opr, create_sym(expr.type));
}
}
}
_AtomExtensionFromExprHandler_type = new WeakMap(), _AtomExtensionFromExprHandler_guard = new WeakMap();
class AtomExtensionBuilderFromExprHandlerBuilder {
constructor(builder, type, guard) {
this.builder = builder;
this.type = type;
this.guard = guard;
}
create(config) {
return new AtomExtensionFromExprHandler(this.builder.create(), this.type, this.guard);
}
}
/**
*
*/
class ExtensionFromExprHandler {
constructor(handler) {
this.handler = handler;
}
get hash() {
throw new Error("Method not implemented.");
}
get name() {
throw new Error("Method not implemented.");
}
iscons() {
throw new Error("Method not implemented.");
}
operator() {
throw new Error("Method not implemented.");
}
isKind(expr, $) {
throw new Error("Method not implemented.");
}
subst(expr, oldExpr, newExpr, $) {
throw new Error("Method not implemented.");
}
toHumanString(expr, $) {
throw new Error("Method not implemented.");
}
toInfixString(expr, $) {
throw new Error("Method not implemented.");
}
toLatexString(expr, $) {
throw new Error("Method not implemented.");
}
toListString(expr, $) {
throw new Error("Method not implemented.");
}
evaluate(opr, argList, $) {
throw new Error("Method not implemented.");
}
transform(expr, $) {
throw new Error("Method not implemented.");
}
valueOf(expr, $) {
throw new Error("Method not implemented.");
}
test(atom, opr, env) {
return this.handler.test(atom, opr, env);
}
binL(lhs, opr, rhs, env) {
return this.handler.binL(lhs, opr, rhs, env);
}
binR(rhs, opr, lhs, env) {
return this.handler.binR(rhs, opr, lhs, env);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
dispatch(target, opr, argList, env) {
return this.handler.dispatch(target, opr, argList, env);
}
}
/**
* Constructs a floating point number object from a number primitive.
* @param value The floating point number value.
* @param pos The start position of the number in the source text.
* @param end The end position of the number in the source text.
*/
function create_flt(value, pos, end) {
if (value === zeroAsFlt.d) {
return zeroAsFlt;
}
if (value === oneAsFlt.d) {
return oneAsFlt;
}
if (value === negOneAsFlt.d) {
return negOneAsFlt;
}
if (value === twoAsFlt.d) {
return twoAsFlt;
}
if (value === negTwoAsFlt.d) {
return negTwoAsFlt;
}
// console.lg("wrap_as_flt", value);
return new Flt(value, pos, end);
}
const zeroAsFlt = new Flt(0.0);
const oneAsFlt = new Flt(1.0);
const twoAsFlt = new Flt(2.0);
const piAsFlt = new Flt(Math.PI);
new Flt(1e-6);
const eAsFlt = new Flt(Math.E);
const negOneAsFlt = new Flt(-1.0);
const negTwoAsFlt = new Flt(-2.0);
// The canonical keys for various mathematical symbols.
// These MUST be unique.
// These MUST be stable over time.
// Think of these as a universal standard identifying mathematical standards.
// Implementations do not need to couple to this file, but they should use it as a standard.
// TODO: Don't need to define functions; these are pluggable and should not be centrally defined.
const MATH_ADD$1 = native_sym(Native.add);
const MATH_COS = native_sym(Native.cos);
const MATH_TAN = native_sym(Native.tan);
const MATH_SUB = native_sym(Native.subtract);
const MATH_MUL$2 = native_sym(Native.multiply);
const MATH_DIV = native_sym(Native.divide);
const MATH_POW$2 = native_sym(Native.pow);
const MATH_OUTER$1 = native_sym(Native.outer);
const MATH_INNER$1 = native_sym(Native.inner);
const MATH_INV = native_sym(Native.inv);
const MATH_LCO$1 = native_sym(Native.lco);
const MATH_RCO$1 = native_sym(Native.rco);
const MATH_SIN$1 = native_sym(Native.sin);
native_sym(Native.succ);
native_sym(Native.pred);
native_sym(Native.E);
const MATH_PI$2 = native_sym(Native.PI);
const MATH_FACTORIAL = native_sym(Native.factorial);
native_sym(Native.iszero);
native_sym(Native.testlt);
native_sym(Native.testgt);
native_sym(Native.testle);
/**
* ':'
*/
create_sym(":");
/**
* tau(x) = 2 * pi * x
*/
native_sym(Native.tau);
const MATH_IMU$1 = native_sym(Native.IMU);
//
// WARNING This module should not depend on anything.
// The imports below are for types only and will not create a dependency.
//
var PrintMode;
(function (PrintMode) {
/**
* Two-dimensional rendering.
*/
PrintMode[PrintMode["Ascii"] = 0] = "Ascii";
/**
* Like infix but with extra whitespace and may have multiplication operators removed.
*/
PrintMode[PrintMode["Human"] = 1] = "Human";
/**
* Infix is how we normally write math but whitespace is removed and may be parsed by a computer.
*/
PrintMode[PrintMode["Infix"] = 2] = "Infix";
/**
* MathJax compatible.
*/
PrintMode[PrintMode["LaTeX"] = 3] = "LaTeX";
/**
* Symbolic Expression is LISP-like.
*/
PrintMode[PrintMode["SExpr"] = 4] = "SExpr";
PrintMode[PrintMode["EcmaScript"] = 5] = "EcmaScript";
})(PrintMode || (PrintMode = {}));
class Defs {
constructor() {
/**
* top of stack
*/
this.tos = 0;
/**
* The program execution stack.
* TODO: This should be moved to the $ to achieve isolation of executions.
* It should also not allow undefined and null values as this requires casting elsewhere.
* Encapsulation with assertion may help.
*/
this.stack = [];
// Nothing to see here yet.
}
}
/**
* Global (singleton) instance of Defs.
*/
const defs = new Defs();
/**
* This should only be used for scripting when the stack is being used.
* Otherwise, there should be a convenient way to throw structured Error(s).
*/
function halt(s) {
move_top_of_stack(0);
throw new Error(`Stop: ${s}`);
}
function move_top_of_stack(stackPos) {
if (defs.tos <= stackPos) {
// we are moving the stack pointer
// "up" the stack (as if we were doing a push)
defs.tos = stackPos;
return;
}
// we are moving the stack pointer
// "down" the stack i.e. as if we were
// doing a pop, we can zero-
// out all the elements that we pass
// so we can reclaim the memory
while (defs.tos > stackPos) {
defs.stack[defs.tos] = null;
defs.tos--;
}
}
function noexpand_unary(func, arg, $) {
$.pushDirective(Directive$1.expanding, 0);
try {
return func(arg, $);
}
finally {
$.popDirective();
}
}
function noexpand_binary(func, lhs, rhs, $) {
$.pushDirective(Directive$1.expanding, 0);
try {
return func(lhs, rhs, $);
}
finally {
$.popDirective();
}
}
function doexpand_unary(func, arg, $) {
$.pushDirective(Directive$1.expanding, 1);
try {
return func(arg, $);
}
finally {
$.popDirective();
}
}
function doexpand_binary(func, lhs, rhs, $) {
$.pushDirective(Directive$1.expanding, 1);
try {
return func(lhs, rhs, $);
}
finally {
$.popDirective();
}
}
/**
*
*/
class DynamicConstants {
static NegOne($) {
return $.getDirective(Directive$1.evaluatingAsFloat) ? negOneAsFlt : negOne$1;
}
static PI($) {
return $.getDirective(Directive$1.evaluatingAsFloat) ? piAsFlt : MATH_PI$2;
}
}
function mmul(a, b) {
return a.multiply(b);
}
function mdiv(a, b) {
return a.divide(b);
}
function mmod(a, b) {
return a.mod(b);
}
// return both quotient and remainder of a/b
// we'd have this method as divmod(number)
// but obviously doesn't change the passed parameters
function mdivrem(a, b) {
const toReturn = a.divmod(b);
return [toReturn.quotient, toReturn.remainder];
}
// Bignum power
function mpow(a, n) {
return a.pow(n);
}
function is_flt(expr) {
return expr instanceof Flt;
}
const BASE = 1e7;
const MAX_INT = 9007199254740992;
const DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
function isPrecise(n) {
return -MAX_INT < n && n < MAX_INT;
}
function truncate(n) {
if (n > 0)
return Math.floor(n);
return Math.ceil(n);
}
const LOBMASK_I = 1 << 30;
function roughLOB(n) {
// get lowestOneBit (rough)
if (n instanceof BigInteger) {
const x = n.value | BigInt(LOBMASK_I);
return x & -x;
}
else {
throw new Error();
}
}
function max(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.greater(b) ? a : b;
}
function min(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.lesser(b) ? a : b;
}
function gcd$1(a, b) {
a = parseValue(a).abs();
b = parseValue(b).abs();
if (a.equals(b))
return a;
if (a.isZero())
return b;
if (b.isZero())
return a;
let c = cache[1];
let d;
while (a.isEven() && b.isEven()) {
d = min(roughLOB(a), roughLOB(b));
a = a.divide(d);
b = b.divide(d);
c = c.multiply(d);
}
while (a.isEven()) {
a = a.divide(roughLOB(a));
}
do {
let t;
while (b.isEven()) {
b = b.divide(roughLOB(b));
}
if (a.greater(b)) {
t = b;
b = a;
a = t;
}
b = b.subtract(a);
} while (!b.isZero());
return c.isUnit() ? a : a.multiply(c);
}
function lcm$1(a, b) {
a = parseValue(a).abs();
b = parseValue(b).abs();
return a.divide(gcd$1(a, b)).multiply(b);
}
function randBetween(a, b, rng) {
const iA = parseValue(a);
const iB = parseValue(b);
const usedRNG = rng || Math.random;
const low = min(iA, iB);
const high = max(iA, iB);
const range = high.subtract(low).add(1);
const digits = toBase(range, BASE).value;
const result = [];
let restricted = true;
for (let i = 0; i < digits.length; i++) {
const top = restricted ? digits[i] + (i + 1 < digits.length ? digits[i + 1] / BASE : 0) : BASE;
const digit = truncate(usedRNG() * top);
result.push(digit);
if (digit < digits[i]) {
restricted = false;
}
}
return low.add(Integer.fromArray(result, BASE, false));
}
const parseBase = function (input, radix, alphabet, caseSensitive) {
alphabet = alphabet || DEFAULT_ALPHABET;
let text = String(input);
if (!caseSensitive) {
text = text.toLowerCase();
alphabet = alphabet.toLowerCase();
}
const length = text.length;
const absBase = Math.abs(radix);
const alphabetValues = {};
for (let i = 0; i < alphabet.length; i++) {
alphabetValues[alphabet[i]] = i;
}
for (let i = 0; i < length; i++) {
const c = text[i];
if (c === "-")
continue;
if (c in alphabetValues) {
if (alphabetValues[c] >= absBase) {
if (c === "1" && absBase === 1)
continue;
throw new Error(c + " is not a valid digit in base " + radix + ".");
}
}
}
const base = parseValue(radix);
const digits = [];
const isNegative = text[0] === "-";
for (let i = isNegative ? 1 : 0; i < text.length; i++) {
const c = text[i];
if (c in alphabetValues)
digits.push(parseValue(alphabetValues[c]));
else if (c === "<") {
const start = i;
do {
i++;
} while (text[i] !== ">" && i < text.length);
digits.push(parseValue(text.slice(start + 1, i)));
}
else
throw new Error(c + " is not a valid character");
}
return parseBaseFromArray(digits, base, isNegative);
};
function parseBaseFromArray(digits, base, isNegative) {
let val = cache[0];
let pow = cache[1];
for (let i = digits.length - 1; i >= 0; i--) {
val = val.add(digits[i].multiply(pow));
pow = pow.multiply(base);
}
return isNegative ? val.negate() : val;
}
function toBase(n, radix) {
const base = bigInt(radix);
if (base.isZero()) {
if (n.isZero())
return { value: [0], isNegative: false };
throw new Error("Cannot convert nonzero numbers to base 0.");
}
if (base.equals(-1)) {
if (n.isZero())
return { value: [0], isNegative: false };
// Creating a variable for the returned value as a means to bypass the type error...
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const values = [];
if (n.isNegative()) {
return {
// eslint-disable-next-line prefer-spread
value: values.concat.apply([], Array.apply(null, Array(-n.toJSNumber())).map(Array.prototype.valueOf, [1, 0])),
isNegative: false
};
}
// eslint-disable-next-line prefer-spread
const arr = Array.apply(null, Array(n.toJSNumber() - 1)).map(Array.prototype.valueOf, [0, 1]);
arr.unshift([1]);
return {
// eslint-disable-next-line prefer-spread
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: values.concat.apply([], arr),
isNegative: false
};
}
let neg = false;
if (n.isNegative() && base.isPositive()) {
neg = true;
n = n.abs();
}
if (base.isUnit()) {
if (n.isZero())
return { value: [0], isNegative: false };
return {
// eslint-disable-next-line prefer-spread
value: Array.apply(null, Array(n.toJSNumber())).map(Number.prototype.valueOf, 1),
isNegative: neg
};
}
const out = [];
let left = n;
while (left.isNegative() || left.compareAbs(base) >= 0) {
const divmod = left.divmod(base);
left = divmod.quotient;
let digit = divmod.remainder;
if (digit.isNegative()) {
digit = base.minus(digit).abs();
left = left.next();
}
out.push(digit.toJSNumber());
}
out.push(left.toJSNumber());
return { value: out.reverse(), isNegative: neg };
}
function parseStringValue(v) {
if (isPrecise(+v)) {
const x = +v;
if (x === truncate(x)) {
return new BigInteger(BigInt(x));
}
throw new Error("Invalid integer: " + v);
}
const sign = v[0] === "-";
if (sign)
v = v.slice(1);
const split = v.split(/e/i);
if (split.length > 2)
throw new Error("Invalid integer: " + split.join("e"));
if (split.length === 2) {
let expo = split[1];
if (expo[0] === "+")
expo = expo.slice(1);
let exp = +expo;
if (exp !== truncate(exp) || !isPrecise(exp))
throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
let text = split[0];
const decimalPlace = text.indexOf(".");
if (decimalPlace >= 0) {
exp -= text.length - decimalPlace - 1;
text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
}
if (exp < 0)
throw new Error("Cannot include negative exponent part for integers");
text += new Array(exp + 1).join("0");
v = text;
}
const isValid = /^([0-9][0-9]*)$/.test(v);
if (!isValid)
throw new Error("Invalid integer: " + v);
return new BigInteger(BigInt(sign ? "-" + v : v));
}
function parseNumberValue(v) {
return new BigInteger(BigInt(v));
}
function parseValue(v) {
if (typeof v === "number") {
return parseNumberValue(v);
}
if (typeof v === "string") {
return parseStringValue(v);
}
if (typeof v === "bigint") {
return new BigInteger(v);