Description

The budgeted consumption policy regulates the interaction within a community of agents that provide services to each other (some of these agents might be servers, and others their clients; alternatively, they might serve each other, in a peer-to-per manner). In order to regulate the number of service requests that agents can send to each others, and to provide for reliable accounting of the number of requests that a given member gets from others, we assume the following policy:

  1. Every member of the community can be assigned a service budget by a distinguished agent called the regulator .
  2. The sending of a request should reduce the service budget of the sender by one; and no request should be sent by an agent with a budget of zero.
  3. The arrival of a request would increment the visit count of the receiver by one.
  4. Every agent can report to the regulator the value of its current visit-count, which would be reset to zero when this report is made.
The implementation of this policy identifies the regulator by its LGI name. Thus, when running this example using your own infrastructure, the law requires to change the name of the regulator accordingly.

The law

The Prolog version of this law follows:

law(bc,language(prolog)).
alias(regulator,'regulator@research.rutgers.edu').


adopted(Par,Cert) :- do(add(budget(0))), do(add(visits(0))).

sent(#regulator,addToBudget(D),Y) :- do(forward).
arrived(#regulator,addToBudget(D),Y) :- do(incr(budget,D)), do(deliver).

sent(X,request(R),Y) :- budget(B)@CS, B > 0, do(decr(budget,1)), do(forward).
arrived(X,request(R),Y) :- do(incr(visits,1)), do(deliver).

sent(X,visitsReport,#regulator) :- visits(V)@CS, do(decr(visits,V)), do(forward(X,visitsReport(V),#regulator)).
arrived(X,visitsReport(V),#regulator) :- do(deliver).

sent(X,M,Y) :- do(deliver(Self,failedSending(M,Y),Self)).

disconnected :- do(quit).

The Prolog law can be found at:
http://www.moses.rutgers.edu/examples/budget/budgeted.law

This is the Java version of the law:

law(bc,language(java))

public class bc extends Law{

    public static final String regulator = "regulator@research.rutgers.edu";

    public void adopted(String arg) { 
        doAdd("budget(0)"); doAdd("visits(0)");
     }

    public void sent(String source, String message, String dest) {
	if(message.equals("getCS")) {
	   doDiscloseAllCS();
	   return;
	}
        if ( (message.startsWith("addToBudget")) && (source.equals(regulator))) {
            doForward();
            return;
        }
        if (message.startsWith("request")) {
	    int b = CS.fetchInt("budget");
	    if(b>0) {
		doDecr("budget", 1);
		doForward();
		return;
	    }
        }
        if ((message.equals("visitsReport")) && (dest.equals(regulator))) {
	    int v = CS.fetchInt("visits");
	    doDecr("visits", v);
	    doForward(Self,"visitsReport("+v+")",regulator);
	    return;
	}
        doDeliver("law", "failedSending(" + message + "," + dest + ")", source);
    }


    public void arrived(String source, String message, String dest) {
        if ((message.startsWith("addToBudget")) && (source.equals(regulator))) {
	    String content = getContentFromMessage(message);
            int b = Integer.parseInt(content);
            doIncr("budget", b);
            doDeliver();
            return;
        }
        if (message.startsWith("request")) {
            doIncr("visits", 1);
            doDeliver();
            return;            
        }
        if ((message.startsWith("visitsReport")) && (dest.equals(regulator))) {
            doDeliver();
            return;
        }
    }

    public void disconnected() {
	doQuit();
    }


    /**
	Helper method to parse the argument out of a regular expression
    */
    public String getContentFromMessage(String anyMessage) { 

        int index = anyMessage.indexOf("(");
        if (index == -1) return ""; 
        else return anyMessage.substring(index+1, anyMessage.length()-1); 

    } 
}
This law can be found at:
http://www.moses.rutgers.edu/examples/budget/budgeted.java1

Running the example

This example requires the pre-existence of a regulating agent. Since the name of the regulator is hard-coded in the law (only to keep the law simple ), prior to running the example one has to modify the law in order to reflect the proper regulator (to be used).

Perform the following steps:

  • giving a running controller on host hostname, download the law and change the regulator address line to the new value regulator@hostname;
  • publish the modified law on your own law server;
  • using the human interface create an agent with the name regulator;
  • create a pair of agents with the names x and y, respectively;
  • try to send the message request(something) from x to y; observe that the message fails;
  • send the message addToBudget(5) from the regulator to x; retry the message request(something) from x to y, and observe that the message arrives at y;
  • try to send the message norequest(something) from x to y, and observe how it fails;
  • observe how the sending of the messages fails after x sends 5 messages to y (after exhausting its budget);
  • from y send the message visitsReport to regulator@hostname; observe the number of visits being reported; re-send the same message and see that the number of visits is 0.