Created
March 13, 2025 02:33
-
-
Save yuya-maemichi-synspective/7a6adb0c701dbfc4342dcf5750c8b87f to your computer and use it in GitHub Desktop.
math complementable interval in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from dataclasses import dataclass, replace | |
import math | |
from numbers import Number | |
from typing import Tuple | |
NEG_INF = -math.inf | |
POS_INF = math.inf | |
@dataclass(frozen=True) | |
class IntervalEnd: | |
value: Number | |
closed: bool | |
@property | |
def is_open(self) -> bool: | |
return not self.closed | |
def invert(self) -> IntervalEnd: | |
return replace(self, closed=not self.closed) | |
def __lt__(self, other: IntervalEnd) -> bool: | |
# Handle infinite bounds first | |
if self.value == NEG_INF: | |
return other.value != NEG_INF | |
if other.value == POS_INF: | |
return self.value != POS_INF | |
# Compare values, then openness (open ends sort before closed at same value) | |
return (self.value, self.is_open) < (other.value, other.is_open) | |
@dataclass(frozen=True) | |
class Interval: | |
left: IntervalEnd | |
right: IntervalEnd | |
def __post_init__(self): | |
if self.left > self.right: | |
raise ValueError(f"Malformed interval: {self.left} > {self.right}") | |
@property | |
def is_empty(self) -> bool: | |
return ( | |
self.left.value > self.right.value or | |
(self.left.value == self.right.value and | |
(self.left.is_open or self.right.is_open)) | |
) | |
def __invert__(self) -> IntervalUnion: | |
if self.is_empty: | |
return IntervalUnion(Interval(NEG_INF_END, POS_INF_END)) | |
return IntervalUnion( | |
Interval(NEG_INF_END, self.left.invert()), | |
Interval(self.right.invert(), POS_INF_END) | |
) | |
def __contains__(self, x: Number) -> bool: | |
left_cond = (x > self.left.value) or (x == self.left.value and self.left.closed) | |
right_cond = (x < self.right.value) or (x == self.right.value and self.right.closed) | |
return left_cond and right_cond | |
@dataclass(frozen=True) | |
class IntervalUnion: | |
intervals: Tuple[Interval, ...] | |
def __invert__(self) -> Interval: | |
# Implement using De Morgan's laws through interval intersections | |
raise NotImplementedError("Requires full interval algebra implementation") | |
# Predefined infinite ends | |
NEG_INF_END = IntervalEnd(NEG_INF, False) | |
POS_INF_END = IntervalEnd(POS_INF, False) |
Maybe just give up IntervalEnd
?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Vibe coding: https://www.perplexity.ai/search/any-idiomatic-notation-of-inve-ivcTRPBDQQ6aNTtYtOsqNw#3