Index: cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- cpp/frams/genetics/f4/f4_general.cpp	(revision 972)
+++ cpp/frams/genetics/f4/f4_general.cpp	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -1293,9 +1293,9 @@
 	if (2 == childCount())
 		if (0 == out[0]) out += ">"; else
-			if ('>' != out[out.len() - 1]) out += ">";
+			if ('>' != out[out.length() - 1]) out += ">";
 	if (NULL != child2)    child2->sprint(out);
 	// make sure last char is a '>'
 	if (0 == out[0]) out += ">"; else
-		if ('>' != out[out.len() - 1]) out += ">";
+		if ('>' != out[out.length() - 1]) out += ">";
 }
 
@@ -1310,5 +1310,5 @@
 
 	// very last '>' can be omitted
-	len = out.len();
+	len = out.length();
 	if (len > 1)
 		if ('>' == out[len - 1]) { (out.directWrite())[len - 1] = 0; out.endWrite(); };
Index: cpp/frams/genetics/f9/f9_conv.cpp
===================================================================
--- cpp/frams/genetics/f9/f9_conv.cpp	(revision 972)
+++ cpp/frams/genetics/f9/f9_conv.cpp	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -32,5 +32,5 @@
 	m.open(using_checkpoints);
 	int recently_added = addSegment(m, 0, vertices, current, 0xDead);
-	for (int i = 0; i < in.len(); i++)
+	for (int i = 0; i < in.length(); i++)
 	{
 		char command = in[i];
@@ -119,5 +119,5 @@
 	double d1 = ind - indpre;
 	double d2 = indpost - ind;
-	double v = indpre == indpost ? v1 : d2*v1 + d1*v2; //d1+d2==1
+	double v = indpre == indpost ? v1 : d2 * v1 + d1 * v2; //d1+d2==1
 	return v;
 }
@@ -136,5 +136,5 @@
 		Joint *j = m.getJoint(i);
 		double x = joints_count < 2 ? 0 : (double)i / (joints_count - 1); //0..1, postion in the rainbow
-		double ind = x*maxind;
+		double ind = x * maxind;
 		j->vcolor.x = mix(r, maxind, ind);
 		j->vcolor.y = mix(g, maxind, ind);
@@ -153,5 +153,5 @@
 			averagecolor += j->vcolor;
 		p->vcolor = averagecolor / count;
-		if (count>5) count = 5; //avoid too fat...
+		if (count > 5) count = 5; //avoid too fat...
 		p->vsize = 0.3 + count / 15.0; //the more Joints is attached to a Part, the fatter it is
 	}
@@ -169,5 +169,5 @@
 			((3 * i + 5) % 10) - 4.5,
 			((7 * i + 2) % 10) - 4.5
-			); //-4.5 .. 4.5 in each axis
+		); //-4.5 .. 4.5 in each axis
 		p->p += noise / 1000;
 	}
Index: cpp/frams/genetics/fB/fB_conv.cpp
===================================================================
--- cpp/frams/genetics/fB/fB_conv.cpp	(revision 972)
+++ cpp/frams/genetics/fB/fB_conv.cpp	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -80,5 +80,5 @@
 		int endoffset = 0;
 		if (gene.indexOf("zz", 0) != -1) endoffset = 2;
-		if (gene.len() - endoffset < 3)
+		if (gene.length() - endoffset < 3)
 		{
 			fH_StickHandle *handle = new fH_StickHandle(dims, start, end);
@@ -124,5 +124,5 @@
 		if (gene.indexOf("zz", 0) != -1) endoffset = 2;
 		int nclassdefcount = 1;
-		while (z < gene.len() - endoffset)
+		while (z < gene.length() - endoffset)
 		{
 			if (processNextLetter(creature, handle, par, gene, propindex, z, ranges, nclassdefcount) == -1)
@@ -185,6 +185,5 @@
 			}
 			nextid++;
-		}
-		while (genotype[nextid] == '"');
+		} while (genotype[nextid] == '"');
 		i = nextid;
 	}
Index: cpp/frams/genetics/fB/fB_general.h
===================================================================
--- cpp/frams/genetics/fB/fB_general.h	(revision 972)
+++ cpp/frams/genetics/fB/fB_general.h	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -35,5 +35,5 @@
 		do {
 			count++;
-			if (start < genotype.len())
+			if (start < genotype.length())
 				result = getNextGene(start, genotype, tmp, start);
 			else
@@ -52,5 +52,5 @@
 		do {
 			count++;
-			if (start < geno.len())
+			if (start < geno.length())
 				getNextGene(start, geno, tmp, start);
 			else
@@ -89,5 +89,5 @@
 		} while (quotecount % 2 != 0 && end != -1);
 
-		if (end == -1) end = genotype.len();
+		if (end == -1) end = genotype.length();
 		else end += 2;
 		start -= 1;
@@ -124,5 +124,5 @@
 		} while (quotecount % 2 != 0 && end != -1);
 
-		if (end == -1) end = genotype.len();
+		if (end == -1) end = genotype.length();
 		else end += 2;
 		start -= 1;
Index: cpp/frams/genetics/fB/fB_oper.cpp
===================================================================
--- cpp/frams/genetics/fB/fB_oper.cpp	(revision 972)
+++ cpp/frams/genetics/fB/fB_oper.cpp	(revision 973)
@@ -47,5 +47,5 @@
 		int endoffset = 0;
 		if (gene.indexOf("zz", 0) != -1) endoffset = 2;
-		if (gene.len() - endoffset < 3)
+		if (gene.length() - endoffset < 3)
 		{
 			return true; // genes with length < 3 are always sticks
@@ -83,5 +83,5 @@
 	}
 	// check if rest of characters are lowercase
