Esempio n. 1
0
def lossy_duplicating_tag_data_channel(name):
    input_channel = z3p.Array('{}_input_channel'.format(name), z3p.IntSort(),
                              z3p.IntSort())
    output_channel = z3p.Array('{}_output_channel'.format(name), z3p.IntSort(),
                               z3p.IntSort())
    tag = z3p.Int('{}_channel_tag'.format(name))
    data = z3p.Int('{}_channel_data'.format(name))
    transitions = []
    transitions.append(('t0', 'empty', input_channel,
                        z3p.BoolVal(True), [(tag, input_channel[0]),
                                            (data, input_channel[1])], 'full'))
    transitions.append(
        ('t1', 'full', output_channel, [tag,
                                        data], z3p.BoolVal(True), [], 'empty'))
    transitions.append(
        ('t2', 'full', input_channel, z3p.BoolVal(True), [], 'full'))
    transitions.append(('t_duplication', 'full', output_channel, [tag, data],
                        z3p.BoolVal(True), [], 'full'))
    transitions.append(
        ('t_loss', 'empty', input_channel, z3p.BoolVal(True), [], 'empty'))
    return automaton.SymbolicAutomaton(
        '{}_tag_data_channel'.format(name), ['empty', 'full'],
        'empty',
        transitions,
        input_channels=[input_channel],
        output_channels=[output_channel],
        variables=[tag, data],
        initial_values=[z3p.IntVal(0), z3p.IntVal(0)],
        variable_ranges={
            tag: (0, 1),
            data: (min_value_message, max_value_message)
        },
        compassion=['t1', 't0'])
Esempio n. 2
0
def lossy_duplicating_tag_channel(name):
    input_channel = z3p.Int('{}_input_channel'.format(name))
    output_channel = z3p.Int('{}_output_channel'.format(name))
    tag = z3p.Int('{}_channel_tag'.format(name))
    transitions = []
    transitions.append(('t0', 'empty', input_channel, z3p.BoolVal(True),
                        [(tag, input_channel)], 'full'))
    transitions.append(
        ('t_loss', 'empty', input_channel, z3p.BoolVal(True), [], 'empty'))
    transitions.append(
        ('t1', 'full', output_channel, [tag], z3p.BoolVal(True), [], 'empty'))
    transitions.append(('t_duplicating', 'full', output_channel, [tag],
                        z3p.BoolVal(True), [], 'full'))
    transitions.append(
        ('t2', 'full', input_channel, z3p.BoolVal(True), [], 'full'))
    return automaton.SymbolicAutomaton(
        '{}_tag_channel'.format(name), ['empty', 'full'],
        'empty',
        transitions,
        input_channels=[input_channel],
        output_channels=[output_channel],
        variables=[tag],
        initial_values=[z3p.IntVal(0)],
        variable_ranges={tag: (0, 1)},
        output_channel_ranges={output_channel: (0, 1)},
        compassion=['t0', 't1'])
Esempio n. 3
0
def python_value_to_z3(value):
    if isinstance(value, bool):
        return z3p.BoolVal(value)
    elif isinstance(value, int) or isinstance(value, long):
        return z3p.IntVal(value)
    else:
        raise NotImplementedError("unknown value {}".format(value))
Esempio n. 4
0
def receiver():
    forward_output_channel = z3p.Array('forward_output_channel', z3p.IntSort(),
                                       z3p.IntSort())
    backward_input_channel = z3p.Int('backward_input_channel')
    receive = z3p.Int('receive')
    input_tag = z3p.Int('receiver_tag')
    input_data = z3p.Int('receiver_data')
    expected_tag = z3p.Int('expected_tag')
    transitions = []
    transitions.append(
        ('t0', 'initial', forward_output_channel, z3p.BoolVal(True),
         [(input_tag, forward_output_channel[0]),
          (input_data, forward_output_channel[1])], 'q0'))
    transitions.append(
        ('t1', 'q0', receive, [input_data], z3p.Eq(input_tag,
                                                   expected_tag), [], 'q1'))
    transitions.append(
        ('t2', 'q1', backward_input_channel, [expected_tag],
         z3p.BoolVal(True), [(expected_tag,
                              z3p.If(z3p.Eq(expected_tag, 0), z3p.IntVal(1),
                                     z3p.IntVal(0)))], 'initial'))
    transitions.append(('t3', 'q0', z3p.Neq(input_tag,
                                            expected_tag), [], 'q2'))
    transitions.append(
        ('t4', 'q2', backward_input_channel,
         [z3p.If(z3p.Eq(expected_tag, 0), z3p.IntVal(1),
                 z3p.IntVal(0))], z3p.BoolVal(True), [], 'initial'))
    return automaton.SymbolicAutomaton(
        'receiver', ['initial', 'q0', 'q1', 'q2'],
        'initial',
        transitions,
        input_channels=[forward_output_channel],
        output_channels=[receive, backward_input_channel],
        variables=[input_tag, input_data, expected_tag],
        initial_values=[z3p.IntVal(0),
                        z3p.IntVal(0),
                        z3p.IntVal(0)],
        variable_ranges={
            input_tag: (0, 1),
            input_data: (min_value_message, max_value_message),
            expected_tag: (0, 1)
        },
        output_channel_ranges={
            receive: (min_value_message, max_value_message),
            backward_input_channel: (0, 1)
        },
        justice=['t3', 't1'])
