You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
2.0 KiB
Kotlin
63 lines
2.0 KiB
Kotlin
package net.cijber.pubgrub
|
|
|
|
import net.cijber.pubgrub.packages.PackageSelection
|
|
import net.cijber.pubgrub.stubs.PackageId
|
|
import net.cijber.pubgrub.stubs.Version
|
|
import net.cijber.pubgrub.version.VersionConstraint
|
|
|
|
|
|
open class Term<P : PackageId, V : Version<V>>(val pkgSelection: PackageSelection<P, V>, val exclusive: Boolean) {
|
|
val constraint
|
|
get() = pkgSelection.constraint
|
|
|
|
val pkg
|
|
get() = pkgSelection.pkg
|
|
|
|
val inverse by lazy {
|
|
Term(pkgSelection, !exclusive)
|
|
}
|
|
|
|
infix fun relation(rhs: Term<P, V>): SetRelation {
|
|
if (rhs.pkg !== pkg) {
|
|
throw RuntimeException("Relations between terms can only be compared if they have the same package id")
|
|
}
|
|
|
|
val rhsConstraint = rhs.constraint
|
|
if (!rhs.exclusive) {
|
|
if (exclusive) {
|
|
if (rhsConstraint.allowsAll(constraint))
|
|
return SetRelation.Subset
|
|
}
|
|
}
|
|
|
|
return SetRelation.Disjoint
|
|
}
|
|
|
|
fun intersect(rhs: Term<P, V>): Term<P, V>? {
|
|
if (rhs.pkg !== pkg) {
|
|
throw RuntimeException("Relations between terms can only be compared if they have the same package id")
|
|
}
|
|
|
|
return if (exclusive != rhs.exclusive) {
|
|
val positive = if (!exclusive) this else rhs
|
|
val negative = if (!exclusive) rhs else this
|
|
|
|
nonEmptyTerm(positive.constraint.difference(negative.constraint), false)
|
|
} else if (!exclusive) {
|
|
nonEmptyTerm(constraint.intersect(rhs.constraint), false)
|
|
} else {
|
|
nonEmptyTerm(constraint.union(rhs.constraint), true)
|
|
}
|
|
}
|
|
|
|
private fun nonEmptyTerm(constraint: VersionConstraint<V>, exclusive: Boolean): Term<P, V>? {
|
|
if (constraint.isEmpty) return null
|
|
|
|
return Term(PackageSelection(pkg, constraint), exclusive)
|
|
}
|
|
|
|
fun satisfies(term: Term<P, V>): Boolean = term.pkg == pkg &&
|
|
(relation(term) == SetRelation.Subset || relation(term) == SetRelation.Equal)
|
|
|
|
fun difference(rhs: Term<P, V>) = intersect(rhs.inverse)
|
|
} |