Coverage Summary for Class: Modules (it.unibo.tuprolog.argumentation.core.runtime.modules)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| Modules |
100%
(1/1)
|
60%
(3/5)
|
50%
(3/6)
|
83.3%
(10/12)
|
87.3%
(96/110)
|
package it.unibo.tuprolog.argumentation.core.runtime.modules
import it.unibo.tuprolog.argumentation.core.Arg2pSolver
import it.unibo.tuprolog.argumentation.core.modules.Loadable
import it.unibo.tuprolog.core.Atom
import it.unibo.tuprolog.solve.ExecutionContext
import it.unibo.tuprolog.solve.exception.error.ExistenceError
import it.unibo.tuprolog.solve.library.Runtime
import it.unibo.tuprolog.solve.primitive.Solve
/**
* The modules of an arg2p solver (its dynamic libraries), loaded on their first call: each solves its goals against
* the libraries of the solver, but for the other modules, and its own.
*/
internal class Modules(
private val solver: Arg2pSolver,
) {
private val loaded = HashMap<String, Module>()
private val moduleAliases: Set<String> by lazy { solver.dynamicLibraries().map { it.alias }.toSet() }
/**
* The module named [name], called by [request] (whose libraries the ones of the module are built from): an
* existence error when the solver has no such module
*/
fun of(
request: Solve.Request<ExecutionContext>,
name: Atom,
): Module = loaded.getOrPut(name.value) { load(request, name) }
/** Forgets the modules loaded so far */
fun clear() = loaded.clear()
private fun load(
request: Solve.Request<ExecutionContext>,
name: Atom,
): Module {
val library =
solver.dynamicLibraries().firstOrNull { (it as? Loadable)?.identifier() == name.value }
?: throw ExistenceError.forResource(request.context, name.value)
val callerLibraries = request.context.libraries.libraries
val shared = Runtime.of(callerLibraries.filterNot { it.alias in moduleAliases })
return Module(name.value, shared + library.content())
}
}