AERA
atom.inline.cpp
1 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 //_/_/
3 //_/_/ AERA
4 //_/_/ Autocatalytic Endogenous Reflective Architecture
5 //_/_/
6 //_/_/ Copyright (c) 2018-2023 Jeff Thompson
7 //_/_/ Copyright (c) 2018-2023 Kristinn R. Thorisson
8 //_/_/ Copyright (c) 2018-2023 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 <iostream>
86 namespace r_code {
87 
88 inline Atom Atom::Float(float32 f) {
89 
90  float32 _f = f;
91  uint32 a = *reinterpret_cast<uint32 *>(&_f);
92  return Atom(a >> 1);
93 }
94 
95 inline Atom Atom::PlusInfinity() {
96 
97  return Atom(0x3FC00000);
98 }
99 
100 inline Atom Atom::MinusInfinity() {
101 
102  return Atom(0x7FC00000);
103 }
104 
105 inline Atom Atom::UndefinedFloat() {
106 
107  return Atom(0xFFFFFFF);
108 }
109 
110 inline Atom Atom::Nil() {
111 
112  return Atom((uint32)(NIL << 24));
113 }
114 
115 inline Atom Atom::Boolean(bool value) {
116 
117  return Atom((BOOLEAN_ << 24) + value);
118 }
119 
120 inline Atom Atom::UndefinedBoolean() {
121 
122  return Atom(0x81FFFFFF);
123 }
124 
125 inline Atom Atom::Wildcard(uint16 opcode) {
126 
127  return Atom((WILDCARD << 24) + ((opcode & 0x0FFF) << 8));
128 }
129 
130 inline Atom Atom::TailWildcard() {
131 
132  return Atom((uint32)(T_WILDCARD << 24));
133 }
134 
135 inline Atom Atom::IPointer(uint16 index) {
136 
137  return Atom((I_PTR << 24) + (index & 0x0FFF));
138 }
139 
140 inline Atom Atom::VLPointer(uint16 index) {
141 
142  return Atom((VL_PTR << 24) + (index & 0x0FFF));
143 }
144 
145 inline Atom Atom::RPointer(uint16 index) {
146 
147  return Atom((R_PTR << 24) + (index & 0x0FFF));
148 }
149 
150 inline Atom Atom::IPGMPointer(uint16 index) {
151 
152  return Atom((IPGM_PTR << 24) + (index & 0x0FFF));
153 }
154 
155 inline Atom Atom::InObjPointer(uint8 input_index, uint16 index) {
156 
157  return Atom((IN_OBJ_PTR << 24) + (input_index << 12) + (index & 0x0FFF));
158 }
159 
160 inline Atom Atom::DInObjPointer(uint8 relative_index, uint16 index) {
161 
162  return Atom((D_IN_OBJ_PTR << 24) + (relative_index << 12) + (index & 0x0FFF));
163 }
164 
165 inline Atom Atom::OutObjPointer(uint16 index) {
166 
167  return Atom((OUT_OBJ_PTR << 24) + (index & 0x0FFF));
168 }
169 
170 inline Atom Atom::ValuePointer(uint16 index) {
171 
172  return Atom((VALUE_PTR << 24) + (index & 0x0FFF));
173 }
174 
175 inline Atom Atom::ProductionPointer(uint16 index) {
176 
177  return Atom((PROD_PTR << 24) + (index & 0x0FFF));
178 }
179 
180 inline Atom Atom::AssignmentPointer(uint8 variable_index, uint16 index) {
181 
182  return Atom((ASSIGN_PTR << 24) + (variable_index << 16) + (index & 0x0FFF));
183 }
184 
185 inline Atom Atom::CodeVLPointer(uint16 index, uint16 cast_opcode) {
186 
187  return Atom((CODE_VL_PTR << 24) + ((cast_opcode & 0x0FFF) << 12) + (index & 0x0FFF));
188 }
189 
190 inline Atom Atom::This() {
191 
192  return Atom((uint32)(THIS << 24));
193 }
194 
195 inline Atom Atom::View() {
196 
197  return Atom((uint32)(VIEW << 24));
198 }
199 
200 inline Atom Atom::Mks() {
201 
202  return Atom((uint32)(MKS << 24));
203 }
204 
205 inline Atom Atom::Vws() {
206 
207  return Atom((uint32)(VWS << 24));
208 }
209 
210 inline Atom Atom::SSet(uint16 opcode, uint8 element_count) {
211 
212  return Atom((S_SET << 24) + ((opcode & 0x0FFF) << 8) + element_count);
213 }
214 
215 inline Atom Atom::Set(uint8 element_count) {
216 
217  return Atom((SET << 24) + element_count);
218 }
219 
220 inline Atom Atom::CPointer(uint8 element_count) {
221 
222  return Atom((C_PTR << 24) + element_count);
223 }
224 
225 inline Atom Atom::Object(uint16 opcode, uint8 arity) {
226 
227  return Atom((OBJECT << 24) + ((opcode & 0x0FFF) << 8) + arity);
228 }
229 
230 inline Atom Atom::Marker(uint16 opcode, uint8 arity) {
231 
232  return Atom((MARKER << 24) + ((opcode & 0x0FFF) << 8) + arity);
233 }
234 
235 inline Atom Atom::Operator(uint16 opcode, uint8 arity) {
236 
237  return Atom((OPERATOR << 24) + ((opcode & 0x0FFF) << 8) + arity);
238 }
239 
240 inline Atom Atom::Node(uint8 node_id) {
241 
242  return Atom((NODE << 24) + (node_id << 8));
243 }
244 
245 inline Atom Atom::UndefinedNode() {
246 
247  return Atom(0xA0FFFFFF);
248 }
249 
250 inline Atom Atom::Device(uint8 node_id, uint8 class_id, uint8 dev_id) {
251 
252  return Atom((DEVICE << 24) + (node_id << 16) + (class_id << 8) + dev_id);
253 }
254 
255 inline Atom Atom::UndefinedDevice() {
256 
257  return Atom(0xA1FFFFFF);
258 }
259 
260 inline Atom Atom::DeviceFunction(uint16 opcode) {
261 
262  return Atom((DEVICE_FUNCTION << 24) + (opcode << 8));
263 }
264 
265 inline Atom Atom::UndefinedDeviceFunction() {
266 
267  return Atom(0xA2FFFFFF);
268 }
269 
270 inline Atom Atom::String(uint8 character_count) {
271 
272  uint8 blocks = character_count / 4;
273  if (character_count % 4)
274  ++blocks;
275  return Atom((STRING << 24) + (blocks << 8) + character_count);
276 }
277 
278 inline Atom Atom::UndefinedString() {
279 
280  return Atom(0xC6FFFFFF);
281 }
282 
283 inline Atom Atom::Timestamp() {
284 
285  return Atom((uint32)(TIMESTAMP << 24));
286 }
287 
288 inline Atom Atom::UndefinedTimestamp() {
289 
290  return Atom(0xC7FFFFFF);
291 }
292 
293 inline Atom Atom::Duration() {
294  return Atom((uint32)(DURATION << 24));
295 }
296 
297 inline Atom Atom::InstantiatedProgram(uint16 opcode, uint8 arity) {
298 
299  return Atom((INSTANTIATED_PROGRAM << 24) + ((opcode & 0x0FFF) << 8) + arity);
300 }
301 
302 inline Atom Atom::Group(uint16 opcode, uint8 arity) {
303 
304  return Atom((GROUP << 24) + ((opcode & 0x0FFF) << 8) + arity);
305 }
306 
307 inline Atom Atom::InstantiatedCPPProgram(uint16 opcode, uint8 arity) {
308 
309  return Atom((INSTANTIATED_CPP_PROGRAM << 24) + ((opcode & 0x0FFF) << 8) + arity);
310 }
311 
312 inline Atom Atom::InstantiatedAntiProgram(uint16 opcode, uint8 arity) {
313 
314  return Atom((INSTANTIATED_ANTI_PROGRAM << 24) + ((opcode & 0x0FFF) << 8) + arity);
315 }
316 
317 inline Atom Atom::InstantiatedInputLessProgram(uint16 opcode, uint8 arity) {
318 
319  return Atom((INSTANTIATED_INPUT_LESS_PROGRAM << 24) + ((opcode & 0x0FFF) << 8) + arity);
320 }
321 
322 inline Atom Atom::CompositeState(uint16 opcode, uint8 arity) {
323 
324  return Atom((COMPOSITE_STATE << 24) + ((opcode & 0x0FFF) << 8) + arity);
325 }
326 
327 inline Atom Atom::Model(uint16 opcode, uint8 arity) {
328 
329  return Atom((MODEL << 24) + ((opcode & 0x0FFF) << 8) + arity);
330 }
331 
332 inline Atom Atom::NullProgram(bool take_past_inputs) {
333 
334  return Atom((NULL_PROGRAM << 24) + (take_past_inputs ? 1 : 0));
335 }
336 
337 // RawPointer is not used. In any case, only define it for ARCH_32. If we want to
338 // define it for ARCH_64, we need to change the byte code to use two uint32 code elements.
339 #if defined ARCH_32
340 inline Atom Atom::RawPointer(void *pointer) {
341 
342  return Atom((uint32)pointer);
343 }
344 #endif
345 
346 inline Atom::Atom(uint32 a) : atom_(a) {
347 }
348 
349 inline Atom::~Atom() {
350 }
351 
352 inline Atom &Atom::operator =(const Atom& a) {
353 
354  atom_ = a.atom_;
355  return *this;
356 }
357 
358 inline bool Atom::operator ==(const Atom& a) const {
359 
360  return atom_ == a.atom_;
361 }
362 
363 inline bool Atom::operator !=(const Atom& a) const {
364 
365  return atom_ != a.atom_;
366 }
367 
368 inline bool Atom::operator !() const {
369 
370  return isUndefined();
371 }
372 
373 inline Atom::operator size_t () const {
374 
375  return (size_t)atom_;
376 }
377 
378 inline bool Atom::isUndefined() const {
379 
380  return atom_ == 0xFFFFFFFF;
381 }
382 
383 inline uint8 Atom::getDescriptor() const {
384 
385  return atom_ >> 24;
386 }
387 
388 inline bool Atom::isStructural() const {
389 
390  return ((atom_ & 0xC0000000) == 0xC0000000 || (atom_ & 0xD0000000) == 0xD0000000);
391 }
392 
393 inline bool Atom::isFloat() const {
394 
395  return atom_ >> 31 == 0;
396 }
397 
398 inline bool Atom::readsAsNil() const {
399 
400  return atom_ == 0x80000000 ||
401  atom_ == 0x3FFFFFFF ||
402  atom_ == 0x81FFFFFF ||
403  atom_ == 0xC1000000 ||
404  atom_ == 0xA0FFFFFF ||
405  atom_ == 0xA1FFFFFF ||
406  atom_ == 0xA2FFFFFF ||
407  atom_ == 0xC6FFFFFF;
408 }
409 
410 inline float32 Atom::asFloat() const {
411 
412  uint32 _f = atom_ << 1;
413  return *reinterpret_cast<const float32 *>(&_f);
414 }
415 
416 inline bool Atom::asBoolean() const {
417 
418  return atom_ & 0x000000FF;
419 }
420 
421 inline bool Atom::isBooleanTrue() const { return getDescriptor() == BOOLEAN_ && asBoolean(); }
422 
423 inline bool Atom::isBooleanFalse() const { return getDescriptor() == BOOLEAN_ && !asBoolean(); }
424 
425 inline uint16 Atom::asIndex() const {
426 
427  return atom_ & 0x00000FFF;
428 }
429 
430 inline uint8 Atom::asInputIndex() const {
431 
432  return (uint8)((atom_ & 0x000FF000) >> 12);
433 }
434 
435 inline uint8 Atom::asRelativeIndex() const {
436 
437  return (uint8)((atom_ & 0x000FF000) >> 12);
438 }
439 
440 inline uint16 Atom::asOpcode() const {
441 
442  return (atom_ >> 8) & 0x00000FFF;
443 }
444 
445 inline uint16 Atom::asCastOpcode() const {
446 
447  return (uint16)((atom_ & 0x00FFF000) >> 12);
448 }
449 
450 inline uint8 Atom::getNodeID() const {
451 
452  return (uint8)((atom_ & 0x00FF0000) >> 16);
453 }
454 
455 inline uint8 Atom::getClassID() const {
456 
457  return (uint8)((atom_ & 0x0000FF00) >> 8);
458 }
459 
460 inline uint8 Atom::getDeviceID() const {
461 
462  return (uint8)(atom_ & 0x000000FF);
463 }
464 
465 inline uint8 Atom::asAssignmentIndex() const {
466 
467  return (uint8)((atom_ & 0x00FF0000) >> 16);
468 }
469 
470 inline uint8 Atom::getAtomCount() const {
471 
472  switch (getDescriptor()) {
473  case SET:
474  case OBJECT:
475  case MARKER:
476  case C_PTR:
477  case OPERATOR:
478  case INSTANTIATED_PROGRAM:
479  case INSTANTIATED_CPP_PROGRAM:
480  case INSTANTIATED_INPUT_LESS_PROGRAM:
481  case INSTANTIATED_ANTI_PROGRAM:
482  case COMPOSITE_STATE:
483  case MODEL:
484  case GROUP:
485  case S_SET: return atom_ & 0x000000FF;
486  case STRING: return (atom_ & 0x0000FF00) >> 8;
487  case TIMESTAMP: return 2;
488  case DURATION: return 2;
489  default:
490  return 0;
491  }
492 }
493 
494 inline bool Atom::takesPastInputs() const {
495 
496  return atom_ & 0x00000001;
497 }
498 }