@cavelang/solver 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +2155 -3
  2. package/dist/src/adapter.d.ts +6 -0
  3. package/dist/src/adapter.d.ts.map +1 -1
  4. package/dist/src/adapter.js +3 -0
  5. package/dist/src/adapter.js.map +1 -1
  6. package/dist/src/balanced-reduce.d.ts +3 -0
  7. package/dist/src/balanced-reduce.d.ts.map +1 -0
  8. package/dist/src/balanced-reduce.js +10 -0
  9. package/dist/src/balanced-reduce.js.map +1 -0
  10. package/dist/src/canonical-owned.d.ts +5 -0
  11. package/dist/src/canonical-owned.d.ts.map +1 -0
  12. package/dist/src/canonical-owned.js +206 -0
  13. package/dist/src/canonical-owned.js.map +1 -0
  14. package/dist/src/canonical.d.ts +3 -2
  15. package/dist/src/canonical.d.ts.map +1 -1
  16. package/dist/src/canonical.js +12 -85
  17. package/dist/src/canonical.js.map +1 -1
  18. package/dist/src/capability.d.ts.map +1 -1
  19. package/dist/src/capability.js +43 -33
  20. package/dist/src/capability.js.map +1 -1
  21. package/dist/src/clone.d.ts +3 -0
  22. package/dist/src/clone.d.ts.map +1 -0
  23. package/dist/src/clone.js +54 -0
  24. package/dist/src/clone.js.map +1 -0
  25. package/dist/src/constant-sign.d.ts +5 -0
  26. package/dist/src/constant-sign.d.ts.map +1 -0
  27. package/dist/src/constant-sign.js +54 -0
  28. package/dist/src/constant-sign.js.map +1 -0
  29. package/dist/src/context.d.ts +6 -0
  30. package/dist/src/context.d.ts.map +1 -0
  31. package/dist/src/context.js +151 -0
  32. package/dist/src/context.js.map +1 -0
  33. package/dist/src/diagnostic-text.d.ts +3 -0
  34. package/dist/src/diagnostic-text.d.ts.map +1 -0
  35. package/dist/src/diagnostic-text.js +5 -0
  36. package/dist/src/diagnostic-text.js.map +1 -0
  37. package/dist/src/evaluate-expression.d.ts +4 -0
  38. package/dist/src/evaluate-expression.d.ts.map +1 -0
  39. package/dist/src/evaluate-expression.js +24 -0
  40. package/dist/src/evaluate-expression.js.map +1 -0
  41. package/dist/src/exact.d.ts +2 -0
  42. package/dist/src/exact.d.ts.map +1 -1
  43. package/dist/src/exact.js +125 -28
  44. package/dist/src/exact.js.map +1 -1
  45. package/dist/src/explain.d.ts +4 -0
  46. package/dist/src/explain.d.ts.map +1 -1
  47. package/dist/src/explain.js +330 -91
  48. package/dist/src/explain.js.map +1 -1
  49. package/dist/src/explanation-budget.d.ts +14 -0
  50. package/dist/src/explanation-budget.d.ts.map +1 -0
  51. package/dist/src/explanation-budget.js +46 -0
  52. package/dist/src/explanation-budget.js.map +1 -0
  53. package/dist/src/expression-key.d.ts +8 -0
  54. package/dist/src/expression-key.d.ts.map +1 -0
  55. package/dist/src/expression-key.js +54 -0
  56. package/dist/src/expression-key.js.map +1 -0
  57. package/dist/src/fraction-product.d.ts +3 -0
  58. package/dist/src/fraction-product.d.ts.map +1 -0
  59. package/dist/src/fraction-product.js +13 -0
  60. package/dist/src/fraction-product.js.map +1 -0
  61. package/dist/src/fraction-sum.d.ts +3 -0
  62. package/dist/src/fraction-sum.d.ts.map +1 -0
  63. package/dist/src/fraction-sum.js +23 -0
  64. package/dist/src/fraction-sum.js.map +1 -0
  65. package/dist/src/integer-gcd.d.ts +3 -0
  66. package/dist/src/integer-gcd.d.ts.map +1 -0
  67. package/dist/src/integer-gcd.js +50 -0
  68. package/dist/src/integer-gcd.js.map +1 -0
  69. package/dist/src/linear.d.ts +2 -1
  70. package/dist/src/linear.d.ts.map +1 -1
  71. package/dist/src/linear.js +85 -17
  72. package/dist/src/linear.js.map +1 -1
  73. package/dist/src/numeric-size.d.ts +2 -0
  74. package/dist/src/numeric-size.d.ts.map +1 -0
  75. package/dist/src/numeric-size.js +33 -0
  76. package/dist/src/numeric-size.js.map +1 -0
  77. package/dist/src/options.d.ts +4 -0
  78. package/dist/src/options.d.ts.map +1 -0
  79. package/dist/src/options.js +18 -0
  80. package/dist/src/options.js.map +1 -0
  81. package/dist/src/result.d.ts +4 -0
  82. package/dist/src/result.d.ts.map +1 -0
  83. package/dist/src/result.js +29 -0
  84. package/dist/src/result.js.map +1 -0
  85. package/dist/src/solve.d.ts.map +1 -1
  86. package/dist/src/solve.js +34 -3
  87. package/dist/src/solve.js.map +1 -1
  88. package/dist/src/validate.d.ts +5 -0
  89. package/dist/src/validate.d.ts.map +1 -1
  90. package/dist/src/validate.js +323 -65
  91. package/dist/src/validate.js.map +1 -1
  92. package/dist/src/workflow.d.ts.map +1 -1
  93. package/dist/src/workflow.js +98 -26
  94. package/dist/src/workflow.js.map +1 -1
  95. package/package.json +2 -2
  96. package/src/adapter.ts +9 -0
  97. package/src/balanced-reduce.ts +9 -0
  98. package/src/canonical-owned.ts +186 -0
  99. package/src/canonical.ts +14 -90
  100. package/src/capability.ts +41 -30
  101. package/src/clone.ts +47 -0
  102. package/src/constant-sign.ts +59 -0
  103. package/src/context.ts +114 -0
  104. package/src/diagnostic-text.ts +4 -0
  105. package/src/evaluate-expression.ts +21 -0
  106. package/src/exact.ts +122 -27
  107. package/src/explain.ts +342 -94
  108. package/src/explanation-budget.ts +47 -0
  109. package/src/expression-key.ts +45 -0
  110. package/src/fraction-product.ts +10 -0
  111. package/src/fraction-sum.ts +20 -0
  112. package/src/integer-gcd.ts +47 -0
  113. package/src/linear.ts +82 -16
  114. package/src/numeric-size.ts +26 -0
  115. package/src/options.ts +18 -0
  116. package/src/result.ts +28 -0
  117. package/src/solve.ts +34 -3
  118. package/src/validate.ts +312 -66
  119. package/src/workflow.ts +92 -26
