Added
- Intervals have a `.left`, `.lower`, `.upper`, and `.right` attribute that refer to its enclosure.
- Intervals have a `.replace` method to create new intervals based on the current one. This method accepts both values and functions.
- Intervals have an `.apply` method to apply a function on the underlying atomic intervals.
- Intervals can be compared with single values as well.
Changed
- `P.empty()` returns the same instance to save memory.
- Infinities are singleton objects.
- Set `len(P.empty()) = 1` and `P.empty()[0] == P.empty().to_atomic()` for consistency.