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

Last change on this file since 1 was 1, checked in by Maciej Komosinski, 15 years ago

added f8 (L-systems) representation and converter f8->f1

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