@@ -0,0 +1,54 @@
1
+ import { types } from 'node:util';
2
+ /** Inspect descriptors without evaluating accessors or touching proxy traps. */
3
+ const portable = (input) => {
4
+ const pending = [input];
5
+ const seen = new WeakSet();
6
+ while (pending.length > 0) {
7
+ const value = pending.pop();
8
+ if (typeof value === 'function' || typeof value === 'symbol')
9
+ return false;
10
+ if (value === null || typeof value !== 'object' || seen.has(value))
11
+ continue;
12
+ if (types.isProxy(value))
13
+ return false;
14
+ seen.add(value);
15
+ const prototype = Object.getPrototypeOf(value);
16
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
17
+ return false;
18
+ for (const key of Object.keys(value)) {
19
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
20
+ if (!Object.hasOwn(descriptor, 'value'))
21
+ return false;
22
+ pending.push(descriptor.value);
23
+ }
24
+ }
25
+ return true;
26
+ };
27
+ /** Copy portable records/arrays without native structured-clone recursion. */
28
+ export const clone = (input) => {
29
+ if (!portable(input))
30
+ return structuredClone(input);
31
+ const copies = new WeakMap();
32
+ const pending = [];
33
+ const allocate = (value) => {
34
+ if (value === null || typeof value !== 'object')
35
+ return value;
36
+ const previous = copies.get(value);
37
+ if (previous !== undefined)
38
+ return previous;
39
+ const target = Array.isArray(value) ? new Array(value.length) : {};
40
+ copies.set(value, target);
41
+ pending.push({ source: value, target });
42
+ return target;
43
+ };
44
+ const result = allocate(input);
45
+ while (pending.length > 0) {
46
+ const { source, target } = pending.pop();
47
+ for (const key of Object.keys(source)) {
48
+ const copied = allocate(source[key]);
49
+ Object.defineProperty(target, key, { value: copied, enumerable: true, writable: true, configurable: true });
50
+ }
51
+ }
52
+ return result;
53
+ };
54
+ //# sourceMappingURL=clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/clone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Expression } from './model.ts';
2
+ import * as Exact from './exact.ts';
3
+ export type Sign = -1 | 0 | 1 | undefined;
4
+ export declare const constantSign: (expression: Expression, cache: WeakMap<Expression, Sign>, literal?: (value: Expression) => Exact.Normalized) => Sign;
5
+ //# sourceMappingURL=constant-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-sign.d.ts","sourceRoot":"","sources":["../../src/constant-sign.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAGnC,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAA;AA8CzC,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,OAAO,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAChC,UAAS,CAAC,KAAK,EAAE,UAAU,KAAK,KAAK,CAAC,UAIrC,KACA,IAAuE,CAAA"}
@@ -0,0 +1,54 @@
1
+ import * as Exact from "./exact.js";
2
+ import { evaluate } from "./evaluate-expression.js";
3
+ const addSigns = (left, right) => left === undefined || right === undefined ? undefined : left === 0 ? right : right === 0 || left === right ? left : undefined;
4
+ /** Prove a constant's sign without constructing large rational intermediates. */
5
+ function* signSteps(expression, literal) {
6
+ switch (expression.kind) {
7
+ case 'literal': {
8
+ if (expression.sort !== 'int' && expression.sort !== 'real')
9
+ return undefined;
10
+ const value = literal(expression);
11
+ return value.numerator === '0' ? 0 : value.numerator.startsWith('-') ? -1 : 1;
12
+ }
13
+ case 'negate': {
14
+ const sign = yield expression.value;
15
+ return sign === undefined ? undefined : -sign;
16
+ }
17
+ case 'add': {
18
+ let sign = 0;
19
+ for (const operand of expression.operands) {
20
+ sign = addSigns(sign, yield operand);
21
+ if (sign === undefined)
22
+ return undefined;
23
+ }
24
+ return sign;
25
+ }
26
+ case 'subtract': {
27
+ const left = yield expression.left;
28
+ const right = yield expression.right;
29
+ return addSigns(left, right === undefined ? undefined : -right);
30
+ }
31
+ case 'multiply': {
32
+ let sign = 1;
33
+ for (const operand of expression.operands) {
34
+ const part = yield operand;
35
+ sign = sign === undefined || part === undefined ? undefined : sign * part;
36
+ }
37
+ return sign;
38
+ }
39
+ case 'divide': {
40
+ const left = yield expression.left;
41
+ const right = yield expression.right;
42
+ return left === undefined || right === undefined || right === 0 ? undefined : left * right;
43
+ }
44
+ default: return undefined;
45
+ }
46
+ }
47
+ export const constantSign = (expression, cache, literal = value => {
48
+ if (value.kind === 'literal' && value.sort === 'int')
49
+ return Exact.rational(String(Exact.integer(value.value)));
50
+ if (value.kind === 'literal' && value.sort === 'real')
51
+ return Exact.rational(value.value);
52
+ throw new TypeError('expected a numeric literal');
53
+ }) => evaluate(expression, value => signSteps(value, literal), cache);
54
+ //# sourceMappingURL=constant-sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-sign.js","sourceRoot":"","sources":["../../src/constant-sign.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Context } from './explain.ts';
2
+ /** Serialize validated input values without depending on the engine's stack limit. */
3
+ export declare const stringifyInput: (value: unknown) => string;
4
+ /** Validate explanation metadata and bindings without resolving external IDs. */
5
+ export declare const validateContext: (context: Context) => void;
6
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAiC3C,sFAAsF;AACtF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,MAiC/C,CAAA;AAED,iFAAiF;AACjF,eAAO,MAAM,eAAe,GAAI,SAAS,OAAO,KAAG,IA2ClD,CAAA"}
@@ -0,0 +1,151 @@
1
+ import { clone } from "./clone.js";
2
+ const validateJson = (root, path) => {
3
+ const active = new WeakSet();
4
+ const completed = new WeakSet();
5
+ const stack = [{ value: root, path }];
6
+ while (stack.length > 0) {
7
+ const frame = stack.pop();
8
+ const value = frame.value;
9
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
10
+ continue;
11
+ if (typeof value === 'number' && Number.isFinite(value))
12
+ continue;
13
+ if (typeof value !== 'object' || value === null)
14
+ throw new TypeError(`${frame.path} must be a finite JSON value`);
15
+ if (frame.leave) {
16
+ active.delete(value);
17
+ completed.add(value);
18
+ continue;
19
+ }
20
+ if (active.has(value))
21
+ throw new TypeError(`${frame.path} contains a JSON cycle`);
22
+ if (completed.has(value))
23
+ continue;
24
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
25
+ throw new TypeError(`${frame.path} must be a plain JSON object or array`);
26
+ if (typeof value.toJSON === 'function')
27
+ throw new TypeError(`${frame.path} must not use a custom JSON serializer`);
28
+ active.add(value);
29
+ stack.push({ ...frame, leave: true });
30
+ if (Array.isArray(value)) {
31
+ for (let index = value.length - 1; index >= 0; index--) {
32
+ if (!Object.hasOwn(value, index))
33
+ throw new TypeError(`${frame.path}[${index}] must not be a sparse JSON array entry`);
34
+ stack.push({ value: value[index], path: `${frame.path}[${index}]` });
35
+ }
36
+ }
37
+ else {
38
+ for (const [key, child] of Object.entries(value)) {
39
+ if (child !== undefined)
40
+ stack.push({ value: child, path: `${frame.path}.${key}` });
41
+ }
42
+ }
43
+ }
44
+ };
45
+ /** Serialize validated input values without depending on the engine's stack limit. */
46
+ export const stringifyInput = (value) => {
47
+ validateJson(value, 'explanation input value');
48
+ value = clone(value);
49
+ validateJson(value, 'explanation input value');
50
+ const output = [];
51
+ const stack = [{ value }];
52
+ while (stack.length > 0) {
53
+ const frame = stack.pop();
54
+ if ('text' in frame) {
55
+ output.push(frame.text);
56
+ continue;
57
+ }
58
+ const current = frame.value;
59
+ if (current === null || typeof current !== 'object') {
60
+ output.push(JSON.stringify(current));
61
+ continue;
62
+ }
63
+ if (Array.isArray(current)) {
64
+ output.push('[');
65
+ stack.push({ text: ']' });
66
+ for (let index = current.length - 1; index >= 0; index--) {
67
+ stack.push({ value: current[index] });
68
+ if (index > 0)
69
+ stack.push({ text: ',' });
70
+ }
71
+ }
72
+ else {
73
+ const entries = Object.entries(current).filter(([, child]) => child !== undefined);
74
+ output.push('{');
75
+ stack.push({ text: '}' });
76
+ for (let index = entries.length - 1; index >= 0; index--) {
77
+ const [key, child] = entries[index];
78
+ stack.push({ value: child }, { text: `${JSON.stringify(key)}:` });
79
+ if (index > 0)
80
+ stack.push({ text: ',' });
81
+ }
82
+ }
83
+ }
84
+ return output.join('');
85
+ };
86
+ /** Validate explanation metadata and bindings without resolving external IDs. */
87
+ export const validateContext = (context) => {
88
+ if (context === null || typeof context !== 'object' || Array.isArray(context))
89
+ throw new TypeError('explanation context must be an object');
90
+ const nonempty = (value, path) => {
91
+ if (typeof value !== 'string' || value.length === 0)
92
+ throw new TypeError(`${path} must be a nonempty string`);
93
+ };
94
+ if (context.modelDigest !== undefined)
95
+ nonempty(context.modelDigest, 'explanation modelDigest');
96
+ if (context.scenario !== undefined) {
97
+ const scenario = context.scenario;
98
+ if (scenario === null || typeof scenario !== 'object' || Array.isArray(scenario))
99
+ throw new TypeError('explanation scenario must be an object');
100
+ for (const key of ['id', 'inputDigest', 'overlayDigest'])
101
+ nonempty(scenario[key], `explanation scenario.${key}`);
102
+ }
103
+ if (context.snapshot !== undefined) {
104
+ const snapshot = context.snapshot;
105
+ if (snapshot === null || typeof snapshot !== 'object' || Array.isArray(snapshot))
106
+ throw new TypeError('explanation snapshot must be an object');
107
+ if (snapshot.transactionTime !== null)
108
+ nonempty(snapshot.transactionTime, 'explanation snapshot.transactionTime');
109
+ if (snapshot.validTime !== undefined)
110
+ nonempty(snapshot.validTime, 'explanation snapshot.validTime');
111
+ if (snapshot.aliases !== undefined && snapshot.aliases !== 'exact' && snapshot.aliases !== 'closure')
112
+ throw new TypeError('explanation snapshot.aliases must be exact or closure');
113
+ if (snapshot.resolution !== undefined && snapshot.resolution !== 'coexisting' && snapshot.resolution !== 'winner')
114
+ throw new TypeError('explanation snapshot.resolution must be coexisting or winner');
115
+ const confidence = snapshot.minimumConfidence;
116
+ if (confidence !== undefined && (typeof confidence !== 'number' || !Number.isFinite(confidence) || confidence < 0 || confidence > 1))
117
+ throw new TypeError('explanation snapshot.minimumConfidence must be a finite number from 0 to 1');
118
+ }
119
+ if (context.inputs === undefined)
120
+ return;
121
+ if (!Array.isArray(context.inputs))
122
+ throw new TypeError('explanation inputs must be an array');
123
+ const ids = new Set();
124
+ for (let index = 0; index < context.inputs.length; index++) {
125
+ const input = context.inputs[index];
126
+ const path = `explanation inputs[${index}]`;
127
+ if (!Object.hasOwn(context.inputs, index) || input === null || typeof input !== 'object' || Array.isArray(input))
128
+ throw new TypeError(`${path} must be an input object`);
129
+ if (typeof input.id !== 'string' || input.id.length === 0)
130
+ throw new TypeError(`${path}.id must be a nonempty string`);
131
+ if (ids.has(input.id))
132
+ throw new TypeError(`${path}.id duplicates ${JSON.stringify(input.id)}`);
133
+ ids.add(input.id);
134
+ for (const key of ['value', 'authoredValue']) {
135
+ if (input[key] !== undefined)
136
+ validateJson(input[key], `${path}.${key}`);
137
+ }
138
+ if (input.query !== undefined && typeof input.query !== 'string')
139
+ throw new TypeError(`${path}.query must be a string`);
140
+ for (const key of ['evidenceRowIds', 'scenarioClaimIds']) {
141
+ const values = input[key];
142
+ if (!Array.isArray(values))
143
+ throw new TypeError(`${path}.${key} must be an array`);
144
+ for (let item = 0; item < values.length; item++) {
145
+ if (!Object.hasOwn(values, item) || typeof values[item] !== 'string' || values[item].length === 0)
146
+ throw new TypeError(`${path}.${key}[${item}] must be a nonempty string`);
147
+ }
148
+ }
149
+ }
150
+ };
151
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,MAAM,YAAY,GAAG,CAAC,IAAa,EAAE,IAAY,EAAQ,EAAE;IACzD,MAAM,MAAM,GAAG,IAAI,OAAO,EAAU,CAAA;IACpC,MAAM,SAAS,GAAG,IAAI,OAAO,EAAU,CAAA;IACvC,MAAM,KAAK,GAAwD,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1F,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;QACzB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;YAAE,SAAQ;QACvF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAQ;QACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,8BAA8B,CAAC,CAAA;QACjH,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,SAAQ;QAAC,CAAC;QACzE,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,wBAAwB,CAAC,CAAA;QACjF,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAQ;QAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,uCAAuC,CAAC,CAAA;QAClM,IAAI,OAAQ,KAA8B,CAAC,MAAM,KAAK,UAAU;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,wCAAwC,CAAC,CAAA;QAC5I,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACjB,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC;oBAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,yCAAyC,CAAC,CAAA;gBACtH,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC,CAAA;YACtE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,IAAI,KAAK,KAAK,SAAS;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC,CAAA;YACrF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAc,EAAU,EAAE;IACvD,YAAY,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAA;IAC9C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IACpB,YAAY,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,KAAK,GAA8C,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IACpE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QAC1B,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,SAAQ;QAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAA;QAC3B,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;YACpC,SAAQ;QACV,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YACzB,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBACrC,IAAI,KAAK,GAAG,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;YAClF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YACzB,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACzD,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAE,CAAA;gBACpC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAA;gBACjE,IAAI,KAAK,GAAG,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACxB,CAAC,CAAA;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAQ,EAAE;IACxD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAA;IAC3I,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAE,IAAY,EAAQ,EAAE;QACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,4BAA4B,CAAC,CAAA;IAC/G,CAAC,CAAA;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAA;IAC/F,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACjC,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAA;QAC/I,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,eAAe,CAAU;YAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,wBAAwB,GAAG,EAAE,CAAC,CAAA;IAC3H,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACjC,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAA;QAC/I,IAAI,QAAQ,CAAC,eAAe,KAAK,IAAI;YAAE,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,sCAAsC,CAAC,CAAA;QACjH,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS;YAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAA;QACpG,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,SAAS,CAAC,uDAAuD,CAAC,CAAA;QAClL,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,IAAI,QAAQ,CAAC,UAAU,KAAK,YAAY,IAAI,QAAQ,CAAC,UAAU,KAAK,QAAQ;YAAE,MAAM,IAAI,SAAS,CAAC,8DAA8D,CAAC,CAAA;QACtM,MAAM,UAAU,GAAG,QAAQ,CAAC,iBAAiB,CAAA;QAC7C,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,4EAA4E,CAAC,CAAA;IACzO,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,OAAM;IACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAA;IAC9F,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAA;IAC7B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,sBAAsB,KAAK,GAAG,CAAA;QAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,0BAA0B,CAAC,CAAA;QACxK,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,+BAA+B,CAAC,CAAA;QACtH,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,kBAAkB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAC/F,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjB,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAU,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS;gBAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAA;QAC1E,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,yBAAyB,CAAC,CAAA;QACvH,KAAK,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,CAAU,EAAE,CAAC;YAClE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;YACzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,IAAI,GAAG,mBAAmB,CAAC,CAAA;YAClF,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;gBAChD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,6BAA6B,CAAC,CAAA;YAC7K,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ /** Keep malformed-input diagnostics small while retaining both ends and exact size. */
2
+ export declare const diagnosticText: (input: string, quoteShort?: boolean) => string;
3
+ //# sourceMappingURL=diagnostic-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-text.d.ts","sourceRoot":"","sources":["../../src/diagnostic-text.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,oBAAiB,KAAG,MAEiD,CAAA"}
@@ -0,0 +1,5 @@
1
+ /** Keep malformed-input diagnostics small while retaining both ends and exact size. */
2
+ export const diagnosticText = (input, quoteShort = true) => input.length <= 160
3
+ ? (quoteShort ? JSON.stringify(input) : input)
4
+ : `${JSON.stringify(input.slice(0, 80))}…${JSON.stringify(input.slice(-80))} (${input.length} UTF-16 code units)`;
5
+ //# sourceMappingURL=diagnostic-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-text.js","sourceRoot":"","sources":["../../src/diagnostic-text.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,UAAU,GAAG,IAAI,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG;IAC7F,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Expression } from './model.ts';
2
+ /** Evaluate a captured expression with an explicit stack and caller-owned cache. */
3
+ export declare const evaluate: <T>(expression: Expression, steps: (value: Expression) => Generator<Expression, T, T>, cache: WeakMap<Expression, T>) => T;
4
+ //# sourceMappingURL=evaluate-expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-expression.d.ts","sourceRoot":"","sources":["../../src/evaluate-expression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,oFAAoF;AACpF,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,YAAY,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,UAAU,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,KAAG,CAiB9I,CAAA"}
@@ -0,0 +1,24 @@
1
+ /** Evaluate a captured expression with an explicit stack and caller-owned cache. */
2
+ export const evaluate = (expression, steps, cache) => {
3
+ if (cache.has(expression))
4
+ return cache.get(expression);
5
+ const stack = [{ expression, iterator: steps(expression) }];
6
+ let step = stack[0].iterator.next();
7
+ while (true) {
8
+ if (step.done) {
9
+ cache.set(stack.pop().expression, step.value);
10
+ if (stack.length === 0)
11
+ return step.value;
12
+ step = stack[stack.length - 1].iterator.next(step.value);
13
+ }
14
+ else if (cache.has(step.value)) {
15
+ step = stack[stack.length - 1].iterator.next(cache.get(step.value));
16
+ }
17
+ else {
18
+ const child = { expression: step.value, iterator: steps(step.value) };
19
+ stack.push(child);
20
+ step = child.iterator.next();
21
+ }
22
+ }
23
+ };
24
+ //# sourceMappingURL=evaluate-expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-expression.js","sourceRoot":"","sources":["../../src/evaluate-expression.ts"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAI,UAAsB,EAAE,KAAyD,EAAE,KAA6B,EAAK,EAAE;IACjJ,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAE,CAAA;IACxD,MAAM,KAAK,GAAG,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC3D,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IACpC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;YAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAA;YACzC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC,CAAA;QACvE,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA;YACrE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -5,6 +5,8 @@ export type Normalized = {
5
5
  };
6
6
  export declare const integer: (input: Integer) => bigint;
7
7
  export declare const rational: (input: Rational) => Normalized;
8
+ /** Normalize integer intermediates without serializing and parsing them again. */
9
+ export declare const fromBigInts: (numerator: bigint, denominator: bigint) => Normalized;
8
10
  export declare const compare: (left: Rational, right: Rational) => -1 | 0 | 1;
9
11
  export declare const isZero: (input: Rational) => boolean;
10
12
  //# sourceMappingURL=exact.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exact.d.ts","sourceRoot":"","sources":["../../src/exact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B,CAAA;AAgBD,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,MAWxC,CAAA;AAsBD,eAAO,MAAM,QAAQ,GAAI,OAAO,QAAQ,KAAG,UAqB1C,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,MAAM,QAAQ,EAAE,OAAO,QAAQ,KAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAKlE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,OAAO,QAAQ,KAAG,OAA4C,CAAA"}
1
+ {"version":3,"file":"exact.d.ts","sourceRoot":"","sources":["../../src/exact.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B,CAAA;AAWD,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,MAYxC,CAAA;AA0CD,eAAO,MAAM,QAAQ,GAAI,OAAO,QAAQ,KAAG,UAoC1C,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,EAAE,aAAa,MAAM,KAAG,UAgBpE,CAAA;AAaD,eAAO,MAAM,OAAO,GAAI,MAAM,QAAQ,EAAE,OAAO,QAAQ,KAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAyBlE,CAAA;AAQD,eAAO,MAAM,MAAM,GAAI,OAAO,QAAQ,KAAG,OAMxC,CAAA"}
package/dist/src/exact.js CHANGED
@@ -1,14 +1,11 @@
1
+ import { diagnosticText } from "./diagnostic-text.js";
2
+ import { gcd } from "./integer-gcd.js";
1
3
  const integerPattern = /^[+-]?\d+$/;
2
4
  const decimalPattern = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/;
3
- const gcd = (left, right) => {
4
- let a = left < 0n ? -left : left;
5
- let b = right < 0n ? -right : right;
6
- while (b !== 0n) {
7
- const remainder = a % b;
8
- a = b;
9
- b = remainder;
10
- }
11
- return a;
5
+ const assertIntegerText = (input) => {
6
+ if (input.match(integerPattern)?.[0] !== input) {
7
+ throw new TypeError(`expected an integer string, received ${diagnosticText(input)}`);
8
+ }
12
9
  };
13
10
  export const integer = (input) => {
14
11
  if (typeof input === 'number') {
@@ -17,40 +14,94 @@ export const integer = (input) => {
17
14
  }
18
15
  return BigInt(input);
19
16
  }
20
- if (!integerPattern.test(input)) {
21
- throw new TypeError(`expected an integer string, received ${JSON.stringify(input)}`);
17
+ if (typeof input !== 'string') {
18
+ throw new TypeError('expected a safe integer number or an integer string');
22
19
  }
20
+ assertIntegerText(input);
23
21
  return BigInt(input);
24
22
  };
25
- const decimal = (input) => {
26
- if (!decimalPattern.test(input)) {
27
- throw new TypeError(`expected an exact decimal string, received ${JSON.stringify(input)}`);
23
+ const decimalParts = (input) => {
24
+ if (input.match(decimalPattern)?.[0] !== input) {
25
+ throw new TypeError(`expected an exact decimal string, received ${diagnosticText(input)}`);
28
26
  }
29
27
  const [coefficient = '', exponentText] = input.toLowerCase().split('e');
30
28
  const exponent = exponentText === undefined ? 0 : Number(exponentText);
31
29
  if (!Number.isSafeInteger(exponent)) {
32
- throw new TypeError(`decimal exponent is outside the supported range: ${JSON.stringify(input)}`);
30
+ throw new TypeError(`decimal exponent is outside the supported range: ${diagnosticText(input)}`);
33
31
  }
32
+ return { coefficient, exponent };
33
+ };
34
+ const decimal = (input) => {
35
+ const { coefficient, exponent } = decimalParts(input);
34
36
  const negative = coefficient.startsWith('-');
35
37
  const unsigned = coefficient.replace(/^[+-]/, '');
36
38
  const [whole = '', fraction = ''] = unsigned.split('.');
37
39
  const digits = `${whole === '' ? '0' : whole}${fraction}`;
38
- const scale = fraction.length - exponent;
39
- const signed = BigInt(digits === '' ? '0' : digits) * (negative ? -1n : 1n);
40
- return scale <= 0
41
- ? [signed * (10n ** BigInt(-scale)), 1n]
42
- : [signed, 10n ** BigInt(scale)];
40
+ let scale = fraction.length - exponent;
41
+ let magnitude = digits.replace(/^0+/, '');
42
+ if (magnitude === '')
43
+ return { numerator: '0', denominator: '1' };
44
+ // Cancel powers of ten in text before allocating either bigint operand.
45
+ let cancelled = 0;
46
+ while (cancelled < scale && magnitude[magnitude.length - cancelled - 1] === '0')
47
+ cancelled++;
48
+ if (cancelled > 0) {
49
+ magnitude = magnitude.slice(0, -cancelled);
50
+ scale -= cancelled;
51
+ }
52
+ if (scale <= 0) {
53
+ return { numerator: `${negative ? '-' : ''}${magnitude}${'0'.repeat(-scale)}`, denominator: '1' };
54
+ }
55
+ return fromBigInts(BigInt(magnitude) * (negative ? -1n : 1n), 10n ** BigInt(scale));
56
+ };
57
+ const assertRationalObject = (input) => {
58
+ if (input === null || typeof input !== 'object') {
59
+ throw new TypeError('expected an exact decimal string or a numerator/denominator object');
60
+ }
43
61
  };
44
62
  export const rational = (input) => {
45
- let numerator;
63
+ let numerator = 0n;
46
64
  let denominator;
47
65
  if (typeof input === 'string') {
48
- ;
49
- [numerator, denominator] = decimal(input);
66
+ return decimal(input);
50
67
  }
51
68
  else {
52
- numerator = integer(input.numerator);
53
- denominator = integer(input.denominator);
69
+ assertRationalObject(input);
70
+ const suppliedNumerator = input.numerator;
71
+ const numeratorText = typeof suppliedNumerator === 'string' ? suppliedNumerator : undefined;
72
+ let zero;
73
+ if (numeratorText !== undefined) {
74
+ assertIntegerText(numeratorText);
75
+ zero = !/[1-9]/.test(numeratorText);
76
+ }
77
+ else {
78
+ numerator = integer(suppliedNumerator);
79
+ zero = numerator === 0n;
80
+ }
81
+ const suppliedDenominator = input.denominator;
82
+ if (zero && typeof suppliedDenominator === 'string') {
83
+ assertIntegerText(suppliedDenominator);
84
+ if (!/[1-9]/.test(suppliedDenominator)) {
85
+ throw new TypeError('rational denominator must not be zero');
86
+ }
87
+ return { numerator: '0', denominator: '1' };
88
+ }
89
+ denominator = integer(suppliedDenominator);
90
+ if (numeratorText !== undefined) {
91
+ if (denominator === 1n || denominator === -1n) {
92
+ const magnitude = numeratorText.replace(/^[+-]?0*/, '');
93
+ const negative = numeratorText.startsWith('-') !== (denominator === -1n);
94
+ return { numerator: magnitude === '' ? '0' : `${negative ? '-' : ''}${magnitude}`, denominator: '1' };
95
+ }
96
+ numerator = BigInt(numeratorText);
97
+ }
98
+ }
99
+ return fromBigInts(numerator, denominator);
100
+ };
101
+ /** Normalize integer intermediates without serializing and parsing them again. */
102
+ export const fromBigInts = (numerator, denominator) => {
103
+ if (typeof numerator !== 'bigint' || typeof denominator !== 'bigint') {
104
+ throw new TypeError('expected bigint numerator and denominator');
54
105
  }
55
106
  if (denominator === 0n) {
56
107
  throw new TypeError('rational denominator must not be zero');
@@ -65,11 +116,57 @@ export const rational = (input) => {
65
116
  denominator: String(denominator / divisor)
66
117
  };
67
118
  };
119
+ /** Compare canonical integer text without allocating bigint magnitudes. */
120
+ const integerOrder = (left, right) => {
121
+ if (left === right)
122
+ return 0;
123
+ const negative = left.startsWith('-');
124
+ if (negative !== right.startsWith('-'))
125
+ return negative ? -1 : 1;
126
+ const a = negative ? left.slice(1) : left;
127
+ const b = negative ? right.slice(1) : right;
128
+ const order = a.length === b.length ? (a < b ? -1 : 1) : a.length < b.length ? -1 : 1;
129
+ return negative ? (order === -1 ? 1 : -1) : order;
130
+ };
68
131
  export const compare = (left, right) => {
69
132
  const a = rational(left);
70
133
  const b = rational(right);
71
- const difference = BigInt(a.numerator) * BigInt(b.denominator) - BigInt(b.numerator) * BigInt(a.denominator);
72
- return difference < 0n ? -1 : difference > 0n ? 1 : 0;
134
+ const numerators = integerOrder(a.numerator, b.numerator);
135
+ const negative = a.numerator.startsWith('-');
136
+ if (a.denominator === b.denominator || a.numerator === '0' || b.numerator === '0' ||
137
+ negative !== b.numerator.startsWith('-')) {
138
+ return numerators;
139
+ }
140
+ const denominators = integerOrder(a.denominator, b.denominator);
141
+ if (numerators === 0) {
142
+ // Equal denominators were handled above. A positive common numerator
143
+ // reverses denominator order; a negative one preserves it.
144
+ return negative ? denominators : denominators === -1 ? 1 : -1;
145
+ }
146
+ // With equal signs, a smaller magnitude numerator and larger denominator
147
+ // reinforce each other. Their ordering needs no cross-product allocation.
148
+ if ((numerators < 0) === (negative ? denominators < 0 : denominators > 0)) {
149
+ return numerators;
150
+ }
151
+ const numeratorA = BigInt(a.numerator), numeratorB = BigInt(b.numerator);
152
+ const denominatorA = BigInt(a.denominator), denominatorB = BigInt(b.denominator);
153
+ const productA = numeratorA * denominatorB;
154
+ const productB = numeratorB * denominatorA;
155
+ return productA < productB ? -1 : productA > productB ? 1 : 0;
156
+ };
157
+ const integerIsZero = (input) => {
158
+ if (typeof input !== 'string')
159
+ return integer(input) === 0n;
160
+ assertIntegerText(input);
161
+ return !/[1-9]/.test(input);
162
+ };
163
+ export const isZero = (input) => {
164
+ if (typeof input === 'string')
165
+ return !/[1-9]/.test(decimalParts(input).coefficient);
166
+ assertRationalObject(input);
167
+ const zero = integerIsZero(input.numerator);
168
+ if (integerIsZero(input.denominator))
169
+ throw new TypeError('rational denominator must not be zero');
170
+ return zero;
73
171
  };
74
- export const isZero = (input) => rational(input).numerator === '0';
75
172
  //# sourceMappingURL=exact.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"exact.js","sourceRoot":"","sources":["../../src/exact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exact.js","sourceRoot":"","sources":["../../src/exact.ts"],"names":[],"mappings":"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"}
@@ -56,9 +56,13 @@ export type AssignmentValue = Element & {
56
56
  };
57
57
  export type Constraint = Element & {
58
58
  readonly evaluation: 'satisfied' | 'violated' | 'indeterminate';
59
+ /** Human-readable local evaluation failure; absent for determinate evaluations. */
60
+ readonly evaluationReason?: string;
59
61
  };
60
62
  export type SoftConstraintResult = Element & {
61
63
  readonly evaluation: 'accepted' | 'violated' | 'indeterminate';
64
+ /** Human-readable local evaluation failure; absent for determinate evaluations. */
65
+ readonly evaluationReason?: string;
62
66
  readonly weight: ReturnType<typeof Exact.rational>;
63
67
  };
64
68
  export type ObjectiveResult = Element & {