Coverage Summary for Class: ContextClosure (it.unibo.tuprolog.argumentation.core.primitives.context)

Class Class, % Method, % Branch, % Line, % Instruction, %
ContextClosure 100% (1/1) 33.3% (1/3) 0% (0/10) 15% (3/20) 12.2% (17/139)


 package it.unibo.tuprolog.argumentation.core.primitives.context
 
 import it.unibo.tuprolog.argumentation.core.primitives.PrimitiveWithSignature
 import it.unibo.tuprolog.argumentation.core.runtime.Arg2pUnificator
 import it.unibo.tuprolog.argumentation.core.runtime.context.ContextBranches
 import it.unibo.tuprolog.core.Struct
 import it.unibo.tuprolog.core.Term
 import it.unibo.tuprolog.core.Var
 import it.unibo.tuprolog.solve.ExecutionContext
 import it.unibo.tuprolog.solve.Signature
 import it.unibo.tuprolog.solve.primitive.Solve
 
 /**
  * context_closure(+Functor, +From, ?To): To is reachable from From through one or more Functor(X, Y) facts,
  * each reachable term once (breadth first)
  */
 internal class ContextClosure(
     private val branches: ContextBranches,
 ) : PrimitiveWithSignature {
     override val signature = Signature("context_closure", 3)
 
     override fun solve(request: Solve.Request<ExecutionContext>): Sequence<Solve.Response> {
         val functor = request.arguments[0].castToAtom().value
         val store = branches.selected
         val next = Var.of("Next")
         val visited = LinkedHashSet<Term>()
         val queue = ArrayDeque<Term>().apply { addLast(request.arguments[1]) }
         while (queue.isNotEmpty()) {
             val current = queue.removeFirst()
             store.solve(Struct.of(functor, current, next)).forEach { solution ->
                 val reached = solution[next] ?: return@forEach
                 if (visited.add(reached)) queue.addLast(reached)
             }
         }
         val target = request.arguments[2]
         return visited.asSequence().mapNotNull { reached ->
             Arg2pUnificator
                 .mgu(target, reached)
                 .takeIf { it.isSuccess }
                 ?.let { request.replyWith(it) }
         }
     }
 }