AERA
group.h
1 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 //_/_/
3 //_/_/ AERA
4 //_/_/ Autocatalytic Endogenous Reflective Architecture
5 //_/_/
6 //_/_/ Copyright (c) 2018-2025 Jeff Thompson
7 //_/_/ Copyright (c) 2018-2025 Kristinn R. Thorisson
8 //_/_/ Copyright (c) 2018-2025 Icelandic Institute for Intelligent Machines
9 //_/_/ http://www.iiim.is
10 //_/_/
11 //_/_/ Copyright (c) 2010-2012 Eric Nivel
12 //_/_/ Center for Analysis and Design of Intelligent Agents
13 //_/_/ Reykjavik University, Menntavegur 1, 102 Reykjavik, Iceland
14 //_/_/ http://cadia.ru.is
15 //_/_/
16 //_/_/ Part of this software was developed by Eric Nivel
17 //_/_/ in the HUMANOBS EU research project, which included
18 //_/_/ the following parties:
19 //_/_/
20 //_/_/ Autonomous Systems Laboratory
21 //_/_/ Technical University of Madrid, Spain
22 //_/_/ http://www.aslab.org/
23 //_/_/
24 //_/_/ Communicative Machines
25 //_/_/ Edinburgh, United Kingdom
26 //_/_/ http://www.cmlabs.com/
27 //_/_/
28 //_/_/ Istituto Dalle Molle di Studi sull'Intelligenza Artificiale
29 //_/_/ University of Lugano and SUPSI, Switzerland
30 //_/_/ http://www.idsia.ch/
31 //_/_/
32 //_/_/ Institute of Cognitive Sciences and Technologies
33 //_/_/ Consiglio Nazionale delle Ricerche, Italy
34 //_/_/ http://www.istc.cnr.it/
35 //_/_/
36 //_/_/ Dipartimento di Ingegneria Informatica
37 //_/_/ University of Palermo, Italy
38 //_/_/ http://diid.unipa.it/roboticslab/
39 //_/_/
40 //_/_/
41 //_/_/ --- HUMANOBS Open-Source BSD License, with CADIA Clause v 1.0 ---
42 //_/_/
43 //_/_/ Redistribution and use in source and binary forms, with or without
44 //_/_/ modification, is permitted provided that the following conditions
45 //_/_/ are met:
46 //_/_/ - Redistributions of source code must retain the above copyright
47 //_/_/ and collaboration notice, this list of conditions and the
48 //_/_/ following disclaimer.
49 //_/_/ - Redistributions in binary form must reproduce the above copyright
50 //_/_/ notice, this list of conditions and the following disclaimer
51 //_/_/ in the documentation and/or other materials provided with
52 //_/_/ the distribution.
53 //_/_/
54 //_/_/ - Neither the name of its copyright holders nor the names of its
55 //_/_/ contributors may be used to endorse or promote products
56 //_/_/ derived from this software without specific prior
57 //_/_/ written permission.
58 //_/_/
59 //_/_/ - CADIA Clause: The license granted in and to the software
60 //_/_/ under this agreement is a limited-use license.
61 //_/_/ The software may not be used in furtherance of:
62 //_/_/ (i) intentionally causing bodily injury or severe emotional
63 //_/_/ distress to any person;
64 //_/_/ (ii) invading the personal privacy or violating the human
65 //_/_/ rights of any person; or
66 //_/_/ (iii) committing or preparing for any act of war.
67 //_/_/
68 //_/_/ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
69 //_/_/ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
70 //_/_/ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
71 //_/_/ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 //_/_/ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
73 //_/_/ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74 //_/_/ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
75 //_/_/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
76 //_/_/ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77 //_/_/ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
78 //_/_/ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
79 //_/_/ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80 //_/_/ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
81 //_/_/ OF SUCH DAMAGE.
82 //_/_/
83 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
84 
85 #ifndef group_h
86 #define group_h
87 
88 #include <set>
89 #include <unordered_map>
90 
91 #include "../submodules/CoreLibrary/CoreLibrary/utils.h"
92 #include "controller.h"
93 #include "object.h"
94 #include "view.h"
95 
96 
97 namespace r_exec {
98 
99 class _Mem;
100 class HLPController;
101 
102 // Shared resources:
103 // all parameters: accessed by Mem::update and reduction cores (via overlay mod/set).
104 // all views: accessed by Mem::update and reduction cores.
105 // viewing_groups_: accessed by Mem::injectNow and Mem::update.
106 class r_exec_dll Group :
107  public LObject,
108  public CriticalSection {
109 private:
110  // Ctrl values.
111  uint32 sln_thr_changes_;
112  float32 acc_sln_thr_;
113  uint32 act_thr_changes_;
114  float32 acc_act_thr_;
115  uint32 vis_thr_changes_;
116  float32 acc_vis_thr_;
117  uint32 c_sln_changes_;
118  float32 acc_c_sln_;
119  uint32 c_act_changes_;
120  float32 acc_c_act_;
121  uint32 c_sln_thr_changes_;
122  float32 acc_c_sln_thr_;
123  uint32 c_act_thr_changes_;
124  float32 acc_c_act_thr_;
125  void reset_ctrl_values();
126 
127  // Stats.
128  float32 avg_sln_;
129  float32 high_sln_;
130  float32 low_sln_;
131  float32 avg_act_;
132  float32 high_act_;
133  float32 low_act_;
134  uint32 sln_updates_;
135  uint32 act_updates_;
136 
137  // Decay.
138  float32 sln_decay_;
139  float32 sln_thr_decay_;
140  int32 decay_periods_to_go_;
141  float32 decay_percentage_per_period_;
142  float32 decay_target_; // -1: none, 0: sln, 1:sln_thr
143  void reset_decay_values();
144 
145  // Notifications.
146  int32 sln_change_monitoring_periods_to_go_;
147  int32 act_change_monitoring_periods_to_go_;
148 
149  void _mod_0_positive(uint16 member_index, float32 value);
150  void _mod_0_plus1(uint16 member_index, float32 value);
151  void _mod_minus1_plus1(uint16 member_index, float32 value);
152  void _set_0_positive(uint16 member_index, float32 value);
153  void _set_0_plus1(uint16 member_index, float32 value);
154  void _set_minus1_plus1(uint16 member_index, float32 value);
155  void _set_0_1(uint16 member_index, float32 value);
156 
157  bool is_active_pgm(View *view);
158  bool is_eligible_input(View *view);
159 
160  void inject(View *view);
161 
162  void notifyNew(View *view);
163  void cov(View *view);
164 
165  class GroupState {
166  public:
167  float32 former_sln_thr;
168  bool was_c_active;
169  bool is_c_active;
170  bool was_c_salient;
171  bool is_c_salient;
172  GroupState(float32 former_sln_thr,
173  bool was_c_active,
174  bool is_c_active,
175  bool was_c_salient,
176  bool is_c_salient) : former_sln_thr(former_sln_thr), was_c_active(was_c_active), is_c_active(is_c_active), was_c_salient(was_c_salient), is_c_salient(is_c_salient) {}
177  };
178 
179  void _update_saliency(GroupState *state, View *view);
180  void _update_activation(GroupState *state, View *view);
181  void _update_visibility(GroupState *state, View *view);
182 
183  void _initiate_sln_propagation(Code *object, float32 change, float32 source_sln_thr) const;
184  void _initiate_sln_propagation(Code *object, float32 change, float32 source_sln_thr, std::vector<Code *> &path) const;
185  void _propagate_sln(Code *object, float32 change, float32 source_sln_thr, std::vector<Code *> &path) const;
186 public:
187  // xxx_views are meant for erasing views with res==0. They are specialized by type to ease update operations.
188  // Active overlays are to be found in xxx_ipgm_views.
189  std::unordered_map<uint32, P<View> > ipgm_views_;
190  std::unordered_map<uint32, P<View> > anti_ipgm_views_;
191  std::unordered_map<uint32, P<View> > input_less_ipgm_views_;
192  std::unordered_map<uint32, P<View> > notification_views_;
193  std::unordered_map<uint32, P<View> > group_views_;
194  std::unordered_map<uint32, P<View> > other_views_;
195 
196  // Defined to create reduction jobs in the viewing groups from the viewed group.
197  // Empty when the viewed group is invisible (this means that visible groups can be non c-active or non c-salient).
198  // Maintained by the viewing groups (at update time).
199  // Viewing groups are c-active and c-salient. the bool is the cov.
200  std::unordered_map<Group *, bool> viewing_groups_;
201 
202  // Populated within update; ordered by increasing ijt; cleared at the beginning of update.
203  std::multiset<P<View>, r_code::_View::Less> newly_salient_views_;
204 
205  // Populated upon ipgm injection; used at update time; cleared afterward.
206  std::vector<Controller *> new_controllers_;
207 
208  class Operation {
209  protected:
210  Operation(uint32 oid) : oid_(oid) {}
211  public:
212  const uint32 oid_; // of the view.
213  virtual void execute(Group *g) const = 0;
214  };
215 
216  class ModSet :
217  public Operation {
218  protected:
219  ModSet(uint32 oid, uint16 member_index, float32 value) : Operation(oid), member_index_(member_index), value_(value) {}
220  const uint16 member_index_;
221  const float32 value_;
222  };
223 
224  class Mod :
225  public ModSet {
226  public:
227  Mod(uint32 oid, uint16 member_index, float32 value) : ModSet(oid, member_index, value) {}
228  void execute(Group *g) const override {
229 
230  View *v = g->get_view(oid_);
231  if (v)
232  v->mod(member_index_, value_);
233  }
234  };
235 
236  class Set :
237  public ModSet {
238  public:
239  Set(uint32 oid, uint16 member_index, float32 value) : ModSet(oid, member_index, value) {}
240  void execute(Group *g) const override {
241 
242  View *v = g->get_view(oid_);
243  if (v)
244  v->set(member_index_, value_);
245  }
246  };
247 
248  // Pending mod/set operations on the group's view, exploited and cleared at update time.
249  std::vector<Operation *> pending_operations_;
250 
251  Group(r_code::Mem *m = NULL);
252  Group(r_code::SysObject *source);
253  virtual ~Group();
254 
255  bool invalidate() override; // removes all views of itself and of any other object.
256 
257  bool all_views_cond(uint8 &selector, std::unordered_map<uint32, P<View> >::const_iterator &it, std::unordered_map<uint32, P<View> >::const_iterator &end) {
258  while (it == end) {
259  switch (selector++) {
260  case 0:
261  it = anti_ipgm_views_.begin();
262  end = anti_ipgm_views_.end();
263  break;
264  case 1:
265  it = input_less_ipgm_views_.begin();
266  end = input_less_ipgm_views_.end();
267  break;
268  case 2:
269  it = notification_views_.begin();
270  end = notification_views_.end();
271  break;
272  case 3:
273  it = group_views_.begin();
274  end = group_views_.end();
275  break;
276  case 4:
277  it = other_views_.begin();
278  end = other_views_.end();
279  break;
280  case 5:
281  selector = 0;
282  return false;
283  }
284  }
285  return true;
286  }
287 
288 #define FOR_ALL_VIEWS_BEGIN(g,it) { \
289  uint8 selector; \
290  std::unordered_map<uint32,P<View> >::const_iterator it=g->ipgm_views_.begin(); \
291  std::unordered_map<uint32,P<View> >::const_iterator end=g->ipgm_views_.end(); \
292  for(selector=0;g->all_views_cond(selector,it,end);++it){
293 
294 #define FOR_ALL_VIEWS_BEGIN_NO_INC(g,it) { \
295  uint8 selector; \
296  std::unordered_map<uint32,P<View> >::const_iterator it=g->ipgm_views_.begin(); \
297  std::unordered_map<uint32,P<View> >::const_iterator end=g->ipgm_views_.end(); \
298  for(selector=0;g->all_views_cond(selector,it,end);){
299 
300 #define FOR_ALL_VIEWS_END } \
301  }
302 
303  bool views_with_inputs_cond(uint8 &selector, std::unordered_map<uint32, P<View> >::const_iterator &it, std::unordered_map<uint32, P<View> >::const_iterator &end) {
304  while (it == end) {
305  switch (selector++) {
306  case 0:
307  it = anti_ipgm_views_.begin();
308  end = anti_ipgm_views_.end();
309  break;
310  case 1:
311  selector = 0;
312  return false;
313  }
314  }
315  return true;
316  }
317 
318 #define FOR_ALL_VIEWS_WITH_INPUTS_BEGIN(g,it) { \
319  uint8 selector; \
320  std::unordered_map<uint32,P<View> >::const_iterator it=g->ipgm_views_.begin(); \
321  std::unordered_map<uint32,P<View> >::const_iterator end=g->ipgm_views_.end(); \
322  for(selector=0;g->views_with_inputs_cond(selector,it,end);++it){
323 
324 #define FOR_ALL_VIEWS_WITH_INPUTS_END } \
325  }
326 
327  bool non_ntf_views_cond(uint8 &selector, std::unordered_map<uint32, P<View> >::const_iterator &it, std::unordered_map<uint32, P<View> >::const_iterator &end) {
328  while (it == end) {
329  switch (selector++) {
330  case 0:
331  it = anti_ipgm_views_.begin();
332  end = anti_ipgm_views_.end();
333  break;
334  case 1:
335  it = input_less_ipgm_views_.begin();
336  end = input_less_ipgm_views_.end();
337  break;
338  case 2:
339  it = group_views_.begin();
340  end = group_views_.end();
341  break;
342  case 3:
343  it = other_views_.begin();
344  end = other_views_.end();
345  break;
346  case 4:
347  selector = 0;
348  return false;
349  }
350  }
351  return true;
352  }
353 
354 #define FOR_ALL_NON_NTF_VIEWS_BEGIN(g,it) { \
355  uint8 selector; \
356  std::unordered_map<uint32,P<View> >::const_iterator it=g->ipgm_views_.begin(); \
357  std::unordered_map<uint32,P<View> >::const_iterator end=g->ipgm_views_.end(); \
358  for(selector=0;g->non_ntf_views_cond(selector,it,end);++it){
359 
360 #define FOR_ALL_NON_NTF_VIEWS_END } \
361  }
362 
363  View *get_view(uint32 OID);
364 
365  uint32 get_upr() const;
366 
367  float32 get_sln_thr() const;
368  float32 get_act_thr() const;
369  float32 get_vis_thr() const;
370 
371  float32 get_c_sln() const;
372  float32 get_c_act() const;
373 
374  float32 get_c_sln_thr() const;
375  float32 get_c_act_thr() const;
376 
377  void mod_sln_thr(float32 value);
378  void set_sln_thr(float32 value);
379  void mod_act_thr(float32 value);
380  void set_act_thr(float32 value);
381  void mod_vis_thr(float32 value);
382  void set_vis_thr(float32 value);
383  void mod_c_sln(float32 value);
384  void set_c_sln(float32 value);
385  void mod_c_act(float32 value);
386  void set_c_act(float32 value);
387  void mod_c_sln_thr(float32 value);
388  void set_c_sln_thr(float32 value);
389  void mod_c_act_thr(float32 value);
390  void set_c_act_thr(float32 value);
391 
392  float32 update_sln_thr(); // computes and applies decay on sln thr if any.
393  float32 update_act_thr();
394  float32 update_vis_thr();
395  float32 update_c_sln();
396  float32 update_c_act();
397  float32 update_c_sln_thr();
398  float32 update_c_act_thr();
399 
400  float32 get_sln_chg_thr();
401  float32 get_sln_chg_prd();
402  float32 get_act_chg_thr();
403  float32 get_act_chg_prd();
404 
405  float32 get_avg_sln();
406  float32 get_high_sln();
407  float32 get_low_sln();
408  float32 get_avg_act();
409  float32 get_high_act();
410  float32 get_low_act();
411 
412  float32 get_high_sln_thr();
413  float32 get_low_sln_thr();
414  float32 get_sln_ntf_prd();
415  float32 get_high_act_thr();
416  float32 get_low_act_thr();
417  float32 get_act_ntf_prd();
418  float32 get_low_res_thr();
419 
420  float32 get_ntf_new();
421 
422  uint16 get_ntf_grp_count();
423  Group *get_ntf_grp(uint16 i); // i starts at 1.
424 
425  // Delegate to views; update stats and notifies.
426  float32 update_res(View *v);
427  float32 update_sln(View *v); // applies decay if any.
428  float32 update_act(View *v);
429 
430  // Target upr, spr, c_sln, c_act, sln_thr, act_thr, vis_thr, c_sln_thr, c_act_thr, sln_chg_thr,
431  // sln_chg_prd, act_chg_thr, act_chg_prd, high_sln_thr, low_sln_thr, sln_ntf_prd, high_act_thr, low_act_thr, act_ntf_prd, low_res_thr, res_ntf_prd, ntf_new,
432  // dcy_per, dcy-tgt, dcy_prd.
433  void mod(uint16 member_index, float32 value) override;
434  void set(uint16 member_index, float32 value) override;
435 
436  void reset_stats(); // called at the begining of an update.
437  void update_stats(); // at the end of an update; may produce notifcations.
438 
439  bool load(View *view, Code *object);
440 
441  // Called at each update period.
442  // - set the final resilience value_, if 0, delete.
443  // - set the final saliency.
444  // - set the final activation.
445  // - set the final visibility, cov.
446  // - propagate saliency changes.
447  // - inject next update job for the group.
448  // - inject new signaling jobs if act pgm with no input or act |pgm.
449  // - notify high and low values.
450  void update(Timestamp planned_time);
451 
452  void inject_new_object(View *view);
453  void inject_existing_object(View *view);
454  void inject_group(View *view);
455  void inject_notification(View *view, bool lock);
456  void inject_hlps(std::vector<View *> &views);
457  void inject_reduction_jobs(View *view);
458 
459  void cov();
460 
461  class Hash {
462  public:
463  size_t operator ()(Group *g) const {
464  return (size_t)g;
465  }
466  };
467 
468  class Equal {
469  public:
470  bool operator ()(const Group *lhs, const Group *rhs) const {
471  return lhs == rhs;
472  }
473  };
474 
475  void delete_view(View *v);
476  void delete_view(std::unordered_map<uint32, P<View> >::const_iterator &v);
477 
478  Group *get_secondary_group();
479  void load_secondary_mdl_controller(View *view);
480  void inject_secondary_mdl_controller(View *view);
481 
482  Timestamp get_next_upr_time(Timestamp now) const;
483  Timestamp get_prev_upr_time(Timestamp now) const;
484 };
485 }
486 
487 
488 #include "object.tpl.cpp"
489 #include "group.inline.cpp"
490 
491 
492 #endif
r_code::SysObject
Definition: r_code/object.h:136
r_exec::LObject
Definition: r_exec/object.h:195
core::P
Definition: base.h:103
r_code::_View::Less
Definition: r_code/object.h:215
r_exec::Group::Operation
Definition: group.h:208
core::CriticalSection
Definition: submodules/CoreLibrary/CoreLibrary/utils.h:233
r_exec::View
Definition: view.h:102
r_exec::Group
Definition: group.h:108
r_exec::Group::ModSet
Definition: group.h:217
r_exec::Group::Mod
Definition: group.h:225
r_exec::Group::Hash
Definition: group.h:461
r_exec::Group::Equal
Definition: group.h:468
r_code::Mem
Definition: r_code/object.h:420
r_exec::Group::Set
Definition: group.h:237