encounter_argumentation/
acceptance.rs1use crate::knowledge::{ArgumentKnowledge, ArgumentPosition};
4use crate::resolver::{ArgumentOutcome, resolve_argument};
5use argumentation_schemes::CatalogRegistry;
6use argumentation_schemes::instance::SchemeInstance;
7use encounter::scoring::{AcceptanceEval, ScoredAffordance};
8
9pub struct ArgumentAcceptanceEval<K> {
19 knowledge: K,
20 registry: CatalogRegistry,
21}
22
23impl<K: ArgumentKnowledge> ArgumentAcceptanceEval<K> {
24 pub fn new(knowledge: K, registry: CatalogRegistry) -> Self {
26 Self {
27 knowledge,
28 registry,
29 }
30 }
31}
32
33impl<K: ArgumentKnowledge, P> AcceptanceEval<P> for ArgumentAcceptanceEval<K> {
34 fn evaluate(&self, responder: &str, action: &ScoredAffordance<P>) -> bool {
35 let action_name = &action.entry.spec.name;
36 let proposer = action
37 .bindings
38 .get("self")
39 .map(|s| s.as_str())
40 .unwrap_or("unknown");
41
42 let proposer_positions =
43 self.knowledge
44 .arguments_for_action(proposer, action_name, &action.bindings);
45
46 if proposer_positions.is_empty() {
47 return true; }
49
50 let responder_positions =
51 self.knowledge
52 .counter_arguments(responder, action_name, &proposer_positions);
53
54 if responder_positions.is_empty() {
55 return true;
56 }
57
58 let proposer_instances = instantiate_positions(&proposer_positions, &self.registry);
59 let responder_instances = instantiate_positions(&responder_positions, &self.registry);
60
61 let outcome = resolve_argument(&proposer_instances, &responder_instances, &self.registry);
62
63 match outcome {
64 ArgumentOutcome::ResponderWins { .. } => false,
65 ArgumentOutcome::ProposerWins { .. } | ArgumentOutcome::Undecided => {
66 let proposer_rank = max_strength_rank(&proposer_positions, &self.registry);
73 let responder_rank = max_strength_rank(&responder_positions, &self.registry);
74 responder_rank <= proposer_rank
75 }
76 }
77 }
78}
79
80fn max_strength_rank(positions: &[ArgumentPosition], registry: &CatalogRegistry) -> u8 {
82 positions
83 .iter()
84 .filter_map(|pos| {
85 registry
86 .by_key(&pos.scheme_key)
87 .map(|s| crate::strength_rank(s.metadata.strength))
88 })
89 .max()
90 .unwrap_or(0)
91}
92
93fn instantiate_positions(
94 positions: &[ArgumentPosition],
95 registry: &CatalogRegistry,
96) -> Vec<SchemeInstance> {
97 positions
98 .iter()
99 .filter_map(|pos| {
100 let scheme = registry.by_key(&pos.scheme_key)?;
101 scheme.instantiate(&pos.bindings).ok()
102 })
103 .collect()
104}