-	for (int i = genstart; i < genotype.len(); i++)
+	for (int i = genstart; i < genotype.length(); i++)
 	{
 		if (!islower(genotype[i]))
@@ -144,5 +144,5 @@
 		fix = true;
 	}
-	for (int i = pos; i < genotype.len(); i++)
+	for (int i = pos; i < genotype.length(); i++)
 	{
 		// if character is not alphabetic - error
@@ -208,5 +208,5 @@
 	std::list<SString> res;
 	int i = 0;
-	while (i < genotype.len())
+	while (i < genotype.length())
 	{
 		// if character is not alphabetic - error
@@ -252,5 +252,5 @@
 		std::advance(it, rndid);
 		SString t = (*it);
-		if ((*it).len() == 1)
+		if ((*it).length() == 1)
 		{
 			if (rndUint(2) == 0)
@@ -264,5 +264,5 @@
 				else (*it).directWrite()[0] = (*it)[0] + 1;
 			}
-			chg = 1.0 / line.len();
+			chg = 1.0 / line.length();
 		}
 		else
@@ -270,5 +270,5 @@
 			// first method needs to extract quotes
 			SString def = (*it);
-			def = def.substr(1, def.len() - 2);
+			def = def.substr(1, def.length() - 2);
 			Geno_fH::mutateNeuronProperties(def);
 			SString res = "\"";
@@ -276,5 +276,5 @@
 			res += "\"";
 			(*it) = res;
-			chg = (double)def.len() / line.len();
+			chg = (double)def.length() / line.length();
 		}
 		line = detokenizeSequence(&tokenized);
@@ -296,5 +296,5 @@
 			res += "\"";
 			tokenized.insert(it, res);
-			chg = (double)classdef.len() / line.len();
+			chg = (double)classdef.length() / line.length();
 			line = detokenizeSequence(&tokenized);
 			break;
@@ -304,5 +304,5 @@
 	case FB_INSERTION:
 	{
-		chg = 1.0 / line.len();
+		chg = 1.0 / line.length();
 		std::list<SString> tokenized = tokenizeSequence(line);
 		int rndid = rndUint(tokenized.size()); // select random insertion point
@@ -317,5 +317,5 @@
 	case FB_DELETION:
 	{
-		chg = 1.0 / line.len();
+		chg = 1.0 / line.length();
 		std::list<SString> tokenized = tokenizeSequence(line);
 		std::list<SString>::iterator it = tokenized.begin();
@@ -332,5 +332,5 @@
 		SString gene = fB_GenoHelpers::getGene(rndgene, line, start, end);
 		if (gene.indexOf("zz", 0) == -1) gene += "zz";
-		chg = (float)gene.len() / line.len();
+		chg = (float)gene.length() / line.length();
 		line = gene + line;
 		break;
@@ -364,5 +364,5 @@
 		//			line.substr(cuts[1], cuts[2] - cuts[1]) + first + line.substr(cuts[3]);
 		line = detokenizeSequence(&res);
-		chg = (float)(cuts[3] - cuts[2] + cuts[1] - cuts[0]) / line.len();
+		chg = (float)(cuts[3] - cuts[2] + cuts[1] - cuts[0]) / line.length();
 		break;
 	}
@@ -412,10 +412,10 @@
 		// add this gene to the beginning of the second parent genotype
 		child2 = gene + parent2;
-		chg2 = (float)parent2.len() / (float)child2.len();
+		chg2 = (float)parent2.length() / (float)child2.length();
 		// do the same for second parent
 		choice = rndUint(fB_GenoHelpers::geneCount(parent2));
 		gene = fB_GenoHelpers::getGene(choice, parent2, start, end);
 		child1 = gene + parent1;
-		chg1 = (float)parent1.len() / (float)child1.len();
+		chg1 = (float)parent1.length() / (float)child1.length();
 		break;
 	}
@@ -523,5 +523,5 @@
 	free(g1);
 	free(g2);
-	if (child1.len() > 0 && child2.len() == 0)
+	if (child1.length() > 0 && child2.length() == 0)
 	{
 		child1 = strdims + "\n" + child1;
@@ -529,5 +529,5 @@
 		g2 = strdup("");
 	}
-	else if (child2.len() > 0 && child1.len() == 0)
+	else if (child2.length() > 0 && child1.length() == 0)
 	{
 		child2 = strdims + "\n" + child2;
Index: cpp/frams/genetics/fF/fF_genotype.h
===================================================================
--- cpp/frams/genetics/fF/fF_genotype.h	(revision 972)
+++ cpp/frams/genetics/fF/fF_genotype.h	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -36,5 +36,5 @@
 		SString s = serialized;
 		ParamInterface::LoadOptions opts;
-		return ((param.load(ParamInterface::FormatSingleLine, s, &opts) == param.getPropCount()) && (opts.offset == s.len()));
+		return ((param.load(ParamInterface::FormatSingleLine, s, &opts) == param.getPropCount()) && (opts.offset == s.length()));
 	}
 
