Coverage Summary for Class: SccModule (it.unibo.tuprolog.argumentation.core.modules.labelling.argument)

Class Class, % Method, % Branch, % Line, % Instruction, %
SccModule 100% (1/1) 100% (4/4) 100% (4/4) 100% (28/28)


 package it.unibo.tuprolog.argumentation.core.modules.labelling.argument
 
 import it.unibo.tuprolog.argumentation.core.modules.PrologModule
 import it.unibo.tuprolog.argumentation.core.primitives.labelling.argument.Selection
 import it.unibo.tuprolog.argumentation.core.primitives.labelling.argument.UndecidedCandidates
 import it.unibo.tuprolog.solve.Signature
 import it.unibo.tuprolog.solve.primitive.Primitive
 
 /**
  * Support module of the SCC-recursive semantics (complete, preferred, stable): their labellings are built one
  * strongly connected component at a time, the semantics only choosing which local labellings to keep.
  */
 object SccModule : PrologModule("prolog.argumentation.graph.labelling.scc", "scc") {
     override val primitives: Map<Signature, Primitive>
         get() = listOf(UndecidedCandidates, Selection).associate { it.signature to it }
 
     override val prologRawTheory: String =
         // language=Prolog
         """
         %! label(+Accept, +Select)
         %  Labellings built one strongly connected component at a time, in topological order.
         %  The labels of a component only depend on the components before it, and are final once it is left.
         %  Within a component the search forces IN its undecided arguments (grounded propagation labels the rest),
         %  then keeps the local labellings that pass Accept and Select:
         %    Accept  admissible - the IN arguments are defended
         %            decided    - admissible, and no argument of the component left UND
         %    Select  all        - every accepted local labelling
         %            maximal    - the accepted ones with a maximal set of IN arguments in the component
         %  Each solution leaves its labelling as the active context, released when the next one is computed.
         label(Accept, Select) :-
             cache_retract(scc_seen(_, _)),
             context_active(Start),
             grounded:::argumentLabelling,
             utils::sccs(Sccs),
             context_active(Root),
             (
                 labelComponents(Accept, Select, Sccs, Root)
             ;
                 context_checkout(Start),
                 context_drop(Root),
                 fail
             ).
 
         labelComponents(_, _, [], Branch) :-
             context_checkout(Branch).
         labelComponents(Accept, Select, [Scc|Sccs], Branch) :-
             context_last(Mark),
             findall(State-Ok, localLabelling(Accept, Scc, Branch, State, Ok), Explored),
             selection(Select, Scc, Explored, Selected),
             context_checkout(Branch),
             % every branch the local search created and did not select
             context_drop_after(Mark, Selected),
             member(Next, Selected),
             (
                 labelComponents(Accept, Select, Sccs, Next)
             ;
                 % a labelling is released once all its continuations are done (Branch by the previous component)
                 Next \== Branch,
                 context_checkout(Branch),
                 context_drop(Next),
                 fail
             ).
 
         % localLabelling(+Accept, +Scc, +Branch, -State, -Ok): State is Branch or a labelling reached from it by
         % forcing IN undecided arguments of Scc, Ok tells whether Accept holds for it
 
         localLabelling(Accept, Scc, Branch, State, Ok) :-
             reachable(Scc, Branch, State),
             context_checkout(State),
             (accepted(Accept, Scc) -> Ok = true ; Ok = false).
 
         accepted(admissible, _) :-
             admissible::admissibleSet.
         accepted(decided, Scc) :-
             admissible::admissibleSet,
             \+ (member(A, Scc), graphStore::argumentLabelById(und, A)).
 
         reachable(_, Branch, Branch).
         reachable(Scc, Branch, State) :-
             findall(I, graphStore::argumentLabelByIdIn(Branch, in, I), Ins),
             undecidedCandidates(Scc, Branch, Candidates),
             member(IdX, Candidates),
             utils::sort([IdX|Ins], Seed),
             \+ cache_check(scc_seen(Scc, Seed)),
             cache_assert(scc_seen(Scc, Seed)),
             graphStore::argumentByIdIn(Branch, IdX, X),
             context_branch(Branch, NewBranch),
             graphStore::unlabelArguments(und),
             graphStore::labelArgument(in, X, IdX),
             grounded::argumentLabelling,
             graphStore::labelledIds(in, Reached),
             utils::sort(Reached, Labelled),
             unexplored(Scc, Seed, Labelled),
             reachable(Scc, NewBranch, State).
 
         % Grounded propagation is monotone, so a labelling only depends on the set of arguments forced IN:
         % scc_seen(Scc, In) marks the labelling reached by forcing In within Scc as explored, whatever the order
 
         unexplored(_, Seed, Seed) :- !.
         unexplored(Scc, _, Labelled) :-
             \+ cache_check(scc_seen(Scc, Labelled)),
             cache_assert(scc_seen(Scc, Labelled)).
         """.trimIndent()
 }