Import/export APX (ASPARTIX interop)
Parse ASPARTIX-compatible APX text into a ValueBasedFramework, or serialise a framework + audience back to APX. Useful for importing benchmark VAFs from the literature, exporting scenes for analysis in ASPARTIX, or sharing fixture frameworks across tools.
Learning objective: round-trip a 4-argument VAF through APX text in under 5 minutes — parse a fixture, modify it programmatically, serialise the result.
Prerequisites
- The
argumentation-valuescrate available (path-dep or registry-dep). - Basic familiarity with
ValueBasedFramework(see Value-based argumentation).
What is APX?
ASPARTIX (TU Wien) defines a Prolog-style fact format for VAFs:
arg(h1).
arg(c1).
att(h1, c1).
att(c1, h1).
val(h1, life).
val(c1, property).
valpref(life, property).
arg(name).— argumentatt(attacker, target).— attack edgeval(arg, value).— value-promotionvalpref(a, b).—astrictly preferred overbin the audience
Comments start with %. Whitespace is ignored.
Step 1: Add the dep
[dependencies]
argumentation-values = "0.1"
Step 2: Parse APX text
use argumentation_values::apx::from_apx;
let input = r#"
% Hal & Carla in APX
arg(h1).
arg(c1).
att(h1, c1).
att(c1, h1).
val(h1, life).
val(c1, property).
valpref(life, property).
"#;
let (vaf, audience) = from_apx(input)?;
assert_eq!(vaf.base().len(), 2);
from_apx returns Result<(ValueBasedFramework<String>, Audience), Error> — argument labels are owned Strings matching the arg(name) identifiers.
Step 3: Use the parsed framework
use argumentation_values::Value;
assert!(audience.prefers(&Value::new("life"), &Value::new("property")));
assert!(vaf.accepted_for(&audience, &"h1".to_string())?);
Step 4: Serialise back to APX
use argumentation_values::apx::to_apx;
let serialised = to_apx(&vaf, &audience);
println!("{}", serialised);
The output is sorted alphabetically (deterministic). Round-trip preserves semantics — the argument set, attack set, value-promotion set, and strict-preference relation — but does not preserve insertion order, comments, or redundant valpref facts. Round-tripping the result through from_apx again gives an equivalent framework.
Step 5: Loop the round trip in a test
#[test]
fn round_trip_preserves_semantics() {
let original = sample_vaf_apx();
let (vaf, audience) = from_apx(&original).unwrap();
let serialised = to_apx(&vaf, &audience);
let (vaf2, audience2) = from_apx(&serialised).unwrap();
assert_eq!(vaf2.base().len(), vaf.base().len());
for v in audience.values() {
for u in audience.values() {
assert_eq!(audience.prefers(v, u), audience2.prefers(v, u));
}
}
}
Parse error handling
Errors carry the line number (1-indexed) and a human-readable reason:
let bad = "arg(a).\nbogus(stuff).\n";
match from_apx(bad) {
Err(argumentation_values::Error::ApxParse { line, reason }) => {
eprintln!("APX error at line {line}: {reason}");
}
_ => unreachable!(),
}
When NOT to use this
- Hand-authored fixtures that won't outlive the test file. Just build the
ValueBasedFrameworkprogrammatically. - Production scene serialisation — APX has no notion of actor attribution, scheme bindings, or affordance state. Use a richer format (or just snapshot
EncounterArgumentationStatedirectly). - Cycles in
valpref— APX cycles silently collapse to a single tier (no error). If you need strict cycle detection, validate the audience before serialising.
ASPARTIX compatibility notes
- ASPARTIX accepts redundant
valpreffacts; we emit the full pairwise transitive closure for determinism rather than the minimal transitive reduction. - ASPARTIX takes the transitive closure of
valprefon import; round-trip is closure-stable. - We don't support ASPARTIX-style quoted atoms (
'arg with space') — argument and value names must be bare alphanumeric. Matches ASPARTIX's permissive default.
Related
- Value-based argumentation — the formalism.
argumentation-valuesreference — full API.- ASPARTIX VAF docs — the canonical APX VAF format definition.