* Match a pattern against concrete indices. * * Patterns can contain: * - Numeric values that must match exactly * - Variable names that match any value * - Repeated variable names that must have equal values (e.g., 'n,n') * * @example * matchPattern({ type: 'exact', values: [0, 0] }, [0, 0]
(pattern: ParsedPattern, indices: number[])
| 127 | * - Numeric values that must match exactly |
| 128 | * - Variable names that match any value |
| 129 | * - Repeated variable names that must have equal values (e.g., 'n,n') |
| 130 | * |
| 131 | * @example |
| 132 | * matchPattern({ type: 'exact', values: [0, 0] }, [0, 0]) → true |
| 133 | * matchPattern({ type: 'pattern', values: ['n', 0] }, [5, 0]) → true |
| 134 | * matchPattern({ type: 'pattern', values: ['n', 'n'] }, [5, 5]) → true |
| 135 | * matchPattern({ type: 'pattern', values: ['n', 'n'] }, [5, 3]) → false |
| 136 | */ |
| 137 | function matchPattern(pattern: ParsedPattern, indices: number[]): boolean { |
| 138 | if (pattern.values.length !== indices.length) return false; |
| 139 | |
| 140 | // Track variable bindings for equality checks (e.g., 'n,n' requires equal values) |
| 141 | const bindings = new Map<string, number>(); |
| 142 | |
| 143 | for (let i = 0; i < pattern.values.length; i++) { |
| 144 | const pv = pattern.values[i]; |
| 145 | const iv = indices[i]; |
| 146 | |
| 147 | if (typeof pv === 'number') { |
| 148 | // Exact value must match |
| 149 | if (pv !== iv) return false; |
| 150 | } else { |
| 151 | // Variable - check if we've seen it before |
| 152 | if (bindings.has(pv)) { |
| 153 | // Variable appeared earlier - values must be equal |
| 154 | if (bindings.get(pv) !== iv) return false; |
| 155 | } else { |
| 156 | // First occurrence - bind it |
| 157 | bindings.set(pv, iv); |
no test coverage detected