Esempio n. 5
0
def z3_expression_to_nusmv(expression, tables=None, other_tables=None):
    z3_to_nusmv = {
        z3p.Z3_OP_AND: ' & ',
        z3p.Z3_OP_ADD: ' + ',
        z3p.Z3_OP_MOD: ' mod ',
        z3p.Z3_OP_EQ: ' = ',
        z3p.Z3_OP_LT: ' < ',
        z3p.Z3_OP_GT: ' > '
    }
    kind = expression.decl().kind()
    if (z3p.is_const(expression)
            and expression.decl().name().startswith('table_')):
        assert tables is not None
        table_name = expression.decl().name()
        assert table_name in tables or table_name in other_tables
        table_expression = tables[
            table_name] if table_name in tables else other_tables[table_name]
        case_expression = 'case '
        for condition, result in table_expression:
            c = z3_expression_to_nusmv(condition, tables)
            r = z3_expression_to_nusmv(result, tables)
            case_expression += '{} : {}; '.format(c, r)
        case_expression += 'esac'
        return case_expression
    elif kind in z3_to_nusmv:
        children = [
            z3_expression_to_nusmv(c, tables) for c in expression.children()
        ]
        return '({})'.format(z3_to_nusmv[kind].join(children))
    elif expression == z3p.BoolVal(True):
        return 'TRUE'
    elif expression == z3p.BoolVal(False):
        return 'FALSE'
    elif kind == z3p.Z3_OP_NOT:
        e = z3_expression_to_nusmv(expression.arg(0))
        return '!({})'.format(e)
    elif z3p.is_const(expression):
        return str(expression)
    elif kind == z3p.Z3_OP_ITE:
        guard = z3_expression_to_nusmv(expression.arg(0))
        then_branch = z3_expression_to_nusmv(expression.arg(1))
        else_branch = z3_expression_to_nusmv(expression.arg(2))
        return '(case {} : {}; TRUE : {}; esac)'.format(
            guard, then_branch, else_branch)
    else:
        raise NotImplementedError(
            'Cannot translate expression {} to nusmv.'.format(expression))
Esempio n. 6
0
def timer():
    timeout = util.new_variable('timeout', 'unit')
    transitions = [('t0', 'initial', timeout, [z3p.IntVal(0)],
                    z3p.BoolVal(True), [], 'initial')]
    return automaton.SymbolicAutomaton('timer', ['initial'],
                                       'initial',
                                       transitions,
                                       output_channels=[timeout])
Esempio n. 7
0
 def create_guard_hole(self, hole_name):
     """ variable is the name of the variable to update
     """
     signature = []
     domains = []
     for variable in self.variables:
         variable_sort = variable.sort()
         signature.append(variable_sort)
         if variable.sort() == z3p.IntSort():
             domains.append(range(self.variable_ranges[variable][0],
                                  self.variable_ranges[variable][1] + 1))
         elif variable.sort() == z3p.BoolSort():
             domains.append([z3p.BoolVal(False), z3p.BoolVal(True)])
         else:
             raise NotImplementedError("Unimplemented type of variable {}".format(variable_sort))
     signature.append(z3p.BoolSort())
     f = z3p.Function(hole_name, *signature)
     return (f, domains, None, None)
