def __init__(self): #Se almacena el nombre del archivo .xml donde se #almacenan los nombres de todas las técnicas con #sus parámetros que se encuentran disponibles para el usuario. self.__features_filename = "Features.xml" #Se guarda el nombre del archivo .xml que contiene #los M.O.P.'s disponibles para el usuario. #Un M.O.P. (Multi-Objective Problem) es un conjunto de variables #de decisión y funciones objetivo cuyo resultado está bien #estudiado, se utiliza principalmente para comprobar que el #funcionamiento del proyecto es el óptimo y además proveer #al usuario de una alternativa rápida y concisa para utilizar #el proyecto. self.__mop_examples_filename = "MOPExamples.xml" #A continuación se toma el nombre del archivo que almacena las #expresiones especiales de Python. #Esto sucede porque en ocasiones hay algunas funciones o constantes #especiales que el intérprete de Python no comprende directamente, #por ello es que se necesita establecer una relación entre las #expresiones que ingresa el usuario y su equivalente en Python. #Por ello es que al crear o evaluar funciones objetivo se debe hacer #uso de estas expresiones. self.__python_expressions_filename = "PythonExpressions.xml" #Se obtiene una instancia de la clase que opera con archivos #.xml. self.__parser = XMLParser() #Se guarda una instancia de la clase que verifica y convierte #apropiadamente los datos que el usuario ingresa para ejecutar #algún algoritmo M.O.E.A. (Multi-Objective Evolutionary Algorithm). self.__verifier = Verifier()
def run(self): # Compile and attempt to run the suite. (output, error) = self.compileSuite() # If an executable is produced, compilation succeeded. if "Segmentation fault" in error: # If there is a segmentation fault, perform verification and re-run. #print error print "Performing Verification" verifier = Verifier() verifier.suite = self.suite verifier.verify(self.suite.getFileName()) print "Attempting to rerun." self.suite.importSuite() self.run() else: # If it ran sucessfully, import the obligation scores and recalculate the suite score. self.suite.importObligations( os.path.basename(self.suite.getFileName()) + "sv") rmProcess = Popen( "rm " + os.path.basename(self.suite.getFileName()) + "sv", stdout=PIPE, stderr=PIPE, shell=True) (rOutput, eError) = rmProcess.communicate()
async def on_member_join(self, member): if self.config['bleeding']: self.log('Initiating verification procedure for user "{}".'.format( member.name)) msg = 'Please send !register followed by your EPITECH mail adress\n' msg += 'i.e.: ```!register [email protected]```\n' msg += 'It has to be an EPITECH address, any other address will not be accepted' await self.send_message(member, msg) Verifier.add(member)
def test1DConfig(): v = Verifier("test/simulation1D_config.ini") v.verify() x = v._data["x"] u = v._data["u"] d2x = v._derivs["x"][2] dt = v._derivs["t"][1] uxx = d2x @ u ut = dt @ u print("1D MAX ERROR: ",str(np.amax(np.abs(v._output))))
class Voter(): __v_server = Verifier() __c_server = Counter() def cast_vote(self, vote): yes, no = self.__v_server.genrate_vote() if vote == 1: self.__c_server.add_vote(yes) elif vote == 0: self.__c_server.add_vote(no) else: print "Invalid Input"
class Counter: verify_server = Verifier() storage = Storage() share_common_storage='' vote_count=0 #global yes #yes = 0 #global no #no = 0 def add_vote(self, envelop, vote, verifier): if vote == 0 or vote ==1: self.vote_count=self.vote_count+1 parts = envelop.split("_") share_common = parts[1] print("Share {0} ").format(share_common) self.storage.write_share(share_common) self.storage.write_voter(vote) self.storage.result() # self.enc_share(pub,share_common) self.enc_vote(pub, vote) verifier.verify(vote) if self.vote_count==2: verifier.decrypt_result(int(self.share_common_storage)) else: print("Invalid vote") def enc_vote(self,pub,vote): res=e_add(pub,vote,vote) self.share_common_storage=self.share_common_storage+str(res) print(e_add(pub,vote,vote)) def enc_share(self, pub, share_common,): print(pub,share_common) enc_share_all=e_add(pub,share_common,share_common) print("share_add",enc_share_all) # for char in enc_share_all: # self.share_common_storage.append(enc_share_all) self.verify_server.decrypt_result() print(self.share_common_storage) return enc_share_all
class Counter: verify_server = Verifier() def add_vote(self, vote): yes, no = pickle.load(open("votesCount.pickle", "rb")) new = self.verify_server.verifyVote(verifyVote=vote) if new == 0: no += 1 print "Yes count : " + yes + "No count : " + no elif new == 1: yes += 1 print "Yes count : " + yes + "No count : " + no else: print "inavalid vote" pickle.dump((yes, no), open("votesCount.pickle", "wb"))
def test2DConfig(): vgood = Verifier("test/simulation2D_config.ini") vgood.verify() vbad = Verifier("test/simulation2Dcorrupt_config.ini") vbad.verify() x = vgood._data["x"] y = vgood._data["y"] t = vgood._data["t"] u = vgood._data["u"] ubad = vbad._data["u"] print("2D MAX ERROR: ",str(np.amax(np.abs(vgood._output)))) contourPlotVector(x,y,t,u,title="Correct data\nDynamic heat equation in isotropic material",nobc=False,tstep=1,filename="correct_data_2D.png") contourPlotVector(x,y,t,ubad,title="Incorrect data\nDynamic heat equation in isotropic material",nobc=False,tstep=1,filename="incorrect_data_2D.png") contourPlotVector(x,y,t,np.abs(vbad._output),title="Identified error",colormap=cm.afmhot,filename="error_2D.png") pyplot.show()
def main(): playerList = [] nbr_players = input( 'Hej! Välkomna till det här enkla Yatzy-spelet. Var vänlig och ange antalet deltagare (1-4): ' ) try: nbr = int(nbr_players) if nbr < 1 or nbr > 4: raise ValueError() for i in range(nbr): name = input(f'Skriv in namnet för spelare {i+1}: ') playerList.append(Player(name, Verifier(), Roll())) except ValueError: print( 'Error. Var vänlig och försök igen och ange antalet deltager i siffror mellan 1-4.' ) plays_list = playerList[0].get_verifier().plays_left() while len(plays_list) > 0: for p in playerList: print('*' * 50) print('Din tur att slå ' + p.get_name()) roller = p.get_roller() verifier = p.get_verifier() roller.first_roll() roller.keep_dices() roller.second_roll() roller.keep_dices() roller.third_roll() verifier.print_plays_left() current_dices = roller.get_kept_dice_list() choice = input( 'Var vänlig att skriv det nummer som du vill lägga till din poäng på (om du inte kan, skriv x:"NUMMER ATT STRYKA"): ' ) todo = roller.get_methods().get(choice) if todo(current_dices): print(f'Lägger till ponäng i {todo}')
def getPreviewUrl(): assert 'previewUrl' in session, "Preloaded image not there" url = session['previewUrl'] assert Verifier.urlValid(url), "Invalid preview url" return url
def setPreviewUrl(url): assert SessionManager.__inSession(), "Not in Flask session" assert Verifier.urlValid(url), "Invalid preview url" session['previewUrl'] = url
def __init__(self): Verifier.__init__(self)
def _verify(self): self.result = Verifier(self.test_case.config_path, self.test_case.name).verify()
class Generator(): # Program to generate tests for. __program = "" # List of functions in that program. __functions = [] # List of global (state) variables. __stateVariables = [] # List of type definitions. __typeDefs = [] # List of struct definitions. __structs = [] # List of union definitions. __unions = [] # List of enum definitions. __enums = [] # Dependency map for state information __dependencyMap = [] # Max suite size maxSuiteSize = 25.0 # Max test length maxLength = 10.0 # Max array size when generating input maxArraySize = 25 # Object that verifies that suites compile and do not cause segmentation fault verifier = Verifier() # Object that runs suites and calculates their score runner = Runner() # Central process of instrumentation def generate(self, outFile): if self.getProgram() == "": raise Exception("No program set for generation.") # Read in program and get list of functions and state variables. if self.getFunctions() == [] or self.getStateVariables( ) == [] or self.getDependencyMap() == []: self.initializeProgramData() suite = TestSuite() # Generate test cases suite.setTests(self.buildSuite()) testList = [] for entry in suite.getTests(): testList.append(1) suite.setTestList(testList) #print(suite.getTests()) # Build suite code suite.setSuiteCode(self.buildCode(suite, outFile)) # Print test suite to file suite.setFileName(outFile) suite.writeSuiteFile() # Perform suite verification self.verifier.suite = suite self.verifier.verify(outFile) # Run the suite and calculate its score self.runner.suite = suite self.runner.run() return suite # Build test suite def buildSuite(self): suite = [] done = 0 generator = GeneratorFactory() generator.typeDefs = self.getTypeDefs() generator.structs = self.getStructs() generator.unions = self.getUnions() while done == 0: # Use a degrading temperature to control the probability of adding an additional test temperature = (self.maxSuiteSize - float(len(suite))) / self.maxSuiteSize if random.random() < temperature: chance = random.random() numStateful = len(self.getDependencyMap()[0]) numStateless = len(self.getDependencyMap()[1]) # Add a stateless test if the random number is less than 0.5 # Or, if there are only stateless funtions # If there are no functions to choose from, throw an exception if numStateful == 0 and numStateless == 0: raise Exception("There are no functions to test") # If there are no state-affecting functions, choose a stateless one elif numStateful == 0: suite.append( self.buildStatelessTest(generator, str(len(suite) + 1))) # If there are no stateless functions, choose a stateful one elif numStateless == 0: suite.append( self.buildStatefulTest(generator, str(len(suite) + 1))) # If there are both, decide based on random number else: if chance < 0.5: suite.append( self.buildStatelessTest(generator, str(len(suite) + 1))) else: suite.append( self.buildStatefulTest(generator, str(len(suite) + 1))) else: done = 1 return suite # Build a non-state-affecting test case def buildStatelessTest(self, inputGenerator, testID): # Choose a function that does not affect global state unsupportedType = 0 index = random.randint(0, len(self.getDependencyMap()[1]) - 1) functionName = self.getDependencyMap()[1][index][0] # Find function for function in self.getFunctions(): if function[0] == functionName: returnType = " ".join(function[1]) inputs = function[2] break test = "void test" + testID + "(){\n" call = " " # If return is not void, assign it to a variable if returnType != "void": call = call + returnType + " call = " call = call + functionName + "(" # Generate inputs createdVars = "" for inputChoice in inputs: words = inputChoice.strip().split() inputName = words[len(words) - 1] typeToGenerate = " ".join(words[:len(words) - 1]) # Is is an array? if "[" in inputName: size = inputName[inputName.index("[") + 1:inputName.index("]")] if size == "": size = random.randint(1, self.maxArraySize) else: size = int(size) inputNameNoArray = inputName[:inputName.index("[")] createdVarName = "inputFor" + functionName + inputNameNoArray createdVar = " " + typeToGenerate + " " + createdVarName + "[" + str( size) + "] = {" for entry in range(0, size): value = inputGenerator.generate(typeToGenerate) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] createdVars = createdVars + " " + toAdd else: value = value[2:] createdVar = "// " + createdVar unsupportedType = 1 createdVar = createdVar + value + ", " createdVar = createdVar[:len(createdVar) - 2] + "};\n" createdVars = createdVars + createdVar call = call + createdVarName + ", " else: value = inputGenerator.generate(typeToGenerate) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 call = call + value + ", " call = call[:len(call) - 2] + ");\n" if unsupportedType == 1: call = "// " + call call = createdVars + call test = test + call test = test + "}\n\n" return test # Build a state-impacting test case def buildStatefulTest(self, inputGenerator, testID): # Test length length = 0 # Variables created in the test, available for use as input to other functions avail = [] inputGenerator.available = avail # Get the list of clear global variables clearVars = self.buildClearList() # Build initial test declaration test = "void test" + testID + "(){\n resetStateVariables();\n" # Set the length temperature ldone = 0 while ldone == 0: ltemperature = (self.maxLength - float(length)) / self.maxLength # Continue adding steps as long as random < ltemperature if random.random() < ltemperature: # Can either make an assignment or call a function inputGenerator.available = self.addClearToAvailable( avail, clearVars) actionTaken = 0 makeAssignment = 0 unsupportedType = 0 while actionTaken == 0: if random.random() < 0.5 or makeAssignment == 1: # Make an assignment call = " " # Choose a state variable index = random.randint( 0, len(self.getStateVariables()) - 1) var = self.getStateVariables()[index] if var[1] == "var": value = inputGenerator.generate(" ".join(var[2])) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 call = call + var[0] + " = " + value + ";\n" if unsupportedType == 1: call = "// " + call elif var[1] == "pointer": # Right now, this is the same as a normal variable. # In the future, will expand value = inputGenerator.generate(" ".join(var[2])) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 call = call + var[0] + " = " + value + ";\n" if unsupportedType == 1: call = "// " + call elif "array" in var[1]: # If the array is uninit, assign values to whole array # Otherwise, either choose an index or assign values initWhole = random.random() for varInit in clearVars: if varInit[0] == var[0]: if varInit[1] == "uninit": initWhole = 1 break if initWhole > 0.5: for index in range(0, int(var[1].split(",")[1])): value = inputGenerator.generate(" ".join( var[2])) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 if unsupportedType == 1: call = call + "//" + var[0] + "[" + str( index) + "] = " + value + ";\n " else: call = call + var[0] + "[" + str( index) + "] = " + value + ";\n " call = call[:len(call) - 4] else: aindex = random.randint( 0, int(var[1].split(",")[1]) - 1) value = inputGenerator.generate(" ".join( var[2])) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split(": ")[1] value = value.split(": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 call = call + var[0] + "[" + str( aindex) + "] = " + value + ";\n" if unsupportedType == 1: call = "// " + call test = test + call actionTaken = 1 # Mark as init in clear var list if unsupportedType == 0: for varIndex in range(0, len(clearVars)): if clearVars[varIndex][0] == var[0]: clearVars[varIndex][1] = "init" break else: # Choose a function that can be used with the current clear list options = [] for index in range(0, len(self.getDependencyMap()[0])): options.append(index) # If no functions can be used, we will make an assignment. while len(options) > 0: index = random.randint( 0, len(self.getDependencyMap()[0]) - 1) if index in options: for identifier in range(0, len(options)): if options[identifier] == index: options.remove(index) break functionName = self.getDependencyMap( )[0][index][0] # Check its needs against the clear list allInit = 1 for entry in self.getDependencyMap( )[0][index][1]: for var in clearVars: if entry == var[0]: if var[1] == "uninit": allInit = 0 break if allInit == 0: break if allInit == 1: # This is a function we can use # Find function for function in self.getFunctions(): if function[0] == functionName: returnType = " ".join(function[1]) inputs = function[2] break call = " " # If return is not void, assign it to a variable if returnType != "void": call = call + returnType + " call" + str( length) + " = " avail.append( ["call" + str(length), returnType]) call = call + functionName + "(" # Generate inputs createdVars = "" for inputChoice in inputs: words = inputChoice.strip().split() inputName = words[len(words) - 1] typeToGenerate = " ".join( words[:len(words) - 1]) # Is is an array? if "[" in inputName: size = inputName[ inputName.index("[") + 1:inputName.index("]")] if size == "": size = random.randint( 1, self.maxArraySize) else: size = int(size) inputNameNoArray = inputName[: inputName . index( "[" )] createdVarName = "inputFor" + functionName + inputNameNoArray + str( length) createdVar = " " + typeToGenerate + " " + createdVarName + "[" + str( size) + "] = {" for entry in range(0, size): value = inputGenerator.generate( typeToGenerate) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split( ": ")[1] value = value.split( ": ")[0] value = value[2:] createdVars = createdVars + " " + toAdd else: value = value[2:] unsupportedType = 1 createdVar = "//" + createdVar createdVar = createdVar + value + ", " createdVar = createdVar[:len( createdVar) - 2] + "};\n" createdVars = createdVars + createdVar call = call + createdVarName + ", " else: value = inputGenerator.generate( typeToGenerate) if "//" in value: if "structInput" in value or "unionInput" in value: toAdd = value.split( ": ")[1] value = value.split( ": ")[0] value = value[2:] call = " " + toAdd + call else: value = value[2:] unsupportedType = 1 call = call + value + ", " call = call[:len(call) - 2] + ");\n" if unsupportedType == 1: call = "//" + call call = createdVars + call test = test + call # Update clear list if unsupportedType == 0: for provides in self.getDependencyMap( )[0][index][2]: for var in range( 0, len(clearVars)): if clearVars[var][ 0] == provides: clearVars[var][1] = "init" break actionTaken = 1 break # If no functions can be used, we will make an assignment. makeAssignment = 1 length += 1 else: ldone = 1 test = test + "}\n\n" inputGenerator.available = [] return test # Append initialized global variables to the available list for generation def addClearToAvailable(self, available, clear): combined = copy.deepcopy(available) for var in clear: if var[1] == "init": if "[" in var[2]: returnType = var[2].split("[")[0] length = var[2].split("[")[1] length = int(length[:len(length) - 1]) for index in range(0, length): combined.append( [var[0] + "[" + str(index) + "]", returnType]) else: combined.append([var[0], var[2]]) return combined # Build suite code def buildCode(self, suite, outFile): code = [] # Add includes statements code.append("#include <stdio.h>\n") code.append("#include \"" + os.path.basename(self.getProgram()) + "\"") # Declare test array code.append( "\n// Array indexing test entries.\n// tests[0] indicates number of tests\n// tests[1] corresponds to test1(), etc.\n" ) code.append("//TESTLIST") # Add code for printing to screen/file and resetting obligation scores. code.append( "\n// Flag for printing obligation scores to a CSV file at the end of execution.\nint print = 1;\n" ) code.append("//FILENAME") code.append( "\n// Flag for printing obligation scores to the screen at the end of execution.\nint screen = 1;\n\n// Prints obligation scores to the screen\nvoid printScoresToScreen(){\n printf(\"# Obligation, Score (Unnormalized)\\n\");\n int obligation;\n for(obligation=1; obligation<=obligations[0]; obligation++){\n printf(\"%d, %f\\n\",obligation,obligations[obligation]);\n }\n}\n\n// Prints obligation scores to a file\nvoid printScoresToFile(){\n FILE *outFile = fopen(fileName,\"w\");\n fprintf(outFile, \"# Obligation, Score (Unnormalized)\\n\");\n int obligation;\n for(obligation=1; obligation<=obligations[0]; obligation++){\n fprintf(outFile,\"%d, %f\\n\",obligation,obligations[obligation]);\n }\n fclose(outFile);\n}\n\n// Resets obligation scores\nvoid resetObligationScores(){\n int obligation;\n for(obligation=1; obligation<=obligations[0]; obligation++){\n // Set to some high level\n obligations[obligation] = 1000000.0;\n }\n}\n" ) # Add state reset code.append(self.buildReset()) code.append("// Test Cases\n") code.append("//TESTS") # Append test runner and main code.append("// Top-level test runner.\nvoid runner(){\n") for test in range(1, len(suite.getTestList()) + 1): code.append(" if(tests[" + str(test) + "] == 1)\n") code.append(" test" + str(test) + "();\n") code.append( "\n if(screen == 1)\n printScoresToScreen();\n if(print == 1)\n printScoresToFile();\n}\n\nint main(){\n runner();\n return(0);\n}\n" ) return code # Take the list of global variables and build a state reset function that can be called by test cases. def buildReset(self): code = "// Resets values of all state values with declared initial values.\nvoid resetStateVariables(){\n" for var in self.getStateVariables(): if var[3] != '': # Has an initial value. if var[1] == "var" or var[1] == "pointer": code = code + " " + var[0] + " = " + var[3] + ";\n" elif var[1] == "array": values = var[3].strip().split(",") for index in range(0, len(values)): code = code + " " + var[0] + "[" + str( index) + "] = " + str( values[index]).strip() + ";\n" code = code + "}\n\n" return code # Read in C file and get list of functions and state variables from it. def initializeProgramData(self): # Parse the program and generate the AST ast = parse_file(self.getProgram(), use_cpp=True, cpp_path="gcc", cpp_args=['-E', r'-Iutils/fake_libc_include']) #ast.show() # Use the ProgramDataVisitor to build the function, type def, and global variable lists pdVisitor = ProgramDataVisitor() pdVisitor.visit(ast) self.setFunctions(pdVisitor.functions) self.setStateVariables(pdVisitor.stateVariables) self.setTypeDefs(pdVisitor.typeDefs) self.setStructs(pdVisitor.structs) self.setUnions(pdVisitor.unions) self.setEnums(pdVisitor.enums) print self.getFunctions() print self.getStateVariables() print self.getTypeDefs() print self.getStructs() print self.getUnions() print self.getEnums() # Use the DependencyMapVisitor to build the dependency map dpVisitor = DependencyMapVisitor(self.getFunctions(), self.getStateVariables()) dpVisitor.visit(ast) sequenceMap = dpVisitor.dependencyMap print sequenceMap # Dependency map has two lists - stateful functions and stateless functions dependencyMap = [[], []] # SequenceMap is a list of defs and uses in order. Transform this into the dependency map, just a simple # list of variables that must be initialized before the function can be called. for function in sequenceMap: clearList = self.buildClearList() dependencyEntry = self.processSequence(clearList, function[0], function[1], sequenceMap) # If the uses and provides lists are empty, this is not a state-based function if dependencyEntry[1] == [] and dependencyEntry[2] == []: dependencyMap[1].append(dependencyEntry) else: dependencyMap[0].append(dependencyEntry) self.setDependencyMap(dependencyMap) print self.getDependencyMap() # Process sequence and return a dependency list def processSequence(self, clearList, function, sequence, sequenceMap): dependencyEntry = [function, [], []] seen = [function] # Go through each interaction. seqLen = len(sequence) interaction = 0 while interaction < seqLen: # If we've seen it already, skip it if sequence[interaction][0] not in dependencyEntry[1] or sequence[ interaction][0] not in dependencyEntry[2]: # It will either be a def, a use, or a function call if sequence[interaction][1] == "def": # Mark it as init for entry in range(0, len(clearList)): if clearList[entry][0] == sequence[interaction][0]: clearList[entry] = [clearList[entry][0], "init"] if sequence[interaction][0] not in dependencyEntry[ 2]: dependencyEntry[2].append( sequence[interaction][0]) break elif sequence[interaction][1] == "use": # If the variable is uninit, then we depend on it being initialized by another function first. for entry in clearList: if entry[0] == sequence[interaction][0]: if entry[1] == "uninit": if sequence[interaction][ 0] not in dependencyEntry[1]: dependencyEntry[1].append( sequence[interaction][0]) break elif sequence[interaction][1] == "function": # If a function is called, put in its interactions and process them. # Only append a function once - if a variable is uninitialized the first time, it doesn't matter if we call it again. if sequence[interaction][0] not in seen: seen.append(sequence[interaction][0]) for toInline in sequenceMap: if toInline[0] == sequence[interaction][0]: # Add interactions to the list for line in range(0, len(toInline[1])): sequence.insert(interaction + line + 1, toInline[1][line]) seqLen = len(sequence) break interaction += 1 return dependencyEntry # Build the clear list - a list of global variables that are safe to use. def buildClearList(self): clearList = [] for var in self.getStateVariables(): returnType = " ".join(var[2]) if "array" in var[1]: returnType = returnType + "[" + var[1].split(",")[1] + "]" if var[3] == '': # No initialized value, so not safe clearList.append([var[0], "uninit", returnType]) else: clearList.append([var[0], "init", returnType]) return clearList # Setters for global variables def setProgram(self, program): self.__program = program def setFunctions(self, functions): self.__functions = functions def setStateVariables(self, stateVariables): self.__stateVariables = stateVariables def setDependencyMap(self, dependencyMap): self.__dependencyMap = dependencyMap def setTypeDefs(self, typeDefs): self.__typeDefs = typeDefs def setStructs(self, structs): self.__structs = structs def setUnions(self, unions): self.__unions = unions def setEnums(self, enums): self.__enums = enums # Getters for global variables def getProgram(self): return self.__program def getFunctions(self): return self.__functions def getStateVariables(self): return self.__stateVariables def getDependencyMap(self): return self.__dependencyMap def getTypeDefs(self): return self.__typeDefs def getStructs(self): return self.__structs def getUnions(self): return self.__unions def getEnums(self): return self.__enums
class Controller: """ | Proporciona la infraestructura adecuada para poder comunicar la sección Vista **(ó View)** con la sección Modelo **(ó Model)**, apoyándose de las clases XMLParser y Verifier. | | El ciclo normal consiste en proporcionar a la capa Vista **(ó View)** la información recabada en los archivos .xml con ayuda de la clase XMLParser con la finalidad de notificar al usuario de todas las técnicas disponibles. | | Una vez ejecutada la opción de iniciar un proceso genético por el usuario, se recaban los datos ingresados por el usuario, los cuales pasan por un proceso de verificación y transformación empleando para ello los métodos de la clase Verifier. | | En caso de haber al menos una falla en alguno de los procedimientos mencionados anteriormente se regresa un mensaje de error, en otro caso se pasa la información respectiva a la capa Model para que pueda operar con ésta. | | En cualquiera de los dos casos anteriores se regresa la información resultante a la Vista. :returns: Controller.Controller :rtype: Instance """ def __init__(self): #Se almacena el nombre del archivo .xml donde se #almacenan los nombres de todas las técnicas con #sus parámetros que se encuentran disponibles para el usuario. self.__features_filename = "Features.xml" #Se guarda el nombre del archivo .xml que contiene #los M.O.P.'s disponibles para el usuario. #Un M.O.P. (Multi-Objective Problem) es un conjunto de variables #de decisión y funciones objetivo cuyo resultado está bien #estudiado, se utiliza principalmente para comprobar que el #funcionamiento del proyecto es el óptimo y además proveer #al usuario de una alternativa rápida y concisa para utilizar #el proyecto. self.__mop_examples_filename = "MOPExamples.xml" #A continuación se toma el nombre del archivo que almacena las #expresiones especiales de Python. #Esto sucede porque en ocasiones hay algunas funciones o constantes #especiales que el intérprete de Python no comprende directamente, #por ello es que se necesita establecer una relación entre las #expresiones que ingresa el usuario y su equivalente en Python. #Por ello es que al crear o evaluar funciones objetivo se debe hacer #uso de estas expresiones. self.__python_expressions_filename = "PythonExpressions.xml" #Se obtiene una instancia de la clase que opera con archivos #.xml. self.__parser = XMLParser() #Se guarda una instancia de la clase que verifica y convierte #apropiadamente los datos que el usuario ingresa para ejecutar #algún algoritmo M.O.E.A. (Multi-Objective Evolutionary Algorithm). self.__verifier = Verifier() def load_features(self): """ | Regresa los datos correspondientes **(debidamente verificados)** a las técnicas disponibles para el usuario, los cuales se mostrarán en **View/MainWindow.py**. | **(véase View/Additional/MenuInternalOption/InternalOptionTab/FeatureFrame.py)**. | Esta técnica tiene como base los símiles que se encuentran en **Controller/XMLParser.py** y **Controller/Verifier.py**. :returns: Una estructura con los métodos disponibles para el usuario. :rtype: Dictionary """ #Aquí se almacenan los datos obtenidos por el método de Controller/XMLParser.py. data = None #Se ejecuta el método que obtiene los datos del archivo .xml correspondiente. #Lo que se extraiga se guarda en la variable creada anteriormente. try: data = self.__parser.load_xml_features(self.__features_filename) #Si por alguna razón ocurre una falla en la carga de datos se almacena #en la variable "data" el valor "ERROR", esto para indicar que ha habido #un desperfecto en el procedimiento. except: data = "ERROR" #Al final se regresan los datos verificados por el método #correspondiente de la clase Controller/Verifier.py return self.__verifier.verify_load_xml_features(data) def load_mop_examples(self): """ | Obtiene los datos correspondietes **(previamente verificados)** a los M.O.P.'s **(Multi-Objective Problems)** que se utilizan en en **View/MainWindow.py** | **(véase View/Additional/MenuInternalOption/InternalOptionTab/MOPExampleFrame.py)**. | Esta técnica tiene como base las análogas que se encuentran en **Controller/XMLParser.py** y **Controller/Verifier.py**. :returns: Una estructura con los M.O.P.'s disponibles para el usuario. :rtype: Dictionary """ #En esta variable se almacenan los datos cargados por el método #localizado en Controller/XMLParser.py. data = None #A continuación se lleva a cabo la carga correspondiente de los datos en el #archivo pertinente, almacenando éstos en la variable creada con anterioridad. try: data = self.__parser.load_xml_mop_examples( self.__mop_examples_filename) #En caso de existir alguna falla durante el proceso la variable data adquiere #el valor "ERROR", para hacer énfasis en el desperfecto. except: data = "ERROR" #Se regresan los datos verificados auxiliándose del método localizado en #Controller/Verifier.py. return self.__verifier.verify_load_xml_mop_examples(data) def load_python_expressions(self): """ | Obtiene los datos correspondietes **(previamente verificados)** a las expresiones de Python, las cuales se usan para evaluar funciones objetivo más eficientemente | **(véase View/Additional/MenuInternalOption/InternalOptionTab/PythonExpressionFrame.py)**. | Esta función se apoya de las homónimas localizadas en **Controller/XMLParser.py** y **Controller/Verifier.py**. :returns: Una estructura con las expresiones de Python disponibles. :rtype: Dictionary """ #En esta variable se almacenan los datos que se vayan a cargar con ayuda de #la función ubicada en Controller/XMLParser.py. data = None #Ahora se ejecuta el método que carga los datos correspondientes, almacenando éstos #en la variable mencionada antes. try: data = self.__parser.load_xml_python_expressions( self.__python_expressions_filename) #Si durante el proceso llega a existir algún inconveniente entonces a la variable #"data" se le asigna el valor "ERROR" para enfatizar que hubo un contratiempo. except: data = "ERROR" #Para finalizar se regresa lo que se obtenga de ejecutar el método correspondiente #que se encuentra en Controller/Verifier.py. return self.__verifier.verify_load_xml_python_expressions(data) def save_python_expressions(self, data): """ Inserta las expresiones de Python que ha ingresado el usuario en el archivo .xml correspondiente. :param data: Un conjunto de las expresiones que ha ingresado el usuario. Cada elemento es a su vez una lista con dos elementos, el primero es la expresión original **(la que es comprensible por el usuario)**, mientras que la segunda es la expresión equivalente en Python. :type data: List :returns: Mensaje "OK" si la inserción ha sido exitosa, mientras que en caso de que haya habido un error entonces el mensaje es "ERROR". :rtype: String """ #Se ejecuta la función pertinente (que reside en Controller/Verifier.py), la cual #revisa que los datos no tengan desperfectos. verifier_code = self.__verifier.verify_write_xml_python_expressions( data) #Si el código que regresa la función es "OK", se realiza la operación de inserción #en el archivo correspondiente. if verifier_code == "OK": self.__parser.write_xml_python_expressions( self.__python_expressions_filename, data) #Sin importar el código resultante, éste se regresa para que pueda ser usado en #otras secciones del programa (véase View/Additional/MenuInternalOption/InternalOptionTab/PythonExpressionFrame.py). return verifier_code def sanitize_settings(self, general_information, features): """ Lleva a cabo la verificación y saneamiento de todos los datos que ha ingresado el usuario en la sección View **(véase View/MainWindow)**. :param general_information: El conjunto de datos que el usuario ha ingresado o seleccionado. :param features: Una colección de todos los elementos con sus características disponibles para el usuario. :type general_information: Dictionary :type features: Dictionary :returns: El diccionario que contiene todos los datos debidamente saneados. :rtype: Dictionary """ #Aquí se almacenan los resultados verificados y saneados. result = {} #Se prepara un diccionario con información genérica sobre algún error #que llegara a ocurrir en esta función. error = { "response": "ERROR", "class": "Controller", "method": "__sanitize_settings", } #Se crean estructuras para guardar las expresiones de Python saneadas (convertidas a instancias). #La copia sirve para evitar la contaminación de dichas expresiones ya que se deberán usar para sanear #las funciones objetivo. sanitized_available_expressions = {} copy_sanitized_available_expressions = {} #Se leen del archivo .xml correspondiente las expresiones personalizadas para Python. available_expressions = self.load_python_expressions() #Si llega a existir una falla en la lectura de dichas expresiones el proceso #se detiene inmediatamente no sin antes haber regresado un mensaje de error #con los elementos relativos a la falla. if available_expressions.has_key("recent"): error["frame"] = available_expressions["recent"]["frame"] error[ "message"] = "A problem with at least one of the Python expressions has occurred." available_expressions["previous"].append( available_expressions["recent"]) available_expressions["recent"] = error return available_expressions #A continuación se transforman las expresiones de Python a instancias para que puedan ser reconocidas #independientemente de la biblioteca usada. #La variable copia es para mantener un registro limpio de dichas instancias ya que para hacer las pruebas #de calidad a las funciones objetivo se usará la otra variable y ésta quedará inevitablemente contaminada. for expression in available_expressions.keys(): sanitized_expression = self.__verifier.get_dynamic_function( available_expressions[expression]) sanitized_available_expressions[expression] = sanitized_expression copy_sanitized_available_expressions[ expression] = sanitized_expression #Posteriormente se lleva a cabo el proceso de sanitización de los tipos de las técnicas, es decir, #las técnicas usadas deben ser o todas de tipo float o todas de tipo binario (aunque hay algunas que #pueden pertenecer a ambos tipos). #En caso de existir un desperfecto el proceso se interrumpe aquí, regresando un mensaje de error #con los detalles. sanitized_techniques = self.__verifier.sanitize_techniques( general_information, features) if sanitized_techniques.has_key("recent"): error["frame"] = sanitized_techniques["recent"]["frame"] error[ "message"] = "A problem with at least one selected technique has occurred." sanitized_techniques["previous"].append( sanitized_techniques["recent"]) sanitized_techniques["recent"] = error return sanitized_techniques #Ahora se lleva a cabo la verificación y saneamiento de las variables de decisión (junto con sus #respectivos rangos). #En caso de existir algún error se interrumpe el proceso, regresando un mensaje con los #detalles de la falla. sanitized_decision_variables = self.__verifier.sanitize_decision_variables( general_information["Decision Variables"]) if sanitized_decision_variables.has_key("recent"): error["frame"] = "Decision Variables" error[ "message"] = "A problem occurred while sanitizing decision variables." sanitized_decision_variables["previous"].append( sanitized_decision_variables["recent"]) sanitized_decision_variables["recent"] = error return sanitized_decision_variables #A continuación se verifican y transforman las funciones objetivo. #Si llega a existir un desperfecto en el proceso se manda un mensaje de error #con las fallas detalladas. sanitized_objective_functions = self.__verifier.sanitize_objective_functions( sanitized_decision_variables, copy_sanitized_available_expressions, general_information["Objective Functions"]) if sanitized_objective_functions.has_key("recent"): error["frame"] = "Objective Functions" error[ "message"] = "A problem occurred while sanitizing objective functions." sanitized_objective_functions["previous"].append( sanitized_objective_functions["recent"]) sanitized_objective_functions["recent"] = error return sanitized_objective_functions #Toca el turno de la verificación y transformación de datos correspondientes #a la categoría "Population Settings" que se encuentra en View/MainWindow.py. #En caso de encontrarse con algún error, el proceso se detiene en este punto #y se obtiene un mensaje de error con las características alusivas a éste. sanitized_population_settings = self.__verifier.sanitize_population_settings( general_information["Population Settings"], features) if sanitized_population_settings.has_key("recent"): error["frame"] = "Population Settings" error[ "message"] = "A problem occurred while sanitizing population settings." sanitized_population_settings["previous"].append( sanitized_population_settings["recent"]) sanitized_population_settings["recent"] = error return sanitized_population_settings #Ahora se revisan y transforman los datos correspondientes a la categoría #"Genetic Operators Settings" que se encuentran en View/MainWindow.py, si #se recaba alguna falla en el procedimiento se detiene esta función regresando #un mensaje de error con las características del desperfecto. sanitized_genetic_operator_settings = self.__verifier.sanitize_genetic_operators_settings( general_information["Genetic Operators Settings"], features, sanitized_decision_variables, sanitized_population_settings["number_of_decimals"]) if sanitized_genetic_operator_settings.has_key("recent"): error["frame"] = "Genetic Operators Settings" error[ "message"] = "A problem occurred while sanitizing genetic operator settings." sanitized_genetic_operator_settings["previous"].append( sanitized_genetic_operator_settings["recent"]) sanitized_genetic_operator_settings["recent"] = error return sanitized_genetic_operator_settings #Para concluir se verifican y sanean los datos relacionados con la categoría #"MOEAs Settings" localizada en View/MainWindow.py. En caso de ocurrir un desperfecto #el proceso es interrumpido en este punto y se devuelve un mensaje de error con los #detalles alusivos a la falla. sanitized_moeas_settings = self.__verifier.sanitize_moeas_settings( general_information["MOEAs Settings"], features) if sanitized_moeas_settings.has_key("recent"): error["frame"] = "MOEAs Settings" error[ "message"] = "A problem occurred while sanitizing moeas settings." sanitized_moeas_settings["previous"].append( sanitized_moeas_settings["recent"]) sanitized_moeas_settings["recent"] = error return sanitized_moeas_settings #Llegados a este punto todos los elementos saneados se agregan en la #estructura creada explícitamente para ello. #Primero se adjuntan las expresiones de Python saneadas, es decir, se convierten #en instancias del tipo de función que representan. result.update( {"available_expressions": sanitized_available_expressions}) #A continuación se añaden las variables de decisión saneadas. result.update(sanitized_decision_variables) #Posteriormente se agregan las funciones objetivo saneadas. result.update(sanitized_objective_functions) #Ahora se adjuntan los elementos saneados de la categoría #gráfica "Population Settings". result.update(sanitized_population_settings) #Luego se anexan los elementos saneados correspondientes #a la cateoría gráfica "Genetic Operator Settings". result.update(sanitized_genetic_operator_settings) #Entonces se colocan los elementos saneados alusivos a la #categoría gráfica "MOEAs Settings". result.update(sanitized_moeas_settings) #Finalmente se regresa el diccionario con todos los elementos #de todas las categorías debidamente saneados. return result def execute_procedure(self, execution_task_count, generations_queue, sanitized_information): """ Realiza la ejecución de algún algoritmo M.O.E.A. **(Multi-Objective Evolutionary Algorithm)** y se encarga de obtener los resultados apropiadamente. :param execution_task_count: Una característica numérica que identifica inequívocamente a esta función que será ejecutada de las demás, ya que el objetivo del proyecto es poder ejecutar varios de estos métodos de manera concurrente **(véase View/Additional/ResultsGrapher/ResultsGrapherToplevel.py)**. :param generations_queue: Una instancia a una cola **(Queue)**, la cual servirá para escribir a esa estructura el número actual de generación por el que cursa el algoritmo. Esta acción es para fines de concurrencia **(véase View/MainWindow.py)**. :param sanitized_information: Los parámetros que ingresó el usuario debidamente verificados y saneados. :type execution_task_count: Integer :type generations_queue: Instance :type sanitized_information: Dictionary :returns: Un diccionario con información de los resultados de haber ejecutado el M.O.E.A. seleccionado por el usuario, la estructura del mismo puede verse en **Model/Community/Community.py**. :rtype: Dictionary """ #Tomando en cuenta la información saneada, ésta se separa apropiadamente #para que pueda pasarse como parámetros en el M.O.E.A. #Este es el número de generaciones. generations = sanitized_information["number_of_generations"] #Este es el tamaño de la población. population_size = sanitized_information["population_size"] #Se obtiene el vector de funciones objetivo. vector_functions = sanitized_information["vector_functions"] #Se obtiene el vector de variables de decisión. vector_variables = sanitized_information["vector_variables"] #Se obtienen las expresiones especiales de Python. available_expressions = sanitized_information["available_expressions"] #Aquí se almacena el número de decimales que llevarán las soluciones #de una Población (véase Model/Community/Population/Population.py). number_of_decimals = sanitized_information["number_of_decimals"] #A continuación se adquiere la instancia de la Comunidad #(véase Model/Community/Community.py). community_instance = sanitized_information["community_instance"] #Se almacenan los valores de la instancia del M.O.E.A. #seleccionado (véase Model/MOEA), así como de sus parámetros. algorithm_instance = sanitized_information["moea_instance"] algorithm_parameters = sanitized_information["moea_parameters"] #Se extraen los valores de la instancia de la técnica de Representación #Cromosómica elegida (Chromosomal Representation, véase Model/ChromosomalRepresentation), #así como de sus parámetros. representation_instance = sanitized_information[ "representation_instance"] representation_parameters = sanitized_information[ "representation_parameters"] #Se obtienen los valores de la instancia de la técnica de Fitness #utilizada (véase Model/Fitness), así como de sus parámetros. fitness_instance = sanitized_information["fitness_instance"] fitness_parameters = sanitized_information["fitness_parameters"] #Ahora se extraen los valores de la instancia de la técnica de Sharing Function #(ó Función de Compartición, véase Model/SharingFunction) escogida, así como de sus parámetros. sharing_function_instance = sanitized_information[ "sharing_function_instance"] sharing_function_parameters = sanitized_information[ "sharing_function_parameters"] #Luego se guardan los valores de la instancia de la técnica de Selection #(ó Selección, véase Model/Operator/Selection) utilizada, así como de sus parámetros. selection_instance = sanitized_information["selection_instance"] selection_parameters = sanitized_information["selection_parameters"] #A continuación se guardan los valores de la instancia de la técnica de Crossover #(ó Cruza, véase Model/Operator/Crossover) empleada, así como de sus parámetros. crossover_instance = sanitized_information["crossover_instance"] crossover_parameters = sanitized_information["crossover_parameters"] #Posteriormente se almacenan los valores de la instancia de la técnica de Mutation #(ó Mutación, véase Model/Operator/Mutation) elegida, así como de sus parámetros. mutation_instance = sanitized_information["mutation_instance"] mutation_parameters = sanitized_information["mutation_parameters"] #Se manda ejecutar el método execute_moea de la instancia del #algoritmo que se creó previamente (véase Verifier.py). #La finalidad de esta implementación es obtener la ejecución de #varios algoritmos de manera dinámica, es decir, sin necesidad #de estar importando bibliotecas y colocando el código de manera #estática. final_results = getattr(algorithm_instance, "execute_moea")( execution_task_count, generations_queue, generations, population_size, vector_functions, vector_variables, available_expressions, number_of_decimals, community_instance, algorithm_parameters, representation_instance, representation_parameters, fitness_instance, fitness_parameters, sharing_function_instance, sharing_function_parameters, selection_instance, selection_parameters, crossover_instance, crossover_parameters, mutation_instance, mutation_parameters) #Nota: no es necesario agregar una capa de error en caso #de recibir algo incorrecto, la misma sección Model se #encarga de todo. #Al final se regresan los resultados de la ejecución del M.O.E.A. return final_results
class Instrumentation(): scoreEpsilon = 1.0 verifier = Verifier() # Central process of instrumentation def instrument(self,program,labelFile,outFile): # Get number of obligations numObs=self.getNumObs(labelFile) # Read in C file and add instrumentation instrumented=[] code=open(program,'r') includes=1 partial="-1" for line in code: # Insert obligations array as a global variable after all include statements are over. # Also insert the constant used in cost functions. if "#includes" not in line and includes==1: includes=0 obDeclaration="float obligations["+str(numObs+1)+"] = {"+str(numObs)+".0" # Initialize all scores to some high constant for ob in range(1,numObs+1): obDeclaration+=", 1000000.0" instrumented.append(obDeclaration+"};") instrumented.append("float scoreEpsilon = "+str(self.scoreEpsilon)+";") instrumented.append(line) # Replace labels with scores elif "pc_label(" in line: if ");" in line: replaced=self.replaceLabel(line.strip()) instrumented.append(replaced) else: partial=line.strip() elif partial != "-1": partial=partial+line.strip() if ");" in line: replaced=self.replaceLabel(partial) instrumented.append(replaced) partial="-1" else: instrumented.append(line) code.close() # Print instrumented code to file self.writeOutFile(instrumented,outFile) # Verify obligations to ensure that they compile. # If they do not, comment them out and replace with dummy score. self.verifier.verify(outFile, outFile) # Gets number of obligations from label file def getNumObs(self,labelFile): labels=open(labelFile, 'r') maxNum=0 lNum=0 for label in labels: lNum+=1 if lNum > 1: words=label.strip().split(",") if int(words[0]) > maxNum: maxNum=int(words[0]) labels.close() return maxNum # Replace label with score calculation def replaceLabel(self,label): # Split label into parts to extract predicate and identifier adjustedLabel=label[label.index("pc_label(")+9:label.index(");")] words=adjustedLabel.strip().split(",") # Prepare new expression newLabel="obligations["+words[1]+"]=" # Break down predicate into cost function lexer = Lexer(words[0]) parser = Parser(lexer) interpreter = Interpreter(parser) equation=interpreter.interpret() # Check whether new score is better than existing score newLabel=newLabel+"(("+equation+" < obligations["+words[1]+"]) ? "+equation+" : obligations["+words[1]+"]);" return newLabel # Write instrumented program to a file def writeOutFile(self,instrumented,outFile): where = open(outFile, 'w') for line in instrumented: where.write(line+"\n") where.close() # Set constant used in cost functions def setScoreEpsilon(self,scoreEpsilon): self.scoreEpsilon = scoreEpsilon