1use std::{collections::BTreeMap, mem};
2
3use graph_lib::prelude::{Graph, GraphB};
4use itertools::Itertools;
5use rand::seq::SliceRandom;
6use rand::Rng;
7use rand_distr::{Distribution, Exp1, Open01, Standard, StandardNormal};
8use tracing::{debug, span, Level};
9
10use crate::{
11 agent::{Agent, Decision},
12 info::{Info, InfoContent, InfoLabel},
13 opinion::{MyFloat, MyOpinions, Trusts},
14 stat::{AgentStat, InfoData, InfoStat, PopData, PopStat, Stat},
15};
16
17pub struct Memory<V, Ax> {
18 pub agents: Vec<AgentWrapper<V, Ax>>,
19 pub id: usize,
20}
21
22impl<V: MyFloat, Ax> Memory<V, Ax> {
23 pub fn new<E, X>(e: &E, id: usize) -> Self
24 where
25 E: Executor<V, Ax, X>,
26 Ax: Default,
27 {
28 let agents = (0..(e.num_agents()))
29 .map(|_| AgentWrapper::default())
30 .collect::<Vec<_>>();
31 Self { agents, id }
32 }
33
34 fn get_agent_mut(&mut self, idx: usize) -> &mut AgentWrapper<V, Ax> {
35 &mut self.agents[idx]
36 }
37
38 fn reset<E, R: Rng>(&mut self, exec: &E, rng: &mut R)
39 where
40 Ax: AgentExtTrait<V, Exec = E>,
41 {
42 for (idx, agent) in self.agents.iter_mut().enumerate() {
43 let span = span!(Level::INFO, "init", "#" = idx);
44 let _guard = span.enter();
45 agent.idx = idx;
46 agent.ext.reset(idx, exec, rng);
47 agent.core.reset(|ops, decision| {
48 Ax::reset_core(ops, decision, exec, rng);
49 });
50 }
51 }
52}
53
54#[derive(Default)]
55pub struct AgentWrapper<V, X> {
56 pub idx: usize,
57 pub core: Agent<V>,
58 pub ext: X,
59}
60
61pub trait AgentExtTrait<V: Clone>: Sized {
62 type Exec;
63 type Ix;
64 fn reset_core<R: Rng>(
65 ops: &mut MyOpinions<V>,
66 decision: &mut Decision<V>,
67 exec: &Self::Exec,
68 rng: &mut R,
69 );
70 fn reset<R: Rng>(&mut self, idx: usize, exec: &Self::Exec, rng: &mut R);
71 fn visit_prob<R: Rng>(&mut self, exec: &Self::Exec, rng: &mut R) -> V;
72 fn informer_trusts<'a, R: Rng>(
73 &mut self,
74 ins: &mut InstanceWrapper<'a, Self::Exec, V, R, Self::Ix>,
75 info_idx: InfoIdx,
76 ) -> Trusts<V>;
77 fn sharer_trusts<'a, R: Rng>(
78 &mut self,
79 ins: &mut InstanceWrapper<'a, Self::Exec, V, R, Self::Ix>,
80 info_idx: InfoIdx,
81 ) -> Trusts<V>;
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
85pub struct AgentIdx(pub usize);
86
87impl From<usize> for AgentIdx {
88 fn from(value: usize) -> Self {
89 Self(value)
90 }
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
94pub struct InfoIdx(pub usize);
95
96impl From<usize> for InfoIdx {
97 fn from(value: usize) -> Self {
98 Self(value)
99 }
100}
101
102pub trait Executor<V, Ax, Ix> {
103 fn num_agents(&self) -> usize;
104 fn graph(&self) -> &GraphB;
105 fn execute<R>(&self, memory: &mut Memory<V, Ax>, num_iter: u32, mut rng: R) -> Vec<Stat>
106 where
107 V: MyFloat,
108 Open01: Distribution<V>,
109 Standard: Distribution<V>,
110 StandardNormal: Distribution<V>,
111 Exp1: Distribution<V>,
112 R: Rng,
113 Ix: InstanceExt<V, R, Self>,
114 Ax: AgentExtTrait<V, Exec = Self, Ix = Ix>,
115 Self: Sized,
116 {
117 let span = span!(Level::INFO, "iter", i = num_iter);
118 let _guard = span.enter();
119 memory.reset(self, &mut rng);
120
121 let instance = InstanceWrapper::new(self, Ix::from_exec(self, &mut rng), rng);
122 instance.my_loop(memory, num_iter)
123 }
124}
125
126pub struct InstanceWrapper<'a, E, V: Clone, R, X> {
127 pub exec: &'a E,
128 infos: Vec<Info<'a, V>>,
129 pub info_data_table: BTreeMap<InfoLabel, InfoData>,
130 pub rng: R,
131 selfishes: Vec<AgentIdx>,
132 info_stat: InfoStat,
133 agent_stat: AgentStat,
134 pop_stat: PopStat,
135 total_num_selfish: usize,
136 prev_num_selfish: usize,
137 rps: Vec<(AgentIdx, InfoIdx)>,
138 pub ext: X,
139}
140
141impl<'a, E, V: MyFloat, R, Ix> InstanceWrapper<'a, E, V, R, Ix> {
142 pub fn new(e: &'a E, ext: Ix, rng: R) -> Self {
143 let infos = Vec::<Info<V>>::new();
144 let info_data_table = BTreeMap::<InfoLabel, InfoData>::new();
145 let selfishes = Vec::new();
146 let info_stat = InfoStat::default();
147 let agent_stat = AgentStat::default();
148 let pop_stat = PopStat::default();
149 let total_num_selfish = 0;
150 let rps = Vec::new();
151 Self {
152 exec: e,
153 infos,
154 info_data_table,
155 rng,
156 selfishes,
157 info_stat,
158 agent_stat,
159 pop_stat,
160 total_num_selfish,
161 prev_num_selfish: 0,
162 rps,
163 ext,
164 }
165 }
166
167 fn push_info_stats(&mut self, num_iter: u32, t: u32) {
168 for (info_label, d) in &mut self.info_data_table {
169 self.info_stat.push(num_iter, t, d, info_label);
170 *d = InfoData::default();
171 }
172 }
173
174 fn received_info(&mut self, info_idx: InfoIdx) {
175 let info = &self.infos[info_idx.0];
176 let d = self.info_data_table.get_mut(info.label()).unwrap();
177 d.received();
178 debug!(target: "recv", l = ?info.label(), "#" = info.idx);
179 }
180
181 fn get_info_mut(&mut self, info_idx: InfoIdx) -> (&mut Info<'a, V>, &mut InfoData) {
182 let info = &mut self.infos[info_idx.0];
183 let d = self.info_data_table.get_mut(info.label()).unwrap();
184 (info, d)
185 }
186
187 pub fn get_info(&self, info_idx: InfoIdx) -> &Info<'_, V> {
188 &self.infos[info_idx.0]
189 }
190
191 pub fn get_info_label(&self, info_idx: InfoIdx) -> &InfoLabel {
192 self.infos[info_idx.0].label()
193 }
194
195 pub fn num_shared(&self, info_idx: InfoIdx) -> usize {
196 self.infos[info_idx.0].num_shared()
197 }
198
199 pub fn total_num_selfish(&self) -> usize {
200 self.total_num_selfish
201 }
202
203 pub fn prev_num_selfish(&self) -> usize {
204 self.prev_num_selfish
205 }
206 fn new_info(&mut self, obj: InfoContent<'a, V>) -> InfoIdx {
207 let info_idx = self.infos.len();
208 let info = Info::new(info_idx, obj);
209 let d = self.info_data_table.entry(*info.label()).or_default();
210 d.posted();
211 self.infos.push(info);
212 info_idx.into()
213 }
214
215 fn my_loop<Ax>(mut self, memory: &mut Memory<V, Ax>, num_iter: u32) -> Vec<Stat>
216 where
217 E: Executor<V, Ax, Ix>,
218 V: MyFloat,
219 Open01: Distribution<V>,
220 Standard: Distribution<V>,
221 StandardNormal: Distribution<V>,
222 Exp1: Distribution<V>,
223 R: Rng,
224 Ix: InstanceExt<V, R, E>,
225 Ax: AgentExtTrait<V, Exec = E, Ix = Ix>,
226 {
227 let mut t = 0;
228 while !self.rps.is_empty() || !self.selfishes.is_empty() || self.ext.is_continued(self.exec)
229 {
230 let span = span!(Level::INFO, "t", t = t);
231 let _guard = span.enter();
232 self.step(memory, num_iter, t);
233 t += 1;
234 }
235 vec![
236 self.info_stat.into(),
237 self.agent_stat.into(),
238 self.pop_stat.into(),
239 ]
240 }
241
242 fn step<Ax>(&mut self, memory: &mut Memory<V, Ax>, num_iter: u32, t: u32)
243 where
244 E: Executor<V, Ax, Ix>,
245 V: MyFloat,
246 Open01: Distribution<V>,
247 Standard: Distribution<V>,
248 StandardNormal: Distribution<V>,
249 Exp1: Distribution<V>,
250 R: Rng,
251 Ix: InstanceExt<V, R, E>,
252 Ax: AgentExtTrait<V, Exec = E, Ix = Ix>,
253 {
254 let ips = self.info_producers(t);
255 for &(agent_idx, info_idx) in &ips {
256 let span = span!(Level::INFO, "IA", "#" = agent_idx.0);
257 let _guard = span.enter();
258 let agent = memory.get_agent_mut(agent_idx.0);
259 let trusts = agent.ext.informer_trusts(self, info_idx);
260 let info = &self.infos[info_idx.0];
261 debug!(target: "recv", l = ?info.label(), "#" = info.idx);
262 agent.core.set_info_opinions(&info, trusts);
263 if agent.core.is_willing_selfish() {
264 self.selfishes.push(agent_idx);
265 }
266 }
267
268 let mut s = Vec::new();
269 for (agent_idx, info_idx) in mem::take(&mut self.rps) {
270 let span = span!(Level::INFO, "SA", "#" = agent_idx.0);
271 let _guard = span.enter();
272 self.received_info(info_idx);
273
274 let agent = memory.get_agent_mut(agent_idx.0);
275 if self.rng.gen::<V>() >= agent.ext.visit_prob(self.exec, &mut self.rng) {
276 continue;
277 }
278
279 let trusts = agent.ext.sharer_trusts(self, info_idx);
280 let (info, d) = self.get_info_mut(info_idx);
281 let b = agent.core.read_info(info, trusts);
282 info.viewed();
283 d.viewed();
284 if b.sharing {
285 info.shared();
286 d.shared();
287 s.push((agent_idx, info_idx));
288 }
289 if b.first_access {
290 d.first_viewed();
291 }
292 if agent.core.is_willing_selfish() {
293 self.selfishes.push(agent_idx);
294 }
295 }
296 let mut next_rps = ips
297 .into_iter()
298 .chain(s.into_iter())
299 .flat_map(|(agent_idx, info_idx)| {
300 self.exec
301 .graph()
302 .successors(agent_idx.0)
303 .map(move |&bid| (bid.into(), info_idx))
304 })
305 .collect_vec();
306 next_rps.shuffle(&mut self.rng);
307 self.rps = next_rps;
308
309 let mut pop_data = PopData::default();
310 let mut temp = Vec::new(); for agent_idx in &self.selfishes {
312 let agent = memory.get_agent_mut(agent_idx.0);
313 let span = span!(Level::INFO, "Ag", "#" = agent_idx.0);
314 let _guard = span.enter();
315 if agent.core.progress_selfish_status() {
316 self.agent_stat.push_selfish(num_iter, t, agent_idx.0);
317 pop_data.selfish();
318 }
319 if agent.core.is_willing_selfish() {
320 temp.push(*agent_idx);
321 }
322 }
323 self.selfishes = temp;
324 self.total_num_selfish += pop_data.num_selfish as usize;
325 self.prev_num_selfish = pop_data.num_selfish as usize;
326 self.pop_stat.push(num_iter, t, pop_data);
327 self.push_info_stats(num_iter, t);
328 }
329
330 fn info_producers<M>(&mut self, t: u32) -> Vec<(AgentIdx, InfoIdx)>
331 where
332 E: Executor<V, M, Ix>,
333 V: MyFloat,
334 Open01: Distribution<V>,
335 Standard: Distribution<V>,
336 StandardNormal: Distribution<V>,
337 Exp1: Distribution<V>,
338 R: Rng,
339 Ix: InstanceExt<V, R, E>,
340 {
341 let mut ips = Vec::new();
342 for (agent_idx, obj) in Ix::get_informers_with(self, t) {
343 ips.push((agent_idx, self.new_info(obj)));
344 }
345 ips
346 }
347}
348
349pub trait InstanceExt<V: Clone, R, E>: Sized {
350 fn from_exec(exec: &E, rng: &mut R) -> Self;
351 fn is_continued(&self, exec: &E) -> bool;
352 fn get_informers_with<'a>(
353 ins: &mut InstanceWrapper<'a, E, V, R, Self>,
354 t: u32,
355 ) -> Vec<(AgentIdx, InfoContent<'a, V>)>;
356}