Meta-argumentation

Ordinarily, a theory argues about statements: rules derive conclusions, and conclusions conflict. The meta features let a theory argue about the argumentation machinery itself — about which rules apply, what counts as a conflict, which rule prevails, and who carries the burden of persuasion.

Each of them turns something that is normally fixed (declared as a fact, or built into the engine) into something a rule can conclude, and therefore something another argument can attack.

FeatureNormallyAs a meta feature
Rulesa rule always appliesmetaRules — a rule applies only if applicable/1 is argued
Conflictsconflict/2 facts and built-in conflictsmetaConflicts — rules conclude conflict/2
Preferencessup/2 factsgraphExtension(defeasiblePref) — rules conclude sup/2
Burden of persuasionbp/1 facts read by the bp_grounded semanticsgraphExtension(bp) — rules conclude bp/1

The meta features are applied while the argumentation graph is built, which the goal-directed evaluation skips. Turn queryMode off when you use them, otherwise they are silently ignored.


Arguable rules

metaRules adds an implicit premise applicable(RuleName) to every rule. A rule then fires only if something argues that it is applicable, which makes rule application itself defeasible.

metaRules.

r1 : p => q.
f1 :=> p.

q is not derived: nothing argues that r1 applies. Supplying the missing premise brings it back:

metaRules.

r1 : p => q.
f1 :=> p.
f2 :=> applicable(r1).
?- arg2p::buildLabelSets(In, Out, Und).

In = [[applicable(r1)], [q], [p]]

Try it — remove the applicable/1 premise and q disappears.

Because applicable/1 is an ordinary conclusion, a second rule can attack it — for instance concluding -applicable(r1) when the rule’s conditions of use are not met.


Arguable conflicts

Without metaConflicts, conflicts come from the built-in table (a versus -a, the deontic pairs) plus any conflict/2 facts in the theory. With metaConflicts, they come from arguments: whatever an argument concludes as conflict/2 becomes a conflict.

metaConflicts.

r0 : [] => conflict(a, b).
f1 :=> a.
f2 :=> b.
?- arg2p::buildLabelSets(In, Out, Und).

In  = [[conflict(a, b)], [a]]
Out = [[b]]

Without r0, a and b coexist happily; the meta conflict is what sets them against each other.

Try it

The conclusion has to name the two statements directly — conflict(a, b), not conflict([a], [b]). A rule concluding the list form parses fine and is simply never matched.

Since the conflict is a conclusion, it can be attacked: an argument for -conflict(a, b) removes the clash again.


Arguable preferences

sup/2 facts are static. To let rules argue about priority, enable one of the defeasible preference models:

graphExtension(defeasiblePref).

r1 : p => q.
r2 : s => -q.
f1 :=> p.
f2 :=> s.
rs : [] => sup(r1, r2).
?- arg2p::buildLabelSets(In, Out, Und).

In  = [[sup(r1, r2)], [s], [q], [p]]
Out = [[- q]]

q prevails because an argument establishes that r1 outranks r2. Under the plain graphExtension(standardPref) the same theory leaves both conclusions undecided: static preference handling reads sup/2 facts only, and ignores a sup/2 that is merely concluded.

Try it — switch the extension to standardPref alone and the preference stops applying.

defeasiblePref covers comparisons that rest on a single superiority. When the comparator has to weigh several superiorities at once — as the elitist and democrat comparisons do over sets of rules — use graphExtension(defeasibleAllPref) instead, which also exposes the preference as a preference/1 statement. The two models are described in the CILC paper listed under References.


Arguable burden of persuasion

This is the one most easily confused with a semantics, so it is worth stating the difference plainly.

As a fact, the burden is input to the labelling: the bp_grounded family reads bp/1 facts and uses them to break deadlocks.

argumentLabellingMode(bp_grounded).

bp(guilty).
r1 : evidence => guilty.
r2 : alibi => -guilty.
f1 :=> evidence.
f2 :=> alibi.
?- arg2p::buildLabelSets(In, Out, Und).

Out = [[guilty]]

As a rule conclusion, with graphExtension(bp), the burden becomes part of the graph: the engine builds an argument for bp(guilty) and an artificial argument for -burdmet([guilty]), recording that the burden has not been met, and attacks the burdened argument with it.

graphExtension(bp).

r0 : [] => bp(guilty).
r1 : evidence => guilty.
r2 : alibi => -guilty.
f1 :=> evidence.
f2 :=> alibi.
?- arg2p::buildLabelSets(In, Out, Und).

In  = [[bp(guilty)], [- burdmet([guilty])], [- guilty], [evidence], [alibi]]
Out = [[guilty]]

The outcome is the same as the fact form — guilty is OUT — which is the point: the two routes express the same burden, and only differ in whether it can be argued about.

Try it

And it can. Add a reason to doubt the allocation:

rx : doubt => -bp(guilty).
f0 :=> doubt.
?- arg2p::buildLabelSets(In, Out, Und).

Und = [[bp(guilty)], [- burdmet([guilty])], [- bp(guilty)], [- guilty], [guilty]]

Now that it is disputed whether the burden falls on guilty at all, the burden argument, its -burdmet/1 consequence and the burdened statement are all undecided: the theory argues about who has to prove what, not merely about what is provable.

Try it — the contested version, for comparison.

The meta-argumentation account of the burden of persuasion is described in Pisano, Calegari, Omicini and Sartor; see References.