source: cpp/frams/genetics/f4/f4_general.h @ 760

Last change on this file since 760 was 760, checked in by Maciej Komosinski, 2 years ago
  • added support for new API for neuron types and their properties
  • added support for checkpoints
  • Property svn:eol-style set to native
File size: 18.0 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5// Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL
6
7#ifndef _F4_GENERAL_H_
8#define _F4_GENERAL_H_
9
10#include <frams/util/3d.h>
11#include <frams/util/sstring.h>
12#include <frams/util/multirange.h>
13#include <frams/genetics/geneprops.h>
14
15#ifdef DMALLOC
16#include <dmalloc.h>
17#endif
18
19/**
20 * Performs single rotation angle decrementation on a given value.
21 * @param v pointer to the decremented value
22 */
23void rolling_dec(double * v);
24
25/**
26 * Performs single rotation angle incrementation on a given value.
27 * @param v pointer to the incremented value
28 */
29void rolling_inc(double * v);
30
31class f4_node;   // later
32class f4_Cell;   // later
33class f4_Cells;  // later
34
35
36/** @name Types of f4_Cell's */
37//@{
38#define T_UNDIFF4 40 ///<undifferentiated cell
39#define T_STICK4  41 ///<differentiated to stick, cannot divide
40#define T_NEURON4 42 ///<differentiated to neuron, can divide
41//@}
42
43/**
44 * Scans f4 genotype string for a stopping character and returns the position of
45 * this stopping character or 1 if the end of string was reached. This method is used
46 * for closing braces, like ), >, ]. It runs recursively when opening braces
47 * like (, <, # are found.
48 * @param s string with the f4 genotype
49 * @param slen length of a given string
50 * @param stopchar character to be found
51 * @return 1 if end of string was reached, or position of found character in sequence
52 */
53int scanrec(const char * s, unsigned int slen, char stopchar);
54
55
56class f4_CellLink;
57
58/** @name Constraints of f4 genotype structures */
59//@{
60#define MAXINPUTS 100 ///<maximum number of neuron inputs
61#define MAX4CELLS 100 ///<maximum number of f4 organism cells
62//@}
63
64/**
65 * Abstract cell type - the representation of single component in the  developmental
66 * encoding. In the beginning, each f4_Cell is undifferentiated. During the process
67 * of development it can divide or differentiate into a stick or a neuron. If it
68 * differentiates to a neuron, then it preserves the ability to divide, but divided
69 * cells will be the same type as the parent cell. If it is a stick, then it cannot
70 * be divided anymore.
71 *
72 * From f4_Cell array the final Model of a creature is created.
73 */
74class f4_Cell
75{
76public:
77        /**
78         * Represents the repetition marker. It holds information about the pointer
79         * to the repetition node and the count of repetitions.
80         */
81        class repeat_ptr
82        {
83        public:
84                repeat_ptr() : node(NULL), count(-1) { };
85
86                /**
87                 * A constructor that takes the pointer to the repetition node and the count of repetitions.
88                 * @param a pointer to f4_node for repetition character
89                 * @param b the number of repetitions
90                 */
91                repeat_ptr(f4_node *a, int b) : node(a), count(b) { };
92
93                inline void makeNull() { node = NULL; count = -1; };
94
95                inline bool isNull() const { return ((node == NULL) || (count <= 0)); };
96
97                inline void dec() { count--; };
98                f4_node    *node; ///<pointer to the repetition code
99                char       count; ///<repetition counter
100        };
101
102        /**
103         * Represents the stack of repeat_ptr objects. The objects are
104         * pushed to the stack when '#' repetition symbol appears, and are popped when
105         * the end of the current cell definition, i.e. the '>' character, appears. After the
106         * '>' character, the cell is duplicated as many times as it is defined after the
107         * repetition marker.
108         */
109        class repeat_stack
110        {
111        public:
112                repeat_stack() { top = 0; }
113
114                inline void clear() { top = 0; }
115
116                /**
117                 * Pushes repeat_ptr object onto the stack. If the stack size is exceeded, then no
118                 * information is provided.
119                 * @param rn repetition node info
120                 */
121                inline void push(repeat_ptr rn) { if (top >= stackSize) return; ptr[top] = rn; top++; }
122
123                inline void pop() { if (top > 0) top--; }
124
125                /**
126                 * Gets the current top element.
127                 * @return pointer to the element on top of the repeat_stack object
128                 */
129                inline repeat_ptr* first() { return &(ptr[top - (top > 0)]); };
130                static const int stackSize = 4;  ///<max 4 nested levels
131                repeat_ptr ptr[stackSize]; ///<array holding pointers to repeat_ptr
132                short int top;  ///<index of the top of the stack
133        };
134
135        /**
136         * Creates a new f4_Cell object.
137         * @param nname name of a cell, can be T_UNDIFF4, T_STICK4 or T_NEURON4
138         * @param ndad pointer to the parent of the created cell
139         * @param nangle the amount of commas affecting branch angles
140         * @param newP genotype properties of a given cell
141         */
142        f4_Cell(int nname,
143                f4_Cell * ndad, int nangle, GeneProps newP);
144        /**
145         * Creates a new f4_Cell object.
146         * @param nO pointer to an organism containing the cell
147         * @param nname name of the cell, can be T_UNDIFF4, T_STICK4 or T_NEURON4
148         * @param ngeno pointer to the root of the genotype tree
149         * @param ngcur pointer to the f4_node representing the current cell in the genotype tree
150         * @param ndad pointer to the parent of the created cell
151         * @param nangle the number of commas affecting branch angles
152         * @param newP genotype properties of a given cell
153         */
154        f4_Cell(f4_Cells *nO, int nname, f4_node *ngeno, f4_node *ngcur,
155                f4_Cell *ndad, int nangle, GeneProps newP);
156
157        ~f4_Cell();
158
159        /**
160         * Performs one step of cell development. This method requires pointer to
161         * f4_Cells object in org attribute. If the current node in genotype tree
162         * represents branching, then the cell divides into two cells, unless the
163         * cell was already differentiated into stick cell. Otherwise the current
164         * differentiation or modification is performed on cell. If current node is
165         * creating a connection between two neuron nodes, and the input node is not
166         * yet developed, then the simulation of current cell halts and waits until
167         * the input node will be developed. The onestep method is ran on each cell
168         * at least once and if one cell requires another to develop, then onestep
169         * should be deployed again on this cell. This method, unlike genotype tree
170         * creation, checks semantics. This means that this function will fail if:
171         *  - the stick cell will have divide node,
172         *  - the undifferentiated cell will have '>' node (end of cell development),
173         *  - the stack of repetition marker '#' will be overflowed,
174         *  - the stick modifiers, like rotation, will be applied on neuron cell,
175         *  - the differentiated cell will be differentiated again,
176         *  - the neuron class inside cell connection definition is not a sensor,
177         *  - the connection between neurons could not be established,
178         *  - the neuron class is not valid.
179         *
180         * @return 0 if development was successful, 1 if there was an error in genotype tree
181         */
182        int onestep();  // execute one simulation step (till a division)
183
184        /**
185         * Add link between this neuron cell and a given neuron cell. If nfrom object
186         * is not given, than neuron type in nt holds the sensor type.
187         * @param nfrom input neuron cell, or NULL if not given
188         * @param nw weight of connection
189         * @param nt empty string or name of sensor class
190         * @return 0 if link is established, -1 otherwise
191         */
192        int   addlink(f4_Cell * nfrom, double nw, string nt);
193
194        /**
195         * Adjusts properties of stick objects.
196         */
197        void  adjustRec();
198
199        int        name;               ///<name of cell(number)
200        int        type;               ///<type
201        f4_Cell *  dadlink;            ///<pointer to cell parent
202        f4_Cells * org;                ///<uplink to organism
203
204        f4_node *  genot;                  ///<genotype tree
205        f4_node *  gcur;               ///<current genotype execution pointer
206        int        active;             ///<whether development is still active
207        repeat_stack repeat;           ///<stack holding repetition nodes and counters
208        int        recProcessedFlag;   ///<used during recursive traverse
209        MultiRange genoRange;          ///<remember the genotype codes affecting this cell so far
210
211        GeneProps     P;               ///<properties
212        int          anglepos;         ///<number of position within dad's children (,)
213        int          childcount;       ///<number of children
214        int          commacount;       ///<number of postitions at lastend (>=childcount)
215        double       rolling;          ///<rolling angle ('R') (around x)
216        double       xrot;                         ///<rotation angle around x
217        double       zrot;             ///<horizontal rotation angle due to branching (around z)
218
219        double       mz;               ///<freedom in z
220        int          p2_refno;         ///<number of last end part object, used in f0
221        int          joint_refno;      ///<number of the joint object, used in f0
222        int          neuro_refno;      ///<number of the neuro object, used in f0
223
224        int          ctrl;             ///<neuron type
225        double       state;            ///<state of neuron
226        double       inertia;          ///<inertia of neuron
227        double       force;            ///<force of neuron
228        double       sigmo;            ///<sigmoid of neuron
229        f4_CellLink* links[MAXINPUTS]; ///<array of neuron links
230        int          nolink;           ///<number of links
231        NeuroClass * neuclass = NULL;  ///<pointer to neuron class
232};
233
234/**
235 * Class representing link between neuron cells.
236 */
237class f4_CellLink
238{
239public:
240        /**
241         * Constructor for f4_CellLink class. Parameter nfrom can represent input
242         * neuron cell or be NULL, if connection has neuron cell definition inside.
243         * The inside definition must be hold in nt parameter and a neuron class
244         * must represent sensor.
245         * @param nfrom pointer to input neuron cell or NULL
246         * @param nw weight of connection
247         * @param nt name of neuron class or empty string
248         */
249        f4_CellLink(f4_Cell * nfrom, double nw, string nt);
250
251        f4_Cell *    from; ///<pointer to input neuron cell
252        string  t;    ///<empty if from cell is given, NeuroClass name otherwise
253        double       w;    ///<weight of connection
254};
255
256
257// a collection of cells, like Organism, for developmental encoding
258/**
259 * Class representing a collection of cells. It is equivalent of organism.
260 */
261class f4_Cells
262{
263public:
264
265        /**
266         * Constructor taking genotype in a form of a tree.
267         * @param genome genotype tree
268         * @param nrepair 0 if nothing to repair
269         */
270        f4_Cells(f4_node * genome, int nrepair);
271
272        /**
273         * Constructor taking genotype in a form of a string.
274         * @param genome genotype string
275         * @param nrepair 0 if nothing to repair
276         */
277        f4_Cells(SString &genome, int nrepair);
278
279        /**
280         * Destructor removing cells from memory.
281         */
282        ~f4_Cells();
283
284        /**
285         * Adds new cell to organism.
286         * @param newcell cell to be added
287         */
288        void addCell(f4_Cell * newcell);
289
290        /**
291         * Creates approximate genotype in f1 encoding and stores it in a given
292         * parameter.
293         * @param out the string in which approximate f1 genotype will be stored
294         */
295        void toF1Geno(SString &out);
296
297        /**
298         * Performs single step of organism development. It runs each active cell
299         * in organism.
300         * @return 0 if all cells are developed, or 1 otherwise
301         */
302        int  onestep();
303
304        /**
305         * Performs full development of organism and returns error code if something
306         * went wrong.
307         * @return 0 if organism developed successfully, error code if something went wrong
308         */
309        int  simulate();
310
311        /**
312         * Returns error code of last simulation.
313         * @return error code
314         */
315        int  geterror() { return error; };
316
317        /**
318         * Returns position of error in genotype.
319         * @return position of error
320         */
321        int  geterrorpos() { return errorpos; };
322
323        /**
324         * Sets error code GENOPER_OPFAIL for simulation on a given position.
325         * @param nerrpos position of error
326         */
327        void setError(int nerrpos);
328
329        /**
330         * Sets the element of genotype to be repaired by removal.
331         * @param nerrpos position of error in genotype
332         * @param rem the f4_node to be removed from genotype tree in order to repair
333         */
334        void setRepairRemove(int nerrpos, f4_node * rem);
335
336        /**
337         * Sets repairing of genotype by inserting new node to current genotype.
338         * @param nerrpos position of error in genotype
339         * @param parent the parent of new element
340         * @param insert the element to be inserted
341         * @return 0 if repair can be performed, -1 otherwise (the repair flag wasn't set in constructor)
342         */
343        int  setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert);
344
345        /**
346         * Repairs genotype according to setRepairRemove or setRepairInsert method.
347         * @param geno pointer to genotype tree
348         * @param whichchild 1 if first child, 2 otherwise
349         */
350        void repairGeno(f4_node * geno, int whichchild);
351
352        // the cells
353        f4_Cell * C[MAX4CELLS]; ///<Array of all cells of organism
354        int       nc;           ///<Number of cells in organism
355
356private:
357        // for error reporting / genotype fixing
358        int repair;
359        int error;
360        int errorpos;
361        f4_node * repair_remove;
362        f4_node * repair_parent;
363        f4_node * repair_insert;
364        void toF1GenoRec(int curc, SString &out);
365        f4_Cell * tmpcel;               // needed by toF1Geno
366        f4_node * f4rootnode;          // used by constructor
367};
368
369
370/**
371 * Class to organize a f4 genotype in a tree structure.
372 */
373class f4_node
374{
375public:
376        string name; ///<one-letter 'name', multiple characters for classes
377        f4_node *parent; ///<parent link, or NULL
378        f4_node *child; ///<child, or NULL
379        f4_node *child2; ///<second child, or NULL
380        int         pos; ///<original position in string
381        int         i1; ///<internal int  parameter1
382        int         l1; ///<internal long parameter1
383        double      f1; ///<internal double parameter1
384        string s1; ///<internal string parameter1
385
386        /**
387         * Default constructor.
388         */
389        f4_node();
390
391        /**
392         * Multiple-character name constructor.
393         * @param nname string from genotype representing node
394         * @param nparent pointer to parent of node
395         * @param npos position of node substring in genotype string
396         */
397        f4_node(string nname, f4_node * nparent, int npos);
398
399        /**
400         * One-character name constructor.
401         * @param nname character from genotype representing node
402         * @param nparent pointer to parent of node
403         * @param npos position of node character in genotype string
404         */
405        f4_node(char nname, f4_node * nparent, int npos);
406
407        /**
408         * Desctructor of object.
409         */
410        ~f4_node();
411
412        /**
413         * Method for adding child to a node.
414         * @param nchi child to be added to node
415         * @return 0 if child could be added, -1 otherwise
416         */
417        int       addChild(f4_node * nchi);
418
419        /**
420         * Method for removing child from node.
421         * @param nchi child to be removed from node
422         * @return 0 if child could be removed, -1 otherwise
423         */
424        int       removeChild(f4_node * nchi);
425
426        /**
427         * Returns number of children.
428         * @return 0, 1 or 2
429         */
430        int       childCount();
431
432        /**
433         * Returns number of nodes coming from this node in a recursive way.
434         * @return number of nodes from this node
435         */
436        int       count();
437
438        /**
439         * Returns the nth subnode (0-)
440         * @param n index of child to be found
441         * @return pointer to nth subnode or NULL if not found
442         */
443        f4_node * ordNode(int n);
444
445        /**
446         * Returns a random subnode.
447         * @return random subnode
448         */
449        f4_node * randomNode();
450
451        /**
452         * Returns a random subnode with given size.
453         * @param min minimum size
454         * @param max maximum size
455         * @return a random subnode with given size or NULL
456         */
457        f4_node * randomNodeWithSize(int min, int max);
458
459        /**
460         * Prints recursively tree from a given node.
461         * @param buf variable storing printing result
462         */
463        void      sprintAdj(char *& buf);
464
465        /**
466         * Recursively copies genotype tree from this node.
467         * @return pointer to a tree copy
468         */
469        f4_node * duplicate();
470
471        /**
472         * Recursively releases memory from all node children.
473         */
474        void      destroy();
475private:
476        void     sprint(SString & out); // print recursively
477};
478
479// convert f4 geno string to tree structure (internal)
480
481/**
482 * Main function to perform conversion of f4 geno to tree structure. Prepares
483 * f4_node root of tree and runs f4_processrec function for it.
484 * @param geno string representing f4 genotype
485 * @return pointer to f4_node object representing f4 tree root
486 */
487f4_node * f4_processtree(const char * geno);
488
489/**
490 * Scans genotype string from a given position. This recursive method creates
491 * tree of f4_node objects. The method extract each potentially functional element
492 * of genotype string to separate f4_nodes. When branching character '<' occurs,
493 * then f4_processrec is ran for latest f4_node element. This method does not
494 * analyse genotype semantically, it checks only if syntax is proper. The only
495 * semantic aspect is neuron class name extraction, in which the GenoOperators
496 * class is used to parse possible neuron class in genotype.
497 * @param genot the string holding all genotype
498 * @param pos0 the current position of processing in string
499 * @param current parent of analysed branch of genotype
500 * @return 0 if processing was successful or position of error in genotype
501 */
502int f4_processrec(const char * genot, unsigned pos0, f4_node * parent);
503
504/**
505 * Function parses notation of neuron connection - it takes beginning of connection
506 * definition, extracts relative position of input neurons and weight of connection.
507 * After successful parsing it returns pointer to first character after connection
508 * definition, or NULL if connection definition was not valid - lack of [, :, ]
509 * characters or wrong value of relfrom or weight.
510 * @param fragm the beginning of connection definition, it should be '[' character
511 * @param relfrom the reference to int variable, in which relative position of input neuron will be stored
512 * @param weight the reference to double variable, in which weight of connection will be stored
513 * @return the pointer to first character in string after connection definition
514 */
515const char * parseConnection(const char * fragm, int& relfrom, double &weight);
516
517/**
518 * Function parses notation of neuron connection with neuron definition - it
519 * takes beginning of connection definition, extracts the name of neuron class
520 * that will be the input for current neuron and weight of connection.
521 * After successful parsing it returns pointer to first character after connection
522 * definition, or NULL if connection definition was not valid - lack of [, :, ]
523 * characters, wrong value of weight or invalid neuron class name.
524 * @param fragm the beginning of connection definition, it should be '[' character
525 * @param neutype the reference to string representing input neuron class name. The name of class is validated with GenoOperators::parseNeuroClass
526 * @param weight the reference to double variable, in which weight of connection will be stored
527 * @return the pointer to first character in string after connection definition
528 */
529const char * parseConnectionWithNeuron(const char * fragm, string& neutype, double &weight);
530
531#endif
Note: See TracBrowser for help on using the repository browser.