def _broadcast(agent, term, intention): # Illocutionary force. ilf = pyson.grounded(term.args[0], intention.scope) if not pyson.is_atom(ilf): return if ilf.functor == "tell": goal_type = pyson.GoalType.belief elif ilf.functor == "achieve": goal_type = pyson.GoalType.achievement else: raise pyson.PysonError("unknown illocutionary force: %s" % ilf) # Prepare message. message = pyson.freeze(term.args[1], intention.scope, {}) tagged_message = message.with_annotation( pyson.Literal("source", (pyson.Literal(agent.name), ))) # Broadcast. for receiver in agent.env.agents.values(): if receiver == agent: continue receiver.call(pyson.Trigger.addition, goal_type, tagged_message, pyson.runtime.Intention()) yield
def _wait(agent, term, intention): # Handle optional arguments. args = [pyson.grounded(arg, intention.scope) for arg in term.args] if len(args) == 2: event, millis = args else: if pyson.is_number(args[0]): millis = args[0] event = None else: millis = None event = args[0] # Type checks. if not (millis is None or pyson.is_number(millis)): raise pyson.PysonError("expected timeout for .wait to be numeric") if not (event is None or pyson.is_string(event)): raise pyson.PysonError("expected event for .wait to be a string") # Event. if event is not None: # Parse event. if not event.endswith("."): event += "." log = pyson.Log(LOGGER, 1) tokens = pyson.lexer.TokenStream(pyson.StringSource("<.wait>", event), log) tok, ast_event = pyson.parser.parse_event(tokens.next(), tokens, log) if tok.lexeme != ".": raise log.error( "expected no further tokens after event for .wait, got: '%s'", tok.lexeme, loc=tok.loc) # Build term. event = ast_event.accept(pyson.runtime.BuildEventVisitor(log)) # Timeout. if millis is None: until = None else: until = agent.env.time() + millis / 1000 # Create waiter. intention.waiter = pyson.runtime.Waiter(event=event, until=until) yield
def _send(agent, recipient, ils, term): group = ils.literal_group() if group == ("tell", 0): frozen = pyson.grounded(term, {}).with_annotation(pyson.Literal("source", (agent.name, ))) agent.emit(recipient, functools.partial(pyson.runtime.add_belief, frozen)) elif group == ("achieve", 0): frozen = term.with_annotation(pyson.Literal("source", (agent.name, ))) agent.emit(recipient, functools.partial(pyson.runtime.call, pyson.Trigger.addition, pyson.GoalType.achievement, frozen)) else: raise pyson.PysonError("unsupported illocutionary force: %s/%d" % (group[0], group[1])) return True
def _send(agent, term, intention): # Find the receivers: By a string, atom or list of strings or atoms. receivers = pyson.grounded(term.args[0], intention.scope) if not pyson.is_list(receivers): receivers = [receivers] receiving_agents = [] for receiver in receivers: if pyson.is_atom(receiver): receiving_agents.append(agent.env.agents[receiver.functor]) else: receiving_agents.append(agent.env.agents[receiver]) # Illocutionary force. ilf = pyson.grounded(term.args[1], intention.scope) if not pyson.is_atom(ilf): return if ilf.functor == "tell": goal_type = pyson.GoalType.belief trigger = pyson.Trigger.addition elif ilf.functor == "untell": goal_type = pyson.GoalType.belief trigger = pyson.Trigger.removal elif ilf.functor == "achieve": goal_type = pyson.GoalType.achievement trigger = pyson.Trigger.addition else: raise pyson.PysonError("unknown illocutionary force: %s" % ilf) # TODO: unachieve, askOne, askAll, tellHow, untellHow, askHow # Prepare message. message = pyson.freeze(term.args[2], intention.scope, {}) tagged_message = message.with_annotation( pyson.Literal("source", (pyson.Literal(agent.name), ))) # Broadcast. for receiver in receiving_agents: receiver.call(trigger, goal_type, tagged_message, pyson.runtime.Intention()) yield