Ejemplo n.º 1
0
 def variables_ufunctions_in_expression(self, expression):
     variables_in_expression = z3p.variables_in_expression(expression)
     variables, ufunctions = [], []
     for v in variables_in_expression:
         if any(v == v2 for v2 in self.variables) or any(v == c for c in self.input_channels):
             variables.append(v)
         else:
             ufunctions.append(v)
     return (variables, ufunctions)
Ejemplo n.º 2
0
 def reading_variables_for_channel(self, channel):
     assert channel.sort_kind() != z3p.Z3_ARRAY_SORT
     variables = set([])
     for a in self.readers[channel]:
         for _, _, data in a.edges(data=True):
             if data['kind'] == 'input' and channel == data['channel'] and len(data['update']) > 0:
                 for update in data['update']:
                     lhs, rhs = update
                     if channel in z3p.variables_in_expression(rhs):
                         variables.add(lhs)
     return list(variables)
Ejemplo n.º 3
0
 def transitions_from_state(self, state1, state2, verbose=0):
     possible_transitions = dict([(a, []) for a in self.automata])
     possible_channels = dict([(a, set([])) for a in self.automata])
     possible_internal_transitions = dict([(a, []) for a in self.automata])
     transition_channels = {}
     for a in self.automata:
         if state1[a] == state2[a]:
             possible_transitions[a].append(None)
         for t in a.edges(data=True):
             if a.can_transition(state1[a], state2[a], t):
                 possible_transitions[a].append(t)
                 channel = t[2]['channel']
                 if channel is None:
                     possible_internal_transitions[a].append(t)
                 else:
                     possible_channels[a].add(channel)
     for a in self.automata:
         for c in list(possible_channels[a]):
             assert c in self.readers, "{} not in {}".format(c, self.readers)
             assert c in self.writer, "{} not in {}".format(c, self.writer)
             automata = self.readers[c] + [self.writer[c]]
             if (any(c not in possible_channels[ap]
                     for ap in automata) or
                     any(None not in possible_transitions[ap]
                         for ap in self.automata if ap not in automata)):
                 possible_channels[a].remove(c)
     if any(len(possible_channels[a]) > 0 for a in self.automata):
         c = next(list(possible_channels[a])[0] for a in self.automata
                  if len(possible_channels[a]) > 0)
         if verbose > 0:
             print "Checking channel {}".format(c)
         for t in possible_transitions[self.writer[c]]:
             writer_transition = t
             if verbose > 0:
                 print "Checking writer transition {}".format(t)
             if t is not None and t[2]['channel'] == c:
                 channel_expressions = t[2]['channel_expression']
                 channel_expression_values = [util.evaluate_expression(channel_expression, {}, state1[self.writer[c]], tables=self.writer[c].tables) for channel_expression in channel_expressions]
                 if verbose > 0:
                     print 'Writer tables are {}'.format(self.writer[c].tables)
                     print 'Channel expressions are {}'.format(channel_expressions)
                     print 'Channel expression values are {}'.format(channel_expression_values)
                 reader_transitions = [next(t for t in possible_transitions[a]
                                            if t is not None and t[2]['channel'] == c)
                                       for a in self.readers[c]]
                 writer_matches_readers = True
                 for rt in reader_transitions:
                     if verbose > 0:
                         print "Checking against reader transition {}".format(rt)
                     ra = rt[2]['automaton']
                     updates = rt[2]['update']
                     for update in updates:
                         if c in z3p.variables_in_expression(update[1]):
                             if isinstance(c, z3p.ArrayRef):
                                 selects = util.selects_in_expression(update[1])
                                 new_reader_concrete_memory = dict(state1[ra])
                                 for select in selects:
                                     index = select.arg(1)
                                     new_reader_concrete_memory[c[index]] = channel_expression_values[index.as_long()]
                                 if state2[ra][update[0]] != util.evaluate_expression(update[1], {}, new_reader_concrete_memory):
                                     writer_matches_readers = False
                             else:
                                 new_reader_concrete_memory = dict(state1[ra])
                                 new_reader_concrete_memory[c] = channel_expression_values[0]
                                 s = z3p.Solver()
                                 s.add(z3p.Neq(state2[ra][update[0]], util.evaluate_expression(update[1], {}, new_reader_concrete_memory)))
                                 if s.check() != z3p.unsat:
                                     if verbose:
                                         print "update does not match {}, {}".format(state2[ra][update[0]], util.evaluate_expression(update[1], {}, new_reader_concrete_memory))
                                     writer_matches_readers = False
                 if writer_matches_readers:
                     return [writer_transition] + reader_transitions
     else:
         for a in self.automata:
             other_automata = [ap for ap in self.automata if a != ap]
             if (len(possible_internal_transitions[a]) > 0 and
                     all(None in possible_transitions[ap]
                         for ap in other_automata)):
                 return [possible_internal_transitions[a]]
