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

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

Once again changed 'for' loops inside which vector's element is erased. This time it should be correct, I hope.

File size: 42.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 = -1.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 = -1.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 = -1.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;
415        if (p->subproductions.size() > 0) {
416                sp = &(p->subproductions.at(randomN(p->subproductions.size())));
417        } else {
418                mutated += in;
419                chg = -1.0;
420                return mutated;
421        }
422       
423        int commandsToInsert = /*randomN(3) +*/ 1;
424        int insertLen = 0;
425        for (int i = 0; i < commandsToInsert; i++) {
426                ActionStrP a;
427                if (actions.size() > 0) {
428                        a.action = actions.at(randomN(actions.size()));
429                } else {
430                        mutated += in;
431                        chg = -1.0;
432                        return mutated;
433                }
434                insertLen += a.action->getF8Representation().len();
435                if (a.action->ignoreParams == false && a.action->name[0] == 'P') {
436                        Production *p = (Production*) a.action;
437                        insertLen += 2;
438                        for (int j = 0; j < p->parameters.size(); j++) {
439                                int rnd = randomN(p->parameters.size() + 1);
440                                if (rnd == 0) {
441                                        a.params.push_back(SString("0;"));
442                                        insertLen += 1;
443                                } else {
444                                        SString s = p->parameters.getParameterName(randomN(p->parameters.size()) + 1);
445                                        a.params.push_back(s + ";");
446                                        insertLen += s.len();
447                                }
448                        }
449                }
450                sp->actions.push_back(a);
451        }
452        //cout << "insertCommands 5" << endl;
453       
454        mutated = lsystem->toString();
455        //cout << "insertCommands 6" << endl;
456        chg = (float) insertLen / (float) in.len();
457       
458        delete lsystem;
459        //cout << "insertCommands 7" << endl;
460                       
461        return mutated;
462}
463
464SString Geno_f8::mutateEncapsulate(SString &in, float& chg) {
465        SString mutated;
466       
467        Lsystem *lsystem = this->converter->createLsystem(in);
468        if (lsystem == NULL || lsystem->productions.size() == 0) {
469                mutated += in;
470                chg = -1.0;
471                return mutated;
472        }
473       
474        int counter = 0;
475        int rnd = randomN(lsystem->productions.size());
476        int len = 0;
477       
478        Production *p = new Production();
479        p->subproductions.push_back(SubProduction());
480        SubProduction *newSubProd = &(p->subproductions.back());
481       
482        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
483                 prodIter != lsystem->productions.end(); prodIter++) {
484                if (counter++ == rnd) {
485                        ParameterCollection *params = &(prodIter->second->parameters);
486                        //copy parameters to the encapsulated production
487                        for (int i = 1; i <= params->size(); i++) {
488                                p->parameters.addParameter(params->getParameterName(i));
489                        }
490                       
491                        SubProduction *subproduction;
492                        if (prodIter->second->subproductions.size() > 0) {
493                                subproduction = &(prodIter->second->subproductions[randomN(prodIter->second->subproductions.size())]);
494                        } else {
495                                mutated += in;
496                                chg = -1.0;
497                                return mutated;
498                        }
499                        int firstActionIdx;
500                        if (subproduction->actions.size() > 0) {
501                                firstActionIdx = randomN(subproduction->actions.size());
502                        } else {
503                                mutated += in;
504                                chg = -1.0;
505                                return mutated;
506                        }
507                        int i;
508                        vector<ActionStrP> newActions;
509                        for (i = 0; i < firstActionIdx; i++) {
510                                newActions.push_back(subproduction->actions[i]);
511                        }
512                        for (i = firstActionIdx; i <= firstActionIdx + randomN(4) + 1
513                                 && i < subproduction->actions.size(); i++) { //1..4 actions
514                                newSubProd->actions.push_back(subproduction->actions[i]);
515                                if (subproduction->actions[i].action != NULL) {
516                                        len += subproduction->actions[i].action->getF8Representation().len();
517                                }
518                        }
519                        ActionStrP a;
520                        a.action = p;
521                        a.params = vector<SString>();
522                        for (int j = 0; j < params->size(); j++) {
523                                //a.params.push_back(SString("0;"));
524                                a.params.push_back(params->getParameterName(j + 1));
525                        }
526                        newActions.push_back(a);
527                        while (i < subproduction->actions.size()) {
528                                if (subproduction->actions[i].action != NULL) {
529                                        newActions.push_back(subproduction->actions[i]);
530                                }
531                                i++;
532                        }
533                        subproduction->actions = newActions;
534                        break;
535                }               
536        }
537       
538        SString newName;
539        for (int i = 0; i < 100000; i++) {
540                newName = "P";
541                newName += SString::valueOf(i);
542                if (lsystem->productions[sstringToString(newName)] == NULL) {
543                        break;
544                }
545        }       
546        p->name = newName;
547        lsystem->productions[sstringToString(newName)] = p;
548       
549        mutated = lsystem->toString();
550       
551        delete lsystem;
552       
553        chg = (float) len / (float) in.len();
554        return mutated;
555}
556
557SString Geno_f8::mutateChangeConditionSign(SString &in, float& chg) {
558        SString mutated;
559       
560        Lsystem *newLsystem = this->converter->createLsystem(in);
561        if (newLsystem == NULL) {
562                mutated += in;
563                chg = -1.0;
564                return mutated;
565        }
566       
567        map<int, SubProduction*> interestingSubproductions;
568        int counter = 0;
569       
570        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
571                 prodIter != newLsystem->productions.end(); prodIter++) {
572                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
573                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
574                        SubProduction *sp = &(*subprodIter);
575                        if (sp->conditions.size() > 0) {
576                                interestingSubproductions[counter++] =  sp;
577                        }
578                }
579        }
580       
581        if (interestingSubproductions.size() > 0) {
582                int random1 = randomN(interestingSubproductions.size());
583                SubProduction *randomSubproduction = interestingSubproductions[random1];
584                int random2 = randomN(randomSubproduction->conditions.size()); //all interesting conditions have conditions.size() > 0
585                Condition *c = &(randomSubproduction->conditions.at(random2));
586                c->relation = this->getDifferentCondition(c->relation);
587                chg = 2.0 / (float) in.len();
588        }
589       
590        mutated = newLsystem->toString();
591       
592        delete newLsystem;
593       
594        return mutated;
595}
596
597SString Geno_f8::mutateAddParameter(SString &in, float& chg) {
598        SString mutated;
599       
600        Lsystem *lsystem = this->converter->createLsystem(in);
601        if (lsystem == NULL || lsystem->productions.size() == 0) {
602                mutated += in;
603                chg = -1.0;
604                return mutated;
605        }
606       
607        //cout << "addParameter 1" << endl;
608        int rnd = randomN(lsystem->productions.size());
609        int chglen = 0;
610       
611        SString prodName = "";
612       
613        int counter = 0;
614        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
615                 prodIter != lsystem->productions.end(); prodIter++) {
616                if (counter++ == rnd) {
617                        prodName = prodIter->second->name;
618                        SString newParam;
619                        for (int i = 0; i < 10000; i++) {
620                                newParam = "n";
621                                newParam += SString::valueOf(i);
622                                if (!prodIter->second->parameters.paramExist(newParam)) {
623                                        prodIter->second->parameters.addParameter(newParam);
624                                        chglen += newParam.len();
625                                        break;
626                                }
627                        }
628                       
629                        if (prodName == stringToSString(lsystem->firstProductionName)) {
630                                lsystem->startParams[sstringToString(newParam)] = 0.0;
631                        }
632                        break;
633                }
634        }
635        //cout << "addParameter 2" << endl;
636        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
637                 prodIter != lsystem->productions.end(); prodIter++) {
638                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
639                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
640                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
641                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
642                                if ((*actionIter).action != NULL && (*actionIter).action->name != NULL) {
643                                        if ((*actionIter).action->name == prodName) {
644                                                int randParamVal = randomN(prodIter->second->parameters.size() + 1);
645                                                SString paramVal = NULL;
646                                                if (randParamVal == 0) {
647                                                        paramVal = "0;";
648                                                } else {
649                                                        paramVal = prodIter->second->parameters.getParameterName(randParamVal) + ";";
650                                                }
651                                                //(*actionIter).params.push_back(paramVal);
652                                                chglen += 2;
653                                        }
654                                }
655                        }
656                }
657        }
658        //cout << "addParameter 3" << endl;
659       
660        mutated = lsystem->toString();
661        //cout << "addParameter 4" << endl;
662       
663        delete lsystem;
664       
665        chg = (float) chglen / (float) in.len();
666        return mutated;
667}
668
669SString Geno_f8::mutateAddCondition(SString &in, float& chg) {
670        SString mutated, before, mid, after, line;
671        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
672        vector<int> interestingProductions;
673        for (int i = 0; i < prodInfo.size(); i++) {
674                if (prodInfo[i].paramNames.size() > 0) {
675                        interestingProductions.push_back(i);
676                }
677        }
678        if (interestingProductions.size() == 0) {
679                chg = -1.0;
680                mutated = in;
681                return mutated;
682        }
683        int rndProd = interestingProductions[randomN(interestingProductions.size())];
684        int pos = 0;
685        mutated = "";
686        while (in.getNextToken(pos, line, '\n')) {
687                if (line.startsWith(prodInfo[rndProd].name) && line.len() > prodInfo[rndProd].name.len()) {
688                        int subproductionsCount = -1;
689                        SString tok;
690                        int pos2 = 0;
691                        while (line.getNextToken(pos2, tok, ':')) {
692                                subproductionsCount++;
693                        }
694                        if (subproductionsCount == 0) {
695                                chg = -1.0;
696                                mutated = in;
697                                return mutated;
698                        }
699                        int rnd = randomN(subproductionsCount);
700                        int counter = 0;
701                        int colonIdx = line.indexOf(':', 0);
702                        pos2 = colonIdx;
703                        while (counter != rnd) {
704                                colonIdx = line.indexOf(':', pos2 + 1);
705                                counter++;
706                        }
707                       
708                        int nextColonIdx = line.indexOf(':', colonIdx + 1);
709                        if (nextColonIdx == -1) {
710                                nextColonIdx = 2147483646;
711                        }
712                        int pipeIdx = line.indexOf('|', colonIdx + 1);
713                        mid = "";
714                        if (pipeIdx < nextColonIdx && pipeIdx != -1) {
715                                //before += line.substr(colonIdx + 1, pipeIdx - colonIdx - 1);
716                                before = line.substr(0, pipeIdx);
717                                mid += ",";
718                                after = line.substr(pipeIdx);                           
719                        } else {
720                                before = line.substr(0, colonIdx + 1);
721                                after = SString("|") + line.substr(colonIdx + 1);
722                        }
723                        int paramIdx = (int) randomN(prodInfo[rndProd].paramNames.size());
724                        mid += prodInfo[rndProd].paramNames[paramIdx];
725                        mid += (randomN(2) == 0) ? ">" : "<";
726                        mid += SString::valueOf((int) randomN(21) - 10);
727                       
728                        mutated += before + mid + after + "\n";
729                        chg = (float) mid.len() / (float)in.len();
730                } else {
731                        mutated += line + "\n";
732                }
733        }
734        return mutated;
735}
736
737SString Geno_f8::mutateDeleteParameter(SString &in, float& chg) {
738        SString mutated;
739       
740        Lsystem *newLsystem = this->converter->createLsystem(in);
741        if (newLsystem == NULL) {
742                mutated += in;
743                chg = -1.0;
744                return mutated;
745        }
746               
747        map<int, Production*> interestingProductions;
748        int counter = 0;
749       
750        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
751                        prodIter != newLsystem->productions.end(); prodIter++) {
752                if (prodIter->second->parameters.size() > 0) {
753                        interestingProductions[counter++] =  prodIter->second;
754                }
755        }
756       
757        if (interestingProductions.size() > 0) {
758                int rnd = randomN(interestingProductions.size());
759               
760                Production *randomProduction = interestingProductions[rnd];
761                SString prodName = randomProduction->name;
762               
763                int paramIndex = randomN(randomProduction->parameters.size()) + 1;
764                SString paramName = randomProduction->parameters.getParameterName(paramIndex);
765                string sparamName = sstringToString(paramName);
766                int change = paramName.len();
767               
768                randomProduction->parameters.removeParameter(paramName);
769               
770                if (prodName == stringToSString(newLsystem->firstProductionName)) {
771                        newLsystem->startParams.erase(sstringToString(paramName));
772                }
773               
774                for (vector<SubProduction>::iterator subProdIter = randomProduction->subproductions.begin();
775                                subProdIter != randomProduction->subproductions.end(); subProdIter++) {
776                        for (vector<Condition>::iterator condIter = (*subProdIter).conditions.begin();
777                                 condIter != (*subProdIter).conditions.end(); /*nothing*/) {
778                                if ((*condIter).parameter == paramName) {
779                                        condIter = (*subProdIter).conditions.erase(condIter);
780                                } else {
781                                        condIter++;
782                                }
783                        }
784                        for (vector<ActionStrP>::iterator actionIter = (*subProdIter).actions.begin();
785                                        actionIter != (*subProdIter).actions.end(); actionIter++) {
786                                for (vector<SString>::iterator paramIter = (*actionIter).params.begin();
787                                                paramIter != (*actionIter).params.end(); paramIter++) {
788                                        string s = sstringToString(*paramIter);
789                                        if (s.find(sparamName, 0) != string::npos) {
790                                                *paramIter = SString("0;");
791                                        }
792                                }
793                        }
794                }
795                               
796                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
797                                prodIter != newLsystem->productions.end(); prodIter++) {
798                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
799                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
800                                subProdIter != subproductions->end(); subProdIter++) {
801                                SubProduction *sp = &(*subProdIter);
802                                for (vector<ActionStrP>::iterator actionIter = sp->actions.begin();
803                                         actionIter != sp->actions.end(); actionIter++) {
804                                        if ((*actionIter).action != NULL) {
805                                                if ((*actionIter).action->name == prodName && (*actionIter).params.size() > paramIndex - 1) {
806                                                        change += paramName.len(); //more less
807                                                        (*actionIter).params.erase((*actionIter).params.begin() + (paramIndex - 1));
808                                                }
809                                        }
810                                }
811                        }
812                }
813                chg = (float) change / (float) in.len();
814        }
815       
816        mutated = newLsystem->toString();
817       
818        delete newLsystem;
819       
820        return mutated;
821}
822
823SString Geno_f8::mutateDeleteCondition(SString &in, float& chg) {
824        SString mutated;
825       
826        Lsystem *newLsystem = this->converter->createLsystem(in);
827        if (newLsystem == NULL) {
828                mutated += in;
829                chg = -1.0;
830                return mutated;
831        }
832               
833        map<int, SubProduction*> interestingSubproductions;
834        int counter = 0;
835       
836        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
837                 prodIter != newLsystem->productions.end(); prodIter++) {
838                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
839                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
840                        SubProduction *sp = &(*subprodIter);
841                        if (sp->conditions.size() > 0) {
842                                interestingSubproductions[counter++] =  sp;
843                        }
844                }
845        }
846       
847        if (interestingSubproductions.size() > 0) {
848                int rnd = randomN(interestingSubproductions.size());
849                SubProduction *randomSubproduction = interestingSubproductions[rnd];
850                vector<Condition>::iterator condIter = randomSubproduction->conditions.begin();
851                condIter += randomN(randomSubproduction->conditions.size() - 1);
852                Condition c = *condIter;
853                chg = (float) (c.parameter.len() + 1 + SString::valueOf(c.value).len()) / (float) in.len();
854                randomSubproduction->conditions.erase(condIter);
855        }
856       
857        mutated = newLsystem->toString();
858       
859        delete newLsystem;
860       
861        return mutated;
862}
863
864SString Geno_f8::mutateAddLoop(SString &in, float& chg) {
865        /*
866         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
867         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
868         */
869        SString mutated, line;
870        int pos = 0;
871        while (in.getNextToken(pos, line, '\n')) {
872                mutated += line + "\n";
873        }
874        chg = 0.0;
875        return mutated;
876}
877
878SString Geno_f8::mutateDeleteLoop(SString &in, float& chg) {
879        /*
880         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
881         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
882         */
883        SString mutated, line;
884        int pos = 0;
885        while (in.getNextToken(pos, line, '\n')) {
886                mutated += line + "\n";
887        }
888        chg = 0.0;
889        return mutated;
890}
891
892SString Geno_f8::mutateAddSubproduction(SString &in, float& chg) {
893        SString mutated, line;
894        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
895        int rndProd = randomN(prodInfo.size());
896        int pos = 0;
897        mutated = "";
898        while (in.getNextToken(pos, line, '\n')) {
899                if (line.startsWith(prodInfo[rndProd].name) && line.indexOf(':', 0) != -1) {
900                        SString tmp = ":";
901                        int paramCount = prodInfo[rndProd].paramNames.size();
902                        if (paramCount > 0) {
903                                tmp += prodInfo[rndProd].paramNames[(int) randomN(paramCount)];
904                                tmp += (randomN(2) == 0) ? ">" : "<";
905                                tmp += SString::valueOf((int) randomN(21) - 10);
906                                tmp += "|";
907                        }
908                        tmp += "X\n";
909                        chg = (float) tmp.len() / (float) in.len();
910                        mutated += line + tmp;
911                } else {
912                        mutated += line + "\n";
913                }
914        }
915        return mutated;
916}
917
918SString Geno_f8::mutateChangeIterationsNumber(SString &in, float& chg) {
919        SString mutated;       
920        Lsystem *newLsystem = this->converter->createLsystem(in);
921        if (newLsystem == NULL) {
922                mutated += in;
923                chg = -1.0;
924                return mutated;
925        }
926       
927        newLsystem->iterations += randomN(7) - 3; //-3..3
928        if (newLsystem->iterations < 1) {
929                newLsystem->iterations = 1;
930        }
931        mutated = newLsystem->toString();       
932        delete newLsystem;     
933        chg = 1.0 / (float) in.len();
934        return mutated;
935}
936
937int Geno_f8::mutate(char *&g,float& chg, int &method) {
938        SString in = g;
939       
940        /*struct timeval tv;
941        gettimeofday(&tv, NULL);
942        srandom(tv.tv_sec + tv.tv_usec);
943        */
944        method = roulette(this->operation, F8_OPERATION_COUNT);
945        if (method < 0) {
946                return GENOPER_OPFAIL;
947        }
948       
949#if GENO_F8_DEBUG > 0
950        string mutationName = (method == 0) ? "F8_CHANGE_BEGINNING_ARG" :
951        (method == 1) ? "F8_CHANGE_ARG" :
952        (method == 2) ? "F8_DELETE_COMMAND" :
953        (method == 3) ? "F8_INSERT_COMMANDS" :
954        (method == 4) ? "F8_ENCAPSULATE" :
955        (method == 5) ? "F8_CHANGE_CONDITION_SIGN" :
956        (method == 6) ? "F8_REPLACE_COMMAND" :
957        (method == 7) ? "F8_ADD_PARAMETER" :
958        (method == 8) ? "F8_ADD_CONDITION" :
959        (method == 9) ? "F8_ADD_SUBPRODUCTION" :
960        (method == 10) ? "F8_CHANGE_ITERATIONS_NUMBER" :
961        (method == 11) ? "F8_DELETE_PARAMETER" :
962        (method == 12) ? "F8_DELETE_CONDITION" :
963        (method == 13) ? "F8_ADD_LOOP" :
964        (method == 14) ? "F8_DELETE_LOOP" :
965        (method == 15) ? "F8_OPERATION_COUNT" : "babol";
966        //cout << "-------------------- " << mutationName << " --------------------" << endl;
967#endif
968       
969        const char* mutatedTmp;
970        SString ssMutatedTmp;
971       
972        //cout << "mutate 1" << endl;
973        switch (method) {
974                case F8_CHANGE_BEGINNING_ARG:
975                        ssMutatedTmp = this->mutateChangeBeginningArg(in, chg);
976                        break;
977                case F8_CHANGE_ARG:
978                        ssMutatedTmp = this->mutateChangeArg(in, chg);
979                        break;
980                case F8_DELETE_COMMAND:
981                        ssMutatedTmp = this->mutateDeleteCommand(in, chg);
982                        break;
983                case F8_INSERT_COMMANDS:
984                        ssMutatedTmp = this->mutateInsertCommands(in, chg);
985                        break;
986                case F8_ENCAPSULATE:
987                        ssMutatedTmp = this->mutateEncapsulate(in, chg);
988                        break;
989                case F8_CHANGE_CONDITION_SIGN:
990                        ssMutatedTmp = this->mutateChangeConditionSign(in, chg);
991                        break;
992                /*case F8_REPLACE_COMMAND:
993                        ssMutatedTmp = this->mutateReplaceCommand(in, chg);
994                        break;*/
995                case F8_ADD_PARAMETER:
996                        ssMutatedTmp = this->mutateAddParameter(in, chg);
997                        break;
998                case F8_ADD_CONDITION:
999                        ssMutatedTmp = this->mutateAddCondition(in, chg);
1000                        break;
1001                case F8_ADD_SUBPRODUCTION:
1002                        ssMutatedTmp = this->mutateAddSubproduction(in, chg);
1003                        break;
1004                case F8_CHANGE_ITERATIONS_NUMBER:
1005                        ssMutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1006                        break;
1007                case F8_DELETE_PARAMETER:
1008                        ssMutatedTmp = this->mutateDeleteParameter(in, chg);
1009                        break;
1010                case F8_DELETE_CONDITION:
1011                        ssMutatedTmp = this->mutateDeleteCondition(in, chg);
1012                        break;
1013                case F8_ADD_LOOP:
1014                        ssMutatedTmp = this->mutateAddLoop(in, chg);
1015                        break;
1016                case F8_DELETE_LOOP:
1017                        ssMutatedTmp = this->mutateDeleteLoop(in, chg);
1018                        break;
1019                default:
1020                        return GENOPER_OPFAIL;
1021        }
1022       
1023        //cout << "mutate 2" << endl;
1024        if (ssMutatedTmp.len() < 16) {
1025                return GENOPER_OPFAIL;
1026        }
1027        if (chg == -1.0) {
1028                chg = 0.0;
1029                return GENOPER_OPFAIL;
1030        }
1031       
1032        mutatedTmp = ssMutatedTmp;
1033       
1034        if (this->checkValidity(mutatedTmp) == GENOPER_OK) {
1035                free(g); //must take care of the original allocation
1036                g = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1037                strcpy(g, mutatedTmp); //the rest is originalg = mutated;
1038                //cout << "mutate 3" << endl;
1039                return GENOPER_OK;
1040        } else {
1041                return GENOPER_OPFAIL;
1042        }
1043}
1044
1045int Geno_f8::crossOver(char *&g1,char *&g2,float& chg1,float& chg2) {
1046        /* wymiana niewielkiej (max. 25%) ilości odpowiadającej sobie informacji
1047         * ma to przypominać "celowaną" mutację, w której osobnik dostaje
1048         * niewiele wiedzy, która sprawdziła się u innego osobnika
1049         */
1050        SString in1 = g1;
1051        SString in2 = g2;
1052        SString mutated;
1053        //SString dst;
1054        //const char* src = in;
1055        //const char* t;
1056       
1057        Lsystem *newLsystem = this->converter->createLsystem(in1);
1058        Lsystem *lsystem2 = this->converter->createLsystem(in2);
1059        if (newLsystem == NULL || lsystem2 == NULL) {
1060                chg1 = 0.0;
1061                chg2 = 0.0;
1062                return GENOPER_OPFAIL;
1063        }
1064       
1065        //shuffle second parent's productions
1066        vector<int> indices;
1067        for (int i = 0; i < lsystem2->productions.size(); i++) {
1068                indices.push_back(i);
1069        }
1070        map<string, Production*> shuffledProductions;
1071        while (!indices.empty()) {
1072                int rnd = randomN(indices.size());
1073                int counter = 0;
1074                //Production *p;
1075                for (map<string, Production*>::iterator it = lsystem2->productions.begin();
1076                         it != lsystem2->productions.end(); it++) {
1077                        if (counter == rnd) {
1078                                //p = it->second;
1079                                shuffledProductions[it->first] = it->second;
1080                                break;
1081                        }
1082                }
1083                //delete index number
1084                indices.erase(indices.begin() + rnd);
1085        }
1086       
1087        int productionCount = randomN(min(newLsystem->productions.size() / 4, lsystem2->productions.size())) + 1;
1088       
1089        int counter = 0;
1090        for (map<string, Production*>::iterator it = shuffledProductions.begin();
1091                 it != shuffledProductions.end() && counter < productionCount; it++) {
1092                //if selected production's name exist in the first parent
1093                if (newLsystem->productions.find(it->first) != newLsystem->productions.end()) {
1094                        newLsystem->productions[it->first]->subproductions = it->second->subproductions;
1095                        counter++;
1096                } else {
1097                        /* This fragment is commented out because we are interested only in matching productions ///////
1098                        //search for first production, which name does not exist in one of the productions
1099                        //selected from second parent
1100                        //this is to avoid information loss when new subproductions will be overwritten
1101                        //just after adding to the child production
1102                        for (map<string, Production*>::iterator it2 = newLsystem->productions.begin();
1103                                 it2 != newLsystem->productions.end(); it2++) {
1104                                if (shuffledProductions.find(it2->first) == shuffledProductions.end()) { //not found
1105                                        it2->second->subproductions = it->second->subproductions;
1106                                        break;
1107                                }
1108                                //there are no "else" because there is at least twice as many productions
1109                                //in the first parent as selected productions from the second parent
1110                                //so always we will find "free" production name
1111                        }*/
1112                }               
1113        }
1114       
1115        //check validity of productions indicated in actions
1116        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
1117                 prodIter != newLsystem->productions.end(); prodIter++) {
1118                vector<SString> paramNames;
1119                for (int i = 1; i <= prodIter->second->parameters.size(); i++) {
1120                        paramNames.push_back(prodIter->second->parameters.getParameterName(i));
1121                }
1122                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
1123                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
1124                        //conditions
1125                        if (paramNames.size() > 0) {
1126                                for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
1127                                         condIter != (*subprodIter).conditions.end(); condIter++) {
1128                                        vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1129                                                                                                                                (*condIter).parameter);
1130                                        if (searchIter == paramNames.end()) { //unknown parameter name!
1131                                                //choose random existing parameter
1132                                                (*condIter).parameter = paramNames[randomN(paramNames.size())];
1133                                        }
1134                                }
1135                        } else { //no params, so delete all conditions
1136                                (*subprodIter).conditions.clear();
1137                        }
1138                       
1139                        //actions
1140                        for (vector<ActionStrP>::iterator i = (*subprodIter).actions.begin();
1141                                 i != (*subprodIter).actions.end(); /*nothing*/) {
1142                                bool deleted = false;
1143                                if ((*i).action == NULL) {
1144                                        continue;
1145                                }
1146                                SString &actionName = (*i).action->name;
1147                                if (actionName[0] == 'n') {
1148                                        if (paramNames.size() > 0) {
1149                                                vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1150                                                                                                                                        actionName);
1151                                                if (searchIter != paramNames.end()) { //valid name
1152                                                        //ensure it is linked to the correct production
1153                                                        (*i).action = newLsystem->getParamProduction(actionName);
1154                                                } else {
1155                                                        //link to random parameter prodution
1156                                                        SString name = paramNames[randomN(paramNames.size())];
1157                                                        (*i).action = newLsystem->getParamProduction(name);
1158                                                }
1159                                        } else { //no params, so delete this param production
1160                                                i = (*subprodIter).actions.erase(i);
1161                                                deleted = true;
1162                                        }
1163                                } else if (actionName[0] == 'P') {
1164                                        if (newLsystem->productions.find(sstringToString(actionName)) != newLsystem->productions.end()) {
1165                                                //ensure it is linked to the correct production
1166                                                (*i).action = newLsystem->productions[sstringToString(actionName)];
1167                                        } else {
1168                                                //delete this action
1169                                                i = (*subprodIter).actions.erase(i);
1170                                                deleted = true;
1171                                        }
1172                                }
1173                                if (!deleted) {
1174                                        i++;
1175                                }
1176                        }
1177                        if ((*subprodIter).actions.size() == 0) { //we erased all the actions
1178                                ActionStrP a;
1179                                a.action = newLsystem->getPrimitiveProduction(SString("X"));
1180                                (*subprodIter).actions.push_back(a);
1181                        }
1182                }
1183        }
1184       
1185        mutated = newLsystem->toString();
1186       
1187        shuffledProductions.clear();
1188       
1189        delete newLsystem;
1190        delete lsystem2;
1191       
1192        free(g1); //must take care of the original allocation
1193        //free(g2);
1194        const char* mutatedTmp = mutated;
1195        char* mutatedTmp2 = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1196    strcpy(mutatedTmp2, mutatedTmp); //the rest is originalg = mutated;
1197        g1 = mutatedTmp2;
1198        chg1 = 0.5;
1199       
1200        return GENOPER_OK;     
1201}
1202
1203unsigned long Geno_f8::style(const char *g, int pos) {
1204        return GENSTYLE_RGBS(0, 0, 0, GENSTYLE_NONE);
1205}
1206
1207char* Geno_f8::getSimplest() {
1208        const char* geno = "1\n---\nP0\nP0():X\n";
1209        char* retGeno = (char*)malloc(strlen(geno) + 1);
1210        strcpy(retGeno, geno);
1211        return retGeno;
1212}
1213
1214bool Geno_f8::checkProdNameExist(vector<ProductionInfo> info, SString name) const {
1215        for (vector<ProductionInfo>::iterator it = info.begin(); it != info.end(); it++) {
1216                if ((*it).name == name) {
1217                        return true;
1218                }
1219        }
1220        return false;
1221}
1222
1223bool Geno_f8::checkParamNameExist(vector<SString> names, SString name) const {
1224        for (vector<SString>::iterator it = names.begin(); it != names.end(); it++ ) {
1225                if ((*it) == name) {
1226                        return true;
1227                }
1228        }
1229        return false;
1230}
1231
1232SString Geno_f8::getOppositeCondition(const SString &c) const {
1233        if (c.equals("=="))
1234                return "!=";
1235        if (c.equals("!="))
1236                return "==";
1237        if (c.equals(">"))
1238                return "<=";
1239        if (c.equals("<"))
1240                return ">=";
1241        if (c.equals(">="))
1242                return "<";
1243        if (c.equals("<="))
1244                return ">";
1245        return "<"; //default
1246}
1247
1248RelationType Geno_f8::getDifferentCondition(RelationType type) {
1249        RelationType types[6];
1250        types[0] = r_greater;
1251        types[1] = r_greaterEqual;
1252        types[2] = r_equal;
1253        types[3] = r_different;
1254        types[4] = r_lessEqual;
1255        types[5] = r_less;
1256       
1257        for (int i = 0; i < 6; i++) {
1258                if (types[i] == type) {
1259                        types[i] = types[5];
1260                        //types[5] = type;
1261                        break;
1262                }
1263        }
1264       
1265        int randomType = randomN(5);
1266        return types[randomType];
1267}
1268
1269SString Geno_f8::removeProductionCalls(const SString production) const {
1270        SString line = trimSString(production);
1271        SString result = "";
1272        bool skip = false;
1273        for (int i = 0; i < line.len(); i++) {
1274                if (skip) {
1275                        if (line[i] == ')') {
1276                                skip = false;
1277                        } else {
1278                                //do nothing
1279                        }
1280                } else {
1281                        if (line[i] == 'P') {
1282                                skip = true;
1283                        } else {
1284                                result += line[i];
1285                        }
1286                }
1287        }
1288        return result;
1289}
1290
1291SString Geno_f8::addParameterToCalls(const SString line, SString &prodName) {
1292        SString newStr = "";
1293        int colonIdx = line.indexOf(':', 0);
1294        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1295                int pos2 = colonIdx;
1296                int beginIdx = 0;
1297                int prodIdx;
1298                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1299                        int indexRBrace = line.indexOf(')', prodIdx);
1300                        newStr += line.substr(beginIdx, indexRBrace);
1301                        if (newStr[newStr.len() - 1] != '(') {
1302                                newStr += SString(",");
1303                        }
1304                        newStr += "0.0";
1305                        beginIdx = indexRBrace;
1306                        pos2 = indexRBrace;
1307                }
1308                newStr += line.substr(pos2);
1309        } else {
1310                newStr = line;
1311        }
1312        return newStr;
1313}
1314
1315SString Geno_f8::deleteParameterFromCalls(const SString line, SString &prodName, int paramIdx) {
1316        SString newStr = "";
1317        SString tmp, before, mid, midTmp;
1318        mid = "";
1319        int colonIdx = line.indexOf(':', 0);
1320        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1321                int pos2 = colonIdx;
1322                int beginIdx = 0;
1323                int prodIdx;
1324                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1325                        int indexRBrace = line.indexOf(')', prodIdx);
1326                        before = line.substr(beginIdx, prodIdx + prodName.len() + 1);
1327                        midTmp = line.substr(prodIdx + prodName.len() + 1, indexRBrace - (prodIdx + prodName.len() + 1));
1328                        pos2 = 0;
1329                        SString tok;
1330                        int i = 0;
1331                        while (midTmp.getNextToken(pos2, tok, ',')) {
1332                                if (i++ == paramIdx) {
1333                                        //do nothing
1334                                } else {
1335                                        mid += tok + ",";
1336                                }
1337                        }
1338                        if (mid[mid.len() - 1] == ',') {
1339                                mid = mid.substr(0, mid.len() - 1);
1340                        }
1341                       
1342                        newStr += before + mid + ")";
1343                        beginIdx = indexRBrace;
1344                        pos2 = indexRBrace;
1345                }
1346                newStr += line.substr(pos2 + 1);
1347        } else {
1348                newStr = line;
1349        }
1350        return newStr;
1351}
1352
1353SString Geno_f8::testMutate(SString &in, int method) {
1354        /*struct timeval tv;
1355        gettimeofday(&tv, NULL);
1356        srandom(tv.tv_sec + tv.tv_usec);
1357        */
1358        SString mutatedTmp;
1359        float chg = 0.0;
1360        switch (method) {
1361                case F8_CHANGE_BEGINNING_ARG:
1362                        mutatedTmp = this->mutateChangeBeginningArg(in, chg);
1363                        break;
1364                case F8_CHANGE_ARG:
1365                        mutatedTmp = this->mutateChangeArg(in, chg);
1366                        break;
1367                case F8_DELETE_COMMAND:
1368                        mutatedTmp = this->mutateDeleteCommand(in, chg);
1369                        break;
1370                case F8_INSERT_COMMANDS:
1371                        mutatedTmp = this->mutateInsertCommands(in, chg);
1372                        break;
1373                case F8_ENCAPSULATE:
1374                        mutatedTmp = this->mutateEncapsulate(in, chg);
1375                        break;
1376                case F8_CHANGE_CONDITION_SIGN:
1377                        mutatedTmp = this->mutateChangeConditionSign(in, chg);
1378                        break;
1379                /*case F8_REPLACE_COMMAND:
1380                        mutatedTmp = this->mutateReplaceCommand(in, chg);
1381                        break;*/
1382                case F8_ADD_PARAMETER:
1383                        mutatedTmp = this->mutateAddParameter(in, chg);
1384                        break;
1385                case F8_ADD_CONDITION:
1386                        mutatedTmp = this->mutateAddCondition(in, chg);
1387                        break;
1388                case F8_ADD_SUBPRODUCTION:
1389                        mutatedTmp = this->mutateAddSubproduction(in, chg);
1390                        break;
1391                case F8_CHANGE_ITERATIONS_NUMBER:
1392                        mutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1393                        break;
1394                case F8_DELETE_PARAMETER:
1395                        mutatedTmp = this->mutateDeleteParameter(in, chg);
1396                        break;
1397                case F8_DELETE_CONDITION:
1398                        mutatedTmp = this->mutateDeleteCondition(in, chg);
1399                        break;
1400                case F8_ADD_LOOP:
1401                        mutatedTmp = this->mutateAddLoop(in, chg);
1402                        break;
1403                case F8_DELETE_LOOP:
1404                        mutatedTmp = this->mutateDeleteLoop(in, chg);
1405                        break;
1406                default:
1407                        mutatedTmp = "";
1408        }
1409        return mutatedTmp;
1410       
1411}
Note: See TracBrowser for help on using the repository browser.