def generate_loop(fail_edge, edges, max_iter, named_states, old_context): context = copy.deepcopy(old_context) loop = [] i = 0 curr_edge = fail_edge einfo = edge_obj(curr_edge[2]) full_guard = einfo['guard'] while i < max_iter: failed = get_failed_guard(full_guard, context) nextedge = get_next_edge(failed, full_guard, curr_edge, edges, named_states, copy.deepcopy(context)) nextinfo = edge_obj(nextedge[2]) context = run_transition(context, nextedge, nextinfo, named_states) loop.append(nextedge) curr_edge = nextedge # failing transition is now traversable, return the loop if (evaluate_guards(full_guard, context) and nextedge[1] == fail_edge[0]): return loop, context i += 1 raise Exception('Unable to find loop')
def get_next_edge(failed_guards, full_guard, curr_edge, edges, named_states, context): outgoing = get_outgoing(curr_edge[0], edges) candidates = [ x for x in outgoing if (evaluate_guards(edge_obj(x[2])['guard'], context)) ] if (len(candidates) > 0): bf_vals = [[] for c in candidates] #current branch function value for all guards curr_bf_vals = eval(full_guard[0]['branch_f']['func'], {}, context) i = 0 for candidate in candidates: ctx = copy.deepcopy(context) curr_cand = edge_obj(candidate[2]) ctx = run_transition(ctx, candidate, curr_cand, named_states) #compute the branch function value of the target guard after executing each candidate transition bf_vals[i] = eval(full_guard[0]['branch_f']['func'], {}, ctx) i += 1 #return the transition that gave the minimum branch function value return candidates[bf_vals.index(min(bf_vals))] else: return None
def print_path(path): for edge in path: einfo = edge_obj(edge[2]) edgelabel = '' if 'event' in einfo and einfo['event']['type'] != 'empty': edgelabel += einfo['event']['code'] + ' ' if 'guard' in einfo: edgelabel += '[ ' for i in range(0, len(einfo['guard'])): if (einfo['guard'][i]['code'] != 'True'): edgelabel += einfo['guard'][i]['code'] if (len(einfo['guard']) > 1 and i < len(einfo['guard']) - 1): edgelabel += ' AND ' edgelabel += ']' if 'action' in einfo: edgelabel += '/ ' for a in einfo['action']: edgelabel += ' ' + a['code'] + ';' print(str(edge[0]) + ' --> ' + str(edge[1]) + ' ' + edgelabel) print('\n')
def handle_executability(path, named_states, edges, mocks_init): newpath = [] context = {} #import mocks for statement in mocks_init: exec(statement, {}, context) i = 0 max_iter = 30 for edge in path: edgeinfo = edge_obj(edge[2]) if (not evaluate_guards(edgeinfo['guard'], context)): loop, ctx = generate_loop(edge, edges, max_iter, named_states, context) if(len(loop) != 0): context = ctx newpath += loop context = run_transition(context, edge, edgeinfo, named_states) newpath.append(edge) i += 1 return newpath