def __is_undirected_graph__(__self): if not __self.is_bidirected_graph(): return False if __self.has_laedges(): return False if __self.has_haedges(): return False f = SpecialMethodGetter(__self.hedge2is_outgoing).__getitem__ return all( f(hedge0) and f(hedge1) for aedge, (hedge0, hedge1) in enumerate(__self.aedge2hedges))
def put_message(self, message): # msg will be stored at data[intf] # but since interface has parameters # , a particular msg will not be store to all interfaces. if message in self.all_messages: return self.check_message(message) xmessage = self.message2xmessage(message) SpecialMethodGetter(self).__push_xmessage_into_queue__(xmessage) self.all_messages.add(message)
def check_interface_message(self, interface, message): cmsg = self.message2constructor(message) cintf = self.interface2constructor(interface) if self.interface_constraint[cintf] != cmsg: raise MessageClosureExecutor_TypeError( f'interface mismatch message: interface={interface!r}, message={message!r}' ) SpecialMethodGetter(self).__check_interface_message__( interface, message)
def check_action(self, action): # action -> None|raise MessageClosureExecutor_TypeError action_constructor = self.action2constructor(action) interface_constructors = self.action_constraint[action_constructor] interfaces = self.action2interfaces(action) _interface_constructors = tuple( map(self.interface2constructor, interfaces)) if interface_constructors != _interface_constructors: raise MessageClosureExecutor_TypeError( f'action.action_constructor.interface_constructors={interface_constructors!r} != {_interface_constructors}=action.interfaces.interface_constructors; interfaces={interfaces!r}' ) SpecialMethodGetter(self).__check_action__(action)
def execute_until_closure(self): #while not SpecialMethodGetter(self).__is_xmessage_queue_empty__(): try: while True: xmessage = SpecialMethodGetter( self).__pull_xmessage_outfrom_queue__() is_message, action_or_message = \ self.distinguish_xmessage(xmessage) if is_message: message = action_or_message self.__execute_message(message) else: action = action_or_message self.__execute_action(action) except MessageClosureExecutor_EmptyError: pass
def __execute_action(self, action): # register to all interfaces print_ferr(lambda: f'register: action={action!r}') interfaces = self.action2interfaces(action) for interface in set(interfaces): _open_write(self.interface2actions, interface).append(action) if not interfaces: messages = () action_constructor = self.action2constructor(action) afunc = self.action_constructor2function[action_constructor] SpecialMethodGetter(self).__execute_action__function_messages( afunc, action, messages) else: def f(interface): return len(_open_read(self.interface2messages, interface)) interface = min(interfaces, key=f) self.__execute_action_from_interface_idx(action, interface, 0)
def __execute_action_from_interface_idx(self, action, interface, begin_idx): action_constructor = self.action2constructor(action) afunc = self.action_constructor2function[action_constructor] messages = _open_read(self.interface2messages, interface) if len(messages) <= begin_idx: return del messages interfaces = self.action2interfaces(action) idc = [ i for i, _interface in enumerate(interfaces) if interface == _interface ] assert idc messagess = [ _open_read(self.interface2messages, interface) for interface in interfaces ] lens = tuple(map(len, messagess)) if any(L == 0 for L in lens): return while idc: last_idx = idc.pop() begins = [0] * len(lens) ends = list(lens) begins[last_idx] = begin_idx for i in idc: ends[i] = begin_idx iterables = map(itertools.islice, messagess, begins, ends) for messages in itertools.product(*iterables): # tuple messages not list messages # tuple messages are args for action # list messages are an interface storage SpecialMethodGetter(self).__execute_action__function_messages( afunc, action, messages)
def interface_constraint(self): #:: {InterfaceConstructor: MessageConstructor} # immutable return MappingProxyType( SpecialMethodGetter(self).__get_interface_constraint__())
def interface_constructor2auto_action_constructors(self): #:: {InterfaceConstructor:{ActionConstructor}} # immutable return MappingProxyType( SpecialMethodGetter( self).__get_interface_constructor2auto_action_constructors__())
def auto_action_constructor2maker(self): #:: {ActionConstructor: Interface -> Action} # immutable return MappingProxyType( SpecialMethodGetter(self).__get_auto_action_constructor2maker__())
def interface2actions(self): #:: {Interface: [Action]} # iff interface in action.interfaces # mutable return SpecialMethodGetter(self).__get_interface2actions__()
def message_constructor2function(self): #:: {MessageConstructor: Message->Iter Interface} # immutable return MappingProxyType( SpecialMethodGetter(self).__get_message_constructor2function__())
def put_action(self, action): if action in self.all_actions: return self.check_action(action) xmessage = self.action2xmessage(action) SpecialMethodGetter(self).__push_xmessage_into_queue__(xmessage) self.all_actions.add(action)
def check_message(self, message): message_constructor = self.message2constructor(message) mfunc = self.message_constructor2function[message_constructor] for interface in mfunc(message): self.check_interface_message(interface, message) SpecialMethodGetter(self).__check_message__(message)
def restart(self): # -> None SpecialMethodGetter(self).__clear_xmessage_queue__() self.__init()
def iter_initial_xmessages(self): return iter(SpecialMethodGetter(self).__get_initial_xmessages__())
def action_constraint(self): #:: {ActionConstructor: (InterfaceConstructor,)*n} # immutable return MappingProxyType( SpecialMethodGetter(self).__get_action_constraint__())
def action_constructor2function(self): #:: {ActionConstructor: Action -> (Message,)*n -> Iter XMessage} #immutable return MappingProxyType( SpecialMethodGetter(self).__get_action_constructor2function__())
def all_messages(self): #:: {Message} # mutable return SpecialMethodGetter(self).__get_all_messages__()
def all_actions(self): #:: {Action} # mutable return SpecialMethodGetter(self).__get_all_actions__()
def interface2messages(self): #:: {Interface: [Message]} # mutable dict<list> should not be defaultdict<list> return SpecialMethodGetter(self).__get_interface2messages__()