MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / cmp

Function cmp

src/compute-engine/boxed-expression/compare.ts:260–636  ·  view source on GitHub ↗
(
  a: Expression,
  b: number | Expression
)

Source from the content-addressed store, hash-verified

258 * compared equal to canonical `Map(…)`s from two different scopes that were
259 * themselves unequal. The bridge sat inside the domain every dedup key uses
260 * (`Terms.find`'s like-term collection, the assumptions `ExpressionMap`).
261 *
262 * Comparing a TEMPLATE against a subject — a rule pattern is raw by
263 * necessity — is now an explicit mode (`sameSyntactic`) rather than an
264 * implicit consequence of unboundness.
265 */
266export function same(
267 a: Expression,
268 b: Expression,
269 boundA?: BinderMap,
270 boundB?: BinderMap,
271 syntactic = false
272): boolean {
273 if (a === b) return true;
274
275 // An OBJECT is compared by reference identity, unconditionally: it is the
276 // one mutable kind, so two objects that are equal by contents now can differ
277 // a moment later, and "are these the same object" is the only question whose
278 // answer stays true. Reaching the structural branches below would answer
279 // `true` for two distinct objects with equal slots. Having already failed
280 // the `a === b` fast path, the answer here is always `false`; it is written
281 // as the identity comparison because that is the rule, not the outcome.
282 if (isObject(a) || isObject(b))
283 return (a as Expression) === (b as Expression);
284
285 // A symbol is compared as a symbol, never as its value: exactly one operand
286 // being a symbol falls through to the type-mismatch branches below and is
287 // `false`.
288
289 //
290 // BoxedFunction
291 // Operator and operands must match
292 //
293 if (isFunction(a)) {
294 if (a.operator !== b.operator) return false;
295 if (!isFunction(b)) return false;
296 if (a.nops !== b.nops) return false;
297 // What this node binds shadows any outer binding of the same name for the
298 // whole subtree. Tracked PER SIDE: `a` and `b` mint their own definitions
299 // for the same bound variable (re-boxing does exactly that), so a single
300 // shared set would be asymmetric — `same(a,b)` could differ from
301 // `same(b,a)`, breaking the equivalence relation this is a key for.
302 const innerA = extendBinders(boundA, boundVariableBindings(a));
303 const innerB = extendBinders(boundB, boundVariableBindings(b));
304 return a.ops.every((op, i) =>
305 same(op, b.ops[i], innerA, innerB, syntactic)
306 );
307 }
308
309 //
310 // BoxedNumber
311 //
312 if (isNumber(a)) {
313 if (!isNumber(b)) return false;
314 const av = a.numericValue;
315 const bv = b.numericValue;
316 if (av === bv) return true;
317 // Two NaN literals are structurally the same number leaf, whether or not

Callers 7

orderFunction · 0.90
isLessFunction · 0.90
isLessEqualFunction · 0.90
isGreaterFunction · 0.90
isGreaterEqualFunction · 0.90
cmpChainFunction · 0.85
intCmpFunction · 0.85

Calls 15

isNumberFunction · 0.90
isSymbolFunction · 0.90
isFunctionFunction · 0.90
compareBoundsFunction · 0.90
isStringFunction · 0.90
isTensorFunction · 0.90
cmpMethod · 0.80
absMethod · 0.65
subMethod · 0.65
_numericValueMethod · 0.65
NMethod · 0.65

Tested by

no test coverage detected