Index: cpp/frams/genetics/fH/fH_general.cpp
===================================================================
--- cpp/frams/genetics/fH/fH_general.cpp	(revision 972)
+++ cpp/frams/genetics/fH/fH_general.cpp	(revision 973)
@@ -214,5 +214,5 @@
 	while (genotype.getNextToken(pos, line, '\n'))
 	{
-		if (line.len() > 0)
+		if (line.length() > 0)
 		{
 			int res = processLine(line, linenumber, lastpos, pos - 1);
Index: cpp/frams/genetics/fL/fL_general.cpp
===================================================================
--- cpp/frams/genetics/fL/fL_general.cpp	(revision 972)
+++ cpp/frams/genetics/fL/fL_general.cpp	(revision 973)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -76,8 +76,8 @@
 {
 	// if position exceeds length then return false
-	if (pos >= src.len()) return false;
+	if (pos >= src.length()) return false;
 	int opencount = -1;
 	int i = pos;
-	for (; i < src.len(); i++)
+	for (; i < src.length(); i++)
 	{
 		// token cannot contain branching parenthesis
@@ -169,5 +169,5 @@
 	SString temp;
 	temp = token.substr(tokpos);
-	temp = temp.substr(0, temp.len() - 1);
+	temp = temp.substr(0, temp.length() - 1);
 
 	// if word has parameters
@@ -199,5 +199,5 @@
 				// if string is empty, then evaluate this with 0
 				// if sequence could not be evaluated, then return error
-				if (seq.len() > 0)
+				if (seq.length() > 0)
 				{
 					eval = new MathEvaluation(numparams);
@@ -217,5 +217,5 @@
 		}
 	}
-	else if (word->npar == 0 && temp.len() > 0)
+	else if (word->npar == 0 && temp.length() > 0)
 	{
 		SString message = "Too many parameters for word:  ";
@@ -351,5 +351,5 @@
 {
 	// if word already exist, then return error
-	if (this->name.len() == 0)
+	if (this->name.length() == 0)
 	{
 		logMessage("fL_Word", "processDefinition", LOG_ERROR, "Axiom name is empty");
@@ -456,26 +456,26 @@
 	switch (type)
 	{
-		case fLElementType::TERM:
-		{
-			tab = fL_word_paramtab;
-			obj = new fL_Word();
-			break;
-		}
-		case fLElementType::INFO:
-		{
-			tab = fL_builder_paramtab;
-			obj = this;
-			break;
-		}
-		case fLElementType::RULE:
-		{
-			tab = fL_rule_paramtab;
-			obj = new fL_Rule(begin, end);
-			break;
-		}
-		default:
-			tab = NULL;
-			obj = NULL;
-			break;
+	case fLElementType::TERM:
+	{
+		tab = fL_word_paramtab;
+		obj = new fL_Word();
+		break;
+	}
+	case fLElementType::INFO:
+	{
+		tab = fL_builder_paramtab;
+		obj = this;
+		break;
+	}
+	case fLElementType::RULE:
+	{
+		tab = fL_rule_paramtab;
+		obj = new fL_Rule(begin, end);
+		break;
+	}
+	default:
+		tab = NULL;
+		obj = NULL;
+		break;
 	}
 	Param par(tab);
@@ -573,5 +573,5 @@
 	while (genotype.getNextToken(pos, line, '\n'))
 	{
-		if (line.len() > 0)
+		if (line.length() > 0)
 		{
 			// words can be defined in the beginning of genotype
@@ -851,5 +851,5 @@
 				{
 					SString t = par.getString(q);
-					if (t.len() > 0)
+					if (t.length() > 0)
 					{
 						fL_Word *attrword = NULL;
@@ -957,5 +957,5 @@
 		}
 		double partprop = (ppar.getDoubleById(fL_part_names[i]) * alterationcount +
-				currval) / (alterationcount + 1.0);
+			currval) / (alterationcount + 1.0);
 		ppar.setDoubleById(fL_part_names[i], partprop);
 	}
@@ -1097,5 +1097,5 @@
 						delete newpart;
 						logMessage("fL_Builder", "developModel", LOG_ERROR,
-								"Error parsing word parameter");
+							"Error parsing word parameter");
 						return 1;
 					}
@@ -1124,5 +1124,5 @@
 						{
 							logMessage("fL_Builder", "developModel", LOG_ERROR,
-									"Error parsing word parameter");
+								"Error parsing word parameter");
 							delete newjoint;
 							return 1;
@@ -1162,5 +1162,5 @@
 			else if (word->name == "C")
 			{
-				connsbuffer.push_back({w, currstate.currneuron});
+				connsbuffer.push_back({ w, currstate.currneuron });
 			}
 			else if (word->name.startsWith("rot"))
@@ -1182,13 +1182,13 @@
 				if (word->name == "rotX")
 				{
-					rotmatrix.rotate(Pt3D(rot,0,0));
+					rotmatrix.rotate(Pt3D(rot, 0, 0));
 				}
 				else if (word->name == "rotY")
 				{
-					rotmatrix.rotate(Pt3D(0,rot,0));
+					rotmatrix.rotate(Pt3D(0, rot, 0));
 				}
 				else if (word->name == "rotZ")
 				{
-					rotmatrix.rotate(Pt3D(0,0,rot));
+					rotmatrix.rotate(Pt3D(0, 0, rot));
 				}
 				currstate.direction = rotmatrix.transform(currstate.direction);
@@ -1212,5 +1212,5 @@
 	{
 		if (connsbuffer[i].second == NULL ||
-				(connsbuffer[i].second->getClass()->getPreferredInputs() != -1 &&
+			(connsbuffer[i].second->getClass()->getPreferredInputs() != -1 &&
 				connsbuffer[i].second->getInputCount() >=
 				connsbuffer[i].second->getClass()->getPreferredInputs()))
@@ -1225,5 +1225,5 @@
 			SString attr = par.getStringById(FL_PE_CONN_ATTR);
 			fL_Word *attractor = NULL;
-			if (attr.len() > 0)
+			if (attr.length() > 0)
 			{
 				createWord(attr, attractor, 0, (*connsbuffer[i].first)->begin, (*connsbuffer[i].first)->end);
@@ -1236,5 +1236,5 @@
 				{
 					logMessage("fL_Builder", "developModel", LOG_ERROR,
-							"Error parsing word parameter");
+						"Error parsing word parameter");
 					delete attractor;
 					return 1;
@@ -1245,6 +1245,6 @@
 				connsbuffer[i].second->addInput(neu, weight);
 				if (using_mapping) neu->addMapping(
-						IRange((*connsbuffer[i].first)->begin,
-								(*connsbuffer[i].first)->end));
+					IRange((*connsbuffer[i].first)->begin,
+						(*connsbuffer[i].first)->end));
 			}
 			else
@@ -1252,6 +1252,6 @@
 				connsbuffer[i].second->addInput(connsbuffer[i].second, weight);
 				if (using_mapping) neu->addMapping(
-						IRange((*connsbuffer[i].first)->begin,
-								(*connsbuffer[i].first)->end));
+					IRange((*connsbuffer[i].first)->begin,
+						(*connsbuffer[i].first)->end));
 			}
 			delete attractor;
@@ -1286,5 +1286,5 @@
 	m->open(using_checkpoints);
 	bool wordsexceeded = false;
-	for (; t <= time; t+= timestamp)
+	for (; t <= time; t += timestamp)
 	{
 		alterTimedProperties(t); // always alter timed properties in the beginning
@@ -1293,5 +1293,5 @@
 		{
 			iterate(t);
-			curriter+=1.0;
+			curriter += 1.0;
 		}
 		if (using_checkpoints)
@@ -1362,5 +1362,5 @@
 {
 	int count = genotype.size();
-	for (fL_Rule *rul: rules)
+	for (fL_Rule *rul : rules)
 	{
 		count += rul->objsucc.size();
@@ -1373,5 +1373,5 @@
 {
 	for (std::vector<fL_Rule *>::iterator it = rules.begin();
-			it != rules.end(); it++)
+		it != rules.end(); it++)
 	{
 		std::vector<fL_Rule *>::iterator it2 = it;
@@ -1393,5 +1393,5 @@
 				{
 					if ((*it)->condeval->getStringifiedRPN() ==
-							(*it2)->condeval->getStringifiedRPN())
+						(*it2)->condeval->getStringifiedRPN())
 					{
 						todelete = true;
Index: cpp/frams/genetics/fL/fL_oper.cpp
===================================================================
--- cpp/frams/genetics/fL/fL_oper.cpp	(revision 972)
+++ cpp/frams/genetics/fL/fL_oper.cpp	(revision 973)
@@ -285,93 +285,87 @@
 	switch (method)
 	{
-		case FL_CHG_ITER:
-		{
-			if (rndUint(2) == 0)
-			{
-				creature->time = creature->time + iterchangestep <= ExtValue::getDouble(FL_MAXITER) ?
-						creature->time + iterchangestep : creature->time - iterchangestep;
-			}
-			else
-			{
-				creature->time = creature->time - iterchangestep >= 0 ?
-						creature->time - iterchangestep : creature->time + iterchangestep;
-			}
+	case FL_CHG_ITER:
+	{
+		if (rndUint(2) == 0)
+		{
+			creature->time = creature->time + iterchangestep <= ExtValue::getDouble(FL_MAXITER) ?
+				creature->time + iterchangestep : creature->time - iterchangestep;
+		}
+		else
+		{
+			creature->time = creature->time - iterchangestep >= 0 ?
+				creature->time - iterchangestep : creature->time + iterchangestep;
+		}
+		break;
+	}
+	case FL_CHG_COND:
+	{
+		if (creature->rules.size() > 0)
+		{
+			int ruleid = rndUint(creature->rules.size());
+			if (!creature->rules[ruleid]->condeval)
+			{
+				creature->rules[ruleid]->condeval = new MathEvaluation(creature->rules[ruleid]->objpred->npar);
+			}
+			creature->rules[ruleid]->condeval->mutateConditional();
 			break;
 		}
-		case FL_CHG_COND:
-		{
-			if (creature->rules.size() > 0)
-			{
-				int ruleid = rndUint(creature->rules.size());
-				if (!creature->rules[ruleid]->condeval)
-				{
-					creature->rules[ruleid]->condeval = new MathEvaluation(creature->rules[ruleid]->objpred->npar);
-				}
-				creature->rules[ruleid]->condeval->mutateConditional();
-				break;
-			}
-			// if there are no rules - create one
-		}
-		[[fallthrough]];
-		case FL_ADD_RULE:
-		{
-			std::unordered_map<std::string, fL_Word *>::iterator pred = creature->words.begin();
-			std::vector<fL_Word *> wordswithnorules;
-			for (; pred != creature->words.end(); pred++)
-			{
-				if (!pred->second->builtin)
-				{
-					bool norules = true;
-					for (fL_Rule * r : creature->rules)
-					{
-						if (pred->second->name == r->objpred->name &&
-								pred->second->npar == r->objpred->npar)
-						{
-							norules = false;
-							break;
-						}
-					}
-					if (norules)
-					{
-						wordswithnorules.push_back(pred->second);
-					}
-				}
-			}
-			if (wordswithnorules.size() > 0)
-			{
-				int predid = rndUint(wordswithnorules.size());
-				fL_Rule *newrule = new fL_Rule(0,0);
-				fL_Word *pred = new fL_Word();
-				*pred = *wordswithnorules[predid];
-				newrule->objpred = pred;
-				fL_Word *initdef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1)); // -1 to avoid branching
-				addWord(&newrule->objsucc, initdef, newrule->objsucc.begin());
-				creature->rules.push_back(newrule);
-				break;
-			}
-			else if (creature->rules.size() > 0)
-			{
-				int ruleid = rndUint(creature->rules.size());
-				fL_Rule *newrule = new fL_Rule(0, 0);
-				fL_Word *pred = new fL_Word();
-				*pred = *creature->rules[ruleid]->objpred;
-				newrule->objpred = pred;
-				if (creature->rules[ruleid]->condeval)
-				{
-					std::string formula = "";
-					creature->rules[ruleid]->condeval->RPNToInfix(formula);
-					if (formula.find("1.0-(") != 0)
-					{
-						std::string res = "1.0-(";
-						res += formula;
-						res += ")";
-						newrule->condeval = new MathEvaluation(pred->npar);
-						newrule->condeval->convertString(res);
-					}
-					else
-					{
-						newrule->condeval = new MathEvaluation(pred->npar);
-						newrule->condeval->mutateConditional();
-					}
+		// if there are no rules - create one
+	}
+	[[fallthrough]];
+	case FL_ADD_RULE:
+	{
+		std::unordered_map<std::string, fL_Word *>::iterator pred = creature->words.begin();
+		std::vector<fL_Word *> wordswithnorules;
+		for (; pred != creature->words.end(); pred++)
+		{
+			if (!pred->second->builtin)
+			{
+				bool norules = true;
+				for (fL_Rule * r : creature->rules)
+				{
+					if (pred->second->name == r->objpred->name &&
+						pred->second->npar == r->objpred->npar)
+					{
+						norules = false;
+						break;
+					}
+				}
+				if (norules)
+				{
+					wordswithnorules.push_back(pred->second);
+				}
+			}
+		}
+		if (wordswithnorules.size() > 0)
+		{
+			int predid = rndUint(wordswithnorules.size());
+			fL_Rule *newrule = new fL_Rule(0, 0);
+			fL_Word *pred = new fL_Word();
+			*pred = *wordswithnorules[predid];
+			newrule->objpred = pred;
+			fL_Word *initdef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1)); // -1 to avoid branching
+			addWord(&newrule->objsucc, initdef, newrule->objsucc.begin());
+			creature->rules.push_back(newrule);
+			break;
+		}
+		else if (creature->rules.size() > 0)
+		{
+			int ruleid = rndUint(creature->rules.size());
+			fL_Rule *newrule = new fL_Rule(0, 0);
+			fL_Word *pred = new fL_Word();
+			*pred = *creature->rules[ruleid]->objpred;
+			newrule->objpred = pred;
+			if (creature->rules[ruleid]->condeval)
+			{
+				std::string formula = "";
+				creature->rules[ruleid]->condeval->RPNToInfix(formula);
+				if (formula.find("1.0-(") != 0)
+				{
+					std::string res = "1.0-(";
+					res += formula;
+					res += ")";
+					newrule->condeval = new MathEvaluation(pred->npar);
+					newrule->condeval->convertString(res);
 				}
 				else
@@ -380,180 +374,211 @@
 					newrule->condeval->mutateConditional();
 				}
-				fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
-				addWord(&newrule->objsucc, worddef, newrule->objsucc.begin());
-				creature->rules.push_back(newrule);
-				break;
-			}
-			// if there are no words, from which rules can be formed, then add one
-		}
-		[[fallthrough]];
-		case FL_ADD_WDEF:
-		{
-			if (creature->countDefinedWords() <= maxdefinedwords)
-			{
-				int npar = rndUint(ExtValue::getInt(FL_MAXPARAMS, false));
-				for (int i = 0; i < maxdefinedwords; i++)
-				{
-					std::string name = "w";
-					name += std::to_string(i);
-					if (creature->words.find(name) == creature->words.end())
-					{
-						fL_Word *word = new fL_Word(false, 0, 0);
-						word->npar = npar;
-						word->name = name.c_str();
-						word->processDefinition(creature);
-						break;
-					}
-				}
-				break;
-			}
-			//no break at the end of case - if there is too many words, then
-			// deletion should be performed
-		}
-		[[fallthrough]];
-		case FL_DEL_WORD:
-		{
+			}
+			else
+			{
+				newrule->condeval = new MathEvaluation(pred->npar);
+				newrule->condeval->mutateConditional();
+			}
+			fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
+			addWord(&newrule->objsucc, worddef, newrule->objsucc.begin());
+			creature->rules.push_back(newrule);
+			break;
+		}
+		// if there are no words, from which rules can be formed, then add one
+	}
+	[[fallthrough]];
+	case FL_ADD_WDEF:
+	{
+		if (creature->countDefinedWords() <= maxdefinedwords)
+		{
+			int npar = rndUint(ExtValue::getInt(FL_MAXPARAMS, false));
+			for (int i = 0; i < maxdefinedwords; i++)
+			{
+				std::string name = "w";
+				name += std::to_string(i);
+				if (creature->words.find(name) == creature->words.end())
+				{
+					fL_Word *word = new fL_Word(false, 0, 0);
+					word->npar = npar;
+					word->name = name.c_str();
+					word->processDefinition(creature);
+					break;
+				}
+			}
+			break;
+		}
+		//no break at the end of case - if there is too many words, then
+		// deletion should be performed
+	}
+	[[fallthrough]];
+	case FL_DEL_WORD:
+	{
+		int numpars = 0;
+		int ruleid = 0;
+		std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, ruleid);
+		if (ruleid == -1 && creature->countSticksInSequence(list) == 1)
+		{
+			if (list->size() > 1)
+			{
+				int rndid = rndUint(list->size() - 1);
+				int j = 0;
+				std::list<fL_Word *>::iterator it = list->begin();
+				if ((*it)->name == "S")
+				{
+					it++;
+				}
+				while (it != list->end() && j < rndid && ((*it)->name == "S"))
+				{
+					if ((*it)->name != "S")
+					{
+						j++;
+					}
+					it++;
+				}
+				if (it != list->end())
+				{
+					if ((*it)->type == fLElementType::BRANCH)
+					{
+						deleteBranch(list, it);
+					}
+					else
+					{
+						delete (*it);
+						list->erase(it);
+					}
+					break;
+				}
+				// else add word
+			}
+			// else add word
+		}
+		else
+		{
+			int rndid = rndUint(list->size());
+			std::list<fL_Word *>::iterator it = list->begin();
+			std::advance(it, rndid);
+			if ((*it)->type == fLElementType::BRANCH)
+			{
+				deleteBranch(list, it);
+			}
+			else
+			{
+				delete (*it);
+				list->erase(it);
+			}
+			if (ruleid > -1 && creature->rules[ruleid]->objsucc.size() == 0)
+			{
+				delete creature->rules[ruleid];
+				creature->rules.erase(creature->rules.begin() + ruleid);
+			}
+			break;
+		}
+		// if no words available, then add word
+	}
+	[[fallthrough]];
+	case FL_ADD_WORD:
+	{
+		int numpars = 0;
+		int tmp = 0;
+		std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
+		int rndid = rndUint(list->size());
+		std::list<fL_Word *>::iterator it = list->begin();
+		std::advance(it, rndid);
+		int meth = roulette(addtypes, FL_ADD_COUNT);
+		if (tmp == -1)
+		{ // if sequence is axiom and it does not have non-builtin words
+			bool hasdefined = false;
+			for (std::list<fL_Word *>::iterator elem = list->begin(); elem != list->end(); elem++)
+			{
+				if (!(*elem)->builtin)
+				{
+					hasdefined = true;
+					break;
+				}
+			}
+			if (!hasdefined)
+			{
+				meth = FL_ADD_OTHER;
+			}
+
+		}
+		if (meth != FL_ADD_BRANCH)
+		{
+			fL_Word *worddef = randomWordDefinition(creature, meth);
+			addWord(list, worddef, it);
+		}
+		else
+		{
+			fL_Branch *start = new fL_Branch(fL_Branch::BranchType::OPEN, 0, 0);
+			list->insert(it, start);
+			int rottype = rndUint(2);
+			switch (rottype)
+			{
+			case 0:
+				addWord(list, creature->words["rotY"], it);
+			case 1:
+				addWord(list, creature->words["rotZ"], it);
+			}
+			addWord(list, creature->words["S"], it);
+			fL_Branch *end = new fL_Branch(fL_Branch::BranchType::CLOSE, 0, 0);
+			list->insert(it, end);
+		}
+		break;
+	}
+	case FL_CHG_WORD:
+	{
+		int numpars = 0;
+		int tmp = 0;
+		std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
+		int rndid = rndUint(list->size());
+		std::list<fL_Word *>::iterator selectedword = list->begin();
+		std::advance(selectedword, rndid);
+		if ((*selectedword)->type == fLElementType::BRANCH)
+		{
+			break;
+		}
+		int chgtype = roulette(chgoperations, FL_CHG_COUNT);
+		if (creature->countSticksInSequence(list) == 1 && tmp == -1) // if sequence is axiom
+		{
+			fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
+
 			int numpars = 0;
-			int ruleid = 0;
-			std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, ruleid);
-			if (ruleid == -1 && creature->countSticksInSequence(list) == 1)
-			{
-				if (list->size() > 1)
-				{
-					int rndid = rndUint(list->size() - 1);
-					int j = 0;
-					std::list<fL_Word *>::iterator it = list->begin();
-					if ((*it)->name == "S")
-					{
-						it++;
-					}
-					while (it != list->end() && j < rndid && ((*it)->name == "S"))
-					{
-						if ((*it)->name != "S")
-						{
-							j++;
-						}
-						it++;
-					}
-					if (it != list->end())
-					{
-						if ((*it)->type == fLElementType::BRANCH)
-						{
-							deleteBranch(list, it);
-						}
-						else
-						{
-							delete (*it);
-							list->erase(it);
-						}
-						break;
-					}
-					// else add word
-				}
-				// else add word
-			}
-			else
-			{
-				int rndid = rndUint(list->size());
-				std::list<fL_Word *>::iterator it = list->begin();
-				std::advance(it, rndid);
-				if ((*it)->type == fLElementType::BRANCH)
-				{
-					deleteBranch(list, it);
-				}
-				else
-				{
-					delete (*it);
-					list->erase(it);
-				}
-				if (ruleid > -1 && creature->rules[ruleid]->objsucc.size() == 0)
-				{
-					delete creature->rules[ruleid];
-					creature->rules.erase(creature->rules.begin() + ruleid);
-				}
-				break;
-			}
-			// if no words available, then add word
-		}
-		[[fallthrough]];
-		case FL_ADD_WORD:
-		{
-			int numpars = 0;
-			int tmp = 0;
 			std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
 			int rndid = rndUint(list->size());
 			std::list<fL_Word *>::iterator it = list->begin();
 			std::advance(it, rndid);
-			int meth = roulette(addtypes, FL_ADD_COUNT);
-			if (tmp == -1)
-			{ // if sequence is axiom and it does not have non-builtin words
-				bool hasdefined = false;
-				for (std::list<fL_Word *>::iterator elem = list->begin(); elem != list->end(); elem++)
-				{
-					if (!(*elem)->builtin)
-					{
-						hasdefined = true;
-						break;
-					}
-				}
-				if (!hasdefined)
-				{
-					meth = FL_ADD_OTHER;
-				}
-
-			}
-			if (meth != FL_ADD_BRANCH)
-			{
-				fL_Word *worddef = randomWordDefinition(creature, meth);
-				addWord(list, worddef, it);
+
+			addWord(list, worddef, it);
+
+			break;
+		}
+		else if (chgtype == FL_CHG_WORD_NAME)
+		{
+			if ((*selectedword)->builtin)
+			{
+				delete (*selectedword);
+				selectedword = list->erase(selectedword);
+				fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
+				addWord(list, worddef, selectedword);
 			}
 			else
 			{
-				fL_Branch *start = new fL_Branch(fL_Branch::BranchType::OPEN, 0, 0);
-				list->insert(it, start);
-				int rottype = rndUint(2);
-				switch (rottype)
-				{
-				case 0:
-					addWord(list, creature->words["rotY"], it);
-				case 1:
-					addWord(list, creature->words["rotZ"], it);
-				}
-				addWord(list, creature->words["S"], it);
-				fL_Branch *end = new fL_Branch(fL_Branch::BranchType::CLOSE, 0, 0);
-				list->insert(it, end);
-			}
-			break;
-		}
-		case FL_CHG_WORD:
-		{
-			int numpars = 0;
-			int tmp = 0;
-			std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
-			int rndid = rndUint(list->size());
-			std::list<fL_Word *>::iterator selectedword = list->begin();
-			std::advance(selectedword, rndid);
-			if ((*selectedword)->type == fLElementType::BRANCH)
-			{
-				break;
-			}
-			int chgtype = roulette(chgoperations, FL_CHG_COUNT);
-			if (creature->countSticksInSequence(list) == 1 && tmp == -1) // if sequence is axiom
-			{
-				fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
-
-				int numpars = 0;
-				std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
-				int rndid = rndUint(list->size());
-				std::list<fL_Word *>::iterator it = list->begin();
-				std::advance(it, rndid);
-
-				addWord(list, worddef, it);
-
-				break;
-			}
-			else if (chgtype == FL_CHG_WORD_NAME)
-			{
-				if ((*selectedword)->builtin)
+				std::vector<fL_Word *> available;
+				for (std::unordered_map<std::string, fL_Word *>::iterator wit = creature->words.begin();
+					wit != creature->words.end(); wit++)
+				{
+					if ((*selectedword)->npar == wit->second->npar &&
+						(*selectedword)->name != wit->second->name &&
+						!wit->second->builtin)
+					{
+						available.push_back(wit->second);
+					}
+				}
+				if (available.size() > 0)
+				{
+					int newnameid = rndUint(available.size());
+					(*selectedword)->name = available[newnameid]->name;
+				}
+				else
 				{
 					delete (*selectedword);
@@ -562,114 +587,89 @@
 					addWord(list, worddef, selectedword);
 				}
-				else
-				{
-					std::vector<fL_Word *> available;
-					for (std::unordered_map<std::string, fL_Word *>::iterator wit = creature->words.begin();
-							wit != creature->words.end(); wit++)
-					{
-						if ((*selectedword)->npar == wit->second->npar &&
-								(*selectedword)->name != wit->second->name &&
-								!wit->second->builtin)
+			}
+		}
+		else
+		{
+			if ((*selectedword)->npar > 0)
+			{
+				int randeval = rndUint((*selectedword)->npar);
+				Param par((*selectedword)->tab, (*selectedword)->data);
+				if ((*selectedword)->builtin && (*selectedword)->name == "N"
+					&& strcmp(par.id(randeval), FL_PE_NEURO_DET) == 0)
+				{
+					SString res = par.getStringById(FL_PE_NEURO_DET);
+					Geno_fH::mutateNeuronProperties(res);
+					par.setStringById(FL_PE_NEURO_DET, res);
+				}
+				else if ((*selectedword)->builtin &&
+					(*selectedword)->name == "C" &&
+					strcmp(par.id(randeval), FL_PE_CONN_ATTR) == 0)
+				{
+					SString strattractor = par.getStringById(FL_PE_CONN_ATTR);
+					if (strattractor.length() > 0)
+					{
+						fL_Word *w = NULL;
+						creature->createWord(strattractor, w, numpars, 0, 0);
+						// mutate attractor parameter
+						if (w->npar > 0)
 						{
-							available.push_back(wit->second);
+							int rndattr = rndUint(w->npar);
+							if (!w->parevals[rndattr])
+							{
+								w->parevals[rndattr] = new MathEvaluation(numpars);
+							}
+							w->parevals[rndattr]->mutate(false, false);
 						}
-					}
-					if (available.size() > 0)
-					{
-						int newnameid = rndUint(available.size());
-						(*selectedword)->name = available[newnameid]->name;
+						strattractor = w->stringify(true);
+						par.setStringById(FL_PE_CONN_ATTR, strattractor);
+						delete w;
 					}
 					else
 					{
-						delete (*selectedword);
-						selectedword = list->erase(selectedword);
-						fL_Word *worddef = randomWordDefinition(creature, roulette(addtypes, FL_ADD_COUNT - 1));
-						addWord(list, worddef, selectedword);
-					}
-				}
-			}
-			else
-			{
-				if ((*selectedword)->npar > 0)
-				{
-					int randeval = rndUint((*selectedword)->npar);
-					Param par((*selectedword)->tab, (*selectedword)->data);
-					if ((*selectedword)->builtin && (*selectedword)->name == "N"
-							&& strcmp(par.id(randeval), FL_PE_NEURO_DET) == 0)
-					{
-						SString res = par.getStringById(FL_PE_NEURO_DET);
-						Geno_fH::mutateNeuronProperties(res);
-						par.setStringById(FL_PE_NEURO_DET, res);
-					}
-					else if ((*selectedword)->builtin &&
-							(*selectedword)->name == "C" &&
-							strcmp(par.id(randeval), FL_PE_CONN_ATTR) == 0)
-					{
-						SString strattractor = par.getStringById(FL_PE_CONN_ATTR);
-						if (strattractor.len() > 0)
+						if (creature->builtincount < (int)creature->words.size())
 						{
-							fL_Word *w = NULL;
-							creature->createWord(strattractor, w, numpars, 0, 0);
-							// mutate attractor parameter
+							fL_Word *wdef = randomWordDefinition(creature, FL_ADD_OTHER);
+							fL_Word *w = new fL_Word();
+							*w = *wdef;
+							w->data = ParamObject::makeObject(w->tab);
+							Param apar(w->tab);
+							apar.select(w->data);
+							apar.setDefault();
 							if (w->npar > 0)
 							{
 								int rndattr = rndUint(w->npar);
-								if (!w->parevals[rndattr])
+								for (int i = 0; i < w->npar; i++)
 								{
-									w->parevals[rndattr] = new MathEvaluation(numpars);
+									if (i == rndattr)
+									{
+										MathEvaluation *ev = new MathEvaluation(numpars);
+										ev->mutate(false, false);
+										w->parevals.push_back(ev);
+									}
+									else
+									{
+										w->parevals.push_back(NULL);
+									}
 								}
-								w->parevals[rndattr]->mutate(false, false);
+
 							}
-							strattractor = w->stringify(true);
+							strattractor = w->stringify(false);
 							par.setStringById(FL_PE_CONN_ATTR, strattractor);
 							delete w;
 						}
-						else
-						{
-							if (creature->builtincount < (int)creature->words.size())
-							{
-								fL_Word *wdef = randomWordDefinition(creature, FL_ADD_OTHER);
-								fL_Word *w = new fL_Word();
-								*w = *wdef;
-								w->data = ParamObject::makeObject(w->tab);
-								Param apar(w->tab);
-								apar.select(w->data);
-								apar.setDefault();
-								if (w->npar > 0)
-								{
-									int rndattr = rndUint(w->npar);
-									for (int i = 0; i < w->npar; i++)
-									{
-										if (i == rndattr)
-										{
-											MathEvaluation *ev = new MathEvaluation(numpars);
-											ev->mutate(false, false);
-											w->parevals.push_back(ev);
-										}
-										else
-										{
-											w->parevals.push_back(NULL);
-										}
-									}
-
-								}
-								strattractor = w->stringify(false);
-								par.setStringById(FL_PE_CONN_ATTR, strattractor);
-								delete w;
-							}
-						}
-					}
-					else
-					{
-						if (!(*selectedword)->parevals[randeval])
-						{
-							(*selectedword)->parevals[randeval] = new MathEvaluation(numpars);
-						}
-						(*selectedword)->parevals[randeval]->mutate(false, iterchangestep != 1.0);
-					}
-				}
-			}
-			break;
-		}
+					}
+				}
+				else
+				{
+					if (!(*selectedword)->parevals[randeval])
+					{
+						(*selectedword)->parevals[randeval] = new MathEvaluation(numpars);
+					}
+					(*selectedword)->parevals[randeval]->mutate(false, iterchangestep != 1.0);
+				}
+			}
+		}
+		break;
+	}
 	}
 
@@ -702,5 +702,5 @@
 	}
 	else if (to->words.find(fromword->name.c_str()) != to->words.end() &&
-			to->words[fromword->name.c_str()]->npar == fromword->npar) // if there is already same word with same number of parameters
+		to->words[fromword->name.c_str()]->npar == fromword->npar) // if there is already same word with same number of parameters
 	{
 		fL_Word *newword = new fL_Word();
@@ -710,5 +710,5 @@
 	}
 	for (std::unordered_map<std::string, fL_Word *>::iterator it = to->words.begin();
-			it != to->words.end(); it++)
+		it != to->words.end(); it++)
 	{ // find word with same number of parameters
 		if (fromword->npar == it->second->npar && map.find(fromword->name.c_str()) == map.end() && !it->second->builtin)
@@ -774,5 +774,5 @@
 					std::string form;
 					if (w->builtin && w->name == "N"
-							&& strcmp(par.id(i), FL_PE_NEURO_DET) == 0)
+						&& strcmp(par.id(i), FL_PE_NEURO_DET) == 0)
 					{
 						SString res = origpar.getStringById(FL_PE_NEURO_DET);
@@ -781,8 +781,8 @@
 					}
 					else if (w->builtin && w->name == "C"
-							&& strcmp(par.id(i), FL_PE_CONN_ATTR) == 0)
+						&& strcmp(par.id(i), FL_PE_CONN_ATTR) == 0)
 					{
 						SString strattractor = origpar.getStringById(FL_PE_CONN_ATTR);
-						if (strattractor.len() > 0)
+						if (strattractor.length() > 0)
 						{
 							fL_Word *tmp = NULL;
Index: cpp/frams/genetics/fS/fS_general.cpp
===================================================================
--- cpp/frams/genetics/fS/fS_general.cpp	(revision 972)
+++ cpp/frams/genetics/fS/fS_general.cpp	(revision 973)
@@ -99,10 +99,10 @@
 		if (separatorIndex == -1)
 		{
-			keyLength = keyValue.len();
+			keyLength = keyValue.length();
 			value = DEFAULT_NEURO_CONNECTION_WEIGHT;
 		} else
 		{
 			keyLength = separatorIndex;
-			size_t valueLength = keyValue.len() - (separatorIndex);
+			size_t valueLength = keyValue.length() - (separatorIndex);
 			value = fS_stod(buffer + separatorIndex + 1, start, &valueLength);
 		}
@@ -859,5 +859,5 @@
 {
 	SString geno;
-	geno.memoryHint(100);     // Provide a small buffer from the start to improve performance
+	geno.reserve(100);     // Provide a small buffer from the start to improve performance
 	startNode->getGeno(geno);
 	return geno;
