def changeRandomModule(self,pString):
        pString = ParametricString.copyFrom(pString)
        available_letters = [m.letter for m in self.template_modules_library.getTemplateModules()]

        # Choose what module we want to change
        modules = pString.getActualModules()
        modules = list(filter(lambda m: m.letter in available_letters,modules))
        index = self.rnd.randint(0,len(modules)-1)
        module_to_change = modules[index]
        #print("We will change module at : " + str(index) + " " + str(module_to_change))

        # Choose what we will change it to, avoid replacing with the same letter
        new_module = self.generateRandomModule(notUsingModules = [module_to_change])
        #print("Changed to " + str(new_module))

        # If parameterized, we make sure that the parameter value remains the same, if possible
        if self.parameterized:
            for i in range(len(new_module.params)):
                if i < len(module_to_change.params):
                    new_module.params[i] = module_to_change.params[i]

        #print("From string " + str(string) + " we change module " + str(string[index]) + " at index " + str(index) + " to a new module " + new_module)
        pString.modulesList[pString.modulesList.index(module_to_change)] = new_module
        #print("Result: " + string)
        return pString
 def removeModule(self,module,input_pstring):
     #print(module)
     #print(pString)
     output_pstring = ParametricString.copyFrom(input_pstring)
     if module in input_pstring.modulesList:
         index = input_pstring.index(module)
         removeBrackets = self.checkBracketsRemoval(index,output_pstring)
         del output_pstring.modulesList[index]
         if removeBrackets: self.performBracketsRemoval(index,output_pstring)
     return output_pstring
    def removeRandomModule(self,pString):
        pString = ParametricString.copyFrom(pString)
        available_letters = [m.letter for m in self.template_modules_library.getTemplateModules()]
        while True:
            index = self.rnd.randint(0,len(pString)-1)
            if not pString[index].isBracket() and pString[index].letter in available_letters: break

        # We also remove the brackets if no other module is there
        removeBrackets = self.checkBracketsRemoval(index, pString)
        del pString.modulesList[index]
        if removeBrackets: self.performBracketsRemoval(index, pString)
        #TODO: Do something if we completely remove this production
        return pString
    def addRandomModule(self,pString):
        """
        Add a random Module to a ParametricString, chosen from the available ones.
        This may select an unused Module too.
        #TODO: this is actually an "insertInRandomModule"
        """
        #print("Current pString: " + str(pString))
        pString = ParametricString.copyFrom(pString)
        new_module = self.generateWeightedRandomModule()#parametric=True)
        index = self.rnd.randint(0,len(pString))    # Max is len(pString) so that we can also insert at the end
        #print("From string " + str(pString) + " we add at index " + str(index) + " a new Module " + str(new_module))
        pString.modulesList.insert(index,new_module)
        #print("Result: " + str(pString))

        if new_module.letter not in self.currentlyUsedLetters:
            self.currentlyUsedLetters.append(new_module.letter)

        return pString
 def iterate_loop(self, N):
     if N is None: N = self.niterations
     currentParametricString = ParametricString.copyFrom(self.axiom) # We create a copy so to not modify the axiom
     #self.axiom.evaluateDefines()
     #print(self)
     #print(self.globalDefines)
     for i in range(N):
         if self.verbose: print("\nStep " + str(i+1))
         currentParametricString.resetConversions()
         # All productions are applied in parallel
         for prod in self.productions:
             if self.verbose: print("Rule: " + str(prod))
             result = prod.check(currentParametricString,self.rnd)
             #print("Rule evaluates: " +  str(result))
             if result:  currentParametricString = prod.convert(currentParametricString)
         if self.verbose: print("String at step " + str(i+1) + " is " + str(currentParametricString))
         ParametricProduction.resetStochasticState()
     currentParametricString.evaluateDefines()
     return currentParametricString
 def insertModuleIntoPstringRandomly(self,new_module,pString):
     pString = ParametricString.copyFrom(pString)
     index = self.rnd.randint(0,len(pString))    # Max is len(pString) so that we can also insert at the end
     pString.modulesList.insert(index,new_module)
     if new_module.letter not in self.currentlyUsedLetters:  self.currentlyUsedLetters.append(new_module.letter)
     return pString
 def appendModuleToPstring(self,new_module,pString):
     pString = ParametricString.copyFrom(pString)
     pString.modulesList.append(new_module)
     if new_module.letter not in self.currentlyUsedLetters:  self.currentlyUsedLetters.append(new_module.letter)
     return pString