Index: cpp/frams/genetics/f4/f4_general.h
===================================================================
--- cpp/frams/genetics/f4/f4_general.h	(revision 829)
+++ cpp/frams/genetics/f4/f4_general.h	(revision 1227)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -29,5 +29,5 @@
 void rolling_inc(double *v);
 
-class f4_node;   // later
+class f4_Node;   // later
 class f4_Cell;   // later
 class f4_Cells;  // later
@@ -36,7 +36,7 @@
 /** @name Types of f4_Cell's */
 //@{
-#define T_UNDIFF4 40 ///<undifferentiated cell
-#define T_STICK4  41 ///<differentiated to stick, cannot divide
-#define T_NEURON4 42 ///<differentiated to neuron, can divide
+#define CELL_UNDIFF 40 ///<undifferentiated cell
+#define CELL_STICK  41 ///<differentiated to stick, cannot divide
+#define CELL_NEURON 42 ///<differentiated to neuron, can divide
 //@}
 
@@ -54,14 +54,14 @@
 
 
-class f4_CellLink;
+class f4_CellConn;
 
 /** @name Constraints of f4 genotype structures */
 //@{
-#define MAXINPUTS 100 ///<maximum number of neuron inputs
-#define MAX4CELLS 100 ///<maximum number of f4 organism cells
+#define F4_MAX_CELL_INPUTS  10 ///<maximum number of neuron inputs in a developing organism
+#define F4_MAX_CELLS 100 ///<maximum number of f4 organism cells
 //@}
 
 /**
- * Abstract cell type - the representation of single component in the  developmental
+ * Abstract cell type - the representation of a single component in the developmental
  * encoding. In the beginning, each f4_Cell is undifferentiated. During the process
  * of development it can divide or differentiate into a stick or a neuron. If it
@@ -86,8 +86,8 @@
 		/**
 		 * A constructor that takes the pointer to the repetition node and the count of repetitions.
-		 * @param a pointer to f4_node for repetition character
+		 * @param a pointer to f4_Node for repetition character
 		 * @param b the number of repetitions
 		 */
-		repeat_ptr(f4_node *a, int b) : node(a), count(b) { };
+		repeat_ptr(f4_Node *a, int b) : node(a), count(b) { };
 
 		inline void makeNull() { node = NULL; count = -1; };
@@ -96,5 +96,5 @@
 
 		inline void dec() { count--; };
-		f4_node    *node; ///<pointer to the repetition code
+		f4_Node    *node; ///<pointer to the repetition code
 		int       count; ///<repetition counter
 	};
@@ -130,26 +130,26 @@
 		static const int stackSize = 4;  ///<max 4 nested levels
 		repeat_ptr ptr[stackSize]; ///<array holding pointers to repeat_ptr
-		short int top;  ///<index of the top of the stack
+		int top;  ///<index of the top of the stack
 	};
 
 	/**
 	 * Creates a new f4_Cell object.
-	 * @param nname name of a cell, can be T_UNDIFF4, T_STICK4 or T_NEURON4
+	 * @param nnr number of the cell
 	 * @param ndad pointer to the parent of the created cell
 	 * @param nangle the amount of commas affecting branch angles
 	 * @param newP genotype properties of a given cell
 	 */
-	f4_Cell(int nname, f4_Cell *ndad, int nangle, GeneProps newP);
+	f4_Cell(int nnr, f4_Cell *ndad, int nangle, GeneProps newP);
 	/**
 	 * Creates a new f4_Cell object.
 	 * @param nO pointer to an organism containing the cell
-	 * @param nname name of the cell, can be T_UNDIFF4, T_STICK4 or T_NEURON4
+	 * @param nnr number of the cell
 	 * @param ngeno pointer to the root of the genotype tree
-	 * @param ngcur pointer to the f4_node representing the current cell in the genotype tree
+	 * @param ngcur pointer to the f4_Node representing the current cell in the genotype tree
 	 * @param ndad pointer to the parent of the created cell
 	 * @param nangle the number of commas affecting branch angles
 	 * @param newP genotype properties of a given cell
 	 */
-	f4_Cell(f4_Cells *nO, int nname, f4_node *ngeno, f4_node *ngcur, f4_Cell *ndad, int nangle, GeneProps newP);
+	f4_Cell(f4_Cells *nO, int nnr, f4_Node *ngeno, f4_Node *ngcur, f4_Cell *ndad, int nangle, GeneProps newP);
 
 	~f4_Cell();
@@ -172,5 +172,4 @@
 	 *  - the stick modifiers, like rotation, will be applied on neuron cell,
 	 *  - the differentiated cell will be differentiated again,
