Skip to main content

Value-based argumentation (VAF)

The argumentation-values crate adds value-based argumentation frameworks to the workspace. This page is the conceptual overview; for API details see the rustdoc.

Bench-Capon (2003) extended Dung frameworks with values — each argument promotes a value, and an audience is an ordering over values. Different audiences reach different rational conclusions from the same framework. Our implementation supports the multi-value generalisation from Kaci & van der Torre (2008).

Types at a glance

use argumentation::ArgumentationFramework;
use argumentation_values::{Audience, Value, ValueAssignment, ValueBasedFramework};

let mut base = ArgumentationFramework::new();
base.add_argument("h1");
base.add_argument("c1");
base.add_attack(&"h1", &"c1").unwrap();
base.add_attack(&"c1", &"h1").unwrap();

let mut values = ValueAssignment::new();
values.promote("h1", Value::new("life"));
values.promote("c1", Value::new("property"));

let vaf = ValueBasedFramework::new(base, values);
let life_first = Audience::total([Value::new("life"), Value::new("property")]);

assert!(vaf.accepted_for(&life_first, &"h1").unwrap());
assert!(!vaf.accepted_for(&life_first, &"c1").unwrap());

Defeat semantics (Kaci & van der Torre 2008, Pareto)

Given attack (A, B) in the underlying Dung framework and audience X, A defeats B in the audience-conditioned graph iff:

for every value v_b promoted by B, there exists some value v_a promoted by A such that v_b is not strictly preferred over v_a under X.

Single-value (Bench-Capon 2003) is the degenerate case where each argument promotes exactly one value.

Special cases:

  • A or B promotes no value → A defeats B (no preference can intervene).
  • A value is unranked in the audience → considered incomparable (no strict preference); attacker side wins ties.

Acceptance modes

MethodCostUse case
accepted_for(&audience, &arg)Polynomial-ish (one preferred-extension call)Runtime: "what does this character believe?"
subjectively_accepted(&arg)NP-complete; capped at 6 distinct valuesAuthoring: "is there any audience under which X is accepted?"
objectively_accepted(&arg)co-NP-complete; capped at 6 distinct valuesAuthoring: "is X accepted under every audience? (i.e., universally compelling)"
MultiAudience::common_grounded(&vaf)k × preferred extensions, where k = audience countMulti-character scenes: "which proposals does the whole council agree on?"

The ENUMERATION_LIMIT cap on subjective/objective queries is per Dunne & Bench-Capon (2004). Past 6 values, methods return Err(Error::AudienceTooLarge) — use a fixed-audience query instead.

Hal & Carla, worked

The canonical example. See the engine-driven scene for the live version.

let mut base = ArgumentationFramework::new();
for a in ["h1", "c1", "h2", "c2"] { base.add_argument(a); }
base.add_attack(&"h1", &"c1").unwrap(); // life attacks property
base.add_attack(&"c1", &"h1").unwrap(); // property attacks life
base.add_attack(&"c2", &"h2").unwrap(); // Carla's "my only dose" defeats fairness appeal
base.add_attack(&"h2", &"c1").unwrap(); // Hal's poverty attacks property

let mut values = ValueAssignment::new();
values.promote("h1", Value::new("life"));
values.promote("c1", Value::new("property"));
values.promote("h2", Value::new("fairness"));
values.promote("c2", Value::new("life"));

let vaf = ValueBasedFramework::new(base, values);

// Audience 1: life > property → Hal goes free.
let life_first = Audience::total([Value::new("life"), Value::new("property")]);
let g1 = vaf.grounded_for(&life_first).unwrap();
assert!(g1.contains("h1") && g1.contains("c2"));

// Audience 2: property > life → Hal punished.
let property_first = Audience::total([Value::new("property"), Value::new("life")]);
let g2 = vaf.grounded_for(&property_first).unwrap();
assert!(g2.contains("c1") && g2.contains("c2"));

Encounter bridge integration

encounter-argumentation ships ValueAwareScorer for runtime use:

use encounter_argumentation::{
EncounterArgumentationState, SchemeActionScorer, ValueAwareScorer,
Audience, Value,
};

let state = EncounterArgumentationState::new(catalog);
state.set_audience("alice", Audience::total([Value::new("duty"), Value::new("survival")]));
state.set_audience("bob", Audience::total([Value::new("survival"), Value::new("duty")]));

let scorer = ValueAwareScorer::new(
SchemeActionScorer::new(knowledge, registry, baseline_scorer, 0.3),
&state,
0.2,
);

Per-character audiences flow through the scorer at resolve time — Alice and Bob score the same affordance differently when their value orderings differ.

See the wiring per-character values how-to for a complete worked example.

APX format I/O

ASPARTIX-compatible APX format with VAF extension:

arg(h1).
arg(c1).
att(h1, c1).
att(c1, h1).
val(h1, life).
val(c1, property).
valpref(life, property).

Use argumentation_values::apx::from_apx(text) to parse, to_apx(&vaf, &audience) to serialise. Round-trips preserve the framework + audience. Useful for importing benchmark VAFs from the literature or exporting scenes for analysis in ASPARTIX.

Bibliography

  • Bench-Capon (2003) — the original VAF paper.
  • Atkinson & Bench-Capon (2007) — practical reasoning over VAFs.
  • Kaci, S. & van der Torre, L. (2008). "Preference-based argumentation: Arguments supporting multiple values." International Journal of Approximate Reasoning 48(3): 730–751.
  • Dunne, P.E. & Bench-Capon, T. (2004). "Complexity in Value-Based Argument Systems." JELIA 2004: 360–371.
  • Bodanza, G.A. & Freidin, E. (2023). "Confronting value-based argumentation frameworks with people's assessment of argument strength." Argument & Computation 14(3): 247–273. — empirical critique; informs why we expose SchemeActionScorer's direct value-importance scoring alongside the orthodox VAF defeat semantics.

Further reading