sim_lib_numbers_stats/
function.rs1use std::{any::Any, sync::Arc};
4
5use sim_kernel::{
6 AbiVersion, Args, Callable, ClassRef, Cx, DefaultFactory, Dependency, Export, Expr, Factory,
7 Lib, LibManifest, LibTarget, Linker, Object, RawArgs, Result, Symbol, Value, Version,
8};
9
10use super::{agent_fixtures, runtime};
11
12pub fn stats_disparate_impact_claim_symbol() -> Symbol {
14 Symbol::qualified("stats", "disparate-impact-claim")
15}
16
17pub fn stats_mean_claim_symbol() -> Symbol {
19 Symbol::qualified("stats", "mean-claim")
20}
21
22pub fn stats_variance_claim_symbol() -> Symbol {
24 Symbol::qualified("stats", "variance-claim")
25}
26
27pub fn stats_entropy_claim_symbol() -> Symbol {
29 Symbol::qualified("stats", "entropy-claim")
30}
31
32pub fn stats_claims_symbol() -> Symbol {
34 Symbol::qualified("stats", "claims")
35}
36
37fn function_symbols() -> [Symbol; 9] {
38 [
39 stats_mean_claim_symbol(),
40 stats_variance_claim_symbol(),
41 stats_entropy_claim_symbol(),
42 stats_disparate_impact_claim_symbol(),
43 stats_claims_symbol(),
44 agent_fixtures::fixture_symbols()[0].clone(),
45 agent_fixtures::fixture_symbols()[1].clone(),
46 agent_fixtures::fixture_symbols()[2].clone(),
47 agent_fixtures::fixture_symbols()[3].clone(),
48 ]
49}
50
51#[derive(Clone)]
52struct StatsFunction {
53 symbol: Symbol,
54}
55
56impl Object for StatsFunction {
57 fn display(&self, _cx: &mut Cx) -> Result<String> {
58 Ok(format!("#<function {}>", self.symbol))
59 }
60
61 fn as_any(&self) -> &dyn Any {
62 self
63 }
64}
65
66impl sim_kernel::ObjectCompat for StatsFunction {
67 fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
68 if let Some(value) = cx
69 .registry()
70 .class_by_symbol(&Symbol::qualified("core", "Function"))
71 {
72 return Ok(value.clone());
73 }
74 DefaultFactory.class_stub(
75 sim_kernel::CORE_FUNCTION_CLASS_ID,
76 Symbol::qualified("core", "Function"),
77 )
78 }
79
80 fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
81 Ok(Expr::Symbol(self.symbol.clone()))
82 }
83
84 fn as_callable(&self) -> Option<&dyn Callable> {
85 Some(self)
86 }
87}
88
89impl Callable for StatsFunction {
90 fn call(&self, cx: &mut Cx, args: Args) -> Result<Value> {
91 if self.symbol == stats_mean_claim_symbol() {
92 return runtime::call_stats_mean_claim(cx, args);
93 }
94 if self.symbol == stats_variance_claim_symbol() {
95 return runtime::call_stats_variance_claim(cx, args);
96 }
97 if self.symbol == stats_entropy_claim_symbol() {
98 return runtime::call_stats_entropy_claim(cx, args);
99 }
100 if self.symbol == stats_disparate_impact_claim_symbol() {
101 return runtime::call_stats_disparate_impact_claim(cx, args);
102 }
103 if self.symbol == stats_claims_symbol() {
104 return runtime::call_stats_claims(cx, args);
105 }
106 if let Some(value) = agent_fixtures::call_fixture(cx, &self.symbol, args)? {
107 return Ok(value);
108 }
109 unreachable!("unregistered stats function {}", self.symbol)
110 }
111
112 fn call_exprs(&self, cx: &mut Cx, args: RawArgs) -> Result<Value> {
113 let values = args
114 .into_exprs()
115 .into_iter()
116 .map(|expr| cx.eval_expr(expr))
117 .collect::<Result<Vec<_>>>()?;
118 self.call(cx, Args::new(values))
119 }
120}
121
122pub struct StatsNumbersLib;
124
125impl StatsNumbersLib {
126 pub fn new() -> Self {
128 Self
129 }
130}
131
132impl Default for StatsNumbersLib {
133 fn default() -> Self {
134 Self::new()
135 }
136}
137
138impl Lib for StatsNumbersLib {
139 fn manifest(&self) -> LibManifest {
140 LibManifest {
141 id: Symbol::qualified("numbers", "stats"),
142 version: Version(env!("CARGO_PKG_VERSION").to_owned()),
143 abi: AbiVersion { major: 0, minor: 1 },
144 target: LibTarget::HostRegistered,
145 requires: Vec::<Dependency>::new(),
146 capabilities: Vec::new(),
147 exports: function_symbols()
148 .into_iter()
149 .map(|symbol| Export::Function {
150 symbol,
151 function_id: None,
152 })
153 .collect(),
154 }
155 }
156
157 fn load(&self, _cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
158 for symbol in function_symbols() {
159 linker.function_value(
160 symbol.clone(),
161 DefaultFactory.opaque(Arc::new(StatsFunction { symbol }))?,
162 )?;
163 }
164 Ok(())
165 }
166}