Ejemplo n.º 4
0
 def transitions_from_state(self, state1, state2, verbose=0):
     possible_transitions = dict([(a, []) for a in self.automata])
     possible_channels = dict([(a, set([])) for a in self.automata])
     possible_internal_transitions = dict([(a, []) for a in self.automata])
     transition_channels = {}
     for a in self.automata:
         if state1[a] == state2[a]:
             possible_transitions[a].append(None)
         for t in a.edges(data=True):
             if a.can_transition(state1[a], state2[a], t):
                 possible_transitions[a].append(t)
                 channel = t[2]["channel"]
                 if channel is None:
                     possible_internal_transitions[a].append(t)
                 else:
                     possible_channels[a].add(channel)
     for a in self.automata:
         for c in list(possible_channels[a]):
             assert c in self.readers, "{} not in {}".format(c, self.readers)
             assert c in self.writer, "{} not in {}".format(c, self.writer)
             automata = self.readers[c] + [self.writer[c]]
             if any(c not in possible_channels[ap] for ap in automata) or any(
                 None not in possible_transitions[ap] for ap in self.automata if ap not in automata
             ):
                 possible_channels[a].remove(c)
     if any(len(possible_channels[a]) > 0 for a in self.automata):
         c = next(list(possible_channels[a])[0] for a in self.automata if len(possible_channels[a]) > 0)
         if verbose > 0:
             print "Checking channel {}".format(c)
         for t in possible_transitions[self.writer[c]]:
             writer_transition = t
             if verbose > 0:
                 print "Checking writer transition {}".format(t)
             if t is not None and t[2]["channel"] == c:
                 channel_expressions = t[2]["channel_expression"]
                 channel_expression_values = [
                     util.evaluate_expression(
                         channel_expression, {}, state1[self.writer[c]], tables=self.writer[c].tables
                     )
                     for channel_expression in channel_expressions
                 ]
                 if verbose > 0:
                     print "Writer tables are {}".format(self.writer[c].tables)
                     print "Channel expressions are {}".format(channel_expressions)
                     print "Channel expression values are {}".format(channel_expression_values)
                 reader_transitions = [
                     next(t for t in possible_transitions[a] if t is not None and t[2]["channel"] == c)
                     for a in self.readers[c]
                 ]
                 writer_matches_readers = True
                 for rt in reader_transitions:
                     if verbose > 0:
                         print "Checking against reader transition {}".format(rt)
                     ra = rt[2]["automaton"]
                     updates = rt[2]["update"]
                     for update in updates:
                         if c in z3p.variables_in_expression(update[1]):
                             if isinstance(c, z3p.ArrayRef):
                                 selects = util.selects_in_expression(update[1])
                                 new_reader_concrete_memory = dict(state1[ra])
                                 for select in selects:
                                     index = select.arg(1)
                                     new_reader_concrete_memory[c[index]] = channel_expression_values[
                                         index.as_long()
                                     ]
                                 if state2[ra][update[0]] != util.evaluate_expression(
                                     update[1], {}, new_reader_concrete_memory
                                 ):
                                     writer_matches_readers = False
                             else:
                                 new_reader_concrete_memory = dict(state1[ra])
                                 new_reader_concrete_memory[c] = channel_expression_values[0]
                                 s = z3p.Solver()
                                 s.add(
                                     z3p.Neq(
                                         state2[ra][update[0]],
                                         util.evaluate_expression(update[1], {}, new_reader_concrete_memory),
                                     )
                                 )
                                 if s.check() != z3p.unsat:
                                     if verbose:
                                         print "update does not match {}, {}".format(
                                             state2[ra][update[0]],
                                             util.evaluate_expression(update[1], {}, new_reader_concrete_memory),
                                         )
                                     writer_matches_readers = False
                 if writer_matches_readers:
                     return [writer_transition] + reader_transitions
     else:
         for a in self.automata:
             other_automata = [ap for ap in self.automata if a != ap]
             if len(possible_internal_transitions[a]) > 0 and all(
                 None in possible_transitions[ap] for ap in other_automata
             ):
                 return [possible_internal_transitions[a]]