( ce: ComputeEngine, e: Entry, fn: () => T )
| 268 | /** |
| 269 | * For variables that have no `Element` conjunct (e.g. AsymptoticTo entries |
| 270 | * with null assumptions), refine `complex` to `integer` when the variable is |
| 271 | * passed directly to a slot whose declared parameter type is integer |
| 272 | * (BellNumber(n), Totient(n), ...). Signature is read from the engine so |
| 273 | * shells and compat overrides are respected. |
| 274 | */ |
| 275 | function refineTypesFromIntegerSlots( |
| 276 | ce: ComputeEngine, |
| 277 | e: Entry, |
| 278 | types: Record<string, string> |
| 279 | ): void { |
| 280 | const untyped = e.variables.filter((v) => !(v in types)); |
| 281 | if (untyped.length === 0) return; |
| 282 | const paramTypes = new Map<string, string[]>(); |
| 283 | const paramsOf = (head: string): string[] => { |
| 284 | if (paramTypes.has(head)) return paramTypes.get(head)!; |
| 285 | let params: string[] = []; |
| 286 | try { |
| 287 | const t = ce.expr(head).type.toString(); |
| 288 | const m = t.match(/^\((.*)\)\s*->/); |
| 289 | if (m) params = m[1].split(',').map((s) => s.trim()); |
| 290 | } catch { |
| 291 | /* not a known function head */ |
| 292 | } |
| 293 | paramTypes.set(head, params); |
no test coverage detected