use crate::types::{Value, ValueAssignment};
use argumentation_schemes::SchemeInstance;
use std::collections::HashMap;
use std::hash::Hash;
pub const DEFAULT_VALUES_SCHEME_NAME: &str = "Argument from Values";
pub fn from_scheme_instances<'a, A, I, F>(
instances: I,
to_arg: F,
) -> ValueAssignment<A>
where
A: Eq + Hash + Clone,
I: IntoIterator<Item = (&'a SchemeInstance, &'a HashMap<String, String>)>,
F: Fn(&SchemeInstance) -> A,
{
from_scheme_instances_with_name(instances, to_arg, DEFAULT_VALUES_SCHEME_NAME)
}
pub fn from_scheme_instances_with_name<'a, A, I, F>(
instances: I,
to_arg: F,
target_scheme_name: &str,
) -> ValueAssignment<A>
where
A: Eq + Hash + Clone,
I: IntoIterator<Item = (&'a SchemeInstance, &'a HashMap<String, String>)>,
F: Fn(&SchemeInstance) -> A,
{
let mut assignment = ValueAssignment::new();
for (instance, bindings) in instances {
if instance.scheme_name.as_str() != target_scheme_name {
continue;
}
let Some(value_str) = bindings.get("value") else {
continue;
};
let arg = to_arg(instance);
assignment.promote(arg, Value::new(value_str.clone()));
}
assignment
}
#[cfg(test)]
mod tests {
use super::*;
use argumentation_schemes::catalog::default_catalog;
#[test]
fn extracts_value_from_argument_from_values_scheme() {
let registry = default_catalog();
let scheme = registry.by_key("argument_from_values").unwrap();
let mut bindings = HashMap::new();
bindings.insert("action".into(), "uphold_honor".into());
bindings.insert("value".into(), "honor".into());
bindings.insert("agent".into(), "alice".into());
let instance = scheme.instantiate(&bindings).unwrap();
let to_arg = |inst: &SchemeInstance| inst.conclusion.to_string();
let assignment = from_scheme_instances(
std::iter::once((&instance, &bindings)),
to_arg,
);
let arg = instance.conclusion.to_string();
let values = assignment.values(&arg);
assert_eq!(values.len(), 1);
assert_eq!(values[0].as_str(), "honor");
}
#[test]
fn skips_non_value_schemes() {
let registry = default_catalog();
let scheme = registry
.by_key("argument_from_expert_opinion")
.expect("argument_from_expert_opinion in default catalog");
let mut bindings = HashMap::new();
bindings.insert("expert".into(), "alice".into());
bindings.insert("domain".into(), "military".into());
bindings.insert("claim".into(), "fortify".into());
let instance = scheme.instantiate(&bindings).unwrap();
let to_arg = |inst: &SchemeInstance| inst.conclusion.to_string();
let assignment = from_scheme_instances(
std::iter::once((&instance, &bindings)),
to_arg,
);
assert!(assignment.values(&instance.conclusion.to_string()).is_empty());
}
#[test]
fn custom_scheme_name_supported() {
let registry = default_catalog();
let scheme = registry.by_key("argument_from_values").unwrap();
let mut bindings = HashMap::new();
bindings.insert("action".into(), "do_x".into());
bindings.insert("value".into(), "honor".into());
bindings.insert("agent".into(), "alice".into());
let instance = scheme.instantiate(&bindings).unwrap();
let to_arg = |inst: &SchemeInstance| inst.conclusion.to_string();
let assignment = from_scheme_instances_with_name(
std::iter::once((&instance, &bindings)),
to_arg,
"Some Other Scheme Name",
);
assert!(assignment.values(&instance.conclusion.to_string()).is_empty());
}
}