Coverage Summary for Class: ClusterSolver (it.unibo.tuprolog.argumentation.parallel.cluster)

Class Method, % Branch, % Line, % Instruction, %
ClusterSolver 80% (8/10) 85.7% (12/14) 90% (81/90)
ClusterSolver$solutions$1 100% (3/3) 100% (2/2) 100% (3/3) 100% (31/31)
Total 84.6% (11/13) 100% (2/2) 88.2% (15/17) 92.6% (112/121)


 @file:Suppress("NON_EXPORTABLE_TYPE")
 
 package it.unibo.tuprolog.argumentation.parallel.cluster
 
 import it.unibo.tuprolog.argumentation.Answer
 import it.unibo.tuprolog.argumentation.Arg2pException
 import it.unibo.tuprolog.argumentation.Solutions
 import it.unibo.tuprolog.argumentation.core.model.Graph
 import it.unibo.tuprolog.argumentation.parallel.LABELLINGS
 import it.unibo.tuprolog.argumentation.parallel.federation.Site
 import it.unibo.tuprolog.argumentation.parallel.graphsOf
 import it.unibo.tuprolog.argumentation.solutionsOf
 import kotlin.js.JsExport
 import kotlin.js.JsName
 import it.unibo.tuprolog.solve.Solution as LogicSolution
 
 /**
  * A cluster as a solver of arg2p, as `Arg2p` is one, on the theory and the flags of the cluster: any goal solved as the
  * standard solver solves it (buildLabelSets/3, answerQuery/4, the Prolog predicates of the theory, ...), one solution
  * at a time, with the graph of each, and the answers of queries. The graph a goal needs is built by the workers of the
  * cluster and of the sites it is federated with (the whole graph, or, in query mode, the part the statements it
  * evaluates depend on, grown by the later ones), and labelled by the catalog of the cluster; the stages of a
  * resolution are not kept, the graph of the last one alone.
  */
 @JsExport
 class ClusterSolver internal constructor(
     private val site: Site,
     private val replies: Replies,
 ) {
     private val solved = Solved()
 
     /** Where what the solver prints goes, as the solutions are given: the standard output by default */
     var output: (String) -> Unit
         get() = solved.output
         set(value) {
             solved.output = value
         }
 
     /**
      * The solutions of [goal], Prolog text, given one at a time as they are asked for (the first one computed at once)
      *
      * @throws Arg2pException for a goal that cannot be read
      */
     fun solve(goal: String): Solutions = solutionsOf(solutions(goal))
 
     /**
      * The statements for [query], Prolog text, labelled in, out and und (see answerQuery/4)
      *
      * @throws Arg2pException if the evaluation halts (a theory its profile refuses, a query that cannot be parsed)
      */
     fun answer(query: String): Answer = solved.answer(replies.replied { site.answer(query, it) })
 
     /**
      * The graph of each labelling of the theory: one, or several for a semantics with several labellings (preferred,
      * stable, ...)
      *
      * @throws Arg2pException if the evaluation halts (a theory its profile refuses)
      */
     @JsExport.Ignore
     @JsName("graphsList")
     fun graphs(): List<Graph> = graphsOf(solutions(LABELLINGS), ::graph)
 
     /** The graph of each labelling of the theory (an array in JavaScript) */
     @JsName("graphs")
     fun graphArray(): Array<Graph> = graphs().toTypedArray()
 
     /** The graph of the last solution given: the one of the last stage of its resolution (none before the first) */
     fun graph(): Graph = solved.graph
 
     /**
      * Stops the goal being solved, from another thread: its solution waited for is a halt, at once (`The evaluation was
      * stopped`), and the work of the cluster for it is given up; the next goals are solved as before. Nothing is done
      * if no goal is being solved.
      */
     fun stop() = site.stop()
 
     // The solutions of [goal], Prolog text, each reply waited for as it is asked for
     private fun solutions(goal: String): Iterator<LogicSolution> {
         val given = Given(goal, solved.checked(replies.replied { site.query(goal, it) }), solved)
         return object : Iterator<LogicSolution> {
             override fun hasNext(): Boolean = given.hasNext()
 
             override fun next(): LogicSolution = given.given(given.first() ?: replies.replied { site.next(given.run, it) })
         }
     }
 }