qualia_core_db/modalities/argumentation/
generation.rs1use super::{Argument, ArgumentationFramework, Attack, AttackType};
8use crate::NQuin;
9
10pub fn framework_from_trace(entries: &[(u64, u64, bool)]) -> ArgumentationFramework {
15 let mut af = ArgumentationFramework::new();
16 for &(id, lit, positive) in entries {
17 let mut concl = NQuin {
18 subject: lit,
19 predicate: positive as u64,
20 object: 0,
21 context: 0,
22 metadata: 0,
23 parity: 0,
24 };
25 concl.parity = concl.subject ^ concl.predicate ^ concl.object ^ concl.context;
26 af.add_argument(Argument::new(id, String::new(), Vec::new(), concl));
27 }
28 for (i, &(id_a, lit_a, pos_a)) in entries.iter().enumerate() {
29 for &(id_b, lit_b, pos_b) in &entries[i + 1..] {
30 if lit_a == lit_b && pos_a != pos_b {
31 af.add_attack(Attack {
32 attacker: id_a,
33 target: id_b,
34 attack_type: AttackType::Rebuttal,
35 strength: 1.0,
36 });
37 af.add_attack(Attack {
38 attacker: id_b,
39 target: id_a,
40 attack_type: AttackType::Rebuttal,
41 strength: 1.0,
42 });
43 }
44 }
45 }
46 af
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn complementary_verdicts_become_a_debate() {
55 let permit = crate::q_hash("act:disclose");
56 let af = framework_from_trace(&[
58 (1, permit, true),
59 (2, permit, false),
60 (3, crate::q_hash("act:other"), true),
61 ]);
62 assert_eq!(af.arguments.len(), 3);
63 assert!(af.attacks.iter().any(|a| a.attacker == 1 && a.target == 2));
65 assert!(af.attacks.iter().any(|a| a.attacker == 2 && a.target == 1));
66 let g = af.grounded_extension();
67 assert!(
68 !g.contains(&1) && !g.contains(&2),
69 "the conflict is undecided in the grounded extension"
70 );
71 assert!(g.contains(&3), "the independent verdict stands");
72 }
73
74 #[test]
75 fn agreeing_verdicts_do_not_attack() {
76 let lit = crate::q_hash("act:x");
77 let af = framework_from_trace(&[(1, lit, true), (2, lit, true)]);
79 assert!(af.attacks.is_empty());
80 let g = af.grounded_extension();
81 assert!(g.contains(&1) && g.contains(&2));
82 }
83}