-	 *  - the neuron class inside cell connection (i.e. N[G:5]) is not a sensor,
 	 *  - the connection between neurons cannot be established,
 	 *  - the neuron class is not valid.
@@ -178,15 +177,13 @@
 	 * @return 0 if development was successful, 1 if there was an error in genotype tree
 	 */
-	int onestep();
-
-	/**
-	 * Adds a link between this neuron cell and a given neuron cell in nfrom. If the nfrom object
-	 * is not given, neuron type in nt should be a sensor type.
-	 * @param nfrom input neuron cell, or NULL if not given
-	 * @param nw weight of connection
-	 * @param nt empty string or name of sensor class
-	 * @return 0 if link is established, -1 otherwise
-	 */
-	int   addlink(f4_Cell *nfrom, double nw, string nt);
+	int oneStep();
+
+	/**
+	 * Adds a connection between this neuron cell and a given neuron cell in nfrom.
+	 * @param nfrom input neuron cell
+	 * @param nweight weight of connection
+	 * @return 0 if connection is established, -1 otherwise
+	 */
+	int   addConnection(f4_Cell *nfrom, double nweight);
 
 	/**
@@ -195,12 +192,12 @@
 	void  adjustRec();
 
-	int        name;               ///<name of cell (number)
+	int        nr;                 ///<number of cell (seems to be used only in old f1 converter for neuron connections)
 	int        type;               ///<type
 	f4_Cell *dadlink;              ///<pointer to cell parent
 	f4_Cells  *org;	               ///<uplink to organism
 
-	f4_node *genot; 	           ///<genotype tree
-	f4_node *gcur;                 ///<current genotype execution pointer
-	int active;                    ///<determines whether development is still active
+	f4_Node *genot; 	           ///<genotype tree
+	f4_Node *gcur;                 ///<current genotype execution pointer
+	bool active;                   ///<determines whether development is still active; even if false, the cell may "yield" - may be halted (but still having its onStep() called) due to neural connections waiting for other cells to potentially develop neurons
 	repeat_stack repeat;           ///<stack holding repetition nodes and counters
 	int recProcessedFlag;          ///<used during recursive traverse
@@ -220,33 +217,28 @@
 	int          neuro_refno;      ///<the number of the neuro object, used in f0
 
-	int          ctrl;             ///<neuron type
 	double       inertia;          ///<inertia of neuron
 	double       force;            ///<force of neuron
 	double       sigmo;            ///<sigmoid of neuron
-	f4_CellLink *links[MAXINPUTS]; ///<array of neuron links
-	int          nolink;           ///<number of links
+	f4_CellConn *conns[F4_MAX_CELL_INPUTS]; ///<array of neuron connections
+	int          conns_count;      ///<number of connections
 	NeuroClass *neuclass;          ///<pointer to neuron class
 };
 
 /**
- * Class representing link between neuron cells.
- */
-class f4_CellLink
+ * Class representing a connection between neuron cells.
+ */
+class f4_CellConn
 {
 public:
 	/**
 	 * Constructor for f4_CellLink class. Parameter nfrom represents input
-	 * neuron cell or NULL if connection has defined sensor type inside, like "[G:5]".
-	 * The name of sensor class defined inside neuron connection is stored in the nt
-	 * parameter.
-	 * @param nfrom pointer to input neuron cell or NULL
-	 * @param nw weight of connection
-	 * @param nt name of neuron class or empty string
-	 */
-	f4_CellLink(f4_Cell *nfrom, double nw, string nt);
-
-	f4_Cell *from; ///<pointer to input neuron cell
-	string t;      ///<empty if 'from' cell is given, NeuroClass name otherwise
-	double w;      ///<weight of connection
+	 * neuron cell.
+	 * @param nfrom pointer to input neuron cell
+	 * @param nweight weight of connection
+	 */
+	f4_CellConn(f4_Cell *nfrom, double nweight);
+
+	f4_Cell *from;  ///<pointer to input neuron cell
+	double weight;  ///<weight of connection
 };
 
@@ -264,5 +256,5 @@
 	 * @param nrepair 0 if nothing to repair
 	 */
-	f4_Cells(f4_node *genome, int nrepair);
+	f4_Cells(f4_Node *genome, int nrepair);
 
 	/**
@@ -291,9 +283,8 @@
 
 	/**
-	 * Performs a single step of organism development. It runs each active cell
-	 * in the organism.
-	 * @return 0 if all cells are developed, or 1 otherwise
-	 */
-	int  onestep();
+	 * Performs a single step of organism development. It runs each active cell in the organism.
+	 * @return false if all cells are developed or there is an error, true otherwise
+	 */
+	bool oneStep();
 
 	/**
@@ -302,5 +293,11 @@
 	 * @return 0 if organism developed successfully, error code if something went wrong
 	 */
