AERA
view.cpp
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 #include "controller.h"
86 #include "view.h"
87 #include "../submodules/CoreLibrary/CoreLibrary/utils.h"
88 #include "group.h"
89 #include "mem.h"
90 
91 #include <limits>
92 
93 using namespace r_code;
94 
95 const float32 PLUS_INFINITY = std::numeric_limits<float>::infinity();
96 
97 
98 namespace r_exec {
99 
100 CriticalSection OIDCS;
101 
102 uint32 View::lastOID_ = 0;
103 
104 View::~View() {
105 
106  if (!!controller_)
107  controller_->invalidate();
108 }
109 
110 uint32 View::GetOID() {
111 
112  OIDCS.enter();
113  uint32 oid = lastOID_++;
114  OIDCS.leave();
115  return oid;
116 }
117 
118 uint16 View::ViewOpcode_;
119 
120 float32 View::MorphValue(float32 value, float32 source_thr, float32 destination_thr) {
121 
122  if (value == 0)
123  return destination_thr;
124 
125  if (source_thr > 0) {
126 
127  if (destination_thr > 0) {
128 
129  float32 r = value * destination_thr / source_thr;
130  if (r > 1) // handles precision errors.
131  r = 1;
132  return r;
133  } else
134  return value;
135  }
136  return destination_thr + value;
137 }
138 
139 float32 View::MorphChange(float32 change, float32 source_thr, float32 destination_thr) { // change is always >0.
140 
141  if (source_thr > 0) {
142 
143  if (destination_thr > 0)
144  return change * destination_thr / source_thr;
145  else
146  return change;
147  }
148  return destination_thr + change;
149 }
150 
151 View::View(View *view, Group *group) : r_code::_View(), controller_(NULL) {
152 
153  Group *source = view->get_host();
154  object_ = view->object_;
155  memcpy(code_, view->code_, VIEW_CODE_MAX_SIZE * sizeof(Atom));
156  code_[VIEW_OID].atom_ = GetOID();
157  references_[0] = group; // host.
158  references_[1] = source; // origin.
159 
160  // morph ctrl values; NB: res is not morphed as it is expressed as a multiple of the upr.
161  code(VIEW_SLN) = Atom::Float(MorphValue(view->code(VIEW_SLN).asFloat(), source->get_sln_thr(), group->get_sln_thr()));
162  switch (object_->code(0).getDescriptor()) {
163  case Atom::GROUP:
164  code(GRP_VIEW_VIS) = Atom::Float(MorphValue(view->code(GRP_VIEW_VIS).asFloat(), source->get_vis_thr(), group->get_vis_thr()));
165  break;
166  case Atom::NULL_PROGRAM:
167  case Atom::INSTANTIATED_PROGRAM:
168  case Atom::INSTANTIATED_CPP_PROGRAM:
169  case Atom::INSTANTIATED_INPUT_LESS_PROGRAM:
170  case Atom::INSTANTIATED_ANTI_PROGRAM:
171  case Atom::COMPOSITE_STATE:
172  case Atom::MODEL:
173  code(VIEW_ACT) = Atom::Float(MorphValue(view->code(VIEW_ACT).asFloat(), source->get_act_thr(), group->get_act_thr()));
174  break;
175  }
176 
177  reset();
178 }
179 
180 void View::set_object(r_code::Code *object) {
181 
182  object_ = object;
183  reset();
184 }
185 
186 void View::reset_ctrl_values() {
187 
188  sln_changes_ = 0;
189  acc_sln_ = 0;
190  act_changes_ = 0;
191  acc_act_ = 0;
192  vis_changes_ = 0;
193  acc_vis_ = 0;
194  res_changes_ = 0;
195  acc_res_ = 0;
196 
197  periods_at_low_sln_ = 0;
198  periods_at_high_sln_ = 0;
199  periods_at_low_act_ = 0;
200  periods_at_high_act_ = 0;
201 }
202 
203 void View::reset_init_sln() {
204 
205  initial_sln_ = get_sln();
206 }
207 
208 void View::reset_init_act() {
209 
210  if (object_ != NULL)
211  initial_act_ = get_act();
212  else
213  initial_act_ = 0;
214 }
215 
216 float32 View::update_res() {
217 
218  float32 new_res = get_res();
219  if (new_res == PLUS_INFINITY)
220  return new_res;
221  if (res_changes_ > 0 && acc_res_ != 0)
222  new_res = get_res() + (float32)acc_res_ / (float32)res_changes_;
223  if (--new_res < 0) // decremented by one on behalf of the group (at upr).
224  new_res = 0;
225  code(VIEW_RES) = r_code::Atom::Float(new_res);
226  acc_res_ = 0;
227  res_changes_ = 0;
228  return get_res();
229 }
230 
231 float32 View::update_sln(float32 low, float32 high) {
232 
233  if (sln_changes_ > 0 && acc_sln_ != 0) {
234 
235  float32 new_sln = get_sln() + acc_sln_ / sln_changes_;
236  if (new_sln < 0)
237  new_sln = 0;
238  else if (new_sln > 1)
239  new_sln = 1;
240  code(VIEW_SLN) = r_code::Atom::Float(new_sln);
241  }
242  acc_sln_ = 0;
243  sln_changes_ = 0;
244 
245  float32 sln = get_sln();
246  if (sln < low)
247  ++periods_at_low_sln_;
248  else {
249 
250  periods_at_low_sln_ = 0;
251  if (sln > high)
252  ++periods_at_high_sln_;
253  else
254  periods_at_high_sln_ = 0;
255  }
256  return sln;
257 }
258 
259 float32 View::update_act(float32 low, float32 high) {
260 
261  if (act_changes_ > 0 && acc_act_ != 0) {
262 
263  float32 new_act = get_act() + acc_act_ / act_changes_;
264  if (new_act < 0)
265  new_act = 0;
266  else if (new_act > 1)
267  new_act = 1;
268  code(VIEW_ACT) = r_code::Atom::Float(new_act);
269  }
270  acc_act_ = 0;
271  act_changes_ = 0;
272 
273  float32 act = get_act();
274  if (act < low)
275  ++periods_at_low_act_;
276  else {
277 
278  periods_at_low_act_ = 0;
279  if (act > high)
280  ++periods_at_high_act_;
281  else
282  periods_at_high_act_ = 0;
283  }
284  return act;
285 }
286 
287 float32 View::update_vis() {
288 
289  if (vis_changes_ > 0 && acc_vis_ != 0) {
290 
291  float32 new_vis = get_vis() + acc_vis_ / vis_changes_;
292  if (new_vis < 0)
293  new_vis = 0;
294  else if (new_vis > 1)
295  new_vis = 1;
296  code(GRP_VIEW_VIS) = r_code::Atom::Float(new_vis);
297  }
298  acc_vis_ = 0;
299  vis_changes_ = 0;
300  return get_vis();
301 }
302 
303 void View::delete_from_object() {
304 
305  object_->acq_views();
306  object_->views_.erase(this);
307  if (object_->views_.size() == 0)
308  object_->invalidate();
309  object_->rel_views();
310 }
311 
312 void View::delete_from_group() {
313 
314  Group *g = get_host();
315  g->enter();
316  g->delete_view(this);
317  g->leave();
318 }
319 
321 
322 NotificationView::NotificationView(Code *origin, Code *destination, Code *marker) : View() {
323 
324  code(VIEW_OPCODE) = r_code::Atom::SSet(ViewOpcode_, VIEW_ARITY); // Structured Set.
325  code(VIEW_SYNC) = r_code::Atom::Float(View::SYNC_ONCE); // sync once.
326  code(VIEW_IJT) = r_code::Atom::IPointer(VIEW_ARITY + 1); // iptr to ijt.
327  code(VIEW_SLN) = r_code::Atom::Float(1); // sln.
328  code(VIEW_RES) = r_code::Atom::Float(_Mem::Get()->get_ntf_mk_res()); // res.
329  code(VIEW_HOST) = r_code::Atom::RPointer(0); // destination.
330  code(VIEW_ORG) = r_code::Atom::RPointer(1); // origin.
331  code(VIEW_ARITY + 1) = r_code::Atom::Timestamp(); // ijt will be set at injection time.
332  code(VIEW_ARITY + 2) = 0;
333  code(VIEW_ARITY + 3) = 0;
334  references_[0] = destination;
335  references_[1] = origin;
336 
337  reset_init_sln();
338 
339  object_ = marker;
340 }
341 }
r_code::_View
Definition: r_code/object.h:164
r_code::Atom
Definition: atom.h:104
r_code::Code
Definition: r_code/object.h:224
core::CriticalSection
Definition: submodules/CoreLibrary/CoreLibrary/utils.h:233