Esempio n. 8
0
def receiver_client():
    transitions = []
    receive = z3p.Int('receive')
    transitions.append(
        ('t0', 'initial', receive, z3p.BoolVal(True), [], 'initial'))
    return automaton.SymbolicAutomaton('receiver_client', ['initial'],
                                       'initial',
                                       transitions,
                                       input_channels=[receive])
Esempio n. 9
0
def sender():
    transitions = []
    input_message = z3p.Int('sender_input_message')
    sender_tag = z3p.Int('sender_tag')
    ack_tag = z3p.Int('ack_tag')
    forward_input_channel = z3p.Array('forward_input_channel', z3p.IntSort(),
                                      z3p.IntSort())
    backward_output_channel = z3p.Int('backward_output_channel')
    send = z3p.Int('send')
    timeout = util.new_variable('timeout', 'unit')
    transitions.append(('t0', 'initial', send, z3p.BoolVal(True),
                        [(input_message, send)], 'q0'))
    transitions.append(
        ('t1', 'q0', forward_input_channel, [sender_tag, input_message],
         z3p.BoolVal(True), [], 'q1'))
    transitions.append(('t2', 'q1', timeout, z3p.BoolVal(True), [], 'q0'))
    transitions.append(('t3', 'q1', backward_output_channel, z3p.BoolVal(True),
                        [(ack_tag, backward_output_channel)], 'q2'))
    transitions.append(('t4', 'q2', z3p.Eq(ack_tag, sender_tag), [
        (sender_tag, z3p.If(z3p.Eq(sender_tag, 0), z3p.IntVal(1),
                            z3p.IntVal(0)))
    ], 'initial'))
    transitions.append(('t5', 'q2', z3p.Neq(ack_tag, sender_tag), [], 'q0'))
    return automaton.SymbolicAutomaton(
        'sender', ['initial', 'q0', 'q1', 'q2'],
        'initial',
        transitions,
        variables=[input_message, sender_tag, ack_tag],
        initial_values=[z3p.IntVal(0),
                        z3p.IntVal(0),
                        z3p.IntVal(0)],
        input_channels=[send, timeout, backward_output_channel],
        output_channels=[forward_input_channel],
        variable_ranges={
            input_message: (min_value_message, max_value_message),
            sender_tag: (0, 1),
            ack_tag: (0, 1)
        },
        output_channel_ranges={
            forward_input_channel[1]: (min_value_message, max_value_message),
            forward_input_channel[0]: (0, 1)
        })
Esempio n. 10
0
 def translate_expression(self, e):
     if e == z3p.BoolVal(True):
         return 'TheLTS->MakeTrue()'
     elif e == z3p.BoolVal(False):
         return 'TheLTS->MakeFalse()'
     elif z3p.is_int_value(e):
         return 'TheLTS->MakeVal("{i}", TheLTS->MakeRangeType({i}, {i}))'.format(i=e)
     elif z3p.is_const(e) and e in self.channels:
         return self.translate_channel_reference(e)
     elif z3p.is_const(e):
         return '{}Exp'.format(to_camel_case(e.decl().name()))
     elif e.num_args() == 1:
         return self.translate_unary_expression(e)
     elif e.num_args() == 2 and e.decl().kind() == z3p.Z3_OP_SELECT:
         return self.translate_channel_reference(e)
     elif e.num_args() == 2:
         return self.translate_binary_expression(e)
     elif e.num_args() == 3:
         return self.translate_ternary_expreession(e)
     else:
         raise NotImplementedError("can't translate expression {} with {}".format(e, e.num_args()))
Esempio n. 11
0
def sender_client():
    transitions = []
    send = z3p.Int('send')
    for i in range(min_value_message, max_value_message + 1):
        transitions.append(('t{}'.format(i), 'initial', send, [z3p.IntVal(i)],
                            z3p.BoolVal(True), [], 'initial'))
    return automaton.SymbolicAutomaton(
        'sender_client', ['initial'],
        'initial',
        transitions,
        output_channels=[send],
        output_channel_ranges={send: (min_value_message, max_value_message)})