-	int  simulate();
+	int simulate();
+
+	/**
+	 * Prints the current state of the organism (for debugging purposes).
+	 * @param description printout header
+	 */
+	void print_cells(const char* description);
 
 	/**
@@ -308,5 +305,5 @@
 	 * @return error code
 	 */
-	int  geterror() { return error; };
+	int getErrorCode() { return errorcode; };
 
 	/**
@@ -314,5 +311,5 @@
 	 * @return position of an error
 	 */
-	int  geterrorpos() { return errorpos; };
+	int getErrorPos() { return errorpos; };
 
 	/**
@@ -325,7 +322,7 @@
 	 * Sets the element of genotype to be repaired by removal.
 	 * @param nerrpos position of an error in genotype
-	 * @param rem the f4_node to be removed from the  genotype tree in order to repair
-	 */
-	void setRepairRemove(int nerrpos, f4_node *rem);
+	 * @param rem the f4_Node to be removed from the  genotype tree in order to repair
+	 */
+	void setRepairRemove(int nerrpos, f4_Node *rem);
 
 	/**
@@ -336,5 +333,5 @@
 	 * @return 0 if repair can be performed, or -1 otherwise because the repair flag wasn't set in the constructor
 	 */
-	int  setRepairInsert(int nerrpos, f4_node *parent, f4_node *insert);
+	int setRepairInsert(int nerrpos, f4_Node *parent, f4_Node *insert);
 
 	/**
@@ -343,21 +340,21 @@
 	 * @param whichchild 1 if first child, 2 otherwise
 	 */
-	void repairGeno(f4_node *geno, int whichchild);
+	void repairGeno(f4_Node *geno, int whichchild);
 
 	// the cells
-	f4_Cell *C[MAX4CELLS];  ///<Array of all cells of an organism
-	int       nc;           ///<Number of cells in an organism
+	f4_Cell *C[F4_MAX_CELLS];  ///<Array of all cells of an organism
+	int     cell_count;        ///<Number of cells in an organism
 
 private:
 	// for error reporting / genotype fixing
 	int repair;
-	int error;
+	int errorcode;
 	int errorpos;
-	f4_node *repair_remove;
-	f4_node *repair_parent;
-	f4_node *repair_insert;
+	f4_Node *repair_remove;
+	f4_Node *repair_parent;
+	f4_Node *repair_insert;
 	void toF1GenoRec(int curc, SString &out);
 	f4_Cell *tmpcel;		// needed by toF1Geno
-	f4_node *f4rootnode;          // used by constructor
+	f4_Node *f4rootnode;          // used by constructor
 };
 
@@ -366,18 +363,21 @@
  * A class to organize a f4 genotype in a tree structure.
  */
