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 var backtracking = false private val decisions = mutableListOf>() private val positive = mutableMapOf>() 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) } } } }