@@ -154,33 +154,39 @@ object Lattice {
154
154
* For an `enum E { case A, B, C }` it will be `A < B < C` */
155
155
inline def sumLattice [T ](using sm : Mirror .SumOf [T ]): Lattice [T ] =
156
156
val lattices : Tuple = summonAll[Tuple .Map [sm.MirroredElemTypes , Lattice ]]
157
- new Derivation .SumLattice [T ](sm, lattices)
157
+ new Derivation .SumLattice [T ](Derivation . MirrorOrdinal ( sm, lattices) )
158
158
159
159
inline def productLattice [T <: Product ](using pm : Mirror .ProductOf [T ]): Lattice [T ] = {
160
160
val lattices : Tuple = summonAll[Tuple .Map [pm.MirroredElemTypes , Lattice ]]
161
161
val bottoms : Tuple = Derivation .summonAllMaybe[Tuple .Map [pm.MirroredElemTypes , Bottom ]]
162
162
new Derivation .ProductLattice [T ](lattices, bottoms, pm, valueOf[pm.MirroredLabel ])
163
163
}
164
164
165
+ trait OrdinalLattices [T ] {
166
+ def compare (left : T , right : T ): Int
167
+ def lattice (elem : T ): Lattice [T ]
168
+ }
169
+
170
+
165
171
object Derivation {
166
172
167
- class SumLattice [T ](sm : Mirror .SumOf [T ], lattices : Tuple ) extends Lattice [T ] {
173
+ case class MirrorOrdinal [T ](sm : Mirror .SumOf [T ], lattices : Tuple ) extends OrdinalLattices [T ] {
174
+ def compare (left : T , right : T ): Int = Integer .compare(sm.ordinal(left), sm.ordinal(right))
175
+ override def lattice (elem : T ): Lattice [T ] = lattices.productElement(sm.ordinal(elem)).asInstanceOf [Lattice [T ]]
176
+ }
177
+
168
178
169
- private def lat ( i : Int ) : Lattice [T ] = lattices.productElement(i). asInstanceOf [ Lattice [T ]]
179
+ class SumLattice [ T ]( ol : OrdinalLattices [T ]) extends Lattice [T ] {
170
180
171
181
def merge (left : T , right : T ): T =
172
- val lo = sm.ordinal(left)
173
- val ro = sm.ordinal(right)
174
- Integer .compare(lo, ro) match
175
- case 0 => lat(lo).merge(left, right)
182
+ ol.compare(left, right) match
183
+ case 0 => ol.lattice(left).merge(left, right)
176
184
case x if x < 0 => right
177
185
case x if x > 0 => left
178
186
179
187
override def subsumption (left : T , right : T ): Boolean =
180
- val lo = sm.ordinal(left)
181
- val ro = sm.ordinal(right)
182
- Integer .compare(lo, ro) match
183
- case 0 => lat(lo).subsumption(left, right)
188
+ ol.compare(left, right) match
189
+ case 0 => ol.lattice(left).subsumption(left, right)
184
190
case other => other < 0
185
191
}
186
192
0 commit comments