Esempio n. 1
0
def calculateBoolean(formula, var_dict):
    """
    given boolean variable value, calculate the value of a boolean formula (!, &, |, brackets are supported)
    :param formula: the formula
    :param var_dict: var_name->value dictionary
    :return:
    """
    token_list = parse(formula, ops, re_splitter)
    stack = list()
    for token in token_list:
        if token == '!':
            stack[-1] = not stack[-1]
        elif token == '&':
            stack[-2] = stack[-1] and stack[-2]
            stack.pop()
        elif token == '|':
            stack[-2] = stack[-1] or stack[-2]
            stack.pop()
        elif token in var_dict:
            stack.append(var_dict[token])
        elif token == '0':
            stack.append(False)
        elif token == '1':
            stack.append(True)
        else:
            raise Exception('Unknown AP token %s in edge formula' % token)
    if len(stack) != 1:
        raise Exception('Wrong edge AP formula format!')

    return stack[0]
Esempio n. 2
0
    def toSpot(self, bdict=default_bdd_dict):
        """
        Translate a (generalized) buchi automaton into bdd in spot package
        :param bdict: the bdd_dict that the output automaton uses
        :return: an spot generalized buchi automaton
        """
        aut = spot.make_twa_graph(bdict)
        ap_list = dict()
        state_map = dict()

        for ap in self.ap_list:
            # if ap not in ['0', '1']:
            ap_list[ap] = buddy.bdd_ithvar(aut.register_ap(ap))

        aut.set_generalized_buchi(self.acc_num)

        aut.prop_state_acc(1)

        new_index = 0
        for index, state in self.state_dict.items():
            aut.new_state()
            state_map[index] = new_index
            new_index = new_index + 1

        aut.set_init_state(state_map[self.getInitState()])

        for edge in self.edge_list:
            acc = self.getStateAcc(edge.src)
            ap_calc_list = parse(edge.ap, ops, re_splitter)
            ap_stack = list()
            for token in ap_calc_list:
                if token == '!':
                    ap_stack[-1] = -ap_stack[-1]
                elif token == '&':
                    ap_stack[-2] = ap_stack[-1] & ap_stack[-2]
                    ap_stack.pop()
                elif token == '|':
                    ap_stack[-2] = ap_stack[-1] | ap_stack[-2]
                    ap_stack.pop()
                elif token in self.ap_list:
                    ap_stack.append(ap_list[token])
                elif token == '0':
                    ap_stack.append(buddy.bddfalse)
                elif token == '1':
                    ap_stack.append(buddy.bddtrue)
                else:
                    raise Exception('Unknown AP token %s in edge formula' %
                                    token)
            if len(ap_stack) != 1:
                raise Exception('Wrong edge AP formula format!')

            aut.new_edge(state_map[edge.src], state_map[edge.dst], ap_stack[0],
                         acc)

        return aut, state_map
Esempio n. 3
0
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
Esempio n. 4
0
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))
Esempio n. 5
0
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]
Esempio n. 6
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
Esempio n. 7
0
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