* Assume a conjunction: each conjunct is assumed independently * (design §3.2, "shallow saturation"). * * Result: `'contradiction'` if any conjunct contradicts, * `'not-a-predicate'` if any conjunct is unsupported, `'tautology'` if * every conjunct was already known, `'ok'` otherwise.
(proposition: Expression)
| 162 | // restore in the current context): `withValueShield` pushes a fresh |
| 163 | // eval-context whose assumptions map is discarded on pop, which would lose |
| 164 | // the very fact being recorded, so it cannot be used here. |
| 165 | return withValueBlindRecording(names, () => assumeDispatch(proposition)); |
| 166 | |
| 167 | /** Strip the assigned value of each name for the duration of `fn`, then |
| 168 | * restore it, so the recording pipeline sees the symbols as valueless (a |
| 169 | * fact `w > 0` instead of the folded `5 > 0 → True`). */ |
| 170 | function withValueBlindRecording<T>(names: string[], fn: () => T): T { |
| 171 | const ce = proposition.engine; |
| 172 | const saved: { name: string; value: Expression }[] = []; |
| 173 | for (const name of names) { |
| 174 | const def = ce.lookupDefinition(name); |
| 175 | if (!isValueDef(def) || def.value.isConstant) continue; |
| 176 | const value = def.value.value; |
| 177 | if (value === undefined || value === null) continue; |
| 178 | saved.push({ name, value }); |
| 179 | ce._setSymbolValue(name, undefined); |
| 180 | } |
| 181 | if (saved.length === 0) return fn(); |
| 182 | try { |
| 183 | return fn(); |
| 184 | } finally { |
| 185 | for (const { name, value } of saved) ce._setSymbolValue(name, value); |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | function assumeDispatch(proposition: Expression): AssumeResult { |
| 191 | const op = proposition.operator; |
| 192 | if (op === 'Element') return assumeElement(proposition); |
| 193 | if (op === 'NotElement') return assumeNotElement(proposition); |
| 194 | if (op === 'Equal') return assumeEquality(proposition); |
| 195 | if (op === 'NotEqual') return assumeNotEqual(proposition); |
| 196 | if (op === 'And') return assumeConjunction(proposition); |
no test coverage detected