def _getTimeExpList(formula): time_exp_list = list() recorded_list = list() re_splitter = r'(\s+|\(|\)|\&|\||!|<|>|=|F|G|U|W|\#|\*|X|@)' ops = { '!': Operator('!', 1, 4, 1), '&': Operator('&', 2, 2, 0), '|': Operator('|', 2, 2, 0), '<': Operator('<', 2, 6, 0), '>': Operator('>', 2, 6, 0), '=': Operator('=', 2, 6, 0), 'G': Operator('G', 1, 3, 1), 'F': Operator('F', 1, 3, 1), 'U': Operator('U', 2, 3, 0), 'X': Operator('X', 1, 3, 1), 'W': Operator('W', 2, 3, 0), '#': Operator('#', 2, 5, 0), '*': Operator('*', 2, 5, 0), '@': Operator('@', 1, 5, 1) } post_exp = parse(formula, ops, re_splitter) stack = list() for token in post_exp: if token not in ops: stack.append(token) else: if ops[token].n_args == 1: stack[-1] = token + str(stack[-1]) if token == '@': recorded_list.append(stack[-1]) elif ops[token].n_args == 2: stack[-2] = stack[-2] + token + stack[-1] if token in ('#', '*'): time_exp_list.append(stack[-2]) stack.pop() return list(set(time_exp_list)), list(set(recorded_list))
def ltlFormat(ltl): def isfloat(s): try: float(s) return True except ValueError: return False re_splitter = r'(\s+|\(|\)|\&|\||!|<|>|=|F|G|U|W|\#|\*|X|@)' ops = { '!': Operator('!', 1, 4, 1), '&': Operator('&', 2, 2, 0), '|': Operator('|', 2, 2, 0), '<': Operator('<', 2, 6, 0), '>': Operator('>', 2, 6, 0), '=': Operator('=', 2, 6, 0), 'G': Operator('G', 1, 3, 1), 'F': Operator('F', 1, 3, 1), 'U': Operator('U', 2, 3, 0), 'X': Operator('X', 1, 3, 1), 'W': Operator('W', 2, 3, 0), '#': Operator('#', 2, 5, 0), '*': Operator('*', 2, 5, 0), '@': Operator('@', 1, 5, 1) } time_record_exp_dict = dict() time_record_prefix = '________________' ltl_post_exp = parse(ltl, ops, re_splitter) stack = list() for token in ltl_post_exp: if token not in ops: stack.append(token) else: if token in ('#', '*'): time_record_exp_dict[time_record_prefix + str( len(time_record_exp_dict))] = stack[-2] + token + stack[-1] stack[-2] = time_record_prefix + str( len(time_record_exp_dict) - 1) stack.pop() elif token == '@': time_record_exp_dict[ time_record_prefix + str(len(time_record_exp_dict))] = token + stack[-1] stack[-1] = time_record_prefix + str( len(time_record_exp_dict) - 1) else: if ops[token].n_args == 2: if token in ('<', '=', '>'): stack[-2] = stack[-2] + token + stack[-1] else: stack[-2] = '(' + stack[-2] + token + stack[-1] + ')' stack.pop() elif ops[token].n_args == 1: stack[-1] = token + '(' + stack[-1] + ')' ltl_post_exp = parse(stack[0], ops, re_splitter) stack = list() for token in ltl_post_exp: if token not in ops: stack.append(token) else: if ops[token].n_args == 2: if token == '<': stack[-2] = stack[-2] + 'LessThan' + stack[-1].replace( '.', '_') elif token == '>': stack[-2] = stack[-2] + 'GreaterThan' + stack[-1].replace( '.', '_') elif token == '=': if stack[-1] == 'true': stack[-2] = stack[-2] + 'IsTrue' elif stack[-1] == 'false': stack[-2] = '!' + stack[-2] + 'IsTrue' elif not isfloat(stack[-1]): # should be set stack[-2] = stack[-2] + 'Is' + stack[-1].capitalize() else: exp1 = '!' + stack[-2] + 'LessThan' + stack[ -1].replace('.', '_') exp2 = '!' + stack[-2] + 'GreaterThan' + stack[ -1].replace('.', '_') stack[-2] = '(' + exp1 + ' & ' + exp2 + ')' else: stack[-2] = '(' + stack[-2] + ' ' + token + ' ' + stack[ -1] + ')' stack.pop() elif ops[token].n_args == 1: stack[-1] = token + '(' + stack[-1] + ')' for key, time_exp in time_record_exp_dict.items(): stack[0] = stack[0].replace(key, '"%s"' % time_exp) return stack[0]
def namedTapFormat(tap_dict, critical_value_dict): def isfloat(s): try: float(s) return True except ValueError: return False new_tap_dict = dict() re_splitter = r'(\s+|\(|\)|\&|\||!|<|>|=|F|G|U|W|\#|\*|X|@)' ops = { '!': Operator('!', 1, 4, 1), '&': Operator('&', 2, 2, 0), '|': Operator('|', 2, 2, 0), '<': Operator('<', 2, 6, 0), '>': Operator('>', 2, 6, 0), '=': Operator('=', 2, 6, 0), 'G': Operator('G', 1, 3, 1), 'F': Operator('F', 1, 3, 1), 'U': Operator('U', 2, 3, 0), 'X': Operator('X', 1, 3, 1), 'W': Operator('W', 2, 3, 0), '#': Operator('#', 2, 5, 0), '*': Operator('*', 2, 5, 0), '@': Operator('@', 1, 5, 1) } for tap_name, tap in tap_dict.items(): new_trigger = list() if not re.match(r'^tick\[(?P<time_exp>[()\w<>=#*.]+)\]$', tap.trigger): trigger_post_exp = parse(tap.trigger, ops, re_splitter) if trigger_post_exp[-1] == '<': value = int(trigger_post_exp[-2]) crit_list = critical_value_dict[trigger_post_exp[-3]] left_list = crit_list[:-1] right_list = crit_list[1:] mid_list = [(v1 + v2) / 2 for v1, v2 in zip(left_list, right_list)] enhanced_list = crit_list + mid_list + [ min(crit_list) - 1, max(crit_list) + 1 ] sat_list = [v for v in enhanced_list if v < value] for sat_val in sat_list: new_trigger.append(trigger_post_exp[-3] + 'SetTo' + str(sat_val).replace('.', '_')) elif trigger_post_exp[-1] == '>': value = int(trigger_post_exp[-2]) crit_list = critical_value_dict[trigger_post_exp[-3]] left_list = crit_list[:-1] right_list = crit_list[1:] mid_list = [(v1 + v2) / 2 for v1, v2 in zip(left_list, right_list)] enhanced_list = crit_list + mid_list + [ min(crit_list) - 1, max(crit_list) + 1 ] sat_list = [v for v in enhanced_list if v > value] for sat_val in sat_list: new_trigger.append(trigger_post_exp[-3] + 'SetTo' + str(sat_val).replace('.', '_')) elif trigger_post_exp[-1] == '=': if not isfloat(trigger_post_exp[-2]): new_trigger.append(trigger_post_exp[-3] + 'Set' + trigger_post_exp[-2].capitalize()) else: new_trigger.append(trigger_post_exp[-3] + 'SetTo' + trigger_post_exp[-2].replace('.', '_')) else: new_trigger.append(tap.trigger) condition = list() for cond in tap.condition: if '#' in cond or '*' in cond: condition.append(cond) else: cond_post_exp = parse(cond, ops, re_splitter) if cond_post_exp[-1] == '=': if cond_post_exp[-2] == 'true': condition.append(cond_post_exp[-3] + 'IsTrue') elif cond_post_exp[-2] == 'false': condition.append('!' + cond_post_exp[-3] + 'IsTrue') elif isfloat(cond_post_exp[-2]): condition.append('!' + cond_post_exp[-3] + 'GreaterThan' + cond_post_exp[-2].replace('.', '_')) condition.append('!' + cond_post_exp[-3] + 'LessThan' + cond_post_exp[-2].replace('.', '_')) else: # should be 'set' condition.append(cond_post_exp[-3] + 'Is' + cond_post_exp[2].capitalize()) elif cond_post_exp[-1] == '<': condition.append(cond_post_exp[-3] + 'LessThan' + cond_post_exp[-2].replace('.', '_')) elif cond_post_exp[-1] == '>': condition.append(cond_post_exp[-3] + 'GreaterThan' + cond_post_exp[-2].replace('.', '_')) act_post_exp = parse(tap.action, ops, re_splitter) if not isfloat(act_post_exp[-2]): action = act_post_exp[-3] + 'Set' + act_post_exp[-2].capitalize() else: action = act_post_exp[-3] + 'SetTo' + act_post_exp[-2].replace( '.', '_') for trigger, new_tap_index in zip(new_trigger, range(len(new_trigger))): new_tap_dict['%s.%d' % (tap_name, new_tap_index)] = Tap( action, trigger, condition) return new_tap_dict
def _getValueDict(formula): value_dict = dict() re_splitter = r'(\s+|\(|\)|\&|\||!|<|>|=|F|G|U|W|\#|\*|X|@)' ops = { '!': Operator('!', 1, 4, 1), '&': Operator('&', 2, 2, 0), '|': Operator('|', 2, 2, 0), '<': Operator('<', 2, 6, 0), '>': Operator('>', 2, 6, 0), '=': Operator('=', 2, 6, 0), 'G': Operator('G', 1, 3, 1), 'F': Operator('F', 1, 3, 1), 'U': Operator('U', 2, 3, 0), 'X': Operator('X', 1, 3, 1), 'W': Operator('W', 2, 3, 0), '#': Operator('#', 2, 5, 0), '*': Operator('*', 2, 5, 0), '@': Operator('@', 1, 5, 1) } post_exp = parse(formula, ops, re_splitter) stack = list() for token in post_exp: if token not in ops: stack.append(token) else: if ops[token].n_args == 1: stack[-1] = token + str(stack[-1]) elif ops[token].n_args == 2: if token in ('<', '>', '='): if stack[-2] not in value_dict: value_dict[stack[-2]] = [stack[-1]] elif stack[-1] not in value_dict[stack[-2]]: value_dict[stack[-2]].append(stack[-1]) stack[-2] = stack[-2] + token + stack[-1] stack.pop() return value_dict
def getChannelList(ltl, tap_list): channel_list = list() re_splitter = r'(\s+|\(|\)|\&|\||!|<|>|=|F|G|U|W|\#|\*|X|@)' ops = { '!': Operator('!', 1, 4, 1), '&': Operator('&', 2, 2, 0), '|': Operator('|', 2, 2, 0), '<': Operator('<', 2, 6, 0), '>': Operator('>', 2, 6, 0), '=': Operator('=', 2, 6, 0), 'G': Operator('G', 1, 3, 1), 'F': Operator('F', 1, 3, 1), 'U': Operator('U', 2, 3, 0), 'X': Operator('X', 1, 3, 1), 'W': Operator('W', 2, 3, 0), '#': Operator('#', 2, 5, 0), '*': Operator('*', 2, 5, 0), '@': Operator('@', 1, 5, 1) } ltl_post_exp = parse(ltl, ops, re_splitter) cap_list = [ token for token in ltl_post_exp if token not in ops and '.' in token and not token[0].isnumeric() ] channel_list = list( set(channel_list + [cap.split('.')[0] for cap in cap_list])) tap_channel_list = list() tap_cap_list = list() for tap in tap_list: time_match = re.match(r'^tick\[(?P<time_exp>[()\w<>=#*]+)\]$', tap.trigger) if time_match: trigger = time_match.group('time_exp') else: trigger = tap.trigger trigger_post_exp = parse(trigger, ops, re_splitter) trigger_channel_l = list({ token.split('.')[0] for token in trigger_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) trigger_cap_l = list({ token for token in trigger_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) action_post_exp = parse(tap.action, ops, re_splitter) action_channel_l = list({ token.split('.')[0] for token in action_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) action_cap_l = list({ token for token in action_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) for cond in tap.condition: cond_post_exp = parse(cond, ops, re_splitter) cond_channel_l = list({ token.split('.')[0] for token in cond_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) cond_cap_l = list({ token for token in cond_post_exp if token not in ops and '.' in token and not token[0].isnumeric() }) trigger_channel_l = list(set(trigger_channel_l + cond_channel_l)) trigger_cap_l = list(set(trigger_cap_l + cond_cap_l)) tap_channel_list.append( (trigger_channel_l, action_channel_l, tap_list.index(tap))) tap_cap_list.append((trigger_cap_l, action_cap_l, tap_list.index(tap))) # TODO: should be careful about this change, seems dangerous to me # channel_to_search = copy.deepcopy(channel_list) # new_tap_list = list() # while channel_to_search: # ch = channel_to_search.pop() # for trigger_channel_l, action_channel_l, tap_index in tap_channel_list: # if ch in action_channel_l: # new_tap_list.append(tap_index) # for ch_t in trigger_channel_l: # if ch_t not in channel_list: # channel_list.append(ch_t) # channel_to_search.append(ch_t) cap_to_search = copy.deepcopy(cap_list) new_tap_list = list() while cap_to_search: cap = cap_to_search.pop() for trigger_cap_l, action_cap_l, tap_index in tap_cap_list: if cap in action_cap_l: new_tap_list.append(tap_index) for cap_t in trigger_cap_l: if cap_t not in cap_list: cap_list.append(cap_t) cap_to_search.append(cap_t) new_tap_list = list(set(new_tap_list)) new_tap_list = [tap_list[index] for index in new_tap_list] channel_list = [cap_name.split('.')[0] for cap_name in cap_list] return list(set(channel_list)), list(set(cap_list)), new_tap_list
import spot import buddy from autotapmc.ts.TransitionSystem import TS, State, Transition import abc import sys import re from autotapmc.utils.Parser import parse, Operator ops = { '!': Operator('!', 1, 3, 0), '&': Operator('&', 2, 1, 0), '|': Operator('|', 2, 1, 0) } re_splitter = r'(\s+|\(|\)|\&|\||!)' #产生默认的BDD描述 default_bdd_dict = spot.make_bdd_dict() class BuchiState(object): """ Data structure to store information in a state-based (generalized) buchi automaton """ def __init__(self, index, description, acc): self.index = index self.acc = acc self.description = description #buchi自動機的state有index,acc和描述組成