1 collections define: #Interval &parents: {NoDuplicatesCollection. Comparable}
2 &slots: {#upperBound -> PositiveInfinity. #lowerBound -> NegativeInfinity. #bestGuess.
3 #upperInclusive -> True. #lowerInclusive -> True}.
4 "The mathematical concept of an interval, all the points between two bounds and
5 possibly including either bound. It is also useful for specifying the possible
6 bounds of an unknown but algorithmically bound quantity, with the bestGuess
7 value to annotate what the likely possibility is.
8 It is non-extensible, non-indexable, and non-enumerable.
9 Operations on intervals should answer new intervals including every result
10 of applying the function to every element of the source interval(s)."
12 i@(Interval traits) newFrom: start to: end
13 [i cloneSettingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive}
14 to: {start. end. True. True}].
16 i@(Interval traits) newFrom: start below: end
17 [i cloneSettingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive}
18 to: {start. end. True. False}].
20 i@(Interval traits) newAbove: start to: end
21 [i cloneSettingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive}
22 to: {start. end. False. True}].
24 i@(Interval traits) newAbove: start below: end
25 [i cloneSettingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive}
26 to: {start. end. False. False}].
28 n@(Number traits) as: i@(Interval traits) &tolerance: tol
30 (i newFrom: n - tol to: n + tol) `>> [bestGuess := n. ]
33 n@(Number traits) +- tol
34 [n as: Interval &tolerance: tol].
36 n@(Number traits) +/- tol
37 [n as: Interval &tolerance: tol].
39 i@(Interval traits) includes: n
41 (n between: i lowerBound and: i upperBound)
42 /\ [i upperInclusive ifFalse: [n ~= i upperBound]]
43 /\ [i lowerInclusive ifFalse: [n ~= i lowerBound]]
46 i@(Interval traits) readFrom: src
47 "Reads the mathematical notation of brackets for intervals from the stream."
51 "Look for an open (square or curved) bracket."
53 caseOf: {$( -> [result lowerInclusive := False].
54 $[ -> [result lowerInclusive := True]}
55 otherwise: [error: 'Unexpected character; bad interval start notation.'].
56 i lowerBound := Number readFrom: input.
57 input next = $, ifFalse:
58 [error: 'Expected comma character not found; bad interval separator notation.'].
59 i upperBound := Number readFrom: input.
60 "Look for a closing (square or curved) bracket."
62 caseOf: {$) -> [result upperInclusive := False].
63 $] -> [result upperInclusive := True]}
64 otherwise: [error: 'Unexpected character; bad interval end notation.'].
68 s@(String traits) as: c@(Interval traits)
71 c@(Interval traits) printContentsOn: o@(PrettyPrinterMixin traits) separatedBy: block
76 c lowerBound ifNil: [o ; ' '] ifNotNil: [c lowerBound printOn: o].
78 c upperBound ifNil: [o ; ' '] ifNotNil: [c upperBound printOn: o].
84 i@(Interval traits) isEmpty
85 [i upperBound < i lowerBound].
87 i@(Interval traits) isSingleton
88 [i upperBound = i lowerBound].
90 i@(Interval traits) includesAllOf: c@(Collection traits)
91 [c allSatisfy: #(i includes: _) `er].
93 i1@(Interval traits) includesAllOf: i2@(Interval traits)
95 i1 isEmpty not \/ [i2 isEmpty] \/
96 [i1 lowerBound < i2 lowerBound /\ [i2 upperBound < i1 upperBound]]
99 Interval traits compareAndHashUsingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive. #bestGuess}.
101 i@(Interval traits) < n
102 [i upperBound < n \/ [n = i upperBound /\ [i upperInclusive not]]].
104 n < i@(Interval traits)
105 [n < i lowerBound \/ [n = i lowerBound /\ [i lowerInclusive not]]].
107 i1@(Interval traits) < i2@(Interval traits)
110 ifTrue: [i1 upperBound < i2 lowerBound]
114 i1@(Interval traits) union: i2@(Interval traits)
117 ifTrue: [i1 cloneSettingSlots: #{#upperBound. #lowerBound. #upperInclusive. #lowerInclusive}
118 to: {i1 upperBound max: i2 upperBound.
119 i2 lowerBound min: i2 lowerBound.
120 i1 upperBound > i2 upperBound ifTrue: [i1 upperInclusive] ifFalse: [i2 upperInclusive].
121 i2 lowerBound < i2 lowerBound ifTrue: [i1 lowerInclusive] ifFalse: [i2 lowerInclusive]}]
122 ifFalse: [TODO: 'Answer the union of two disjoint intervals.']
125 i1@(Interval traits) intersect: i2@(Interval traits)
129 ifFalse: [TODO: 'Answer the empty set / Bottom for non-intersecting intervals.']
132 i1@(Interval traits) includesAnyOf: i2@(Interval traits)
134 (i1 upperBound > i2 lowerBound /\ [i1 lowerBound < i2 upperBound])
135 \/ [i2 upperBound > i1 lowerBound /\ [i2 lowerBound < i1 upperBound]]
138 i@(Interval traits) + n
139 [i cloneSettingSlots: #{#upperBound. #lowerBound}
140 to: {i upperBound + n. i lowerBound + n}].
142 i@(Interval traits) - n
143 [i cloneSettingSlots: #{#upperBound. #lowerBound}
144 to: {i upperBound - n. i lowerBound - n}].
146 i@(Interval traits) * n
147 [i cloneSettingSlots: #{#upperBound. #lowerBound}
148 to: {i upperBound * n. i lowerBound * n}].
150 i@(Interval traits) / n
151 [i cloneSettingSlots: #{#upperBound. #lowerBound}
152 to: {i upperBound / n. i lowerBound / n}].
154 i1@(Interval traits) + i2@(Interval traits)
155 [i1 cloneSettingSlots: #{#upperBound. #lowerBound}
156 to: {i1 upperBound + i2 upperBound. i1 lowerBound + i2 lowerBound}].
158 i1@(Interval traits) - i2@(Interval traits)
159 [i1 cloneSettingSlots: #{#upperBound. #lowerBound}
160 to: {i1 lowerBound - i2 upperBound. i1 upperBound - i2 lowerBound}].
162 i1@(Interval traits) * i2@(Interval traits)
165 i1 lowerBound * i2 lowerBound.
166 i1 lowerBound * i2 upperBound.
167 i1 upperBound * i2 lowerBound.
168 i1 upperBound * i2 upperBound
170 i1 cloneSettingSlots: #{#upperBound. #lowerBound}
171 to: {products reduce: #min:`er. products reduce: #max:`er}
174 i1@(Interval traits) / i2@(Interval traits)
177 i1 lowerBound / i2 lowerBound.
178 i1 lowerBound / i2 upperBound.
179 i1 upperBound / i2 lowerBound.
180 i1 upperBound / i2 upperBound
182 i1 cloneSettingSlots: #{#upperBound. #lowerBound}
183 to: {quotients reduce: #min:`er. quotients reduce: #max:`er}
186 i1@(Interval traits) raisedTo: n
192 [i1 cloneSettingSlots: #{#upperBound. #lowerBound}
193 to: {i1 upperBound raisedTo: n. i2 lowerBound raisedTo: n}]
196 collections define: #IntervalComplement &parents: {NoDuplicatesCollection}
199 ic@(IntervalComplement traits) newOn: i
200 [ic cloneSettingSlots: #{#basis} to: {i}].
202 i@(Interval traits) complement
203 [IntervalComplement newOn: i].
205 ic@(IntervalComplement traits) complement
208 ic@(IntervalComplement traits) lowerInclusive
209 [ic basis upperInclusive not].
211 ic@(IntervalComplement traits) upperInclusive
212 [ic basis lowerInclusive not].
214 ic@(IntervalComplement traits) + n
215 [ic cloneSettingSlots: #{#basis} to: {ic basis + n}].
217 ic@(IntervalComplement traits) - n
218 [ic cloneSettingSlots: #{#basis} to: {ic basis - n}].
220 ic@(IntervalComplement traits) * n
221 [ic cloneSettingSlots: #{#basis} to: {ic basis * n}].
223 ic@(IntervalComplement traits) / n
224 [ic cloneSettingSlots: #{#basis} to: {ic basis / n}].