Index: cpp/f8-to-f1/geno_f8.cpp
===================================================================
--- cpp/f8-to-f1/geno_f8.cpp	(revision 24)
+++ cpp/f8-to-f1/geno_f8.cpp	(revision 30)
@@ -25,18 +25,19 @@
 {
 {"Genetics: f8",1,F8_OPERATION_COUNT,},
-{"f8_mut_chg_begin_arg", 0, 0, "Change beginning argument", "f 0 100 8", FIELD(operation[F8_CHANGE_BEGINNING_ARG]),"mutation: probability of changing a beginning argument", },
-{"f8_mut_chg_arg", 0, 0, "Change argument", "f 0 100 8", FIELD(operation[F8_CHANGE_ARG]),"mutation: probability of changing a production's argument", },
+{"f8_mut_chg_begin_arg", 0, 0, "Change beginning argument", "f 0 100 7", FIELD(operation[F8_CHANGE_BEGINNING_ARG]),"mutation: probability of changing a beginning argument", },
+{"f8_mut_chg_arg", 0, 0, "Change argument", "f 0 100 7", FIELD(operation[F8_CHANGE_ARG]),"mutation: probability of changing a production's argument", },
 {"f8_mut_del_comm", 0, 0, "Delete command", "f 0 100 8", FIELD(operation[F8_DELETE_COMMAND]),"mutation: probability of deleting a command", },
-{"f8_mut_insert_comm", 0, 0, "Insert commands", "f 0 100 9", FIELD(operation[F8_INSERT_COMMANDS]),"mutation: probability of inserting commands", },
-{"f8_mut_enc", 0, 0, "Encapsulate commands", "f 0 100 10",FIELD(operation[F8_ENCAPSULATE]),"mutation: probability of encapsulating commands", },
-{"f8_mut_chg_cond_sign", 0, 0, "Change condition sign", "f 0 100 8",FIELD(operation[F8_CHANGE_CONDITION_SIGN]),"mutation: probability of changing a condition sign", },
-{"f8_mut_add_param", 0, 0, "Add parameter", "f 0 100 9", FIELD(operation[F8_ADD_PARAMETER]),"mutation: probability of adding a parameter to the production", },
+{"f8_mut_insert_comm", 0, 0, "Insert commands", "f 0 100 8", FIELD(operation[F8_INSERT_COMMANDS]),"mutation: probability of inserting commands", },
+{"f8_mut_enc", 0, 0, "Encapsulate commands", "f 0 100 8",FIELD(operation[F8_ENCAPSULATE]),"mutation: probability of encapsulating commands", },
+{"f8_mut_chg_cond_sign", 0, 0, "Change condition sign", "f 0 100 7",FIELD(operation[F8_CHANGE_CONDITION_SIGN]),"mutation: probability of changing a condition sign", },
+{"f8_mut_add_param", 0, 0, "Add parameter", "f 0 100 8", FIELD(operation[F8_ADD_PARAMETER]),"mutation: probability of adding a parameter to the production", },
 {"f8_mut_add_cond", 0, 0, "Add condition", "f 0 100 8", FIELD(operation[F8_ADD_CONDITION]),"mutation: probability of ading a condition to the subproduction", },
 {"f8_mut_add_subprod", 0, 0, "Add subproduction", "f 0 100 8", FIELD(operation[F8_ADD_SUBPRODUCTION]),"mutation: probability of adding a subproduction", },
-{"f8_mut_chg_iter_number", 0, 0, "Change iteration number", "f 0 100 8", FIELD(operation[F8_CHANGE_ITERATIONS_NUMBER]),"mutation: probability of changing an iterations number", },
+{"f8_mut_chg_iter_number", 0, 0, "Change iteration number", "f 0 100 7", FIELD(operation[F8_CHANGE_ITERATIONS_NUMBER]),"mutation: probability of changing an iterations number", },
 {"f8_mut_del_param", 0, 0, "Delete parameter", "f 0 100 8", FIELD(operation[F8_DELETE_PARAMETER]),"mutation: probability of deleting a parameter", },
 {"f8_mut_del_cond", 0, 0, "Delete condition", "f 0 100 8", FIELD(operation[F8_DELETE_CONDITION]),"mutation: probability of deleting a condition", },
 {"f8_mut_add_loop", 0, 0, "Add loop", "f 0 100 0", FIELD(operation[F8_ADD_LOOP]),"mutation: probability of ading a loop", },
 {"f8_mut_del_loop", 0, 0, "Delete loop", "f 0 100 0", FIELD(operation[F8_DELETE_LOOP]),"mutation: probability of deleting a loop", },
+{"f8_mut_del_prod", 0, 0, "Delete production", "f 0 100 8", FIELD(operation[F8_DELETE_PRODUCTION]),"mutation: probability of deleting a production", },
 {0,},
 };
@@ -555,4 +556,123 @@
 }
 