Esempio n. 12
0
 def create_update_hole(self, variable_or_variable_name, hole_name):
     """ variable is the name of the variable to update
     """
     if isinstance(variable_or_variable_name, str):
         variable_to_update = next(v for v in self.variables
                                   if v.decl().name() == variable_or_variable_name)
     else:
         variable_to_update = variable_or_variable_name
     signature = []
     domains = []
     for variable in self.variables:
         variable_sort = variable.sort()
         signature.append(variable_sort)
         if variable.sort() == z3p.IntSort():
             domains.append([z3p.IntVal(i) for i in range(self.variable_ranges[variable][0],
                                                          self.variable_ranges[variable][1] + 1)])
         elif variable.sort() == z3p.BoolSort():
             domains.append([z3p.BoolVal(False), z3p.BoolVal(True)])
         else:
             raise NotImplementedError("Unimplemented type of variable {}".format(variable_sort))
     signature.append(variable_to_update.sort())
     f = z3p.Function(hole_name, *signature)
     constraint = z3p.And([z3p.Or([z3p.Eq(f(*arg), z3p.IntVal(result)) for result in range(self.variable_ranges[variable_to_update][0], self.variable_ranges[variable_to_update][1] + 1)]) for arg in itertools.product(*domains)])
     return (f, domains, constraint, (variable_to_update, self.variables.index(variable_to_update)))
Esempio n. 13
0
 def condition_to_resolve_deadlock(self, locations, memory, verbose=1):
     """Locations is a map from automaton to current location
     Memory can contain symbolic values.
     """
     if verbose > 0:
         print "Deadlock locations {}".format(locations)
     candidates = self.candidate_transitions(locations)
     if verbose > 0:
         print "Candidates are {}".format(candidates)
     if len(candidates) == 0:
         return z3p.BoolVal(False)
     else:
         return z3p.Or([z3p.And([a.transition_condition(edge[2]['name'], memory[a])
                                 for a, edge in candidate])
                        for candidate in candidates])
Esempio n. 14
0
def lookup_table_to_conditional_expression(lookup_table, input_variables):
    conditional_expression = []
    for input_values, output_value in lookup_table.items():
        if len(input_values) == 1:
            conditional = z3p.Eq(input_variables[0], input_values[0])
        elif len(input_values) == 0:
            assert len(lookup_table.values()) == 1
            return [(z3p.BoolVal(True), output_value)]
        else:
            conditional = z3p.And([
                z3p.Eq(var, val)
                for var, val in zip(input_variables, input_values)
            ])
        conditional_expression += [(conditional, output_value)]
    return conditional_expression
Esempio n. 15
0
 def guard_enabled(self, state, guard, verbose=0):
     if guard.decl().name().startswith('table'):
         conditional = self.tables[guard.decl().name()]
         expression = z3p.BoolVal(False)
         for condition, result in conditional:
             expression = z3p.Or(expression, condition if z3p.is_true(result) else z3p.BoolVal(False))
         guard = expression
     guard_evaluated = util.evaluate_expression(guard, {}, state, self.tables)
     if verbose > 0:
         print 'Evaluated guard is {}'.format(guard_evaluated)
         print 'Simplified guard is {}'.format(z3p.simplify(guard_evaluated))
     s = z3p.Solver()
     s.add(z3p.Neq(guard_evaluated, True))
     if s.check() == z3p.unsat:
         return True
     else:
         return False
Esempio n. 16
0
def evaluate_expression(expression,
                        symbolic_memory,
                        concrete_memory,
                        tables=None):
    if isinstance(expression, int):
        return expression
    if isinstance(expression, tuple):
        return expression
    if z3p.is_const(expression):
        if z3p.is_bool_or_int_value(expression):
            return expression
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        elif expression.decl().name().startswith('table_'):
            assert expression.decl().name() in tables
            table_expression = tables[expression.decl().name()]
            first_value = table_expression[0][1]
            if first_value.sort() == z3p.IntSort():
                last_else = z3p.IntVal(0)
            else:
                last_else = z3p.BoolVal(False)
            if_expression = None
            for conditional, value in table_expression:
                guard = evaluate_expression(conditional, symbolic_memory,
                                            concrete_memory)
                last_else = z3p.If(guard, value, last_else)
            return z3p.simplify(last_else)
        else:
            return concrete_memory[expression]
    elif expression.decl().kind() == z3p.Z3_OP_SELECT:
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        else:
            return concrete_memory[expression]
    else:
        new_args = [
            evaluate_expression(expression.arg(i), symbolic_memory,
                                concrete_memory, tables)
            for i in range(expression.num_args())
        ]
        if expression.decl().kind() == z3p.Z3_OP_AND:
            return z3p.And(*new_args)
        else:
            return expression.decl()(*new_args)
