Current scope: arg2p| all classes
|
it.unibo.tuprolog.argumentation.core.primitives.labelling.argument
Coverage Summary for Class: NaiveSubset (it.unibo.tuprolog.argumentation.core.primitives.labelling.argument)
| Class | Method, % | Branch, % | Line, % | Instruction, % |
|---|---|---|---|---|
| NaiveSubset | 100% (3/3) | 100% (7/7) | 100% (55/55) | |
| NaiveSubset$solve$subsets$1 | 100% (1/1) | 100% (14/14) | 100% (9/9) | 100% (213/213) |
| Total | 100% (4/4) | 100% (14/14) | 100% (16/16) | 100% (268/268) |
package it.unibo.tuprolog.argumentation.core.primitives.labelling.argument
import it.unibo.tuprolog.argumentation.core.primitives.graph.conflictGraph
import it.unibo.tuprolog.argumentation.core.primitives.ids
import it.unibo.tuprolog.argumentation.core.primitives.replyList
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.solve.ExecutionContext
import it.unibo.tuprolog.solve.Signature
import it.unibo.tuprolog.solve.primitive.Primitive
import it.unibo.tuprolog.solve.primitive.Solve
/**
* naiveSubset(+Args, +Forced, +In, -Set): the maximal conflict-free subsets of Args including Forced, each once:
* every argument of Args left out either attacks itself or conflicts with an argument of Set or In (already IN).
* An argument left out that no later argument can conflict with prunes the search.
*/
internal object NaiveSubset : Primitive {
val signature: Signature = Signature("naiveSubset", 4)
override fun solve(request: Solve.Request<ExecutionContext>): Sequence<Solve.Response> {
val args = request.ids(0)
val forced = request.ids(1).toSet()
val alreadyIn = request.ids(2)
val graph = request.conflictGraph()
// pending: arguments left out that nothing chosen conflicts with yet
fun subsets(
i: Int,
chosen: List<Term>,
pending: List<Term>,
): Sequence<List<Term>> =
sequence {
if (pending.any { x -> (i until args.size).none { graph.conflict(x, args[it]) } }) return@sequence
if (i == args.size) {
yield(chosen)
return@sequence
}
val a = args[i]
if (!graph.selfAttacking(a) && chosen.none { graph.conflict(a, it) }) {
yieldAll(subsets(i + 1, chosen + a, pending.filterNot { graph.conflict(it, a) }))
}
if (a !in forced) {
val blocked = graph.selfAttacking(a) || (chosen + alreadyIn).any { graph.conflict(a, it) }
yieldAll(subsets(i + 1, chosen, if (blocked) pending else pending + a))
}
}
return subsets(0, emptyList(), emptyList()).mapNotNull { request.replyList(3, it) }
}
}