Skip to content
Snippets Groups Projects
Commit 0bcb8572 authored by braught2's avatar braught2
Browse files

update main method to show easy usage

parent 422ebd69
No related branches found
No related tags found
No related merge requests found
......@@ -244,16 +244,45 @@ def createTransition(path, vertices, modes):
return edges
class controller_ast():
'''
Initalizing function for a controller_ast object.
Reads in the code and parses it to a python ast and statement tree.
Statement tree is a tree of nodes that contain a list in their data. The list contains a single guard or a list of resets.
Variables (inputs to the controller) are collected.
Modes are collected from all enums that have the word "mode" in them.
Vertices are generated by taking the products of mode types.
'''
def __init__(self, code):
self.code = code
self.tree = ast.parse(code)
#statement tree is a tree of nodes that contain a list in their data. The list contains a single guard or a list of resets
self.statementtree, self.variables, self.modes = self.initalwalktree(code, tree)
self.statementtree, self.variables, self.modes = self.initalwalktree(code, self.tree)
self.vertices = []
self.vertexStrings = []
for vertex in itertools.product(*self.modes.values()):
self.vertices.append(vertex)
vertexstring = vertex[0]
for index in range(1,len(vertex)):
vertexstring += ";" + vertex[index]
self.vertexStrings.append(vertexstring)
self.paths = None
'''
Function to populate paths variable with all paths of the controller.
'''
def getAllPaths(self):
currentModes = []
for modeTypes in self.modes.values():
currentModes.extend(modeTypes)
self.paths = self.getNextModes(currentModes)
return self.paths
#assume that currentModes is a list of all node types!
#TODO: should we not force all modes be listed? Or rerun for each unknown/don't care node? Or add them all to the list
'''
getNextModes takes in a list of current modes. It should include all modes.
getNextModes returns a list of paths that can be followed when in the given mode.
A path is a list of statements, all guards and resets along the path. They are in the order they are encountered in the code.
TODO: should we not force all modes be listed? Or rerun for each unknown/don't care node? Or add them all to the list
'''
def getNextModes(self, currentModes):
#walk the tree and capture all paths that have modes that are listed. Path is a list of statements
paths = []
......@@ -263,6 +292,10 @@ class controller_ast():
return paths
'''
Helper function to walk the statement tree from parentnode and find paths that are allowed in the currentMode.
Returns a list of paths.
'''
def walkstatements(self, parentnode, currentModes):
nextsPaths = []
......@@ -292,7 +325,15 @@ class controller_ast():
return nextsPaths
def create_json(input_file_name, output_file_name):
'''
Function to create a json of the full graph.
Requires that paths class variables has been set.
'''
def create_json(self, input_file_name, output_file_name):
if not self.paths:
print("Cannot call create_json without calling getAllPaths")
return
with open(input_file_name) as in_json_file:
input_json = json.load(in_json_file)
......@@ -305,16 +346,16 @@ class controller_ast():
guards = []
resets = []
for path in paths:
transitions = createTransition(path, vertices, modes)
for path in self.paths:
transitions = createTransition(path, self.vertices, self.modes)
for edge in transitions:
edges.append([edge.source, edge.dest])
guards.append(guardString(edge.guards))
resets.append(resetString(edge.resets))
output_dict['vertex'] = vertexStrings
output_dict['vertex'] = self.vertexStrings
#print(vertices)
output_dict['variables'] = variables
output_dict['variables'] = self.variables
# #add edge, transition(guards) and resets
output_dict['edge'] = edges
#print(len(edges))
......@@ -331,6 +372,10 @@ class controller_ast():
print("wrote json to " + output_file_name)
#inital tree walk, parse into a tree of resets/modes
'''
Function called by init function. Walks python ast and parses to a statement tree.
Returns a statement tree (nodes contain a list of either a single guard or muliple resets), the variables, and a mode dictionary
'''
def initalwalktree(self, code, tree):
vars = []
out = []
......@@ -346,17 +391,19 @@ class controller_ast():
if isinstance(node, ast.FunctionDef):
if node.name == 'controller':
#print(node.body)
out = self.parsenodelist(code, node.body, False, Tree(), None)
statementtree = self.parsenodelist(code, node.body, False, Tree(), None)
#print(type(node.args))
args = node.args.args
for arg in args:
if "mode" not in arg.arg:
vars.append(arg.arg)
#todo: what to add for return values
return [out, vars, mode_dict]
return [statementtree, vars, mode_dict]
'''
Helper function for initalwalktree which parses the statements in the controller function into a statement tree
'''
def parsenodelist(self, code, nodes, addResets, tree, parent):
childrens_guards=[]
childrens_resets=[]
......@@ -407,80 +454,37 @@ if __name__ == "__main__":
input_file_name = 'billiard_input.json' #sys.argv[2]
output_file_name = 'out.json' #sys.argv[3]
with open(input_file_name) as in_json_file:
input_json = json.load(in_json_file)
output_dict = {
}
#read in the controler code
f = open(input_code_name,'r')
code = f.read()
tree = ast.parse(code)
#tree = ast.parse()
#paths, variables, modes = walktree(code, tree)
test = controller_ast(code)
paths = test.getNextModes("NormalA;Normal3")
variables = test.variables
modes = test.modes
#parse the controller code into our controller ast objct
controller_obj = controller_ast(code)
#demonstrate you can check getNextModes after only initalizing
paths = controller_obj.getNextModes("NormalA;Normal3")
print("Results")
for path in paths:
for item in path:
print(item.code)
print()
print("Done")
#print("Paths found:")
#for result in paths:
# for item in result:
#item.print()
#print(item.mode)
#print(item.modeType)
# print()
#print("Modes found: ")
#print(modes)
output_dict.update(input_json)
vertices = []
vertexStrings = []
for vertex in itertools.product(*modes.values()):
vertices.append(vertex)
vertexstring = vertex[0]
for index in range(1,len(vertex)):
vertexstring += ";" + vertex[index]
vertexStrings.append(vertexstring)
edges = []
guards = []
resets = []
#attempt to write to json, fail because we haven't populated paths yet
controller_obj.create_json(input_file_name, output_file_name)
for path in paths:
transitions = createTransition(path, vertices, modes)
for edge in transitions:
edges.append([edge.source, edge.dest])
guards.append(guardString(edge.guards))
resets.append(resetString(edge.resets))
output_dict['vertex'] = vertexStrings
#print(vertices)
output_dict['variables'] = variables
# #add edge, transition(guards) and resets
output_dict['edge'] = edges
#print(len(edges))
output_dict['guards'] = guards
#print(len(guards))
output_dict['resets'] = resets
#print(len(resets))
output_json = json.dumps(output_dict, indent=4)
outfile = open(output_file_name, "w")
outfile.write(output_json)
outfile.close()
print("wrote json to " + output_file_name)
controller_obj.getAllPaths()
controller_obj.create_json(input_file_name, output_file_name)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment