Coverage Summary for Class: ArgumentBuilderModule (it.unibo.tuprolog.argumentation.core.modules.graph.argument)

Class Class, % Method, % Branch, % Line, % Instruction, %
ArgumentBuilderModule 100% (1/1) 100% (3/3) 100% (3/3) 100% (7/7)


 package it.unibo.tuprolog.argumentation.core.modules.graph.argument
 
 import it.unibo.tuprolog.argumentation.core.modules.PrologModule
 
 /**
  * The arguments of a theory (module `argumentBuilder`): every argument its premises and rules make, built round after
  * round from the conclusions of the previous one, and saved in the context with their supports (see the module
  * graphStore).
  */
 object ArgumentBuilderModule : PrologModule("prolog.argumentation.graph.arguments", "argumentBuilder") {
     override val prologRawTheory: String =
         // language=Prolog
         """
         %! buildArguments
         %  The arguments made of a premise, those of the rules with no premise to support, and then, round after round,
         %  those of the rules using a conclusion of the previous round.
         buildArguments :-
             buildArgumentsFromPremises,
             buildArgumentsFromEmptyRules,
             findall([RuleID, RuleBody, RuleHead], (
                 parser::classicRule(RuleID, RuleBody, RuleHead),
                 \+ emptyRule([RuleID, RuleBody, RuleHead])
             ), Rules),
             context_retract(graphRule(_)),
             storeRules(Rules),
             findall(X, graphStore::newConclusion(a, [X]), N),
             buildArgumentsFromRules(N, b).
 
         % The rules are kept in the context rather than passed around: they are not ground, so carrying their list
         % in the goals makes every resolution step copy it. Asserted from the last, as context_check returns the
         % newest clauses first.
         storeRules([]).
         storeRules([Rule|Rules]) :-
             storeRules(Rules),
             context_assert(graphRule(Rule)).
 
         buildArgumentsFromPremises :-
             findall(_, (
                 parser::classicRule(PremiseID, Premise),
                 defeasibleIds(PremiseID, DefeasiblePremises),
                 argument::infoParts(Info, [], [], DefeasiblePremises),
                 argument::new([PremiseID], none, Premise, [], Info, Argument),
                 graphStore::saveArgument(a, Premise, Argument)
             ), _).
 
         buildArgumentsFromEmptyRules :-
             findall(_, (
                 emptyRule([RuleID, RulePrem, RuleHead]),
                 ruleBodyIsSupported(RulePrem, rule(RuleID, RuleHead, RulePrem), [[], [], [], []], _),
                 defeasibleIds(RuleID, DefeasibleRules),
                 argument::infoParts(Info, DefeasibleRules, DefeasibleRules, []),
                 argument::new([RuleID], RuleID, RuleHead, RulePrem, Info, Argument),
                 graphStore::saveArgument(a, RuleHead, Argument)
             ), _).
 
         % A rule with no premise to support with an argument: only contraries and Prolog checks
         emptyRule([RuleID, Body, RuleHead]) :-
             parser::classicRule(RuleID, Body, RuleHead),
             \+ (member(X, Body), X \= ~(_), X \= prolog(_)).
 
         % The defeasible ones among the rule or premise Id: none if strict
         defeasibleIds(Id, []) :- parser::checkStrict(Id), !.
         defeasibleIds(Id, [Id]).
 
         % A round fires every rule whose body uses a conclusion derived in the previous round (N), tagging the new
         % conclusions with Tn: the rounds go on while they derive something
         buildArgumentsFromRules(N, Tn) :-
             findall(_, (
                 context_check(graphRule([Id, Body, Conc])),
                 utils::containsAny(Body, N),
                 buildArgumentsFromRule(Tn, [Id, Body, Conc])
             ), _),
             (graphStore::newConclusion(Tn, _) -> nextRound(Tn) ; true).
 
         buildArgumentsFromRule(Tn, [RuleID, RuleBody, RuleHead]) :-
             ruleBodyIsSupported(RuleBody, rule(RuleID, RuleHead, RuleBody), [[], [], [], []], Argument),
             graphStore::saveArgument(Tn, RuleHead, Argument).
 
         nextRound(Tn) :-
             otherTag(Tn, Tx),
             graphStore::forgetNewConclusions(Tx),
             findall(X, graphStore::newConclusion(Tn, [X]), N),
             buildArgumentsFromRules(N, Tx).
 
         otherTag(a, b).
         otherTag(b, a).
 
         ruleStrictness(Id, strict) :- parser::checkStrict(Id), !.
         ruleStrictness(_, defeasible).
 
         % ruleBodyIsSupported(Body, rule(RuleID, RuleHead, RuleBody), [All, LastDefRules, DefRules, DefPremises], Argument):
         % Argument is built from RuleID by supporting each statement in Body with a saved argument, collecting the rules
         % and premises of the supports. Only Body is matched in the clause heads, everything else is unpacked in the
         % bodies: matching heads with many arguments against every clause is what makes this predicate expensive.
         ruleBodyIsSupported([], Rule, Acc, Argument) :-
             Rule = rule(RuleID, RuleHead, RuleBody),
             ruleStrictness(RuleID, Strict),
             argument::rulesAndInfo(RuleID, Strict, Acc, Rules, Info),
             argument::new(Rules, RuleID, RuleHead, RuleBody, Info, Argument),
             \+ graphStore::argumentFor(RuleHead, Argument).
         ruleBodyIsSupported([~(_)|Others], Rule, Acc, Argument) :-
             ruleBodyIsSupported(Others, Rule, Acc, Argument).
         ruleBodyIsSupported([prolog(Check)|Others], Rule, Acc, Argument) :-
             (callable(Check) -> call(Check); Check),
             ruleBodyIsSupported(Others, Rule, Acc, Argument).
         ruleBodyIsSupported([Statement|Others], Rule, Acc, Argument) :-
             Acc = [All, LastDef, Def, Prem],
             graphStore::argumentFor([Statement], Support),
             argument::rules(Support, Rules),
             argument::info(Support, Info),
             argument::infoParts(Info, SupportLastDef, SupportDef, SupportPrem),
             ruleBodyIsSupported(Others, Rule, [[Rules|All], [SupportLastDef|LastDef], [SupportDef|Def], [SupportPrem|Prem]], Argument),
             graphStore::saveSupport(Support, Argument).
         """.trimIndent()
 }