Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  //----------------------------------------------------------------------------
  // Copyright (C) 2003  Rafael H. Bordini, Jomi F. Hubner, et al.
  // 
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  // 
  // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 // 
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 // 
 // To contact the authors:
 // http://www.inf.ufrgs.br/~bordini
 // http://www.das.ufsc.br/~jomi
 //
 //----------------------------------------------------------------------------
 
 
 package jason.stdlib;
 
 

Internal action: .send.

Description: sends a message to an agent.

Parameters:

  • + receiver (atom, string, or list): the receiver of the message. It is the unique name of the agent that will receive the message (or list of names).
  • + ilf (atom): the illocutionary force of the message (tell, achieve, ...).
  • + message (literal): the content of the message.
  • + answer (any term [optional]): the answer of an ask message (for performatives askOne, askAll, and askHow).
  • + timeout (number [optional]): timeout (in milliseconds) when waiting for an ask answer.

Messages with an ask illocutionary force can optionally have arguments 3 and 4. In case they are given, .send suspends the intention until an answer is received and unified with arg[3], or the message request times out as specified by arg[4]. Otherwise, the intention is not suspended and the answer (which is a tell message) produces a belief addition event as usual.

Examples (suppose that agent jomi is sending the messages):

  • .send(rafael,tell,value(10)): sends value(10) to the agent named rafael. The literal value(10)[source(jomi)] will be added as a belief in rafael's belief base.
  • .send(rafael,achieve,go(10,30): sends go(10,30) to the agent named rafael. When rafael receives this message, an event <+!go(10,30)[source(jomi)],T> will be added in rafael's event queue.
  • .send(rafael,askOne,value(beer,X)): sends value(beer,X) to the agent named rafael. This askOne is an asynchronous ask since it does not suspend jomi's intention. If rafael has, for instance, the literal value(beer,2) in its belief base, this belief is automatically sent to jomi. Otherwise an event like +?value(beer,X)[source(self)] is generated in rafael's side and the result of this query is then sent to jomi. In the jomi's side, the rafael's answer is added in the jomi's belief base and an event like +value(beer,10)[source(rafael)] is generated.
  • .send(rafael,askOne,value(beer,X),A): sends value(beer,X) to the agent named rafael. This askOne is a synchronous askOne, it suspends jomi's intention until rafael's answer is received. The answer (something like value(beer,10)) unifies with A.
  • .send(rafael,askOne,value(beer,X),A,2000): as in the previous example, but agent jomi waits for 2 seconds. If no message is received by then, A unifies with timeout.

public class send extends DefaultInternalAction {
    
    @Override
    public boolean canBeUsedInContext() {
        return false;
    }
    private boolean lastSendWasSynAsk = false
    
    @Override public int getMinArgs() { return 3; }
    @Override public int getMaxArgs() { return 5; }
    @Override protected void checkArguments(Term[] argsthrows JasonException {
        super.checkArguments(args); // check number of arguments
        if (!args[0].isAtom() && !args[0].isList() && !args[0].isString())
            throw JasonException.createWrongArgument(this,"TO parameter ('"+args[0]+"') must be an atom, a string or a list of receivers!");
        if (! args[1].isAtom())
            throw JasonException.createWrongArgument(this,"illocutionary force parameter ('"+args[1]+"') must be an atom!");
    }
    @Override
    public Object execute(final TransitionSystem tsUnifier unTerm[] argsthrows Exception {
        checkArguments(args);
        
        final Term to   = args[0];
        Term ilf  = args[1];
        Term pcnt = args[2];
        
        // remove source annots in the content (in case it is a pred)
        // -- CHANGE: use nested annots 
        //try {
        //    ((Pred)pcnt).delSources();
        //} catch (Exception e) {}
        
    
        // create a message to be sent
        final Message m = new Message(ilf.toString(), ts.getUserAgArch().getAgName(), nullpcnt);
        // async ask has a fourth argument and should suspend the intention
         = m.isAsk() && args.length > 3;
        if () {
            m.setSyncAskMsgId();
        	ts.getC().addPendingIntention(m.getMsgId(), ts.getC().getSelectedIntention());
        }
        // (un)tell or unknown performative with 4 args is a reply to
        if ( (m.isTell() || m.isUnTell() || !m.isKnownPerformative()) && args.length > 3) {
            Term mid = args[3];
            if (! mid.isAtom()) {
                throw new JasonException("The Message ID ('"+mid+"') parameter of the internal action 'send' is not an atom!");
            }
            m.setInReplyTo(mid.toString());
        }
    
        // send the message
        if (to.isList()) {
            for (Term t: (ListTerm)to) {
                delegateSendToArch(ttsm);
            }
        } else {
            delegateSendToArch(totsm);
        }
        
        if ( && args.length == 5) {
            // get the timeout deadline
            Term tto = args[4];
            if (tto.isNumeric()) {
                ts.getAg().getScheduler().schedulenew Runnable() {
                    public void run() {
                        // if the intention is still in PI, brings it back to C.I with the timeout
                        Intention intention = ts.getC().removePendingIntention(m.getMsgId());
                        if (intention != null) {
                            // unify "timeout" with the fourth parameter of .send
                            Structure send = (Structure)intention.peek().removeCurrentStep();
                            Term timeoutAns = null;
                            if (to.isList()) {
                                VarTerm answers = new VarTerm("AnsList___"+m.getMsgId());
                                Unifier un = intention.peek().getUnif();
                                timeoutAns = un.get(answers);
                                if (timeoutAns == null)
                                    timeoutAns = new ListTermImpl();
                            } else {
                                timeoutAns = new Atom("timeout");
                            }
                            intention.peek().getUnif().unifies(send.getTerm(3), timeoutAns);
                            // add the intention back in C.I
                            ts.getC().resumeIntention(intention);
                            ts.getUserAgArch().wake();                                
                        }
                    }
                }, (long)((NumberTerm)tto).solve(), .);
            } else {
                throw new JasonException("The 5th parameter of send must be a number (timeout) and not '"+tto+"'!");
            }
        }
        
        return true;
    }
    private void delegateSendToArch(Term toTransitionSystem tsMessage mthrows Exception {
        if (!to.isAtom() && !to.isString()) 
            throw new JasonException("The TO parameter ('"+to+"') of the internal action 'send' is not an atom!");
        String rec = null;
        if (to.isString())
            rec = ((StringTerm)to).getString();
        else
            rec = to.toString();
        if (rec.equals("self"))
            rec = ts.getUserAgArch().getAgName();
        m.setReceiver(rec);
        ts.getUserAgArch().sendMsg(m);
    }
    
    @Override
    public boolean suspendIntention() {
        return ;
    }    
New to GrepCode? Check out our FAQ X