v2/
exec.rs

1use std::{borrow::Cow, collections::BTreeMap};
2
3use base::{
4    agent::Decision,
5    executor::{AgentExtTrait, AgentIdx, Executor, InfoIdx, InstanceExt, InstanceWrapper},
6    info::{InfoContent, InfoLabel},
7    opinion::{MyFloat, MyOpinions, OtherTrusts, Trusts},
8};
9use graph_lib::prelude::{Graph, GraphB};
10use rand::{seq::IteratorRandom, seq::SliceRandom, Rng};
11use rand_distr::{Distribution, Exp1, Open01, Standard, StandardNormal};
12
13use crate::parameter::{
14    CptSamples, InformationSamples, Informing, InformingParams, OpinionSamples, PopSampleType,
15    ProbabilitySamples, ProspectSamples, SharerTrustSamples, SupportLevelTable,
16};
17
18pub struct Exec<V: MyFloat>
19where
20    Open01: Distribution<V>,
21{
22    pub enable_inhibition: bool,
23    pub graph: GraphB,
24    pub fnum_agents: V,
25    pub mean_degree: V,
26    pub sharer_trust: SharerTrustSamples<V>,
27    pub opinion: OpinionSamples<V>,
28    pub information: InformationSamples<V>,
29    pub informing: InformingParams<V>,
30    pub community_psi1: SupportLevelTable<V>,
31    pub probabilities: ProbabilitySamples<V>,
32    pub prospect: ProspectSamples<V>,
33    pub cpt: CptSamples<V>,
34    pub delay_selfish: u32,
35}
36
37impl<V> Executor<V, AgentExt<V>, Instance> for Exec<V>
38where
39    V: MyFloat,
40    Open01: Distribution<V>,
41    Standard: Distribution<V>,
42    StandardNormal: Distribution<V>,
43    Exp1: Distribution<V>,
44    <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
45{
46    fn num_agents(&self) -> usize {
47        self.graph.node_count()
48    }
49
50    fn graph(&self) -> &GraphB {
51        &self.graph
52    }
53}
54
55#[derive(Default)]
56pub struct AgentExt<V> {
57    trusts: InfoMap<V>,
58    arrival_prob: Option<V>,
59    /// (friend, social)
60    viewing_probs: Option<(V, V)>,
61    /// (friend, social)
62    plural_ignores: Option<(V, V)>,
63    visit_prob: Option<V>,
64    psi1_support_level: V,
65}
66
67impl<V> AgentExt<V>
68where
69    V: MyFloat,
70    Open01: Distribution<V>,
71    <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
72{
73    fn get_trust<R: Rng>(&mut self, label: InfoLabel, exec: &Exec<V>, rng: &mut R) -> V {
74        *self.trusts.entry(label).or_insert_with(|| match label {
75            InfoLabel::Misinfo => {
76                // let p = self.psi1_support_level;
77                // let d = p.min(V::one() - p);
78                // let u = *exec.sharer_trust.misinfo.choose(rng).unwrap(); // 0<u<1
79                // let x = d * (u * (V::one() + V::one()) - V::one()); // -d < x < d
80                // p + x // lv - d < lv + x < lv + d
81                exec.sharer_trust.misinfo.choose(rng)
82            }
83            InfoLabel::Corrective => {
84                // let p = V::one() - self.psi1_support_level; // opposite of support level
85                // let d = p.min(V::one() - p);
86                // let u = *exec.sharer_trust.correction.choose(rng).unwrap(); // 0<u<1
87                // let x = d * (u * (V::one() + V::one()) - V::one()); // -d < x < d
88                // p + x // lv - d < lv + x < lv + d
89                exec.sharer_trust.correction.choose(rng)
90            }
91            InfoLabel::Observed => exec.sharer_trust.obserbation.choose(rng),
92            InfoLabel::Inhibitive => exec.sharer_trust.inhibition.choose(rng),
93        })
94    }
95
96    fn get_plural_ignorances<'a, R: Rng>(&mut self, exec: &Exec<V>, rng: &mut R) -> (V, V) {
97        *self.plural_ignores.get_or_insert_with(|| {
98            (
99                exec.probabilities.plural_ignore_friend.choose(rng),
100                exec.probabilities.plural_ignore_social.choose(rng),
101            )
102        })
103    }
104
105    fn viewing_probs<'a, R: Rng>(&mut self, exec: &Exec<V>, rng: &mut R) -> (V, V) {
106        *self.viewing_probs.get_or_insert_with(|| {
107            (
108                exec.probabilities.viewing_friend.choose(rng),
109                exec.probabilities.viewing_social.choose(rng),
110            )
111        })
112    }
113
114    fn arrival_prob<'a, R: Rng>(&mut self, exec: &Exec<V>, rng: &mut R) -> V {
115        *self
116            .arrival_prob
117            .get_or_insert_with(|| exec.probabilities.arrival_friend.choose(rng))
118    }
119}
120
121fn new_trusts<V: MyFloat>(
122    my_trust: V,
123    trust_mis: V,
124    receipt_prob: V,
125    friend_viewing_probs: V,
126    social_viewing_probs: V,
127    arrival_prob: V,
128    friend_plural_ignorance: V,
129    social_plural_ignorance: V,
130) -> Trusts<V> {
131    Trusts {
132        my_trust,
133        social_trusts: OtherTrusts {
134            trust: my_trust,
135            certainty: social_viewing_probs * receipt_prob,
136        },
137        friend_trusts: OtherTrusts {
138            trust: my_trust,
139            certainty: friend_viewing_probs * receipt_prob,
140        },
141        pred_friend_trusts: OtherTrusts {
142            trust: my_trust,
143            certainty: friend_viewing_probs * arrival_prob,
144        },
145        social_misinfo_trusts: OtherTrusts {
146            trust: trust_mis,
147            certainty: social_plural_ignorance,
148        },
149        friend_misinfo_trusts: OtherTrusts {
150            trust: trust_mis,
151            certainty: friend_plural_ignorance,
152        },
153    }
154}
155
156impl<V> AgentExtTrait<V> for AgentExt<V>
157where
158    V: MyFloat,
159    Standard: Distribution<V>,
160    StandardNormal: Distribution<V>,
161    Exp1: Distribution<V>,
162    Open01: Distribution<V>,
163    <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
164{
165    type Exec = Exec<V>;
166    type Ix = Instance;
167
168    fn informer_trusts<'a, R: Rng>(
169        &mut self,
170        ins: &mut InstanceWrapper<'a, Self::Exec, V, R, Self::Ix>,
171        _: InfoIdx,
172    ) -> Trusts<V> {
173        let my_trust = V::one();
174        let trust_mis = self.get_trust(InfoLabel::Misinfo, ins.exec, &mut ins.rng);
175        let (fpi, kpi) = self.get_plural_ignorances(ins.exec, &mut ins.rng);
176        new_trusts(
177            my_trust,
178            trust_mis,
179            V::zero(),
180            V::zero(),
181            V::zero(),
182            V::zero(),
183            fpi,
184            kpi,
185        )
186    }
187
188    fn sharer_trusts<'a, R: Rng>(
189        &mut self,
190        ins: &mut InstanceWrapper<'a, Self::Exec, V, R, Self::Ix>,
191        info_idx: InfoIdx,
192    ) -> Trusts<V> {
193        let my_trust = self.get_trust(*ins.get_info_label(info_idx), ins.exec, &mut ins.rng);
194        let trust_mis = self.get_trust(InfoLabel::Misinfo, ins.exec, &mut ins.rng);
195        let r = Instance::receipt_prob(ins, info_idx);
196        let (fq, kq) = self.viewing_probs(ins.exec, &mut ins.rng);
197        let arr = self.arrival_prob(ins.exec, &mut ins.rng);
198        let (fpi, kpi) = self.get_plural_ignorances(ins.exec, &mut ins.rng);
199        new_trusts(my_trust, trust_mis, r, fq, kq, arr, fpi, kpi)
200    }
201
202    fn visit_prob<R: Rng>(&mut self, exec: &Self::Exec, rng: &mut R) -> V {
203        *self
204            .visit_prob
205            .get_or_insert_with(|| exec.probabilities.viewing.choose(rng))
206    }
207
208    fn reset_core<R: Rng>(
209        ops: &mut MyOpinions<V>,
210        decision: &mut Decision<V>,
211        exec: &Self::Exec,
212        rng: &mut R,
213    ) {
214        decision.reset(exec.delay_selfish, |prospect, cpt| {
215            exec.opinion.reset_to(ops, rng);
216            exec.prospect.reset_to(prospect, rng);
217            exec.cpt.reset_to(cpt, rng);
218        });
219    }
220
221    fn reset<R: Rng>(&mut self, idx: usize, exec: &Exec<V>, _: &mut R) {
222        self.trusts = InfoMap::new();
223        self.arrival_prob = None;
224        self.viewing_probs = None;
225        self.plural_ignores = None;
226        self.visit_prob = None;
227        self.psi1_support_level = exec.community_psi1.level(idx);
228    }
229}
230
231#[derive(Default)]
232struct InfoMap<T> {
233    misinfo: Option<T>,
234    correction: Option<T>,
235    observation: Option<T>,
236    inhibition: Option<T>,
237}
238
239impl<T> InfoMap<T> {
240    fn new() -> Self {
241        Self {
242            misinfo: None,
243            correction: None,
244            observation: None,
245            inhibition: None,
246        }
247    }
248    fn entry(&mut self, label: InfoLabel) -> MyEntry<'_, T> {
249        let value = match label {
250            InfoLabel::Misinfo => &mut self.misinfo,
251            InfoLabel::Corrective => &mut self.correction,
252            InfoLabel::Observed => &mut self.observation,
253            InfoLabel::Inhibitive => &mut self.inhibition,
254        };
255        MyEntry { value }
256    }
257}
258
259struct MyEntry<'a, T> {
260    value: &'a mut Option<T>,
261}
262
263impl<'a, T> MyEntry<'a, T> {
264    fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> &'a mut T {
265        self.value.get_or_insert_with(default)
266    }
267}
268
269pub struct Instance {
270    misinfo_informers: BTreeMap<u32, Vec<AgentIdx>>,
271    corection_informers: BTreeMap<u32, Vec<AgentIdx>>,
272    inhibition_informers: BTreeMap<u32, Vec<AgentIdx>>,
273    observation: Vec<AgentIdx>,
274    max_step_num_observation: usize,
275}
276
277impl Instance {
278    fn receipt_prob<'a, V, R>(
279        ins: &InstanceWrapper<'a, Exec<V>, V, R, Self>,
280        info_idx: InfoIdx,
281    ) -> V
282    where
283        V: MyFloat,
284        Open01: Distribution<V>,
285        <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
286    {
287        V::one()
288            - (V::one() - V::from_usize(ins.num_shared(info_idx)).unwrap() / ins.exec.fnum_agents)
289                .powf(ins.exec.mean_degree)
290    }
291}
292
293impl<V, R> InstanceExt<V, R, Exec<V>> for Instance
294where
295    V: MyFloat,
296    Open01: Distribution<V>,
297    Standard: Distribution<V>,
298    StandardNormal: Distribution<V>,
299    Exp1: Distribution<V>,
300    R: Rng,
301    <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
302{
303    fn from_exec(exec: &Exec<V>, rng: &mut R) -> Self {
304        let mut is_observation = vec![true; exec.graph.node_count()];
305
306        fn make_informers<V: MyFloat, R: Rng>(
307            exec: &Exec<V>,
308            rng: &mut R,
309            sampling: &PopSampleType<V>,
310            informings: &[Informing<V>],
311            is_observation: &mut [bool],
312        ) -> BTreeMap<u32, Vec<AgentIdx>>
313        where
314            Open01: Distribution<V>,
315            <V as rand_distr::uniform::SampleUniform>::Sampler: Sync + Send,
316        {
317            let mut informers = BTreeMap::new();
318            let samples = match sampling {
319                &PopSampleType::Random(p) => exec
320                    .community_psi1
321                    .random(V::to_usize(&(exec.fnum_agents * p)).unwrap(), rng),
322                &PopSampleType::Top(p) => exec
323                    .community_psi1
324                    .top(V::to_usize(&(exec.fnum_agents * p)).unwrap(), rng),
325                &PopSampleType::Middle(p) => exec
326                    .community_psi1
327                    .middle(V::to_usize(&(exec.fnum_agents * p)).unwrap(), rng),
328                &PopSampleType::Bottom(p) => exec
329                    .community_psi1
330                    .bottom(V::to_usize(&(exec.fnum_agents * p)).unwrap(), rng),
331            };
332            let mut iter = samples.into_iter();
333            for Informing { step, pop_agents } in informings {
334                if iter.len() == 0 {
335                    continue;
336                }
337                if informers.contains_key(step) {
338                    continue;
339                }
340                let n = V::to_usize(&(*pop_agents * exec.fnum_agents)).unwrap();
341                let agents = (0..n)
342                    .flat_map(|_| {
343                        iter.next().map(|i| {
344                            is_observation[i] = false;
345                            AgentIdx(i)
346                        })
347                    })
348                    .collect::<Vec<_>>();
349                informers.insert(*step, agents);
350            }
351            informers
352        }
353
354        let misinfo_informers = make_informers(
355            exec,
356            rng,
357            &PopSampleType::Top(exec.informing.max_pop_misinfo),
358            &exec.informing.misinfo,
359            &mut is_observation,
360        );
361        let corection_informers = make_informers(
362            exec,
363            rng,
364            &PopSampleType::Bottom(exec.informing.max_pop_correction),
365            &exec.informing.correction,
366            &mut is_observation,
367        );
368        let inhibition_informers = make_informers(
369            exec,
370            rng,
371            &exec.informing.max_pop_inhibition,
372            &exec.informing.inhibition,
373            &mut is_observation,
374        );
375        let mut observation = is_observation
376            .into_iter()
377            .enumerate()
378            .filter_map(|(i, b)| if b { Some(i.into()) } else { None })
379            .take(V::to_usize(&(exec.informing.max_pop_observation * exec.fnum_agents)).unwrap())
380            .collect::<Vec<_>>();
381        observation.shuffle(rng);
382
383        Self {
384            misinfo_informers,
385            corection_informers,
386            inhibition_informers: if exec.enable_inhibition {
387                inhibition_informers
388            } else {
389                BTreeMap::new()
390            },
391            observation,
392            max_step_num_observation: V::to_usize(
393                &(exec.informing.max_step_pop_observation * exec.fnum_agents),
394            )
395            .unwrap(),
396        }
397    }
398
399    fn is_continued(&self, _: &Exec<V>) -> bool {
400        !self.misinfo_informers.is_empty()
401            || !self.corection_informers.is_empty()
402            || !self.inhibition_informers.is_empty()
403    }
404
405    fn get_informers_with<'a>(
406        ins: &mut InstanceWrapper<'a, Exec<V>, V, R, Self>,
407        t: u32,
408    ) -> Vec<(AgentIdx, InfoContent<'a, V>)> {
409        let mut informers = Vec::new();
410        if let Some(d) = ins.ext.misinfo_informers.remove(&t) {
411            for agent_idx in d {
412                informers.push((
413                    agent_idx.into(),
414                    InfoContent::Misinfo {
415                        op: Cow::Borrowed(
416                            ins.exec.information.misinfo.choose(&mut ins.rng).unwrap(),
417                        ),
418                    },
419                ));
420            }
421        }
422        if let Some(d) = ins.ext.corection_informers.remove(&t) {
423            for agent_idx in d {
424                informers.push((
425                    agent_idx.into(),
426                    InfoContent::Correction {
427                        op: Cow::Borrowed(
428                            ins.exec
429                                .information
430                                .correction
431                                .choose(&mut ins.rng)
432                                .unwrap(),
433                        ),
434                        misinfo: Cow::Borrowed(
435                            ins.exec.information.misinfo.choose(&mut ins.rng).unwrap(),
436                        ),
437                    },
438                ));
439            }
440        }
441        if !ins.ext.observation.is_empty() {
442            let p = V::from_usize(ins.prev_num_selfish()).unwrap() / ins.exec.fnum_agents;
443            for _ in 0..ins.ext.max_step_num_observation {
444                if ins.exec.informing.prob_post_observation * p <= ins.rng.gen() {
445                    continue;
446                }
447                if let Some(agent_idx) = ins.ext.observation.pop() {
448                    let op = ins
449                        .exec
450                        .information
451                        .observation
452                        .iter()
453                        .choose(&mut ins.rng)
454                        .unwrap();
455                    informers.push((
456                        agent_idx,
457                        InfoContent::Observation {
458                            op: Cow::Borrowed(op),
459                        },
460                    ));
461                }
462            }
463        }
464        if let Some(d) = ins.ext.inhibition_informers.remove(&t) {
465            for agent_idx in d {
466                let (op1, op2, op3) = ins
467                    .exec
468                    .information
469                    .inhibition
470                    .choose(&mut ins.rng)
471                    .unwrap();
472                informers.push((
473                    agent_idx.into(),
474                    InfoContent::Inhibition {
475                        op1: Cow::Borrowed(op1),
476                        op2: Cow::Borrowed(op2),
477                        op3: Cow::Borrowed(op3),
478                    },
479                ));
480            }
481        }
482
483        informers
484    }
485}
486
487#[cfg(test)]
488mod tests {
489    use std::borrow::Cow;
490
491    use base::{
492        agent::{Agent, Decision},
493        decision::{LevelSet, CPT},
494        executor::InstanceExt,
495        info::{Info, InfoContent},
496        opinion::{FPsi, FixedOpinions, MyOpinions, Psi, Thetad, A, FH, FO},
497    };
498    use rand::{rngs::SmallRng, SeedableRng};
499    use subjective_logic::{
500        iter::FromFn,
501        marr_d1, marr_d2,
502        mul::{
503            labeled::{OpinionD1, OpinionD2, OpinionRefD1, SimplexD1},
504            InverseCondition, MergeJointConditions2, Simplex,
505        },
506        multi_array::labeled::{MArrD1, MArrD2},
507        ops::{Product2, Projection},
508    };
509
510    use super::{new_trusts, Exec, Instance};
511    use crate::config::Config;
512
513    #[test]
514    fn test_instance() -> anyhow::Result<()> {
515        let config = Config::try_new(
516            "./test/network_config.toml",
517            "./test/agent_config.toml",
518            "./test/strategy_config.toml",
519        )?;
520        let exec: Exec<f32> = config.into_exec(true, 0)?;
521        let mut rng = SmallRng::seed_from_u64(0);
522        let ins = Instance::from_exec(&exec, &mut rng);
523        for t in [0, 1, 2] {
524            assert_eq!(ins.misinfo_informers.get(&t).unwrap().len(), 2);
525        }
526        for t in [2, 3, 4] {
527            assert_eq!(ins.corection_informers.get(&t).unwrap().len(), 2);
528        }
529        for t in [4, 5, 6] {
530            assert_eq!(ins.inhibition_informers.get(&t).unwrap().len(), 2);
531        }
532        assert_eq!(ins.observation.len(), 40);
533        Ok(())
534    }
535
536    fn fix_reset(fixed: &mut FixedOpinions<f32>) {
537        let o_b = marr_d1![
538            Simplex::new(marr_d1![0.95, 0.0], 0.05),
539            Simplex::new(marr_d1![0.40, 0.2], 0.40)
540        ];
541        let a_fh = marr_d1![
542            Simplex::new(marr_d1![0.95, 0.0], 0.05),
543            Simplex::new(marr_d1![0.2, 0.6], 0.2)
544        ];
545        let b_kh = marr_d1![
546            Simplex::new(marr_d1![0.95, 0.0], 0.05),
547            Simplex::new(marr_d1![0.1, 0.5], 0.4)
548        ];
549        let theta_h = marr_d1![
550            Simplex::new(marr_d1![0.95, 0.0], 0.05),
551            Simplex::new(marr_d1![0.1, 0.5], 0.4)
552        ];
553        let thetad_h = marr_d1![
554            Simplex::new(marr_d1![0.95, 0.0], 0.05),
555            Simplex::new(marr_d1![0.1, 0.5], 0.4)
556        ];
557        let h_psi_if_phi0 = marr_d1![
558            // Simplex::new(marr_d1![0.25, 0.25], 0.5),
559            // Simplex::new(marr_d1![0.0, 0.0], 1.0),
560            Simplex::new(marr_d1![0.0, 0.0], 1.0),
561            Simplex::new(marr_d1![0.5, 0.25], 0.25)
562        ];
563        let h_b_if_phi0 = marr_d1![
564            Simplex::new(marr_d1![0.5, 0.0], 0.5),
565            Simplex::new(marr_d1![0.1, 0.8], 0.1)
566        ];
567        let uncertainty_fh_fpsi_if_fphi0 = marr_d1![0.3, 0.3];
568        let uncertainty_kh_kpsi_if_kphi0 = marr_d1![0.3, 0.3];
569        let uncertainty_fh_fphi_fo = marr_d2![[0.3, 0.3], [0.3, 0.3]];
570        let uncertainty_kh_kphi_ko = marr_d2![[0.3, 0.3], [0.3, 0.3]];
571        fixed.reset(
572            o_b,
573            b_kh,
574            a_fh,
575            theta_h,
576            thetad_h,
577            h_psi_if_phi0,
578            h_b_if_phi0,
579            uncertainty_fh_fpsi_if_fphi0,
580            uncertainty_kh_kpsi_if_kphi0,
581            uncertainty_fh_fphi_fo,
582            uncertainty_kh_kphi_ko,
583        );
584    }
585
586    fn reset_agent(agent: &mut Agent<f32>) {
587        agent.reset(|ops: &mut MyOpinions<f32>, dec: &mut Decision<f32>| {
588            dec.reset(0, |prs, cpt| {
589                prs.reset(-1.0, -8.00, -0.001);
590                cpt.reset(0.88, 0.88, 2.25, 0.61, 0.69);
591            });
592            fix_reset(&mut ops.fixed);
593            let psi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
594            let phi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
595            let o = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
596            let h_psi_if_phi1 = vec![SimplexD1::vacuous(), SimplexD1::vacuous()]
597                .try_into()
598                .unwrap();
599            let h_b_if_phi1 = vec![SimplexD1::vacuous(), SimplexD1::vacuous()]
600                .try_into()
601                .unwrap();
602            let fo = OpinionD1::vacuous_with(vec![0.5, 0.5].try_into().unwrap());
603            let fpsi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
604            let fphi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
605            let fh_fpsi_if_fphi1 = vec![SimplexD1::vacuous(), SimplexD1::vacuous()]
606                .try_into()
607                .unwrap();
608            let ko = OpinionD1::vacuous_with(vec![0.5, 0.5].try_into().unwrap());
609            let kpsi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
610            let kphi = OpinionD1::vacuous_with(vec![0.95, 0.05].try_into().unwrap());
611            let kh_kpsi_if_kphi1 = vec![SimplexD1::vacuous(), SimplexD1::vacuous()]
612                .try_into()
613                .unwrap();
614            ops.state.reset(
615                psi,
616                phi,
617                o,
618                fo,
619                ko,
620                h_psi_if_phi1,
621                h_b_if_phi1,
622                fpsi,
623                fphi,
624                fh_fpsi_if_fphi1,
625                kpsi,
626                kphi,
627                kh_kpsi_if_kphi1,
628            );
629            let h = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
630            let fh = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
631            let kh = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
632            let a = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
633            let b = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
634            let theta = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
635            let thetad = OpinionD1::vacuous_with(marr_d1![0.95, 0.05].try_into().unwrap());
636            ops.ded.reset(h, fh, kh, a, b, theta, thetad);
637        });
638    }
639
640    #[tracing_test::traced_test]
641    #[test]
642    fn test_agent() -> anyhow::Result<()> {
643        let m_op = Cow::<OpinionD1<Psi, f32>>::Owned(OpinionD1::new(
644            marr_d1![0.0, 0.95],
645            0.05,
646            marr_d1![0.1, 0.9],
647        ));
648        let c_op = Cow::Owned(OpinionD1::new(
649            marr_d1![0.95, 0.0],
650            0.05,
651            marr_d1![0.5, 0.5],
652        ));
653        let m_info = Info::new(0, InfoContent::Misinfo { op: m_op.clone() });
654        let c_info = Info::new(
655            1,
656            InfoContent::Correction {
657                op: c_op,
658                misinfo: m_op.clone(),
659            },
660        );
661
662        let mut agent = Agent::<f32>::default();
663        // let o = InfoContent::Observation {
664        //     op: Cow::Owned(OpinionD1::new(marr_d1![0.9, 0.0], 0.1, marr_d1![0.9, 0.1])),
665        // };
666        // let o_info = Info::new(2, o);
667        // agent.reset(reset);
668        // agent.read_info(&m_info, new_trusts(0.5, 0.9, 0.5, 0.1, 0.1, 0.5, 0.9, 0.5));
669        // agent.reset(reset);
670        agent.read_info(&c_info, new_trusts(1.0, 0.9, 0.5, 0.1, 0.5, 0.5, 0.9, 0.95));
671        // agent.reset(reset);
672        // agent.read_info(&o_info, new_trusts(1.0, 0.9, 0.5, 0.1, 0.5, 0.5, 0.9, 0.95));
673        reset_agent(&mut agent);
674        agent.read_info(&m_info, new_trusts(1.0, 0.9, 0.5, 0.5, 0.5, 1.0, 0.9, 0.95));
675        // agent.reset(reset);
676        // agent.read_info(&m_info, new_trusts(0.6, 0.9, 0.5, 0.1, 0.5, 0.5, 0.9, 0.95));
677        // agent.reset(reset);
678        // agent.read_info(&m_info, new_trusts(0.5, 0.9, 0.5, 0.1, 0.5, 0.5, 0.9, 0.95));
679        // agent.reset(reset);
680        // agent.read_info(&c_info, new_trusts(1.0, 0.9, 0.5, 0.8, 0.5, 0.5, 0.9, 0.95));
681        // agent.reset(reset);
682        // agent.read_info(&m_info, new_trusts(0.8, 0.9, 0.5, 0.8, 0.5, 0.5, 0.9, 0.95));
683        // agent.read_info(&c_info, new_trusts(1.0, 0.9, 0.5, 0.8, 0.5, 0.5, 0.9, 0.95));
684        // agent.read_info(&c_info, new_trusts(1.0, 0.9, 0.5, 0.8, 0.5, 0.5, 0.9, 0.95));
685        Ok(())
686    }
687
688    #[test]
689    fn test_cond() {
690        let c0 = marr_d1!(FPsi; [
691            SimplexD1::new(marr_d1!(FH;[0.89, 0.10]), 0.01),
692            SimplexD1::new(marr_d1![0.10, 0.89], 0.01),
693        ]);
694        let c1 = marr_d1!(FO; [
695            SimplexD1::new(marr_d1!(FH;[0.94, 0.05]), 0.01),
696            SimplexD1::new(marr_d1![0.11, 0.88], 0.01),
697        ]);
698
699        let a0 = marr_d1!(FPsi; [0.37, 0.63]);
700        let a1 = marr_d1!(FO; [0.5, 0.5]);
701        let ay = marr_d1!(FH; [0.85, 0.15]); // marr_d1!(FPsi; [0.95, 0.05]);
702        let inv_c0 = c0.inverse(&a0, &ay); // mbr(&a0, &c0).as_ref().unwrap());
703        let inv_c1 = c1.inverse(&a1, &ay); // mbr(&a1, &c1).as_ref().unwrap());
704        let inv_c01 = MArrD1::<FH, _>::from_fn(|fh| {
705            let r0 = OpinionRefD1::from((&inv_c0[fh], &a0));
706            let r1 = OpinionRefD1::from((&inv_c1[fh], &a1));
707            OpinionD2::product2(r0, r1).simplex
708        });
709        let c01 = inv_c01.inverse(&ay, &MArrD2::product2(&a0, &a1));
710        println!("{:?}", inv_c0);
711        println!("{:?}", inv_c1);
712        println!("{:?}", c01);
713        // let x1_y = y_x1.inverse(ax1, mbr(ax1, y_x1).as_ref().unwrap_or(ay));
714        // let x2_y = y_x2.inverse(ax2, mbr(ax2, y_x2).as_ref().unwrap_or(ay));
715        // let x12_y = CX1X2Y::from_fn(|y| {
716        //     let x1yr = OpinionRef::from((x1_y[y].borrow(), ax1));
717        //     let x2yr = OpinionRef::from((x2_y[y].borrow(), ax2));
718        //     let OpinionBase { simplex, .. } = Product2::product2(x1yr, x2yr);
719        //     simplex
720        // });
721        // let ax12 = mbr(ay, &x12_y).unwrap_or_else(|| Product2::product2(ax1, ax2));
722        // x12_y.inverse(ay, &ax12)
723
724        let c: MArrD2<FPsi, FO, SimplexD1<FH, f32>> =
725            MArrD1::<FH, _>::merge_cond2(&c0, &c1, &a0, &a1, &ay);
726        println!("{:?}", c[(FPsi(0), FO(0))]);
727        println!("{:?}", c[(FPsi(0), FO(1))]);
728        println!("{:?}", c[(FPsi(1), FO(0))]);
729        println!("{:?}", c[(FPsi(1), FO(1))]);
730    }
731
732    #[test]
733    fn test_sharing() {
734        let mut cpt = CPT::default();
735        cpt.reset(0.88, 0.88, 0.69, 2.25, 0.61);
736
737        let x0 = -1.0;
738        let x1 = -10.0;
739        let y = -0.001;
740        let d0 = LevelSet::<(A, Thetad), f32>::new(&marr_d2!(A, Thetad; [[0.0, x1], [x0, x0]]));
741        let d1 = LevelSet::<(A, Thetad), f32>::new(
742            &marr_d2!(A, Thetad; [[y, x1 + y], [x0 + y, x0 + y]]),
743        );
744        // b=A[0.1856482,  0.20050177], u=0.61385006, a=A[0.49628967, 0.50371027]
745        // b=A[0.15187897, 0.17525421], u=0.6728668 , a=A[0.48121205, 0.5187879]
746        // b=Thetad[0.45818824, 0.12272677], u=0.41908503, a=Thetad[0.79127306, 0.2087269]
747        // b=Thetad[0.44344428, 0.14268395], u=0.41387182, a=Thetad[0.7584604, 0.24153961]
748        let wa0 = OpinionD1::<A, f32>::new(marr_d1![0.19, 0.20], 0.61, marr_d1![0.50, 0.50]);
749        let wa1 = OpinionD1::<A, f32>::new(marr_d1![0.10, 0.29], 0.61, marr_d1![0.48, 0.52]);
750        let wthetad0 =
751            OpinionD1::<Thetad, f32>::new(marr_d1![0.46, 0.12], 0.42, marr_d1![0.80, 0.20]);
752        let wthetad1 =
753            OpinionD1::<Thetad, f32>::new(marr_d1![0.50, 0.08], 0.42, marr_d1![0.76, 0.24]);
754        let w0 = OpinionD2::product2(&wa0, &wthetad0);
755        let w1 = OpinionD2::product2(&wa1, &wthetad1);
756        let p0 = w0.projection();
757        let p1 = w1.projection();
758        println!("{w0:?}");
759        println!("{w1:?}");
760        println!("{p0:?}");
761        println!("{p1:?}");
762        let v0 = cpt.valuate(&d0, &p0);
763        let v1 = cpt.valuate(&d1, &p1);
764        println!("{v0}, {v1}");
765        // 2024-09-02T11:36:03.828566Z  INFO test_agent:    THd: P=A[Thetad[0.38723496, 0.10306068], Thetad[0.40256393, 0.1071404]]
766        // 2024-09-02T11:36:03.828596Z  INFO test_agent:   ~THd: P=A[Thetad[0.36024895, 0.115421645], Thetad[0.39710066, 0.12722872]]
767    }
768}