Current scope: arg2p| all classes
|
it.unibo.tuprolog.argumentation.core.primitives.labelling.argument
Coverage Summary for Class: ConflictFreeSubset (it.unibo.tuprolog.argumentation.core.primitives.labelling.argument)
| Class | Method, % | Branch, % | Line, % | Instruction, % |
|---|---|---|---|---|
| ConflictFreeSubset | 100% (3/3) | 100% (6/6) | 100% (47/47) | |
| ConflictFreeSubset$solve$subsets$1 | 100% (1/1) | 87.5% (7/8) | 100% (5/5) | 100% (117/117) |
| Total | 100% (4/4) | 87.5% (7/8) | 100% (11/11) | 100% (164/164) |
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
/**
* conflictFreeSubset(+Args, +Forced, -Set): the subsets of Args including Forced where no argument attacks another
* one (itself included), each once. The search only adds arguments compatible with those already chosen, so every
* branch ends in a solution: the cost grows with the number of sets, not with the subsets of Args.
*/
internal object ConflictFreeSubset : Primitive {
val signature: Signature = Signature("conflictFreeSubset", 3)
override fun solve(request: Solve.Request<ExecutionContext>): Sequence<Solve.Response> {
val args = request.ids(0)
val forced = request.ids(1).toSet()
val graph = request.conflictGraph()
fun subsets(
i: Int,
chosen: List<Term>,
): Sequence<List<Term>> =
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))
if (a !in forced) yieldAll(subsets(i + 1, chosen))
}
return subsets(0, emptyList()).mapNotNull { request.replyList(2, it) }
}
}