source: cpp/f8-to-f1/geno_f8.cpp @ 8

Last change on this file since 8 was 8, checked in by mwajcht, 15 years ago

Returning GENOPER_OPFAIL in case mutation fails.

File size: 41.1 KB
Line 
1/*
2 *  geno_f8.cpp
3 *  L-systemToF1
4 *
5 *  Created by Maciej Wajcht on 08-06-07.
6 *  Copyright 2008 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10#include "geno_f8.h"
11#include <cstdlib>
12//#include <sys/time.h>
13#include "conv_f8tof1.h"
14#include "multimap.h"
15#include <iostream>
16#include <string>
17#include "sstringutils.h"
18#include "conv_f8_utils.h"
19
20#define GENO_F8_DEBUG 1 //0 - off, 1 - on
21
22#define FIELDSTRUCT Geno_f8
23
24static ParamEntry GENO8param_tab[]=
25{
26{"Genetics: f8",1,F8_OPERATION_COUNT,},
27{"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", },
28{"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", },
29{"f8_mut_del_comm", 0, 0, "Delete command", "f 0 100 8", FIELD(operation[F8_DELETE_COMMAND]),"mutation: probability of deleting a command", },
30{"f8_mut_insert_comm", 0, 0, "Insert commands", "f 0 100 9", FIELD(operation[F8_INSERT_COMMANDS]),"mutation: probability of inserting commands", },
31{"f8_mut_enc", 0, 0, "Encapsulate commands", "f 0 100 10",FIELD(operation[F8_ENCAPSULATE]),"mutation: probability of encapsulating commands", },
32{"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", },
33{"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", },
34{"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", },
35{"f8_mut_add_subprod", 0, 0, "Add subproduction", "f 0 100 8", FIELD(operation[F8_ADD_SUBPRODUCTION]),"mutation: probability of adding a subproduction", },
36{"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", },
37{"f8_mut_del_param", 0, 0, "Delete parameter", "f 0 100 8", FIELD(operation[F8_DELETE_PARAMETER]),"mutation: probability of deleting a parameter", },
38{"f8_mut_del_cond", 0, 0, "Delete condition", "f 0 100 8", FIELD(operation[F8_DELETE_CONDITION]),"mutation: probability of deleting a condition", },
39{"f8_mut_add_loop", 0, 0, "Add loop", "f 0 100 0", FIELD(operation[F8_ADD_LOOP]),"mutation: probability of ading a loop", },
40{"f8_mut_del_loop", 0, 0, "Delete loop", "f 0 100 0", FIELD(operation[F8_DELETE_LOOP]),"mutation: probability of deleting a loop", },
41{0,},
42};
43
44#undef FIELDSTRUCT
45
46ProductionInfo::ProductionInfo(SString name, int paramCount) {
47        this->name = name;
48        this->paramCount = paramCount;
49}
50
51Geno_f8::Geno_f8() {
52        supported_format = '8';
53        this->simpleCommandLetters.push_back('X');
54        this->simpleCommandLetters.push_back('R');
55        this->simpleCommandLetters.push_back('r');
56        this->simpleCommandLetters.push_back('C');
57        this->simpleCommandLetters.push_back('c');
58        this->simpleCommandLetters.push_back('Q');
59        this->simpleCommandLetters.push_back('q');
60        this->simpleCommandLetters.push_back('[');
61        this->simpleCommandLetters.push_back(']');
62        this->simpleCommandLetters.push_back('^');
63        this->converter = new GenoConv_F8ToF1();
64       
65        par.setParamTab(GENO8param_tab);
66        par.select(this);
67        par.setDefault();
68       
69        /*mutation_method_names = new char*[F8_OPERATION_COUNT - 1];
70        int index = 0;
71        mutation_method_names[index++]="changed beginning argument";
72        mutation_method_names[index++]="changed argument";
73        mutation_method_names[index++]="deleted command";
74        mutation_method_names[index++]="inserted command";
75        mutation_method_names[index++]="encapsulated command";
76        mutation_method_names[index++]="changed condition sign";
77        mutation_method_names[index++]="added parameter";
78        mutation_method_names[index++]="added condition";
79        mutation_method_names[index++]="added subproduction";
80        mutation_method_names[index++]="changed iterations number";
81        mutation_method_names[index++]="deleted parameter";
82        mutation_method_names[index++]="deleted condition";
83        mutation_method_names[index++]="added loop";
84        mutation_method_names[index++]="deleted loop";
85        */
86       
87#ifdef GENO_F8_DEBUG > 0
88        for (int i = 0; i < F8_OPERATION_COUNT; i++) {
89                this->operation[i] = 1.0 / (double)F8_OPERATION_COUNT;
90        }
91#endif
92}
93
94Geno_f8::~Geno_f8() {
95        delete this->converter;
96}
97
98int Geno_f8::checkValidity(const char * geno) {
99        SString ssgeno = SString(geno);
100        SString f1ssgeno = this->converter->convert(ssgeno, NULL);
101        const char* f1genosrc = f1ssgeno;
102        Geno f1geno(f1genosrc);
103        if (this->converter->checkSyntax(geno) && f1geno.isValid()) {
104                return GENOPER_OK;
105        } else {
106                return 1;
107        }
108}
109
110int Geno_f8::validate(char *& geno) {
111        SString in = geno;
112        SString validated = "";
113        SString line;
114        int pos = 0;
115        bool firstLine = true;
116        bool beforeDelim = true;
117        bool justAfterDelim = false;
118        while (in.getNextToken(pos, line, '\n')) {
119                if (firstLine) {
120                        firstLine = false;
121                        const char* str = geno;
122                        std::istringstream i(str);
123                        double x;
124                        if (i >> x) {
125                                validated += line + "\n";
126                        } else {
127                                validated += "10\n";
128                        }
129                } else if (beforeDelim) {
130                        if (line[0] == 'P' && line.indexOf('(') != -1 && line.indexOf(')') != -1 && line.indexOf(':') != -1) {
131                                validated += "---\n";
132                                validated += line + "\n";
133                                beforeDelim = false;
134                        }
135                        int eqSignPos = line.indexOf('=');
136                        if (line[0] == 'n' && eqSignPos != -1) {
137                                validated += line + "\n";
138                        } else if (line == SString("---")) {
139                                validated += line + "\n";
140                                beforeDelim = false;
141                                justAfterDelim = true;
142                        }
143                } else if (justAfterDelim && line[0] == 'P') {
144                        const char* digits = "0123456789";
145                        SString s = line.substr(1);
146                        bool ok = true;
147                        for (int i = 0; i < s.len(); i++) {
148                                if (!strContainsOneOf(s(i), digits)) {
149                                        ok = false;
150                                        break;
151                                }
152                        }
153                        if (ok) {
154                                validated += line +"\n";
155                        }
156                        justAfterDelim = false;
157                } else if (line[0] == 'P' && line.indexOf('(') != -1 && line.indexOf(')') != -1 && line.indexOf(':') != -1) {
158                        validated += line + "\n";
159                }
160        }
161        free(geno); //must take care of the original allocation
162        char* validatedTmp = (char*)malloc(strlen(validated) + 1); //allocate for mutated genotype
163        strcpy(validatedTmp, validated); //the rest is originalg = mutated;
164        geno = validatedTmp;
165       
166        return GENOPER_OK;
167}
168
169int Geno_f8::getProductionsCount(const SString &in) {
170        int pos = 0;
171        SString line;
172        int counter = 0;
173        bool beforeDelim = true;
174        while (in.getNextToken(pos, line, '\n')) {
175                if (line.startsWith("---")) {
176                        beforeDelim = false;
177                        //also skip the start production
178                        in.getNextToken(pos, line, '\n');
179                        continue;
180                } else if (beforeDelim) {
181                        continue;
182                } else {
183                        counter++;
184                }                               
185        }
186        return counter;
187}
188
189vector<ProductionInfo> Geno_f8::getProductionsInfo(const SString &in) {
190        vector<ProductionInfo> productions;
191        SString line;
192        int pos = 0;
193        bool beforeFirstProd = true;
194        SString firstProdName;
195        while (in.getNextToken(pos, line, '\n')) {
196                if (line.startsWith("P") && line.indexOf('(', 0) == -1) {
197                        firstProdName = line;
198                        beforeFirstProd = false;
199                        continue;
200                }
201                if (beforeFirstProd) {
202                        continue;
203                }
204                int lParenIndex = line.indexOf('(', 0);
205                int rParenIndex = line.indexOf(')', 0);
206                if (line[0] == 'P' && lParenIndex != -1 && rParenIndex != -1) {
207                        ProductionInfo info;
208                        SString prodName = line.substr(0, lParenIndex);
209                        info.name = prodName;
210                        info.paramCount = 0;
211                        //if (line[lParenIndex + 1] == 'n') {
212                        SString strParams = line.substr(lParenIndex + 1, rParenIndex - lParenIndex - 1);
213                        int pos2 = 0;
214                        SString tok;
215                        while (strParams.getNextToken(pos2, tok, ',')) {
216                                info.paramCount++;
217                                info.paramNames.push_back(tok);
218                        }
219                        //}
220                        info.isFirstProduction = (prodName == firstProdName) ? true : false;
221                        productions.push_back(info);
222                }
223        }
224        return productions;
225}
226
227SString Geno_f8::mutateChangeBeginningArg(SString &in, float& chg) {
228        SString mutated, line, before, mid, after, tmp;
229        int counter = 0;
230        int pos = 0;
231        bool afterDelim = false;
232        bool firstLine = true;
233        while (in.getNextToken(pos, line, '\n')) {
234                if (firstLine) {
235                        firstLine = false;
236                        before += line + "\n";
237                        continue;
238                }
239                if (afterDelim) {
240                        after += line + "\n";
241                        continue;
242                }
243                if (line.startsWith("---")) {
244                        afterDelim = true;
245                        after += line + "\n";                                   
246                } else {
247                        mid += line + "\n";
248                        counter++;
249                }                               
250        }
251        if (counter == 0) {
252                chg = 0.0;
253                mutated = in;
254        } else {
255                int randNbr = randomN(counter);
256                pos = 0;
257                counter = 0;
258                while (mid.getNextToken(pos, line, '\n')) {
259                        if (counter++ == randNbr) {
260                                int pos2 = 0;
261                                SString tok;
262                                line.getNextToken(pos2, tok, '=');
263                                tmp += tok + "=";
264                                line.getNextToken(pos2, tok, '=');
265                                double arg = parseDouble(tok);
266                                arg += (double) (randomN(11) - 5); //-5..5
267                                tmp += SString::valueOf(arg) + "\n";
268                                chg = (float) (SString::valueOf(arg).len()) / (float) in.len();
269                        } else {
270                                tmp += line + "\n";
271                        }
272                }
273                mid = tmp;
274                mutated += before;
275                mutated += mid;
276                mutated += after;
277        }
278        return mutated;
279}
280
281SString Geno_f8::mutateChangeArg(SString &in, float& chg) {
282        SString mutated;
283       
284        Lsystem *newLsystem = this->converter->createLsystem(in);
285        if (newLsystem == NULL) {
286                mutated += in;
287                chg = 0.0;
288                return mutated;
289        }
290       
291        vector<Production*> interestingProductions;
292       
293        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
294                 prodIter != newLsystem->productions.end(); prodIter++) {
295                if (prodIter->second->parameters.size() > 0) {
296                        interestingProductions.push_back(prodIter->second);
297                }
298        }
299       
300        if (interestingProductions.size() > 0) {
301                int rnd = randomN(interestingProductions.size());
302               
303                Production *randomProduction = interestingProductions[rnd];
304                SString prodName = randomProduction->name;
305               
306                int paramIndex = randomN(randomProduction->parameters.size());
307               
308                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
309                         prodIter != newLsystem->productions.end(); prodIter++) {
310                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
311                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
312                                 subProdIter != subproductions->end(); subProdIter++) {
313                                SubProduction *sp = &(*subProdIter);
314                                for (vector<ActionStrP>::iterator actionIter = sp->actions.begin();
315                                         actionIter != sp->actions.end(); actionIter++) {
316                                        if ((*actionIter).action != NULL && (*actionIter).action->name == prodName && (*actionIter).params.size() > paramIndex) {
317                                                SString param = (*actionIter).params[paramIndex];
318                                                int counter = 0;
319                                                int pos = 0;
320                                                SString tok;
321                                                while (in.getNextToken(pos, tok, ',')) {
322                                                        counter++;
323                                                }
324                                                int rnd = randomN(counter);
325                                                pos = 0;
326                                                counter = 0;
327                                                SString newParam = "";
328                                                if (randomN(2) == 0 || prodIter->second->parameters.size() == 0) {
329                                                        int rnd2 = randomN(5) + 1;
330                                                        newParam += param + SString::valueOf(rnd2) + ";";
331                                                } else {
332                                                        SString paramName = prodIter->second->parameters.getParameterName(randomN(prodIter->second->parameters.size())+1);
333                                                        newParam += param + paramName + ";";
334                                                }
335                                                newParam += (rnd == 0) ? SString("+;") : SString("-;");
336                                                (*actionIter).params[paramIndex] = newParam;
337                                                goto label;
338                                        }
339                                }
340                        }
341                }
342        label:
343                chg = 2.0 / (float) in.len();
344        }
345       
346        mutated = newLsystem->toString();
347       
348        delete newLsystem;
349       
350        return mutated;
351}
352
353SString Geno_f8::mutateDeleteCommand(SString &in, float& chg) {
354        SString mutated;
355       
356        Lsystem *lsystem = this->converter->createLsystem(in);
357        if (lsystem == NULL) {
358                mutated += in;
359                chg = 0.0;
360                return mutated;
361        }
362       
363        map<string, Production*>::iterator prodIter = lsystem->productions.begin();
364        for (int i = 0; i < randomN(lsystem->productions.size()); i++) {
365                if (i != 0) {
366                        prodIter++;
367                }
368        }
369       
370        Production *randomProduction = prodIter->second;
371        if (randomProduction->subproductions.size() > 0) {
372                vector<ActionStrP> *actions = &(randomProduction->subproductions.at(randomN(randomProduction->subproductions.size())).actions);
373                int rnd = randomN(actions->size());
374                if (actions->size() > 0) {
375                        Action *a = actions->at(rnd).action;
376                        if (a != NULL) {
377                                chg = (float) (a->getF8Representation().len()) / (float) in.len();
378                                actions->erase(actions->begin() + rnd);
379                        }
380                }
381        }
382       
383        mutated = lsystem->toString();
384       
385        delete lsystem;
386       
387        return mutated;
388}
389
390SString Geno_f8::mutateInsertCommands(SString &in, float& chg) {
391        SString mutated;
392       
393        //cout << "insertCommands 1" << endl;
394        Lsystem *lsystem = this->converter->createLsystem(in);
395        if (lsystem == NULL) {
396                mutated += in;
397                chg = 0.0;
398                return mutated;
399        }
400       
401        //cout << "insertCommands 2" << endl;
402        vector<Action*> actions = lsystem->getAllActions(true, true, false, false);
403        //cout << "insertCommands 3" << endl;
404       
405        int random1 = randomN(lsystem->productions.size());
406       
407        map<string, Production*>::iterator prodIter = lsystem->productions.begin();
408        for (int counter = 0; counter < random1; counter++) {
409                prodIter++;
410        }
411        //cout << "insertCommands 4" << endl;
412       
413        Production *p = prodIter->second;
414        SubProduction *sp = &(p->subproductions.at(randomN(p->subproductions.size())));
415       
416        int commandsToInsert = /*randomN(3) +*/ 1;
417        int insertLen = 0;
418        for (int i = 0; i < commandsToInsert; i++) {
419                ActionStrP a;
420                a.action = actions.at(randomN(actions.size()));
421                insertLen += a.action->getF8Representation().len();
422                if (a.action->ignoreParams == false && a.action->name[0] == 'P') {
423                        Production *p = (Production*) a.action;
424                        insertLen += 2;
425                        for (int j = 0; j < p->parameters.size(); j++) {
426                                int rnd = randomN(p->parameters.size() + 1);
427                                if (rnd == 0) {
428                                        a.params.push_back(SString("0;"));
429                                        insertLen += 1;
430                                } else {
431                                        SString s = p->parameters.getParameterName(randomN(p->parameters.size()) + 1);
432                                        a.params.push_back(s + ";");
433                                        insertLen += s.len();
434                                }
435                        }
436                }
437                sp->actions.push_back(a);
438        }
439        //cout << "insertCommands 5" << endl;
440       
441        mutated = lsystem->toString();
442        //cout << "insertCommands 6" << endl;
443        chg = (float) insertLen / (float) in.len();
444       
445        delete lsystem;
446        //cout << "insertCommands 7" << endl;
447                       
448        return mutated;
449}
450
451SString Geno_f8::mutateEncapsulate(SString &in, float& chg) {
452        SString mutated;
453       
454        Lsystem *lsystem = this->converter->createLsystem(in);
455        if (lsystem == NULL) {
456                mutated += in;
457                chg = 0.0;
458                return mutated;
459        }
460       
461        int counter = 0;
462        int rnd = randomN(lsystem->productions.size());
463        int len = 0;
464       
465        Production *p = new Production();
466        p->subproductions.push_back(SubProduction());
467        SubProduction *newSubProd = &(p->subproductions.back());
468       
469        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
470                 prodIter != lsystem->productions.end(); prodIter++) {
471                if (counter++ == rnd) {
472                        ParameterCollection *params = &(prodIter->second->parameters);
473                        //copy parameters to the encapsulated production
474                        for (int i = 1; i <= params->size(); i++) {
475                                p->parameters.addParameter(params->getParameterName(i));
476                        }
477                       
478                        SubProduction *subproduction = &(prodIter->second->subproductions[randomN(prodIter->second->subproductions.size())]);
479                        int firstActionIdx = randomN(subproduction->actions.size());
480                        int i;
481                        vector<ActionStrP> newActions;
482                        for (i = 0; i < firstActionIdx; i++) {
483                                newActions.push_back(subproduction->actions[i]);
484                        }
485                        for (i = firstActionIdx; i <= firstActionIdx + randomN(4) + 1
486                                 && i < subproduction->actions.size(); i++) { //1..4 actions
487                                newSubProd->actions.push_back(subproduction->actions[i]);
488                                if (subproduction->actions[i].action != NULL) {
489                                        len += subproduction->actions[i].action->getF8Representation().len();
490                                }
491                        }
492                        ActionStrP a;
493                        a.action = p;
494                        a.params = vector<SString>();
495                        for (int j = 0; j < params->size(); j++) {
496                                //a.params.push_back(SString("0;"));
497                                a.params.push_back(params->getParameterName(j + 1));
498                        }
499                        newActions.push_back(a);
500                        while (i < subproduction->actions.size()) {
501                                if (subproduction->actions[i].action != NULL) {
502                                        newActions.push_back(subproduction->actions[i]);
503                                }
504                                i++;
505                        }
506                        subproduction->actions = newActions;
507                        break;
508                }               
509        }
510       
511        SString newName;
512        for (int i = 0; i < 100000; i++) {
513                newName = "P";
514                newName += SString::valueOf(i);
515                if (lsystem->productions[sstringToString(newName)] == NULL) {
516                        break;
517                }
518        }       
519        p->name = newName;
520        lsystem->productions[sstringToString(newName)] = p;
521       
522        mutated = lsystem->toString();
523       
524        delete lsystem;
525       
526        chg = (float) len / (float) in.len();
527        return mutated;
528}
529
530SString Geno_f8::mutateChangeConditionSign(SString &in, float& chg) {
531        SString mutated;
532       
533        Lsystem *newLsystem = this->converter->createLsystem(in);
534        if (newLsystem == NULL) {
535                mutated += in;
536                chg = 0.0;
537                return mutated;
538        }
539       
540        map<int, SubProduction*> interestingSubproductions;
541        int counter = 0;
542       
543        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
544                 prodIter != newLsystem->productions.end(); prodIter++) {
545                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
546                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
547                        SubProduction *sp = &(*subprodIter);
548                        if (sp->conditions.size() > 0) {
549                                interestingSubproductions[counter++] =  sp;
550                        }
551                }
552        }
553       
554        if (interestingSubproductions.size() > 0) {
555                int random1 = randomN(interestingSubproductions.size());
556                SubProduction *randomSubproduction = interestingSubproductions[random1];
557                int random2 = randomN(randomSubproduction->conditions.size());
558                Condition *c = &(randomSubproduction->conditions.at(random2));
559                c->relation = this->getDifferentCondition(c->relation);
560                chg = 2.0 / (float) in.len();
561        }
562       
563        mutated = newLsystem->toString();
564       
565        delete newLsystem;
566       
567        return mutated;
568}
569
570SString Geno_f8::mutateAddParameter(SString &in, float& chg) {
571        SString mutated;
572       
573        Lsystem *lsystem = this->converter->createLsystem(in);
574        if (lsystem == NULL) {
575                mutated += in;
576                chg = 0.0;
577                return mutated;
578        }
579       
580        //cout << "addParameter 1" << endl;
581        int rnd = randomN(lsystem->productions.size());
582        int chglen = 0;
583       
584        SString prodName = "";
585       
586        int counter = 0;
587        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
588                 prodIter != lsystem->productions.end(); prodIter++) {
589                if (counter++ == rnd) {
590                        prodName = prodIter->second->name;
591                        SString newParam;
592                        for (int i = 0; i < 10000; i++) {
593                                newParam = "n";
594                                newParam += SString::valueOf(i);
595                                if (!prodIter->second->parameters.paramExist(newParam)) {
596                                        prodIter->second->parameters.addParameter(newParam);
597                                        chglen += newParam.len();
598                                        break;
599                                }
600                        }
601                       
602                        if (prodName == stringToSString(lsystem->firstProductionName)) {
603                                lsystem->startParams[sstringToString(newParam)] = 0.0;
604                        }
605                        break;
606                }
607        }
608        //cout << "addParameter 2" << endl;
609        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
610                 prodIter != lsystem->productions.end(); prodIter++) {
611                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
612                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
613                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
614                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
615                                if ((*actionIter).action != NULL && (*actionIter).action->name != NULL) {
616                                        if ((*actionIter).action->name == prodName) {
617                                                int randParamVal = randomN(prodIter->second->parameters.size() + 1);
618                                                SString paramVal = NULL;
619                                                if (randParamVal == 0) {
620                                                        paramVal = "0;";
621                                                } else {
622                                                        paramVal = prodIter->second->parameters.getParameterName(randParamVal) + ";";
623                                                }
624                                                //(*actionIter).params.push_back(paramVal);
625                                                chglen += 2;
626                                        }
627                                }
628                        }
629                }
630        }
631        //cout << "addParameter 3" << endl;
632       
633        mutated = lsystem->toString();
634        //cout << "addParameter 4" << endl;
635       
636        delete lsystem;
637       
638        chg = (float) chglen / (float) in.len();
639        return mutated;
640}
641
642SString Geno_f8::mutateAddCondition(SString &in, float& chg) {
643        SString mutated, before, mid, after, line;
644        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
645        vector<int> interestingProductions;
646        for (int i = 0; i < prodInfo.size(); i++) {
647                if (prodInfo[i].paramNames.size() > 0) {
648                        interestingProductions.push_back(i);
649                }
650        }
651        if (interestingProductions.size() == 0) {
652                chg = 0.0;
653                mutated = in;
654                return mutated;
655        }
656        int rndProd = interestingProductions[randomN(interestingProductions.size())];
657        int pos = 0;
658        mutated = "";
659        while (in.getNextToken(pos, line, '\n')) {
660                if (line.startsWith(prodInfo[rndProd].name) && line.len() > prodInfo[rndProd].name.len()) {
661                        int subproductionsCount = -1;
662                        SString tok;
663                        int pos2 = 0;
664                        while (line.getNextToken(pos2, tok, ':')) {
665                                subproductionsCount++;
666                        }
667                        if (subproductionsCount == 0) {
668                                chg = 0.0;
669                                mutated = in;
670                                return mutated;
671                        }
672                        int rnd = randomN(subproductionsCount);
673                        int counter = 0;
674                        int colonIdx = line.indexOf(':', 0);
675                        pos2 = colonIdx;
676                        while (counter != rnd) {
677                                colonIdx = line.indexOf(':', pos2 + 1);
678                                counter++;
679                        }
680                       
681                        int nextColonIdx = line.indexOf(':', colonIdx + 1);
682                        if (nextColonIdx == -1) {
683                                nextColonIdx = 2147483646;
684                        }
685                        int pipeIdx = line.indexOf('|', colonIdx + 1);
686                        mid = "";
687                        if (pipeIdx < nextColonIdx && pipeIdx != -1) {
688                                //before += line.substr(colonIdx + 1, pipeIdx - colonIdx - 1);
689                                before = line.substr(0, pipeIdx);
690                                mid += ",";
691                                after = line.substr(pipeIdx);                           
692                        } else {
693                                before = line.substr(0, colonIdx + 1);
694                                after = SString("|") + line.substr(colonIdx + 1);
695                        }
696                        int paramIdx = (int) randomN(prodInfo[rndProd].paramNames.size());
697                        mid += prodInfo[rndProd].paramNames[paramIdx];
698                        mid += (randomN(2) == 0) ? ">" : "<";
699                        mid += SString::valueOf((int) randomN(21) - 10);
700                       
701                        mutated += before + mid + after + "\n";
702                        chg = (float) mid.len() / (float)in.len();
703                } else {
704                        mutated += line + "\n";
705                }
706        }
707        return mutated;
708}
709
710SString Geno_f8::mutateDeleteParameter(SString &in, float& chg) {
711        SString mutated;
712       
713        Lsystem *newLsystem = this->converter->createLsystem(in);
714        if (newLsystem == NULL) {
715                mutated += in;
716                chg = 0.0;
717                return mutated;
718        }
719               
720        map<int, Production*> interestingProductions;
721        int counter = 0;
722       
723        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
724                        prodIter != newLsystem->productions.end(); prodIter++) {
725                if (prodIter->second->parameters.size() > 0) {
726                        interestingProductions[counter++] =  prodIter->second;
727                }
728        }
729       
730        if (interestingProductions.size() > 0) {
731                int rnd = randomN(interestingProductions.size());
732               
733                Production *randomProduction = interestingProductions[rnd];
734                SString prodName = randomProduction->name;
735               
736                int paramIndex = randomN(randomProduction->parameters.size()) + 1;
737                SString paramName = randomProduction->parameters.getParameterName(paramIndex);
738                string sparamName = sstringToString(paramName);
739                int change = paramName.len();
740               
741                randomProduction->parameters.removeParameter(paramName);
742               
743                if (prodName == stringToSString(newLsystem->firstProductionName)) {
744                        newLsystem->startParams.erase(sstringToString(paramName));
745                }
746               
747                for (vector<SubProduction>::iterator subProdIter = randomProduction->subproductions.begin();
748                                subProdIter != randomProduction->subproductions.end(); subProdIter++) {
749                        for (int condIter = 0; condIter < (*subProdIter).conditions.size(); condIter++) {
750                                Condition c = (*subProdIter).conditions[condIter];
751                                if (c.parameter == paramName) {
752                                        (*subProdIter).conditions.erase((*subProdIter).conditions.begin() + condIter);
753                                }
754                        }
755                        for (vector<ActionStrP>::iterator actionIter = (*subProdIter).actions.begin();
756                                        actionIter != (*subProdIter).actions.end(); actionIter++) {
757                                for (vector<SString>::iterator paramIter = (*actionIter).params.begin();
758                                                paramIter != (*actionIter).params.end(); paramIter++) {
759                                        string s = sstringToString(*paramIter);
760                                        if (s.find(sparamName, 0) != string::npos) {
761                                                *paramIter = SString("0;");
762                                        }
763                                }
764                        }
765                }
766                               
767                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
768                                prodIter != newLsystem->productions.end(); prodIter++) {
769                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
770                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
771                                subProdIter != subproductions->end(); subProdIter++) {
772                                SubProduction *sp = &(*subProdIter);
773                                for (int actionIter = 0; actionIter < sp->actions.size(); actionIter++) {
774                                        ActionStrP *actionstrp = &(sp->actions.at(actionIter));
775                                        if (actionstrp->action != NULL) {
776                                                if (actionstrp->action->name == prodName && actionstrp->params.size() > paramIndex - 1) {
777                                                        change += paramName.len(); //more less
778                                                        actionstrp->params.erase(actionstrp->params.begin() + (paramIndex - 1));
779                                                }
780                                        }
781                                }
782                        }
783                }
784                chg = (float) change / (float) in.len();
785        }
786       
787        mutated = newLsystem->toString();
788       
789        delete newLsystem;
790       
791        return mutated;
792}
793
794SString Geno_f8::mutateDeleteCondition(SString &in, float& chg) {
795        SString mutated;
796       
797        Lsystem *newLsystem = this->converter->createLsystem(in);
798        if (newLsystem == NULL) {
799                mutated += in;
800                chg = 0.0;
801                return mutated;
802        }
803               
804        map<int, SubProduction*> interestingSubproductions;
805        int counter = 0;
806       
807        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
808                 prodIter != newLsystem->productions.end(); prodIter++) {
809                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
810                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
811                        SubProduction *sp = &(*subprodIter);
812                        if (sp->conditions.size() > 0) {
813                                interestingSubproductions[counter++] =  sp;
814                        }
815                }
816        }
817       
818        if (interestingSubproductions.size() > 0) {
819                int rnd = randomN(interestingSubproductions.size());
820                SubProduction *randomSubproduction = interestingSubproductions[rnd];
821                vector<Condition>::iterator condIter = randomSubproduction->conditions.begin();
822                condIter += randomN(randomSubproduction->conditions.size() - 1);
823                Condition c = *condIter;
824                chg = (float) (c.parameter.len() + 1 + SString::valueOf(c.value).len()) / (float) in.len();
825                randomSubproduction->conditions.erase(condIter);
826        }
827       
828        mutated = newLsystem->toString();
829       
830        delete newLsystem;
831       
832        return mutated;
833}
834
835SString Geno_f8::mutateAddLoop(SString &in, float& chg) {
836        /*
837         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
838         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
839         */
840        SString mutated, line;
841        int pos = 0;
842        while (in.getNextToken(pos, line, '\n')) {
843                mutated += line + "\n";
844        }
845        chg = 0.0;
846        return mutated;
847}
848
849SString Geno_f8::mutateDeleteLoop(SString &in, float& chg) {
850        /*
851         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
852         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
853         */
854        SString mutated, line;
855        int pos = 0;
856        while (in.getNextToken(pos, line, '\n')) {
857                mutated += line + "\n";
858        }
859        chg = 0.0;
860        return mutated;
861}
862
863SString Geno_f8::mutateAddSubproduction(SString &in, float& chg) {
864        SString mutated, line;
865        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
866        int rndProd = randomN(prodInfo.size());
867        int pos = 0;
868        mutated = "";
869        while (in.getNextToken(pos, line, '\n')) {
870                if (line.startsWith(prodInfo[rndProd].name) && line.indexOf(':', 0) != -1) {
871                        SString tmp = ":";
872                        int paramCount = prodInfo[rndProd].paramNames.size();
873                        if (paramCount > 0) {
874                                tmp += prodInfo[rndProd].paramNames[(int) randomN(paramCount)];
875                                tmp += (randomN(2) == 0) ? ">" : "<";
876                                tmp += SString::valueOf((int) randomN(21) - 10);
877                                tmp += "|";
878                        }
879                        tmp += "X\n";
880                        chg = (float) tmp.len() / (float) in.len();
881                        mutated += line + tmp;
882                } else {
883                        mutated += line + "\n";
884                }
885        }
886        return mutated;
887}
888
889SString Geno_f8::mutateChangeIterationsNumber(SString &in, float& chg) {
890        SString mutated;       
891        Lsystem *newLsystem = this->converter->createLsystem(in);
892        if (newLsystem == NULL) {
893                mutated += in;
894                chg = 0.0;
895                return mutated;
896        }
897       
898        newLsystem->iterations += randomN(7) - 3; //-3..3
899        if (newLsystem->iterations < 1) {
900                newLsystem->iterations = 1;
901        }
902        mutated = newLsystem->toString();       
903        delete newLsystem;     
904        chg = 1.0 / (float) in.len();
905        return mutated;
906}
907
908int Geno_f8::mutate(char *&g,float& chg, int &method) {
909        SString in = g;
910       
911        /*struct timeval tv;
912        gettimeofday(&tv, NULL);
913        srandom(tv.tv_sec + tv.tv_usec);
914        */
915        method = roulette(this->operation, F8_OPERATION_COUNT);
916        if (method < 0) {
917                return GENOPER_OPFAIL;
918        }
919       
920#if GENO_F8_DEBUG > 0
921        string mutationName = (method == 0) ? "F8_CHANGE_BEGINNING_ARG" :
922        (method == 1) ? "F8_CHANGE_ARG" :
923        (method == 2) ? "F8_DELETE_COMMAND" :
924        (method == 3) ? "F8_INSERT_COMMANDS" :
925        (method == 4) ? "F8_ENCAPSULATE" :
926        (method == 5) ? "F8_CHANGE_CONDITION_SIGN" :
927        (method == 6) ? "F8_REPLACE_COMMAND" :
928        (method == 7) ? "F8_ADD_PARAMETER" :
929        (method == 8) ? "F8_ADD_CONDITION" :
930        (method == 9) ? "F8_ADD_SUBPRODUCTION" :
931        (method == 10) ? "F8_CHANGE_ITERATIONS_NUMBER" :
932        (method == 11) ? "F8_DELETE_PARAMETER" :
933        (method == 12) ? "F8_DELETE_CONDITION" :
934        (method == 13) ? "F8_ADD_LOOP" :
935        (method == 14) ? "F8_DELETE_LOOP" :
936        (method == 15) ? "F8_OPERATION_COUNT" : "babol";
937        //cout << "-------------------- " << mutationName << " --------------------" << endl;
938#endif
939       
940        const char* mutatedTmp;
941        SString ssMutatedTmp;
942       
943        //cout << "mutate 1" << endl;
944        //TODO dodac parametr ok, mowiacy, czy wszystko bylo ok
945        switch (method) {
946                case F8_CHANGE_BEGINNING_ARG:
947                        ssMutatedTmp = this->mutateChangeBeginningArg(in, chg);
948                        break;
949                case F8_CHANGE_ARG:
950                        ssMutatedTmp = this->mutateChangeArg(in, chg);
951                        break;
952                case F8_DELETE_COMMAND:
953                        ssMutatedTmp = this->mutateDeleteCommand(in, chg);
954                        break;
955                case F8_INSERT_COMMANDS:
956                        ssMutatedTmp = this->mutateInsertCommands(in, chg);
957                        break;
958                case F8_ENCAPSULATE:
959                        ssMutatedTmp = this->mutateEncapsulate(in, chg);
960                        break;
961                case F8_CHANGE_CONDITION_SIGN:
962                        ssMutatedTmp = this->mutateChangeConditionSign(in, chg);
963                        break;
964                /*case F8_REPLACE_COMMAND:
965                        ssMutatedTmp = this->mutateReplaceCommand(in, chg);
966                        break;*/
967                case F8_ADD_PARAMETER:
968                        ssMutatedTmp = this->mutateAddParameter(in, chg);
969                        break;
970                case F8_ADD_CONDITION:
971                        ssMutatedTmp = this->mutateAddCondition(in, chg);
972                        break;
973                case F8_ADD_SUBPRODUCTION:
974                        ssMutatedTmp = this->mutateAddSubproduction(in, chg);
975                        break;
976                case F8_CHANGE_ITERATIONS_NUMBER:
977                        ssMutatedTmp = this->mutateChangeIterationsNumber(in, chg);
978                        break;
979                case F8_DELETE_PARAMETER:
980                        ssMutatedTmp = this->mutateDeleteParameter(in, chg);
981                        break;
982                case F8_DELETE_CONDITION:
983                        ssMutatedTmp = this->mutateDeleteCondition(in, chg);
984                        break;
985                case F8_ADD_LOOP:
986                        ssMutatedTmp = this->mutateAddLoop(in, chg);
987                        break;
988                case F8_DELETE_LOOP:
989                        ssMutatedTmp = this->mutateDeleteLoop(in, chg);
990                        break;
991                default:
992                        return GENOPER_OPFAIL;
993        }
994       
995        //cout << "mutate 2" << endl;
996        if (ssMutatedTmp.len() < 16) {
997                return GENOPER_OPFAIL;
998        }
999       
1000        mutatedTmp = ssMutatedTmp;
1001       
1002        if (this->checkValidity(mutatedTmp) == GENOPER_OK) {
1003                free(g); //must take care of the original allocation
1004                g = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1005                strcpy(g, mutatedTmp); //the rest is originalg = mutated;
1006                //cout << "mutate 3" << endl;
1007                return GENOPER_OK;
1008        } else {
1009                chg = 0.0;
1010                return GENOPER_OPFAIL;
1011        }
1012}
1013
1014int Geno_f8::crossOver(char *&g1,char *&g2,float& chg1,float& chg2) {
1015        /* wymiana niewielkiej (max. 25%) ilości odpowiadającej sobie informacji
1016         * ma to przypominać "celowaną" mutację, w której osobnik dostaje
1017         * niewiele wiedzy, która sprawdziła się u innego osobnika
1018         */
1019        SString in1 = g1;
1020        SString in2 = g2;
1021        SString mutated;
1022        //SString dst;
1023        //const char* src = in;
1024        //const char* t;
1025       
1026        Lsystem *newLsystem = this->converter->createLsystem(in1);
1027        Lsystem *lsystem2 = this->converter->createLsystem(in2);
1028        if (newLsystem == NULL || lsystem2 == NULL) {
1029                chg1 = 0.0;
1030                chg2 = 0.0;
1031                return GENOPER_OPFAIL;
1032        }
1033       
1034        //shuffle second parent's productions
1035        vector<int> indices;
1036        for (int i = 0; i < lsystem2->productions.size(); i++) {
1037                indices.push_back(i);
1038        }
1039        map<string, Production*> shuffledProductions;
1040        while (!indices.empty()) {
1041                int rnd = randomN(indices.size());
1042                int counter = 0;
1043                //Production *p;
1044                for (map<string, Production*>::iterator it = lsystem2->productions.begin();
1045                         it != lsystem2->productions.end(); it++) {
1046                        if (counter == rnd) {
1047                                //p = it->second;
1048                                shuffledProductions[it->first] = it->second;
1049                                break;
1050                        }
1051                }
1052                //delete index number
1053                indices.erase(indices.begin() + rnd);
1054        }
1055       
1056        int productionCount = randomN(min(newLsystem->productions.size() / 4, lsystem2->productions.size())) + 1;
1057       
1058        int counter = 0;
1059        for (map<string, Production*>::iterator it = shuffledProductions.begin();
1060                 it != shuffledProductions.end() || counter < productionCount; it++) {
1061                //if selected production's name exist in the first parent
1062                if (newLsystem->productions.find(it->first) != newLsystem->productions.end()) {
1063                        newLsystem->productions[it->first]->subproductions = it->second->subproductions;
1064                        counter++;
1065                } else {
1066                        /* This fragment is commented out because we are interested only in matching productions ///////
1067                        //search for first production, which name does not exist in one of the productions
1068                        //selected from second parent
1069                        //this is to avoid information loss when new subproductions will be overwritten
1070                        //just after adding to the child production
1071                        for (map<string, Production*>::iterator it2 = newLsystem->productions.begin();
1072                                 it2 != newLsystem->productions.end(); it2++) {
1073                                if (shuffledProductions.find(it2->first) == shuffledProductions.end()) { //not found
1074                                        it2->second->subproductions = it->second->subproductions;
1075                                        break;
1076                                }
1077                                //there are no "else" because there is at least twice as many productions
1078                                //in the first parent as selected productions from the second parent
1079                                //so always we will find "free" production name
1080                        }*/
1081                }               
1082        }
1083       
1084        //check validity of productions indicated in actions
1085        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
1086                 prodIter != newLsystem->productions.end(); prodIter++) {
1087                vector<SString> paramNames;
1088                for (int i = 1; i <= prodIter->second->parameters.size(); i++) {
1089                        paramNames.push_back(prodIter->second->parameters.getParameterName(i));
1090                }
1091                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
1092                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
1093                        //conditions
1094                        for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
1095                                 condIter != (*subprodIter).conditions.end(); condIter++) {
1096                                vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1097                                                                                                                        (*condIter).parameter);
1098                                if (searchIter == paramNames.end()) { //unknown parameter name!
1099                                        //choose random existing parameter
1100                                        (*condIter).parameter = paramNames[randomN(paramNames.size())];
1101                                }
1102                        }
1103                       
1104                        //actions
1105                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
1106                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
1107                                SString &actionName = (*actionIter).action->name;
1108                                if (actionName[0] == 'n') {
1109                                        vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1110                                                                                                                                actionName);
1111                                        if (searchIter != paramNames.end()) { //valid name
1112                                                //ensure it is linked to the correct production
1113                                                (*actionIter).action = newLsystem->getParamProduction(actionName);
1114                                        } else {
1115                                                //link to random parameter prodution
1116                                                SString name = paramNames[randomN(paramNames.size())];
1117                                                (*actionIter).action = newLsystem->getParamProduction(name);
1118                                        }
1119                                } else if (actionName[0] == 'P') {
1120                                        if (newLsystem->productions.find(sstringToString(actionName)) != newLsystem->productions.end()) {
1121                                                //ensure it is linked to the correct production
1122                                                (*actionIter).action = newLsystem->productions[sstringToString(actionName)];
1123                                        } else {
1124                                                //delete this action
1125                                                (*subprodIter).actions.erase(actionIter);
1126                                        }
1127                                }
1128                        }
1129                        if ((*subprodIter).actions.size() == 0) { //we erased all the actions
1130                                ActionStrP a;
1131                                a.action = newLsystem->getPrimitiveProduction(SString("X"));
1132                                (*subprodIter).actions.push_back(a);
1133                        }
1134                }
1135        }
1136       
1137        mutated = newLsystem->toString();
1138       
1139        shuffledProductions.clear();
1140       
1141        delete newLsystem;
1142        delete lsystem2;
1143       
1144        free(g1); //must take care of the original allocation
1145        //free(g2);
1146        const char* mutatedTmp = mutated;
1147        char* mutatedTmp2 = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1148    strcpy(mutatedTmp2, mutatedTmp); //the rest is originalg = mutated;
1149        g1 = mutatedTmp2;
1150        chg1 = 0.5;
1151       
1152        return GENOPER_OK;     
1153}
1154
1155unsigned long Geno_f8::style(const char *g, int pos) {
1156        return GENSTYLE_RGBS(0, 0, 0, GENSTYLE_NONE);
1157}
1158
1159char* Geno_f8::getSimplest() {
1160        const char* geno = "1\n---\nP0\nP0():X\n";
1161        char* retGeno = (char*)malloc(strlen(geno) + 1);
1162        strcpy(retGeno, geno);
1163        return retGeno;
1164}
1165
1166bool Geno_f8::checkProdNameExist(vector<ProductionInfo> info, SString name) const {
1167        for (vector<ProductionInfo>::iterator it = info.begin(); it != info.end(); it++) {
1168                if ((*it).name == name) {
1169                        return true;
1170                }
1171        }
1172        return false;
1173}
1174
1175bool Geno_f8::checkParamNameExist(vector<SString> names, SString name) const {
1176        for (vector<SString>::iterator it = names.begin(); it != names.end(); it++ ) {
1177                if ((*it) == name) {
1178                        return true;
1179                }
1180        }
1181        return false;
1182}
1183
1184SString Geno_f8::getOppositeCondition(const SString &c) const {
1185        if (c.equals("=="))
1186                return "!=";
1187        if (c.equals("!="))
1188                return "==";
1189        if (c.equals(">"))
1190                return "<=";
1191        if (c.equals("<"))
1192                return ">=";
1193        if (c.equals(">="))
1194                return "<";
1195        if (c.equals("<="))
1196                return ">";
1197        return "<"; //default
1198}
1199
1200RelationType Geno_f8::getDifferentCondition(RelationType type) {
1201        RelationType types[6];
1202        types[0] = r_greater;
1203        types[1] = r_greaterEqual;
1204        types[2] = r_equal;
1205        types[3] = r_different;
1206        types[4] = r_lessEqual;
1207        types[5] = r_less;
1208       
1209        for (int i = 0; i < 6; i++) {
1210                if (types[i] == type) {
1211                        types[i] = types[5];
1212                        types[5] = type;
1213                        break;
1214                }
1215        }
1216       
1217        int randomType = randomN(5);
1218        return types[randomType];
1219}
1220
1221SString Geno_f8::removeProductionCalls(const SString production) const {
1222        SString line = trimSString(production);
1223        SString result = "";
1224        bool skip = false;
1225        for (int i = 0; i < line.len(); i++) {
1226                if (skip) {
1227                        if (line[i] == ')') {
1228                                skip = false;
1229                        } else {
1230                                //do nothing
1231                        }
1232                } else {
1233                        if (line[i] == 'P') {
1234                                skip = true;
1235                        } else {
1236                                result += line[i];
1237                        }
1238                }
1239        }
1240        return result;
1241}
1242
1243SString Geno_f8::addParameterToCalls(const SString line, SString &prodName) {
1244        SString newStr = "";
1245        int colonIdx = line.indexOf(':', 0);
1246        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1247                int pos2 = colonIdx;
1248                int beginIdx = 0;
1249                int prodIdx;
1250                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1251                        int indexRBrace = line.indexOf(')', prodIdx);
1252                        newStr += line.substr(beginIdx, indexRBrace);
1253                        if (newStr[newStr.len() - 1] != '(') {
1254                                newStr += SString(",");
1255                        }
1256                        newStr += "0.0";
1257                        beginIdx = indexRBrace;
1258                        pos2 = indexRBrace;
1259                }
1260                newStr += line.substr(pos2);
1261        } else {
1262                newStr = line;
1263        }
1264        return newStr;
1265}
1266
1267SString Geno_f8::deleteParameterFromCalls(const SString line, SString &prodName, int paramIdx) {
1268        SString newStr = "";
1269        SString tmp, before, mid, midTmp;
1270        mid = "";
1271        int colonIdx = line.indexOf(':', 0);
1272        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1273                int pos2 = colonIdx;
1274                int beginIdx = 0;
1275                int prodIdx;
1276                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1277                        int indexRBrace = line.indexOf(')', prodIdx);
1278                        before = line.substr(beginIdx, prodIdx + prodName.len() + 1);
1279                        midTmp = line.substr(prodIdx + prodName.len() + 1, indexRBrace - (prodIdx + prodName.len() + 1));
1280                        pos2 = 0;
1281                        SString tok;
1282                        int i = 0;
1283                        while (midTmp.getNextToken(pos2, tok, ',')) {
1284                                if (i++ == paramIdx) {
1285                                        //do nothing
1286                                } else {
1287                                        mid += tok + ",";
1288                                }
1289                        }
1290                        if (mid[mid.len() - 1] == ',') {
1291                                mid = mid.substr(0, mid.len() - 1);
1292                        }
1293                       
1294                        newStr += before + mid + ")";
1295                        beginIdx = indexRBrace;
1296                        pos2 = indexRBrace;
1297                }
1298                newStr += line.substr(pos2 + 1);
1299        } else {
1300                newStr = line;
1301        }
1302        return newStr;
1303}
1304
1305SString Geno_f8::testMutate(SString &in, int method) {
1306        /*struct timeval tv;
1307        gettimeofday(&tv, NULL);
1308        srandom(tv.tv_sec + tv.tv_usec);
1309        */
1310        SString mutatedTmp;
1311        float chg = 0.0;
1312        switch (method) {
1313                case F8_CHANGE_BEGINNING_ARG:
1314                        mutatedTmp = this->mutateChangeBeginningArg(in, chg);
1315                        break;
1316                case F8_CHANGE_ARG:
1317                        mutatedTmp = this->mutateChangeArg(in, chg);
1318                        break;
1319                case F8_DELETE_COMMAND:
1320                        mutatedTmp = this->mutateDeleteCommand(in, chg);
1321                        break;
1322                case F8_INSERT_COMMANDS:
1323                        mutatedTmp = this->mutateInsertCommands(in, chg);
1324                        break;
1325                case F8_ENCAPSULATE:
1326                        mutatedTmp = this->mutateEncapsulate(in, chg);
1327                        break;
1328                case F8_CHANGE_CONDITION_SIGN:
1329                        mutatedTmp = this->mutateChangeConditionSign(in, chg);
1330                        break;
1331                /*case F8_REPLACE_COMMAND:
1332                        mutatedTmp = this->mutateReplaceCommand(in, chg);
1333                        break;*/
1334                case F8_ADD_PARAMETER:
1335                        mutatedTmp = this->mutateAddParameter(in, chg);
1336                        break;
1337                case F8_ADD_CONDITION:
1338                        mutatedTmp = this->mutateAddCondition(in, chg);
1339                        break;
1340                case F8_ADD_SUBPRODUCTION:
1341                        mutatedTmp = this->mutateAddSubproduction(in, chg);
1342                        break;
1343                case F8_CHANGE_ITERATIONS_NUMBER:
1344                        mutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1345                        break;
1346                case F8_DELETE_PARAMETER:
1347                        mutatedTmp = this->mutateDeleteParameter(in, chg);
1348                        break;
1349                case F8_DELETE_CONDITION:
1350                        mutatedTmp = this->mutateDeleteCondition(in, chg);
1351                        break;
1352                case F8_ADD_LOOP:
1353                        mutatedTmp = this->mutateAddLoop(in, chg);
1354                        break;
1355                case F8_DELETE_LOOP:
1356                        mutatedTmp = this->mutateDeleteLoop(in, chg);
1357                        break;
1358                default:
1359                        mutatedTmp = "";
1360        }
1361        return mutatedTmp;
1362       
1363}
Note: See TracBrowser for help on using the repository browser.