+SString Geno_f8::mutateDeleteProduction(SString &in, float& chg) {
+	SString mutated;
+	
+	Lsystem *lsystem = this->converter->createLsystem(in);
+	if (lsystem == NULL || lsystem->productions.size() == 0) {
+		mutated += in;
+		chg = -1.0;
+		return mutated;
+	}
+	
+	if (lsystem->productions.size() < 2) {
+		mutated += in;
+		chg = 0.0;
+		return mutated;
+	}
+	
+	int counter = 0;
+	vector<SString> productionNamesSS = this->converter->readProductionNames(in);
+	vector<string> productionNames;
+	for (int ssI = 0; ssI < productionNamesSS.size(); ssI++) {
+		productionNames.push_back(sstringToString(productionNamesSS[ssI]));
+	}
+	vector<string>::iterator prodNameIter = productionNames.begin();
+	while (prodNameIter != productionNames.end()) {
+		//delete first production from candidate list
+		if ((*prodNameIter).compare(lsystem->firstProductionName) == 0) {
+			prodNameIter = productionNames.erase(prodNameIter);
+		} else {
+			prodNameIter++;
+		}
+	}
+	//choose production to delete
+	string prodNameToDelete = productionNames[randomN(productionNames.size())];
+	productionNames.push_back(lsystem->firstProductionName);
+	prodNameIter = productionNames.begin();
+	while (prodNameIter != productionNames.end()) {
+		//delete prodNameToDelete from candidate list
+		if ((*prodNameIter).compare(prodNameToDelete) == 0) {
+			prodNameIter = productionNames.erase(prodNameIter);
+		} else {
+			prodNameIter++;
+		}
+	}
+	//choose production to which we will append the contents of deleted production
+	string prodNameToAppendTo = productionNames[randomN(productionNames.size())];
+	
+	int len = 0;
+	
+	Production* deletedProd = lsystem->productions[prodNameToDelete];
+	Production* appendProd = lsystem->productions[prodNameToAppendTo];
+	//add missing parameters
+	for (int i = 1; i <= deletedProd->parameters.size(); i++) {
+		SString paramName = deletedProd->parameters.getParameterName(i);
+		if (appendProd->parameters.paramExist(paramName) == false) {
+			appendProd->parameters.addParameter(paramName);
+		}
+	}
+	
+	//copy subproductions
+	for (vector<SubProduction>::iterator subprodIter = deletedProd->subproductions.begin();
+		 subprodIter != deletedProd->subproductions.end(); subprodIter++) {
+		SubProduction sp;
+		//copy conditions
+		for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
+			 condIter != (*subprodIter).conditions.end(); condIter++) {
+			Condition *cFrom = &(*condIter);
+			Condition cTo;
+			cTo.parameter = SString(cFrom->parameter);
+			cTo.relation = cFrom->relation;
+			cTo.value = cFrom->value;
+			sp.conditions.push_back(cTo);
+		}
+		for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
+			 actionIter != (*subprodIter).actions.end(); actionIter++) {
+			ActionStrP aFrom = *actionIter;
+			ActionStrP aTo;
+			aTo.action = aFrom.action;
+			aTo.params = vector<SString>(aFrom.params);
+			sp.actions.push_back(aTo);
+		}
+		appendProd->subproductions.push_back(sp);
+	}
+	lsystem->productions.erase(string(prodNameToDelete));
+	
+	int paramCount = appendProd->parameters.size();
+	for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
+		 prodIter != lsystem->productions.end(); prodIter++) {
+		for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
+			 subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
+			for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
+				 actionIter != (*subprodIter).actions.end(); actionIter++) {
+				if ((*actionIter).action != NULL && (*actionIter).action->name != NULL) { 
+					if ((*actionIter).action->name == stringToSString(prodNameToDelete)) {
+						(*actionIter).action = appendProd;
+						(*actionIter).params = vector<SString>(paramCount, SString("0;"));
+					}
+					if ((*actionIter).action->name == stringToSString(prodNameToAppendTo)) {
+						(*actionIter).action = appendProd;
+						SString paramVal = "0;";
+						for (int i = (*actionIter).params.size(); i < paramCount; i++) {
+							(*actionIter).params.push_back("0;");
+						}
+					}
+					
+				}
+			}
+		}
+	}
+	delete deletedProd;
+		
+	
+	mutated = lsystem->toString();
+	
+	delete lsystem;
+	
+	chg = (float) len / (float) in.len();
+	return mutated;
+}
+
 SString Geno_f8::mutateChangeConditionSign(SString &in, float& chg) {
 	SString mutated;
@@ -1016,4 +1136,7 @@
 		case F8_DELETE_LOOP:
 			ssMutatedTmp = this->mutateDeleteLoop(in, chg);
+			break;
+		case F8_DELETE_PRODUCTION:
+			ssMutatedTmp = this->mutateDeleteProduction(in, chg);
 			break;
 		default:
