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

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

Added some checking against NULLs

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 (int condIter = 0; condIter < (*subProdIter).conditions.size(); condIter++) {
777                                Condition c = (*subProdIter).conditions[condIter];
778                                if (c.parameter == paramName) {
779                                        (*subProdIter).conditions.erase((*subProdIter).conditions.begin() + condIter);
780                                }
781                        }
782                        for (vector<ActionStrP>::iterator actionIter = (*subProdIter).actions.begin();
783                                        actionIter != (*subProdIter).actions.end(); actionIter++) {
784                                for (vector<SString>::iterator paramIter = (*actionIter).params.begin();
785                                                paramIter != (*actionIter).params.end(); paramIter++) {
786                                        string s = sstringToString(*paramIter);
787                                        if (s.find(sparamName, 0) != string::npos) {
788                                                *paramIter = SString("0;");
789                                        }
790                                }
791                        }
792                }
793                               
794                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
795                                prodIter != newLsystem->productions.end(); prodIter++) {
796                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
797                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
798                                subProdIter != subproductions->end(); subProdIter++) {
799                                SubProduction *sp = &(*subProdIter);
800                                for (int actionIter = 0; actionIter < sp->actions.size(); actionIter++) {
801                                        ActionStrP *actionstrp = &(sp->actions.at(actionIter));
802                                        if (actionstrp->action != NULL) {
803                                                if (actionstrp->action->name == prodName && actionstrp->params.size() > paramIndex - 1) {
804                                                        change += paramName.len(); //more less
805                                                        actionstrp->params.erase(actionstrp->params.begin() + (paramIndex - 1));
806                                                }
807                                        }
808                                }
809                        }
810                }
811                chg = (float) change / (float) in.len();
812        }
813       
814        mutated = newLsystem->toString();
815       
816        delete newLsystem;
817       
818        return mutated;
819}
820
821SString Geno_f8::mutateDeleteCondition(SString &in, float& chg) {
822        SString mutated;
823       
824        Lsystem *newLsystem = this->converter->createLsystem(in);
825        if (newLsystem == NULL) {
826                mutated += in;
827                chg = -1.0;
828                return mutated;
829        }
830               
831        map<int, SubProduction*> interestingSubproductions;
832        int counter = 0;
833       
834        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
835                 prodIter != newLsystem->productions.end(); prodIter++) {
836                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
837                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
838                        SubProduction *sp = &(*subprodIter);
839                        if (sp->conditions.size() > 0) {
840                                interestingSubproductions[counter++] =  sp;
841                        }
842                }
843        }
844       
845        if (interestingSubproductions.size() > 0) {
846                int rnd = randomN(interestingSubproductions.size());
847                SubProduction *randomSubproduction = interestingSubproductions[rnd];
848                vector<Condition>::iterator condIter = randomSubproduction->conditions.begin();
849                condIter += randomN(randomSubproduction->conditions.size() - 1);
850                Condition c = *condIter;
851                chg = (float) (c.parameter.len() + 1 + SString::valueOf(c.value).len()) / (float) in.len();
852                randomSubproduction->conditions.erase(condIter);
853        }
854       
855        mutated = newLsystem->toString();
856       
857        delete newLsystem;
858       
859        return mutated;
860}
861
862SString Geno_f8::mutateAddLoop(SString &in, float& chg) {
863        /*
864         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
865         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
866         */
867        SString mutated, line;
868        int pos = 0;
869        while (in.getNextToken(pos, line, '\n')) {
870                mutated += line + "\n";
871        }
872        chg = 0.0;
873        return mutated;
874}
875
876SString Geno_f8::mutateDeleteLoop(SString &in, float& chg) {
877        /*
878         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
879         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
880         */
881        SString mutated, line;
882        int pos = 0;
883        while (in.getNextToken(pos, line, '\n')) {
884                mutated += line + "\n";
885        }
886        chg = 0.0;
887        return mutated;
888}
889
890SString Geno_f8::mutateAddSubproduction(SString &in, float& chg) {
891        SString mutated, line;
892        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
893        int rndProd = randomN(prodInfo.size());
894        int pos = 0;
895        mutated = "";
896        while (in.getNextToken(pos, line, '\n')) {
897                if (line.startsWith(prodInfo[rndProd].name) && line.indexOf(':', 0) != -1) {
898                        SString tmp = ":";
899                        int paramCount = prodInfo[rndProd].paramNames.size();
900                        if (paramCount > 0) {
901                                tmp += prodInfo[rndProd].paramNames[(int) randomN(paramCount)];
902                                tmp += (randomN(2) == 0) ? ">" : "<";
903                                tmp += SString::valueOf((int) randomN(21) - 10);
904                                tmp += "|";
905                        }
906                        tmp += "X\n";
907                        chg = (float) tmp.len() / (float) in.len();
908                        mutated += line + tmp;
909                } else {
910                        mutated += line + "\n";
911                }
912        }
913        return mutated;
914}
915
916SString Geno_f8::mutateChangeIterationsNumber(SString &in, float& chg) {
917        SString mutated;       
918        Lsystem *newLsystem = this->converter->createLsystem(in);
919        if (newLsystem == NULL) {
920                mutated += in;
921                chg = -1.0;
922                return mutated;
923        }
924       
925        newLsystem->iterations += randomN(7) - 3; //-3..3
926        if (newLsystem->iterations < 1) {
927                newLsystem->iterations = 1;
928        }
929        mutated = newLsystem->toString();       
930        delete newLsystem;     
931        chg = 1.0 / (float) in.len();
932        return mutated;
933}
934
935int Geno_f8::mutate(char *&g,float& chg, int &method) {
936        SString in = g;
937       
938        /*struct timeval tv;
939        gettimeofday(&tv, NULL);
940        srandom(tv.tv_sec + tv.tv_usec);
941        */
942        method = roulette(this->operation, F8_OPERATION_COUNT);
943        if (method < 0) {
944                return GENOPER_OPFAIL;
945        }
946       
947#if GENO_F8_DEBUG > 0
948        string mutationName = (method == 0) ? "F8_CHANGE_BEGINNING_ARG" :
949        (method == 1) ? "F8_CHANGE_ARG" :
950        (method == 2) ? "F8_DELETE_COMMAND" :
951        (method == 3) ? "F8_INSERT_COMMANDS" :
952        (method == 4) ? "F8_ENCAPSULATE" :
953        (method == 5) ? "F8_CHANGE_CONDITION_SIGN" :
954        (method == 6) ? "F8_REPLACE_COMMAND" :
955        (method == 7) ? "F8_ADD_PARAMETER" :
956        (method == 8) ? "F8_ADD_CONDITION" :
957        (method == 9) ? "F8_ADD_SUBPRODUCTION" :
958        (method == 10) ? "F8_CHANGE_ITERATIONS_NUMBER" :
959        (method == 11) ? "F8_DELETE_PARAMETER" :
960        (method == 12) ? "F8_DELETE_CONDITION" :
961        (method == 13) ? "F8_ADD_LOOP" :
962        (method == 14) ? "F8_DELETE_LOOP" :
963        (method == 15) ? "F8_OPERATION_COUNT" : "babol";
964        //cout << "-------------------- " << mutationName << " --------------------" << endl;
965#endif
966       
967        const char* mutatedTmp;
968        SString ssMutatedTmp;
969       
970        //cout << "mutate 1" << endl;
971        switch (method) {
972                case F8_CHANGE_BEGINNING_ARG:
973                        ssMutatedTmp = this->mutateChangeBeginningArg(in, chg);
974                        break;
975                case F8_CHANGE_ARG:
976                        ssMutatedTmp = this->mutateChangeArg(in, chg);
977                        break;
978                case F8_DELETE_COMMAND:
979                        ssMutatedTmp = this->mutateDeleteCommand(in, chg);
980                        break;
981                case F8_INSERT_COMMANDS:
982                        ssMutatedTmp = this->mutateInsertCommands(in, chg);
983                        break;
984                case F8_ENCAPSULATE:
985                        ssMutatedTmp = this->mutateEncapsulate(in, chg);
986                        break;
987                case F8_CHANGE_CONDITION_SIGN:
988                        ssMutatedTmp = this->mutateChangeConditionSign(in, chg);
989                        break;
990                /*case F8_REPLACE_COMMAND:
991                        ssMutatedTmp = this->mutateReplaceCommand(in, chg);
992                        break;*/
993                case F8_ADD_PARAMETER:
994                        ssMutatedTmp = this->mutateAddParameter(in, chg);
995                        break;
996                case F8_ADD_CONDITION:
997                        ssMutatedTmp = this->mutateAddCondition(in, chg);
998                        break;
999                case F8_ADD_SUBPRODUCTION:
1000                        ssMutatedTmp = this->mutateAddSubproduction(in, chg);
1001                        break;
1002                case F8_CHANGE_ITERATIONS_NUMBER:
1003                        ssMutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1004                        break;
1005                case F8_DELETE_PARAMETER:
1006                        ssMutatedTmp = this->mutateDeleteParameter(in, chg);
1007                        break;
1008                case F8_DELETE_CONDITION:
1009                        ssMutatedTmp = this->mutateDeleteCondition(in, chg);
1010                        break;
1011                case F8_ADD_LOOP:
1012                        ssMutatedTmp = this->mutateAddLoop(in, chg);
1013                        break;
1014                case F8_DELETE_LOOP:
1015                        ssMutatedTmp = this->mutateDeleteLoop(in, chg);
1016                        break;
1017                default:
1018                        return GENOPER_OPFAIL;
1019        }
1020       
1021        //cout << "mutate 2" << endl;
1022        if (ssMutatedTmp.len() < 16) {
1023                return GENOPER_OPFAIL;
1024        }
1025        if (chg == -1.0) {
1026                chg = 0.0;
1027                return GENOPER_OPFAIL;
1028        }
1029       
1030        mutatedTmp = ssMutatedTmp;
1031       
1032        if (this->checkValidity(mutatedTmp) == GENOPER_OK) {
1033                free(g); //must take care of the original allocation
1034                g = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1035                strcpy(g, mutatedTmp); //the rest is originalg = mutated;
1036                //cout << "mutate 3" << endl;
1037                return GENOPER_OK;
1038        } else {
1039                return GENOPER_OPFAIL;
1040        }
1041}
1042
1043int Geno_f8::crossOver(char *&g1,char *&g2,float& chg1,float& chg2) {
1044        /* wymiana niewielkiej (max. 25%) ilości odpowiadającej sobie informacji
1045         * ma to przypominać "celowaną" mutację, w której osobnik dostaje
1046         * niewiele wiedzy, która sprawdziła się u innego osobnika
1047         */
1048        SString in1 = g1;
1049        SString in2 = g2;
1050        SString mutated;
1051        //SString dst;
1052        //const char* src = in;
1053        //const char* t;
1054       
1055        Lsystem *newLsystem = this->converter->createLsystem(in1);
1056        Lsystem *lsystem2 = this->converter->createLsystem(in2);
1057        if (newLsystem == NULL || lsystem2 == NULL) {
1058                chg1 = 0.0;
1059                chg2 = 0.0;
1060                return GENOPER_OPFAIL;
1061        }
1062       
1063        //shuffle second parent's productions
1064        vector<int> indices;
1065        for (int i = 0; i < lsystem2->productions.size(); i++) {
1066                indices.push_back(i);
1067        }
1068        map<string, Production*> shuffledProductions;
1069        while (!indices.empty()) {
1070                int rnd = randomN(indices.size());
1071                int counter = 0;
1072                //Production *p;
1073                for (map<string, Production*>::iterator it = lsystem2->productions.begin();
1074                         it != lsystem2->productions.end(); it++) {
1075                        if (counter == rnd) {
1076                                //p = it->second;
1077                                shuffledProductions[it->first] = it->second;
1078                                break;
1079                        }
1080                }
1081                //delete index number
1082                indices.erase(indices.begin() + rnd);
1083        }
1084       
1085        int productionCount = randomN(min(newLsystem->productions.size() / 4, lsystem2->productions.size())) + 1;
1086       
1087        int counter = 0;
1088        for (map<string, Production*>::iterator it = shuffledProductions.begin();
1089                 it != shuffledProductions.end() || counter < productionCount; it++) {
1090                //if selected production's name exist in the first parent
1091                if (newLsystem->productions.find(it->first) != newLsystem->productions.end()) {
1092                        newLsystem->productions[it->first]->subproductions = it->second->subproductions;
1093                        counter++;
1094                } else {
1095                        /* This fragment is commented out because we are interested only in matching productions ///////
1096                        //search for first production, which name does not exist in one of the productions
1097                        //selected from second parent
1098                        //this is to avoid information loss when new subproductions will be overwritten
1099                        //just after adding to the child production
1100                        for (map<string, Production*>::iterator it2 = newLsystem->productions.begin();
1101                                 it2 != newLsystem->productions.end(); it2++) {
1102                                if (shuffledProductions.find(it2->first) == shuffledProductions.end()) { //not found
1103                                        it2->second->subproductions = it->second->subproductions;
1104                                        break;
1105                                }
1106                                //there are no "else" because there is at least twice as many productions
1107                                //in the first parent as selected productions from the second parent
1108                                //so always we will find "free" production name
1109                        }*/
1110                }               
1111        }
1112       
1113        //check validity of productions indicated in actions
1114        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
1115                 prodIter != newLsystem->productions.end(); prodIter++) {
1116                vector<SString> paramNames;
1117                for (int i = 1; i <= prodIter->second->parameters.size(); i++) {
1118                        paramNames.push_back(prodIter->second->parameters.getParameterName(i));
1119                }
1120                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
1121                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
1122                        //conditions
1123                        if (paramNames.size() > 0) {
1124                                for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
1125                                         condIter != (*subprodIter).conditions.end(); condIter++) {
1126                                        vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1127                                                                                                                                (*condIter).parameter);
1128                                        if (searchIter == paramNames.end()) { //unknown parameter name!
1129                                                //choose random existing parameter
1130                                                (*condIter).parameter = paramNames[randomN(paramNames.size())];
1131                                        }
1132                                }
1133                        } else { //no params, so delete all conditions
1134                                (*subprodIter).conditions.clear();
1135                        }
1136                       
1137                        //actions
1138                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
1139                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
1140                                if ((*actionIter).action == NULL) {
1141                                        continue;
1142                                }
1143                                SString &actionName = (*actionIter).action->name;
1144                                if (actionName[0] == 'n') {
1145                                        if (paramNames.size() > 0) {
1146                                                vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1147                                                                                                                                        actionName);
1148                                                if (searchIter != paramNames.end()) { //valid name
1149                                                        //ensure it is linked to the correct production
1150                                                        (*actionIter).action = newLsystem->getParamProduction(actionName);
1151                                                } else {
1152                                                        //link to random parameter prodution
1153                                                        SString name = paramNames[randomN(paramNames.size())];
1154                                                        (*actionIter).action = newLsystem->getParamProduction(name);
1155                                                }
1156                                        } else { //no params, so delete this param production
1157                                                (*subprodIter).actions.erase(actionIter);  //TODO sprawdzić zachowanie iteratora!!!
1158                                        }
1159                                } else if (actionName[0] == 'P') {
1160                                        if (newLsystem->productions.find(sstringToString(actionName)) != newLsystem->productions.end()) {
1161                                                //ensure it is linked to the correct production
1162                                                (*actionIter).action = newLsystem->productions[sstringToString(actionName)];
1163                                        } else {
1164                                                //delete this action
1165                                                (*subprodIter).actions.erase(actionIter);
1166                                        }
1167                                }
1168                        }
1169                        if ((*subprodIter).actions.size() == 0) { //we erased all the actions
1170                                ActionStrP a;
1171                                a.action = newLsystem->getPrimitiveProduction(SString("X"));
1172                                (*subprodIter).actions.push_back(a);
1173                        }
1174                }
1175        }
1176       
1177        mutated = newLsystem->toString();
1178       
1179        shuffledProductions.clear();
1180       
1181        delete newLsystem;
1182        delete lsystem2;
1183       
1184        free(g1); //must take care of the original allocation
1185        //free(g2);
1186        const char* mutatedTmp = mutated;
1187        char* mutatedTmp2 = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1188    strcpy(mutatedTmp2, mutatedTmp); //the rest is originalg = mutated;
1189        g1 = mutatedTmp2;
1190        chg1 = 0.5;
1191       
1192        return GENOPER_OK;     
1193}
1194
1195unsigned long Geno_f8::style(const char *g, int pos) {
1196        return GENSTYLE_RGBS(0, 0, 0, GENSTYLE_NONE);
1197}
1198
1199char* Geno_f8::getSimplest() {
1200        const char* geno = "1\n---\nP0\nP0():X\n";
1201        char* retGeno = (char*)malloc(strlen(geno) + 1);
1202        strcpy(retGeno, geno);
1203        return retGeno;
1204}
1205
1206bool Geno_f8::checkProdNameExist(vector<ProductionInfo> info, SString name) const {
1207        for (vector<ProductionInfo>::iterator it = info.begin(); it != info.end(); it++) {
1208                if ((*it).name == name) {
1209                        return true;
1210                }
1211        }
1212        return false;
1213}
1214
1215bool Geno_f8::checkParamNameExist(vector<SString> names, SString name) const {
1216        for (vector<SString>::iterator it = names.begin(); it != names.end(); it++ ) {
1217                if ((*it) == name) {
1218                        return true;
1219                }
1220        }
1221        return false;
1222}
1223
1224SString Geno_f8::getOppositeCondition(const SString &c) const {
1225        if (c.equals("=="))
1226                return "!=";
1227        if (c.equals("!="))
1228                return "==";
1229        if (c.equals(">"))
1230                return "<=";
1231        if (c.equals("<"))
1232                return ">=";
1233        if (c.equals(">="))
1234                return "<";
1235        if (c.equals("<="))
1236                return ">";
1237        return "<"; //default
1238}
1239
1240RelationType Geno_f8::getDifferentCondition(RelationType type) {
1241        RelationType types[6];
1242        types[0] = r_greater;
1243        types[1] = r_greaterEqual;
1244        types[2] = r_equal;
1245        types[3] = r_different;
1246        types[4] = r_lessEqual;
1247        types[5] = r_less;
1248       
1249        for (int i = 0; i < 6; i++) {
1250                if (types[i] == type) {
1251                        types[i] = types[5];
1252                        //types[5] = type;
1253                        break;
1254                }
1255        }
1256       
1257        int randomType = randomN(5);
1258        return types[randomType];
1259}
1260
1261SString Geno_f8::removeProductionCalls(const SString production) const {
1262        SString line = trimSString(production);
1263        SString result = "";
1264        bool skip = false;
1265        for (int i = 0; i < line.len(); i++) {
1266                if (skip) {
1267                        if (line[i] == ')') {
1268                                skip = false;
1269                        } else {
1270                                //do nothing
1271                        }
1272                } else {
1273                        if (line[i] == 'P') {
1274                                skip = true;
1275                        } else {
1276                                result += line[i];
1277                        }
1278                }
1279        }
1280        return result;
1281}
1282
1283SString Geno_f8::addParameterToCalls(const SString line, SString &prodName) {
1284        SString newStr = "";
1285        int colonIdx = line.indexOf(':', 0);
1286        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1287                int pos2 = colonIdx;
1288                int beginIdx = 0;
1289                int prodIdx;
1290                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1291                        int indexRBrace = line.indexOf(')', prodIdx);
1292                        newStr += line.substr(beginIdx, indexRBrace);
1293                        if (newStr[newStr.len() - 1] != '(') {
1294                                newStr += SString(",");
1295                        }
1296                        newStr += "0.0";
1297                        beginIdx = indexRBrace;
1298                        pos2 = indexRBrace;
1299                }
1300                newStr += line.substr(pos2);
1301        } else {
1302                newStr = line;
1303        }
1304        return newStr;
1305}
1306
1307SString Geno_f8::deleteParameterFromCalls(const SString line, SString &prodName, int paramIdx) {
1308        SString newStr = "";
1309        SString tmp, before, mid, midTmp;
1310        mid = "";
1311        int colonIdx = line.indexOf(':', 0);
1312        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1313                int pos2 = colonIdx;
1314                int beginIdx = 0;
1315                int prodIdx;
1316                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1317                        int indexRBrace = line.indexOf(')', prodIdx);
1318                        before = line.substr(beginIdx, prodIdx + prodName.len() + 1);
1319                        midTmp = line.substr(prodIdx + prodName.len() + 1, indexRBrace - (prodIdx + prodName.len() + 1));
1320                        pos2 = 0;
1321                        SString tok;
1322                        int i = 0;
1323                        while (midTmp.getNextToken(pos2, tok, ',')) {
1324                                if (i++ == paramIdx) {
1325                                        //do nothing
1326                                } else {
1327                                        mid += tok + ",";
1328                                }
1329                        }
1330                        if (mid[mid.len() - 1] == ',') {
1331                                mid = mid.substr(0, mid.len() - 1);
1332                        }
1333                       
1334                        newStr += before + mid + ")";
1335                        beginIdx = indexRBrace;
1336                        pos2 = indexRBrace;
1337                }
1338                newStr += line.substr(pos2 + 1);
1339        } else {
1340                newStr = line;
1341        }
1342        return newStr;
1343}
1344
1345SString Geno_f8::testMutate(SString &in, int method) {
1346        /*struct timeval tv;
1347        gettimeofday(&tv, NULL);
1348        srandom(tv.tv_sec + tv.tv_usec);
1349        */
1350        SString mutatedTmp;
1351        float chg = 0.0;
1352        switch (method) {
1353                case F8_CHANGE_BEGINNING_ARG:
1354                        mutatedTmp = this->mutateChangeBeginningArg(in, chg);
1355                        break;
1356                case F8_CHANGE_ARG:
1357                        mutatedTmp = this->mutateChangeArg(in, chg);
1358                        break;
1359                case F8_DELETE_COMMAND:
1360                        mutatedTmp = this->mutateDeleteCommand(in, chg);
1361                        break;
1362                case F8_INSERT_COMMANDS:
1363                        mutatedTmp = this->mutateInsertCommands(in, chg);
1364                        break;
1365                case F8_ENCAPSULATE:
1366                        mutatedTmp = this->mutateEncapsulate(in, chg);
1367                        break;
1368                case F8_CHANGE_CONDITION_SIGN:
1369                        mutatedTmp = this->mutateChangeConditionSign(in, chg);
1370                        break;
1371                /*case F8_REPLACE_COMMAND:
1372                        mutatedTmp = this->mutateReplaceCommand(in, chg);
1373                        break;*/
1374                case F8_ADD_PARAMETER:
1375                        mutatedTmp = this->mutateAddParameter(in, chg);
1376                        break;
1377                case F8_ADD_CONDITION:
1378                        mutatedTmp = this->mutateAddCondition(in, chg);
1379                        break;
1380                case F8_ADD_SUBPRODUCTION:
1381                        mutatedTmp = this->mutateAddSubproduction(in, chg);
1382                        break;
1383                case F8_CHANGE_ITERATIONS_NUMBER:
1384                        mutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1385                        break;
1386                case F8_DELETE_PARAMETER:
1387                        mutatedTmp = this->mutateDeleteParameter(in, chg);
1388                        break;
1389                case F8_DELETE_CONDITION:
1390                        mutatedTmp = this->mutateDeleteCondition(in, chg);
1391                        break;
1392                case F8_ADD_LOOP:
1393                        mutatedTmp = this->mutateAddLoop(in, chg);
1394                        break;
1395                case F8_DELETE_LOOP:
1396                        mutatedTmp = this->mutateDeleteLoop(in, chg);
1397                        break;
1398                default:
1399                        mutatedTmp = "";
1400        }
1401        return mutatedTmp;
1402       
1403}
Note: See TracBrowser for help on using the repository browser.