Coverage Summary for Class: RulesAndInfo (it.unibo.tuprolog.argumentation.core.primitives.data)

Class Class, % Method, % Branch, % Line, % Instruction, %
RulesAndInfo 100% (1/1) 100% (2/2) 60.7% (17/28) 84.4% (27/32) 84.1% (232/276)


 package it.unibo.tuprolog.argumentation.core.primitives.data
 
 import it.unibo.tuprolog.argumentation.core.model.terms.ArgumentTerm
 import it.unibo.tuprolog.argumentation.core.primitives.utils.distinctSortedTerms
 import it.unibo.tuprolog.argumentation.core.primitives.utils.sortedTerms
 import it.unibo.tuprolog.argumentation.core.runtime.Arg2pUnificator
 import it.unibo.tuprolog.core.Atom
 import it.unibo.tuprolog.core.List
 import it.unibo.tuprolog.core.Tuple
 import it.unibo.tuprolog.solve.ExecutionContext
 import it.unibo.tuprolog.solve.Signature
 import it.unibo.tuprolog.solve.exception.error.TypeError
 import it.unibo.tuprolog.solve.primitive.Primitive
 import it.unibo.tuprolog.solve.primitive.Solve
 
 /**
  * argument::rulesAndInfo(+RuleId, +Strict, +[Rules, LastDefRules, DefRules, DefPremises], ?SortedRules, ?Info): the rules and
  * the info of an argument built from RuleId on top of some sub-arguments, given the lists of their rules, last
  * defeasible rules, defeasible rules and defeasible premises; Strict tells whether RuleId is strict (strict) or not.
  * Fails if RuleId already occurs among the rules of the sub-arguments, or if it is none and not strict.
  * SortedRules: RuleId and the rules, as sort/2. Info: [LastDefRules, DefRules, DefPremises], each as sortDistinct/2.
  */
 internal object RulesAndInfo : Primitive {
     val signature: Signature = Signature("rulesAndInfo", 5)
 
     override fun solve(request: Solve.Request<ExecutionContext>): Sequence<Solve.Response> {
         val ruleId = request.arguments[0]
         val strict = request.arguments[1].let { it is Atom && it.value == "strict" }
         val parts = request.arguments[2].let { it as? List }?.toList()
         if (parts == null || parts.size != 4) {
             throw TypeError.forGoal(request.context, request.signature, TypeError.Expected.LIST, request.arguments[2])
         }
         val (all, lastDef, def, premises) =
             parts.map { lists ->
                 (lists as? List ?: throw TypeError.forGoal(request.context, request.signature, TypeError.Expected.LIST, lists))
                     .toList()
                     .flatMap {
                         (
                             it as? List ?: throw TypeError.forGoal(
                                 request.context,
                                 request.signature,
                                 TypeError.Expected.LIST,
                                 it,
                             )
                         ).toList()
                     }
             }
         if (all.any { Arg2pUnificator.match(it, ruleId) }) return emptySequence()
         val (newLastDef, newDef) =
             when {
                 strict -> lastDef to def
                 ruleId is Atom && ruleId.value == "none" -> return emptySequence()
                 else -> listOf(ruleId) to listOf(ruleId) + def
             }
         val info =
             ArgumentTerm.info(
                 List.of(List.of(newLastDef).distinctSortedTerms().asReversed()),
                 List.of(List.of(newDef).distinctSortedTerms().asReversed()),
                 List.of(List.of(premises).distinctSortedTerms().asReversed()),
             )
         val rules = List.of(List.of(listOf(ruleId) + all).sortedTerms().asReversed())
         val unifier = Arg2pUnificator.mgu(Tuple.of(request.arguments[3], request.arguments[4]), Tuple.of(rules, info))
         return sequenceOf(if (unifier.isSuccess) request.replyWith(unifier) else request.replyFail())
     }
 }