-class f4_node
+class f4_Node
 {
 public:
-	string name; ///<one-letter 'name', multiple characters for classes
-	f4_node *parent; ///<parent link or NULL
-	f4_node *child; ///<child or NULL
-	f4_node *child2; ///<second child or NULL
+	string name; ///<one-letter gene code or multiple characters for neuron classes (then neuclass != NULL)
+	f4_Node *parent; ///<parent link or NULL
+	f4_Node *child; ///<child or NULL
+	f4_Node *child2; ///<second child or NULL
 	int pos; ///<original position in the string
-	int i1; ///<internal int parameter1
-	int l1; ///<internal long parameter1 (now also int, since long is not well specified and it is in our scenarios equivalent to int)
-	double f1; ///<internal double parameter1
-	string s1; ///<internal string parameter1
-
-	f4_node();
+
+	int reps; ///<repetition counter for the '#' gene
+	char prop_symbol; ///<old-style properties (force,intertia,sigmoid) of the N neuron: !=/
+	bool prop_increase; ///<false=decrease neuron property (force,intertia,sigmoid), true=increase it
+	int conn_from; ///<relative number of the neuron this neuron get an input from
+	double conn_weight; ///<neuron connection weight
+	NeuroClass *neuclass; ///< NULL or not if "name" is a neuroclass name with a proper genotype context ("N:neuroclassname"). New in 2023-04 - to fix fatal flaw with fundamental assumptions: it was impossible to distinguish between single-character neuron names such as S, D, G and single-character modifiers. They were all stored in the "name" field. Before 2018 this was never a problem because the only supported neuroclasses had distinctive symbols such as @|*GTS, and the set of supported modifiers was small and different from neuroclass letters (no G,D,S clash).
+
+	f4_Node();
 
 	/**
@@ -387,5 +387,5 @@
 	 * @param npos position of node substring in the genotype string
 	 */
-	f4_node(string nname, f4_node *nparent, int npos);
+	f4_Node(string nname, f4_Node *nparent, int npos);
 
 	/**
@@ -395,7 +395,14 @@
 	 * @param npos position of node character in the genotype string
 	 */
-	f4_node(char nname, f4_node *nparent, int npos);
-
-	~f4_node();
+	f4_Node(char nname, f4_Node *nparent, int npos);
+
+	~f4_Node();
+
+	/**
+	 * Recursively print subtree (for debugging).
+	 * @param root starting node
+	 * @param indent initial indentation
+	 */
+	static void print_tree(const f4_Node *root, int indent);
 
 	/**
@@ -404,5 +411,5 @@
 	 * @return 0 if the child could be added, -1 otherwise
 	 */
-	int addChild(f4_node *nchi);
+	int addChild(f4_Node *nchi);
 
 	/**
@@ -411,5 +418,5 @@
 	 * @return 0 if child could be removed, -1 otherwise
 	 */
-	int removeChild(f4_node *nchi);
+	int removeChild(f4_Node *nchi);
 
 	/**
@@ -423,5 +430,5 @@
 	 * @return the number of nodes from this node
 	 */
-	int count();
+	int count() const;
 
 	/**
@@ -430,5 +437,5 @@
 	 * @return pointer to the nth subnode or NULL if not found
 	 */
-	f4_node* ordNode(int n);
+	f4_Node* ordNode(int n);
 
 	/**
@@ -436,5 +443,5 @@
 	 * @return random subnode
 	 */
-	f4_node* randomNode();
+	f4_Node* randomNode();
 
 	/**
@@ -444,5 +451,5 @@
 	 * @return a random subnode with a given size or NULL
 	 */
-	f4_node* randomNodeWithSize(int min, int max);
+	f4_Node* randomNodeWithSize(int min, int max);
 
 	/**
@@ -456,5 +463,5 @@
 	 * @return pointer to a tree copy
 	 */
-	f4_node* duplicate();
+	f4_Node* duplicate();
 
 	/**
@@ -468,15 +475,15 @@
 /**
  * The main function for converting a string of f4 encoding to a tree structure. Prepares
- * f4_node root of tree and runs f4_processrec function for it.
+ * f4_Node root of tree and runs f4_processrec function for it.
  * @param geno the string representing an f4 genotype
- * @return a pointer to the f4_node object representing the f4 tree root
- */
-f4_node* f4_processtree(const char *geno);
+ * @return a pointer to the f4_Node object representing the f4 tree root
+ */
+f4_Node* f4_processtree(const char *geno);
 
 /**
  * Scans a genotype string starting from a given position. This recursive method creates
- * a tree of f4_node objects. This method extracts each potentially functional element
- * of a genotype string to a separate f4_nodes. When the branching character '<' occurs,
- * f4_processrec is deployed for the latest f4_node element. This method does not
+ * a tree of f4_Node objects. This method extracts each potentially functional element
+ * of a genotype string to a separate f4_Nodes. When the branching character '<' occurs,
+ * f4_processrec is deployed for the latest f4_Node element. This method does not
  * analyse the genotype semantically, it only checks if the syntax is proper. The only
  * semantic aspect is neuron class name extraction, where the GenoOperators
@@ -487,5 +494,5 @@
  * @return 0 if processing was successful, otherwise returns the position of an error in the genotype
  */
-int f4_processrec(const char *genot, unsigned pos0, f4_node *parent);
+int f4_processrec(const char *genot, unsigned pos0, f4_Node *parent);
 
 /**
@@ -502,17 +509,3 @@
 const char *parseConnection(const char *fragm, int &relfrom, double &weight);
 
-/**
- * Parses the notation of the neuron connection with neuron definition - takes
- * the beginning of the connection definition, extracts the name of neuron class
- * that will be the input for the current neuron and the weight of the connection.
- * After successful parsing, returns a pointer to the first character after the connection
- * definition, or NULL if the connection definition was not valid due to the lack of [, :, ]
- * characters, an invalid value of the weight or an invalid neuron class name.
- * @param fragm the beginning of the connection definition, should be the '[' character
- * @param neutype the reference to a string representing the input neuron class name. The name of the class is validated with GenoOperators::parseNeuroClass()
- * @param weight the reference to a double variable in which the weight of the connection will be stored
- * @return the pointer to the first character in string after the connection definition
- */
-const char *parseConnectionWithNeuron(const char *fragm, string &neutype, double &weight);
-
 #endif
