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

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