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:
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).
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 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:
regulator@hostname;
regulator;
x and y, respectively;
request(something) from x to y; observe that the message fails;
addToBudget(5) from the regulator
to x; retry the message request(something) from x to y,
and observe that the message arrives at y;
norequest(something) from x
to y, and observe how it fails;
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.