# Untitled

Dec 6th, 2023
715
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. class PartialLinearMapping:
2.     range_start: int
3.     width: int
4.     destination_range_start: int
5.
6.     def domain() -> Interval:
7.         return Interval(self.range_start, self.range_start + self.width)
8.
9.     def codomain() -> Interval:
10.         return Interval(self.destination_range_start, self.destination_range_start + self.width)
11.
12.     def last_included_number(self) -> int:
13.         return self.range_start + self.width - 1
14.
15.     def apply(num: int) -> int:
16.         if num in range(self.range_start, self.range_start + self.width):
17.             return num - self.range_start + self.destination_range_start
18.         return num
19.
20.     def unapply(num: int) -> int:
21.         if num in range(self.destination_range_start, self.destination_range_start + self.width):
22.             return num - self.destination_range_start + self.range_start
23.         return num
24.
25.
26. class Interval:
27.     begin: int
28.     end: int
29.
30.     def __contains__(self, num):
31.         return num in range(self.begin, end)
32.
33.     def difference(self, other: Interval) -> list[Interval]:
34.         # the other is bigger than us
35.         if self.begin in other and self.end - 1 in other:
36.             return []
37.
38.         # the other is disjoint from us
39.         if not (other.begin in self or other.end - 1 in self):
40.             return [self]
41.
42.         # the other is partial overlapped with us
43.         if other.begin in self and other.end - 1 in self:
44.             return [Interval(self.begin, other.begin), Interval(other.end, self.end)]
45.
46.         if other.begin in self:
47.             return Interval(self.begin, other.begin)
48.         else:
49.             return Interval(other.end, self.end)
50.
51.     def intersection(self, other: Interval) -> Interval | None:
52.         # the other is bigger than us
53.         if self.begin in other and self.end - 1 in other:
54.             return self
55.
56.         # the other is disjoint from us
57.         if not (other.begin in self or other.end - 1 in self):
58.             return None
59.
60.         # the other is partial overlapped with us
61.         return Interval(max(self.begin, other.begin), min(self.end, other.end))
62.
63.
64. def compose(
65.     f: PartialLinearMapping,
66.     g: PartialLinearMapping,
67. ) -> tuple[list[PartialLinearMapping], list[PartialLinearMapping]]:
68.     """
69.    the left element is the old domain mapped in the new one
70.    the right element is the new domain remaining from the partial function applied to the old one (basically its the non overlapping
71.    domain of the second function with the codomain of the first)
72.    """
73.     f_o_g_domain = f.codomain().intersection(g.domain())
74.
75.     # this is a list, we need to compute all the intervals that comes from here
76.     f_minus_g = f.codomain().difference(g.domain())
77.
78.     # this is uncomplete/wrong, I'm missing the
79.     old_domain_mapped = list(
80.         lambda x: x is None,
81.         filter(
82.             [
83.                 PartialLinearMapping(
84.                     f.range_start,
85.                     f.unapply(f_o_g_domain.begin),
86.                     f.destination_range_start
87.                 ),
88.                 PartialLinearMapping(
89.                     f_o_g_domain.begin,
90.                     f_o_g_domain.end,
91.                     g.destination_range_start
92.                 )
93.             ]
94.         )
95.     )