package net.cijber.pubgrub import net.cijber.pubgrub.packages.PackageSelection import net.cijber.pubgrub.stubs.PackageId import net.cijber.pubgrub.stubs.Version class PartialSolution
> {
private var decisionLevel = 0
private val assignments = mutableListOf >()
private val negative = mutableMapOf >()
infix fun relation(term: Term ): SetRelation {
positive.get(term.pkg)?.let {
return it relation term
}
negative.get(term.pkg)?.let {
return it relation term
}
return SetRelation.Overlaps
}
fun derive(pkg: PackageSelection , exclusive: Boolean, incompatibility: Incompatibility ) {
assign(Assignment(pkg, !exclusive, incompatibility, decisionLevel, assignments.count()))
}
private fun assign(assignment: Assignment ) {
assignments.add(assignment)
register(assignment)
}
private fun register(assignment: Assignment ) {
val pkg = assignment.pkg
val oldPositive = positive[pkg]
if (oldPositive != null) {
positive.remove(pkg)
oldPositive.intersect(assignment)?.let {
positive[pkg] = it
}
}
val oldNegative = negative[pkg]
val term = if (oldNegative == null) {
assignment
} else {
assignment.intersect(oldNegative)!!
}
if (!term.exclusive) {
negative.remove(pkg)
positive[pkg] = term
} else {
negative[pkg] = term
}
}
fun satisfier(term: Term ): Assignment {
var assignedTerm: Term ? = null;
for (assignment in assignments) {
if (assignment.pkg != term.pkg) continue
assignedTerm = if (assignedTerm == null) {
assignment
} else {
assignedTerm.intersect(assignment)
}
if (assignedTerm?.satisfies(term) == true) {
return assignment
}
}
error("[BUG] $term is not satisfied")
}
fun backtrack(decisionLevel: Int) {
backtracking = true
val packages = mutableSetOf ()
while (assignments.lastOrNull()?.decisionLevel?.let { it > decisionLevel } == true) {
val removed = assignments.removeAt(assignments.lastIndex)
packages.add(removed.pkg)
if (removed.isDecision) {
decisions.remove(removed)
}
}
for (pkg in packages) {
positive.remove(pkg)
negative.remove(pkg)
}
for (assignment in assignments) {
if (packages.contains(assignment.pkg)) {
register(assignment)
}
}
}
}