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

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

Fixed one bug in converter. Fixed checking if mutation was unsuccessful.

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