base/
executor.rs

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(); // mem::take(&mut self.selfishes);
311        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}