Commit 89d96c3
`or` is commutative and this reduction was not:
(not (x < 0) or (x < 0)).Simplify() -> True
((x < 0) or not (x < 0)).Simplify() -> x < 0 or x >= 0
There was one excluded-middle rule, Orf(Notf(a), a), matching the negation on the left
operand only, and no mirror of it anywhere in the file. So the same proposition had two
answers depending on which side it was written on.
A bare variable hid it: `p or not p` and `not p or p` both give True, because the boolean
minimiser reduces expressions over boolean variables whichever way round they are. It takes
an operand the minimiser does not treat as an atom -- a comparison -- to see the hole, which
is why this survived. It reproduces on <, >, <=, = and in:
(x < 0) or not (x < 0) was x < 0 or x >= 0 now True
(x > 0) or not (x > 0) was x > 0 or x <= 0 now True
(x <= 0) or not (x <= 0) was x <= 0 or x > 0 now True
(a = b) or not (a = b) was a = b or not a = b now True
(x in RR) or not (x in RR) was x in RR or not x in RR now True
The `=` case is what rules out the obvious explanation. For `<` the negation is rewritten to
`>=` before the disjunction is looked at, which would destroy the pattern on its own; for `=`
there is no such rewrite, the shape Orf(a, Notf(a)) is intact, and it still did not reduce.
The missing mirror is the whole cause.
`and` is not affected: it has no contradiction rule on either side, so it is symmetric. Where
`(x < 0) and not (x < 0)` reduces to False it is comparison reasoning about x < 0 and x >= 0
being unsatisfiable, not this rule, and it already worked both ways round.
This does not touch the soundness half of #876, which stays open. Excluded middle needs the
proposition to have a truth value, and over the default complex codomain `i < 0` is NaN, so
the left-handed form was already answering True where the honest value is NaN. This change
makes that reachable from one more spelling rather than introducing it; the fix wants the
rules to read MathS.Settings.Codomain, which nothing outside the limit machinery does yet.
DomainCondition is not the mechanism for it -- it records singularities, not where an order
comparison is defined.
Verified: 6227 C# tests and 130 F# tests pass, 0 fail. propcheck 1340 checks 0 failures,
simpsweep 62778 point comparisons 0 disagreements, rootcheck 596 cases 0 incomplete and
0 unsound, casbench 117/119 with 0 wrong, 0 error and 0 timeout, every verdict and answer
in coverage.md byte-identical. boolmin unchanged at 6/9.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 363edfa commit 89d96c3
2 files changed
Lines changed: 26 additions & 0 deletions
File tree
- Sources
- AngouriMath/Functions/Simplification/Patterns
- Tests/UnitTests/Common
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
31 | 34 | | |
32 | 35 | | |
33 | 36 | | |
| |||
Lines changed: 23 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
434 | 434 | | |
435 | 435 | | |
436 | 436 | | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
437 | 460 | | |
438 | 461 | | |
0 commit comments