mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-03 13:23:10 +00:00
[ty] Some more simplifications when rendering constraint sets (#21009)
This PR adds another useful simplification when rendering constraint sets: `T = int` instead of `T = int ∧ T ≠ str`. (The "smaller" constraint `T = int` implies the "larger" constraint `T ≠ str`. Constraint set clauses are intersections, and if one constraint in a clause implies another, we can throw away the "larger" constraint.) While we're here, we also normalize the bounds of a constraint, so that we equate e.g. `T ≤ int | str` with `T ≤ str | int`, and change the ordering of BDD variables so that all constraints with the same typevar are ordered adjacent to each other. Lastly, we also add a new `display_graph` helper method that prints out the full graph structure of a BDD. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
81c1d36088
commit
766ed5b5f3
6 changed files with 314 additions and 23 deletions
|
|
@ -601,3 +601,40 @@ def _[T, U]() -> None:
|
|||
# revealed: ty_extensions.ConstraintSet[always]
|
||||
reveal_type(~union | union)
|
||||
```
|
||||
|
||||
## Other simplifications
|
||||
|
||||
When displaying a constraint set, we transform the internal BDD representation into a DNF formula
|
||||
(i.e., the logical OR of several clauses, each of which is the logical AND of several constraints).
|
||||
This section contains several examples that show that we simplify the DNF formula as much as we can
|
||||
before displaying it.
|
||||
|
||||
```py
|
||||
from ty_extensions import range_constraint
|
||||
|
||||
def f[T, U]():
|
||||
t1 = range_constraint(str, T, str)
|
||||
t2 = range_constraint(bool, T, bool)
|
||||
u1 = range_constraint(str, U, str)
|
||||
u2 = range_constraint(bool, U, bool)
|
||||
|
||||
# revealed: ty_extensions.ConstraintSet[(T@f = bool) ∨ (T@f = str)]
|
||||
reveal_type(t1 | t2)
|
||||
# revealed: ty_extensions.ConstraintSet[(U@f = bool) ∨ (U@f = str)]
|
||||
reveal_type(u1 | u2)
|
||||
# revealed: ty_extensions.ConstraintSet[((T@f = bool) ∧ (U@f = bool)) ∨ ((T@f = bool) ∧ (U@f = str)) ∨ ((T@f = str) ∧ (U@f = bool)) ∨ ((T@f = str) ∧ (U@f = str))]
|
||||
reveal_type((t1 | t2) & (u1 | u2))
|
||||
```
|
||||
|
||||
The lower and upper bounds of a constraint are normalized, so that we equate unions and
|
||||
intersections whose elements appear in different orders.
|
||||
|
||||
```py
|
||||
from typing import Never
|
||||
|
||||
def f[T]():
|
||||
# revealed: ty_extensions.ConstraintSet[(T@f ≤ int | str)]
|
||||
reveal_type(range_constraint(Never, T, str | int))
|
||||
# revealed: ty_extensions.ConstraintSet[(T@f ≤ int | str)]
|
||||
reveal_type(range_constraint(Never, T, int | str))
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue