@@ -116,15 +116,15 @@ trait SpaceLogic {
116
116
/** Simplify space such that a space equal to `Empty` becomes `Empty` */
117
117
def simplify (space : Space )(using Context ): Space = trace(s " simplify ${show(space)} --> " , debug, show)(space match {
118
118
case Prod (tp, fun, spaces) =>
119
- val sps = spaces.map (simplify(_) )
119
+ val sps = spaces.mapconserve (simplify)
120
120
if (sps.contains(Empty )) Empty
121
121
else if (canDecompose(tp) && decompose(tp).isEmpty) Empty
122
- else Prod (tp, fun, sps)
122
+ else if sps eq spaces then space else Prod (tp, fun, sps)
123
123
case Or (spaces) =>
124
- val spaces2 = spaces.map(simplify(_) ).filter(_ != Empty )
124
+ val spaces2 = spaces.map(simplify).filter(_ != Empty )
125
125
if spaces2.isEmpty then Empty
126
- else if spaces2.lengthCompare( 1 ) == 0 then spaces2.head
127
- else Or (spaces2)
126
+ else if spaces2.lengthIs == 1 then spaces2.head
127
+ else if spaces2.corresponds(spaces)(_ eq _) then space else Or (spaces2)
128
128
case Typ (tp, _) =>
129
129
if (canDecompose(tp) && decompose(tp).isEmpty) Empty
130
130
else space
@@ -164,12 +164,15 @@ trait SpaceLogic {
164
164
List (space)
165
165
}
166
166
167
- /** Is `a` a subspace of `b`? Equivalent to `a - b == Empty`, but faster */
167
+ /** Is `a` a subspace of `b`? Equivalent to `simplify(simplify(a) - simplify(b)) == Empty`, but faster */
168
168
def isSubspace (a : Space , b : Space )(using Context ): Boolean = trace(s " isSubspace( ${show(a)}, ${show(b)}) " , debug) {
169
169
def tryDecompose1 (tp : Type ) = canDecompose(tp) && isSubspace(Or (decompose(tp)), b)
170
170
def tryDecompose2 (tp : Type ) = canDecompose(tp) && isSubspace(a, Or (decompose(tp)))
171
171
172
- (simplify(a), simplify(b)) match {
172
+ val a2 = simplify(a)
173
+ val b2 = simplify(b)
174
+ if (a ne a2) || (b ne b2) then isSubspace(a2, b2)
175
+ else (a, b) match {
173
176
case (Empty , _) => true
174
177
case (_, Empty ) => false
175
178
case (Or (ss), _) =>
@@ -266,9 +269,11 @@ trait SpaceLogic {
266
269
tryDecompose2(tp2)
267
270
else
268
271
a
272
+ case (Prod (tp1, fun1, ss1), Prod (tp2, fun2, ss2))
273
+ if (! isSameUnapply(fun1, fun2)) => a
274
+ case (Prod (tp1, fun1, ss1), Prod (tp2, fun2, ss2))
275
+ if (fun1.symbol.name == nme.unapply && ss1.length != ss2.length) => a
269
276
case (Prod (tp1, fun1, ss1), Prod (tp2, fun2, ss2)) =>
270
- if (! isSameUnapply(fun1, fun2)) return a
271
- if (fun1.symbol.name == nme.unapply && ss1.length != ss2.length) return a
272
277
273
278
val range = (0 until ss1.size).toList
274
279
val cache = Array .fill[Space | Null ](ss2.length)(null )
0 commit comments