Esempio n. 17
0
 def lookup_table_for_function(self, function_name):
     """Returns a model for the function as a dictionary.
     The dictionary has tuples of argument values as keys. In particular,
     if the function has a single argument, the key will still be a single element tuple.
     """
     assert (function_name in self.function_names
             and function_name in self.z3_functions_by_name)
     z3_function = self.z3_functions_by_name[function_name]
     model = self.solver.model()
     table = {}
     for i in self.function_name_to_domain_values[function_name]:
         table[i] = model.evaluate(z3_function(i))
         # If a value is unconstrained the z3 model might just return
         # a variable back, therefore for the boolean case
         if not z3p.is_bool_or_int_value(
                 table[i]) and table[i].sort() == z3p.BoolSort():
             # a constant value is returned here.
             table[i] = z3p.BoolVal(False)
     return table
Esempio n. 18
0
def liveness_monitor2():
    send = z3p.Int('send')
    receive = z3p.Int('receive')
    transitions = []
    transitions.append(
        ('t1', 'initial', receive, z3p.BoolVal(True), [], 'accept'))
    transitions.append(
        ('t2', 'initial', receive, z3p.BoolVal(True), [], 'initial'))
    transitions.append(
        ('t3', 'initial', send, z3p.BoolVal(True), [], 'initial'))
    transitions.append(
        ('t4', 'accept', receive, z3p.BoolVal(True), [], 'accept'))
    transitions.append(('t5', 'accept', send, z3p.BoolVal(True), [], 'final'))
    transitions.append(
        ('t6', 'final', receive, z3p.BoolVal(True), [], 'final'))
    transitions.append(('t7', 'final', send, z3p.BoolVal(True), [], 'final'))
    return automaton.SymbolicAutomaton('liveness_monitor2',
                                       ['initial', 'accept', 'final'],
                                       'initial',
                                       transitions,
                                       input_channels=[receive, send])
Esempio n. 19
0
def safety_monitor():
    safety_data_sent = z3p.Int('safety_data_sent')
    safety_data_received = z3p.Int('safety_data_received')
    variable_ranges = {
        safety_data_sent: (min_value_message, max_value_message),
        safety_data_received: (min_value_message, max_value_message)
    }
    send = z3p.Int('send')
    receive = z3p.Int('receive')
    transitions = []
    transitions.append(('t0', 'waiting_for_send', send, z3p.BoolVal(True),
                        [(safety_data_sent, send)], 'waiting_for_receive'))
    transitions.append(
        ('t1', 'waiting_for_receive', receive, z3p.BoolVal(True),
         [(safety_data_received, receive)], 'check_received_data'))
    transitions.append(('t2', 'check_received_data',
                        z3p.Neq(safety_data_sent,
                                safety_data_received), [], 'error'))
    transitions.append(('t3', 'check_received_data',
                        z3p.Eq(safety_data_sent,
                               safety_data_received), [], 'waiting_for_send'))
    transitions.append(
        ('t4', 'waiting_for_send', receive, z3p.BoolVal(True), [], 'error'))
    transitions.append(
        ('t5', 'waiting_for_receive', send, z3p.BoolVal(True), [], 'error'))
    transitions.append(('t6', 'error', send, z3p.BoolVal(True), [], 'error'))
    transitions.append(
        ('t6', 'error', receive, z3p.BoolVal(True), [], 'error'))
    return automaton.SymbolicAutomaton(
        'safety_monitor', [
            'waiting_for_send', 'waiting_for_receive', 'error',
            'check_received_data'
        ],
        'waiting_for_send',
        transitions, [safety_data_sent, safety_data_received],
        [z3p.IntVal(0), z3p.IntVal(0)],
        input_channels=[send, receive],
        variable_ranges=variable_ranges)
Esempio n. 20
0
import automaton
import util
import z3p

TRUE = z3p.BoolVal(True)


def INT(x):
    return z3p.IntVal(x)


ZERO = z3p.IntVal(0)

ONE = z3p.IntVal(1)

NUM_ADDRESSES = 1
NUM_CACHES = 2
NUM_DIRECTORIES = 1
NUM_VALUES = 1

LDMsg = {}
STMsg = {}
EVMsg = {}
FwdGetXMsgP = {}
FwdGetSMsgP = {}
InvAckMsg = {}
InvAckMsgP = {}
DataMsgD2CP = {}
WBAckMsgP = {}
DataMsgC2C = {}
DataMsgC2CP = {}