Example Interaction Models

We provide here a collection of examples of interaction models taken from our test cases, based on areas such as bioinformatics, business and emergency response.

Business

Customer and vendor negotiation

A customer, C, can send a request to a vendor, V, to buy an item, X, that the customer needs and believes the vendor sells. Then the customer takes the role of negotiator with the vendor.

A negotiating customer with a set, S, of negotiated attributes of the desired item, X, either receives an offer of a new attribute, A, or it receives a request to commit to the current set of negotiated attributes and replies with the constrants, CA, it wishes to impose on those attributes. In the scenario of purchasing a computer, A could represent, for example, the size of the monitor.

A vendor, V, receives a request from a customer, C, to buy an item, X; then takes the role of negotiator with the customer over the attribute set, S, that applies to that item.

A negotiating vendor with a set, S, of negotiable attributes of the desired item, X, either takes the first attribute, A, of S and offers it to the customer for acceptance, or if S is empty it asks the customer to commit to the attributes they have discussed and receives the customer's constraints, CA, on the final values of those attributes. If these are satisfiable, it informs the customer of the final attribute values, F, for the sold item.


//  Written by Dave Robertson
//
//  LCC Specification for a customer and vendor negotiation:

a(customer,C)::
	ask(buy(X)) => a(vendor,V) <- need(X) and sells(X,V) then
	a(neg_customer(X,V,[]),C)

a(neg_customer(X,V,S),C)::
	(
		offer(A) <= a(neg_vendor(X,C,_),V) then
		accept(A) => a(neg_vendor(X,C,_),V) <- acceptable(A) then
		a(neg_customer(X,V,[att(A)|S],C)
	)
	or
	(
		ask(commit) <= a(neg_vendor(X,C,_),V) then
		tell(commit(S,CA)) => a(neg_vendor(X,C,_),V) <- choose(S,CA) then
		tell(sold(F)) <= a(neg_vendor(X,C,_),V)
	)

a(vendor,V)::
	ask(buy(X)) <= a(customer,C) then
	a(neg_vendor(X,C,S),V) <- attributes(X,S)

a(neg_vendor(X,C,S),V)::
	(
		offer(A) <= a(neg_customer(X,V,_),C) <- S=[A|T] and available(A) then
		accept(A) => a(neg_customer(X,V,_),C) then
		a(neg_vendor(X,C,T),V)	
	)
	or
	(
		ask(commit) => a(neg_customer(X,V,_),C) <- S = [] then
		tell(commit(F,CA)) <= a(neg_customer(X,V,_),C) then
		tell(sold(F)) => a(neg_customer(X,V,_),C) <- CA
	)

Printing sales orders

An input device, I, can send a message to a sales agent, S, containing information about an order, X; it then continues in the same role.

A sales agent, S, can receive from an input device an order, X, and can send to a printer, P, the order X that the sales believes to be a valid input. Then the sales either receives from the printer that the order has been successfully printed or that the order has failed to print. In both cases, the sales continues in the same role.

A printer, P, can receive an order, X, from a sales, S, and either sends to the sales that the order has been successfully printed if the printing was completed. Otherwise, the printer can ask the administrator, A, for assistance, receive a response from the administrator, and sends a response to the sales that the printing has failed.

An administrator, A, receives a request from a printer, P, for help and then sends it a response offering help.

[More details]

//  Written by Li Guo and modified by Michael Chan
//
//  LCC Specification for a sales order printing process:

r( inputdevice, initial)
r( sales, necessary, 1)
r( printer, necessary, 1)
r( admin, necessary,1)

a(I, inputdevice)::
	getInput(X) => a(S, sales) then
	a(I, inputdevice)

a(S, sales)::
	getInput(X) <= a(I, inputdevice) then
	saleOrder(X) => a(printer, P) <- validInput(X) then
	(
		(printed(SaleOrder(X)) <= a(P, printer) 
		then
			a(S, sales)) 
		or
		(
			failed(saleOrder(X)) <= a(P, printer) 
			then
			a(loop(X), sales)
		)
	)

a(P, printer)::
saleOrder(X) <= a(loop(X), sales) 
	then
	(
		printed(saleOrder(X)) => a(loop(X), sales) 
		or
		(
			askForHelp(help) => a(A, admin) 
			then
			(help) <= a(A, admin) 
			then
			failed(saleOrder(X)) => a(X, sales) 
			then
			a(P, printer)
		)
	)

a(A, admin)::
	askForHelp(help) <= a(P, printer) then
	(help) => a(P, printer)

Stock lookup

A requestor, ID, sends a request, Req, to a stock quote service provider, QSP, for a quote for a foreign stock, the price of which is based on a foreign currency. The requestor then receives a response, Res, from the service provider the quote in the requestor's local currency.

A stock quote service provider, QSP, can receive a look-up request, Req, from a requestor, ID, for a quote on a foreign stock. The provider then sends a request to a stock provider, SP, and receives the price, P, of the requested stock in the stock's listed currency. Similarly, the service provider sends a request to a currency provider, CP, to obtain the exchange rate, R, between the stock's listed currency and the requestor's local currency. The quote service provider then sends a request to a price calculator, PC, to compute the stock's price in the requestor's local currency, and then sends the total, T, to the requestor.

A stock provider, SP, receives a request for a stock quote from a quote service provider, QSP, and sends back the quote, P, for the requested stock to the service provider.

A currency provider, CP, receives a request for a currency exchange rate check from a quote service provider, QSP, and sends back the exchange rate, R, of the requested currency to the service provider.

A price calculator, PC, receives a request from a quote service provider, QSP, for a computation of the product of the stock price, P, and the exchange rate, R, and sends the product back to QSP.

[More details]

//  Written by Li Guo and modified by Michael Chan
//
//  LCC Specification for a stock lookup process:

r( requestor, initial)
r( quoteserviceprovider, necessary, 1)
r( stockprovider, necessary, 1)
r( currencyprovider, necessary, 1)
r( pricecalculator, necessary,1)

a(requestor, ID) ::
	request(requestlookup(Req)) => a(quoteserviceprovider, QSP) then
	response(Res) : <= a(quoteserviceprovider, QSP)

a(quoteserviceprovider, QSP)::
	request(requestlookup(Req)) <= a(requestor, ID) then
	(
		(
			getstockquote(getquote(Req)) => a(stockprovider, SP)
			then
			stockquote(P) <= a(stockprovider, SP)
		)
		par	
		(
			getexchangerate(getrate(Req)) => a(currencyprovider, CP) 
			then
			currencyquote(R) <= a(currencyprovider, CP)
		)
	) 
	then
	multiplyfloat(multiply(P, R)) => a(pricecalculator, PC) then
	product(T) <= a(pricecalculator, PC) then
	response(T) => a(requestor, ID)	

a(stockprovider, SP) ::
	getstockquote(getquote(P)) <= a(quoteserviceprovider, QSP) then
	stockquote(SRes) => a(quoteserviceprovider, QSP)

a(currencyprovider, CP) ::
	getexchangerate(getrate(R)) <= a(quoteserviceprovider, QSP) then
	currencyquote(CRes) => a(quoteserviceprovider, QSP)

a(pricecalculator, PC) ::
	multiplyfloat(multiply(P, R)) <= a(quoteserviceprovider, QSP) then
	product(Total) => a(quoteserviceprovider, QSP)
		

Shipping service

A shipping service customer, C, can send a request to a shipping service, P, for a shipment. It then either receives a single notice from the shipping service informing it that the items have been shipped or takes the role of a pending shipment customer when some items are yet to be shipped.

A pending shipment customer, PC, receives a notice from the priority shipping service provider, PP, until all requested items have been shipped. It continues in this role until all items have been shipped.

A shipping service provider, P, receives a shipping request from a shipping service customer, C. It then either sends a shipping notice to the customer if the shipment is complete, or takes the role of a priority shipping service provider, PP, if there remain some unshipped items.

A priority shipping service provider, PP, sends notices to the pending shipment customer, PC, and continues to be in this role until all items have been shipped.

[More details]

//  Written by Li Guo and modified by Michael Chan
//
//  LCC Specification for a shipping service process:

a(shippingservicecustomer, C) ::
	shiprequest => a(shippingservice, P) then
	(
		shippingnotice(status) <= a(shippingservice, P)
		or
		(
			a(pendingshipmentcustomer(loop(m)), PC) <-
			(itemsshipped = 0) and itemsshipped < itemstotal
		)
		or null
	)

a(pendingshipmentcustomer(loop(m)), PC) ::
	shippingnotice(status) <= a(priorityshippingservice(loop(m)), PP) then
	(
		a(pendingshipmentcustomer(loop(m)), PC) <- 
		(itemsshipped < itemstotal) and itemsshipped = itemsshipped + itemscount
	)
	or null

a(shippingservice, P) ::
	shiprequest <= a(shippingservicecustomer, C) then
	(
		(
			shippingnotice(status) => a(shippingservicecustomer, C)
			<- (status = itemscount) and getvariableproperty(shiprequest, shipcomplete)
		)
		or
		(
			a(priorityshippingservice(loop(m)), PP)
			<- (itemsshipped = 0) and (itemsshipped < itemstotal)
		)
		or null
	)

a(priorityshippingservice(loop(m)), PP) ::
	shippingnotice(status) => a(pendingshipmentcustomer(loop(m)), PC) <- status = yes then
	(
		(
			a(priorityshippingservice(loop(m)), P) 
			<- (itemsshipped < itemstotal) and (itemsshipped = itemsshipped + itemscount)
		)
		or null
	)

Bioinformatics

3-D Structure Prediction of Yeast Proteins

 


//  Written by Xueping Quan and modified by Paolo Besana
//
//  LCC Specification for consistency checking of yeast protein 3-D models:

r( experimenter, initial)
r( data_coordinator, necessary, 1)
r( data_collector, auxiliary, 1)
r( data_retriever, auxiliary,1)
r( data_source, necessary, 1)
r( data_filter, necessary, 1)
r( data_comparer, necessary, 1)
r( pairwise_comparer,necessary,1)

a(experimenter, E)::
data_request(Is) => a(data_coordinator, X) <- ask_user(Is) then
data_compared(Is,Sd) <= a(data_coordinator, X) then
null <- printresults(Sd)

a(data_coordinator, X)::
data_request(Is) <= a(experimenter, E) then
null<-getInterestedRole(R) and getPeers(R,Sp) and 
	makeEmptyList(SdS) then
a(data_collector(Is, Sp, SdS, SdF),X) then
filter(Is,Sp,SdF) => a(data_filter,Y) then
filtered(S) <= a(data_filter, Y) then
filtered(Is,Sp,S) => a(data_comparer, C) then
data_compared(Is,Df) <= a(data_comparer, C) then
data_compared(Is,Df) => a(experimenter,E)

a(data_collector(Is,Sp,SdS,SdF),X)::
null <- Is=[] and assign(SdS,SdF) or
(null <- Is=[I|Ri] then
data_request(I) => a(data_source,P) then
data_report(I,Ds) <= a(data_source,P) then
null <- NewSdS=[Ds|SdS] then
a(data_collector(Ri,Sp,NewSdS,SdF),X))

a(data_retriever(I,Sp,SBuildUp,SF),X)::
null <- Sp=[] and assign(SBuildUp, SF) or
(null <- Sp = [P|Rp] then
data_request(I) => a(data_source,P) then
data_report(I,Ds) <= a(data_source,P) then
null <- NewSBuildUp = [Ds|SBuildUp] then
a(data_retriever(I,Rp,NewSBuildUp,SF),X))

a(data_filter, Y)::
filter(Is,Sp,Sd) <= a(data_coordinator,X) then
filtered(S) => a(data_coordinator,X) <- apply_filter(Sd,S)

a(data_source, P)::
data_request(I) <= a(data_collector,X) then
data_report(I,Ds) => a(data_collector,X) <- lookup(I,Ds)

a(data_comparer, C)::
filtered(Is,Sp,S) <= a(data_coordinator,X) then
data_tocompare(Is,Sp,S) => a(pairwise_comparer, M) then
data_pairwise(Is, Pc) <= a(pairwise_comparer, M) then
data_compared(Is,Df) => a(data_coordinator,X) <-
		     threeway_check(Is,Pc,Df)

a(pairwise_comparer, M)::
data_tocompare(Is,Sp,S) <= a(data_comparer, C) then
data_pairwise(Is,Pc) => a(data_comparer, C) <- 
		     pairwise_check(Is,S,Pc)

 

De Novo Protein Sequencing by MS/MS

 


//  Written by Xueping Quan and modified by Paolo Besana
//
//  LCC Specification for cross-checking of de novo sequencing by MS/MS:

r( experimenter, initial)
r( data_coordinator, necessary, 1)
r( data_collector, auxiliary, 1)
r( data_retriever, auxiliary,1)
r( data_source, necessary, 1)
r( data_comparer, necessary, 1)

a(experimenter, E)::
null <- ask_files(Lst_dtas_file) then
null <- get_content_from_file(Lst_dtas_file, Dtas) then
data_request(Lst_dtas_file, Dtas) => a(data_coordinator, X) then
data_compared(Lst_dtas_file,Sd) <= a(data_coordinator, X)  then
null <- printresults(Sd)

a(data_coordinator, X)::
data_request(Lst_dtas_file, Dtas) <= a(experimenter, E) then
null <- getInterestedRole(R) and getPeers(R,Sp) and 
	makeEmptyList(SdS)  then
a(data_collector(Lst_dtas_file, Dtas, Sp, SdS, SdF),X) then
data_tocompare(Lst_dtas_file,Sp,SdF) => a(data_comparer, C)  then
data_compared(Lst_dtas_file,Df) <= a(data_comparer, C) then
data_compared(Lst_dtas_file,Sd) => a(experimenter,E)

a(data_collector(Lst_dtas_file, Dtas, Sp, SdS, SdF),X)::
null <- Lst_dtas_file=[] and assign(SdS,SdF) or
(null <- Lst_dtas_file=[F|Rdtas_filesTail] and Dtas = [D|DtasTail]
then
data_request(F,D) => a(data_source,P) then
data_report(F,Ds) <= a(data_source,P)  then
null <- NewSdS=[Ds|SdS] then
a(data_collector(Rdtas_filesTail,DtasTail,Sp,NewSdS,SdF),X))

a(data_retriever(I,Sp,SBuildUp,SF),X)::
null <- Sp=[] and assign(SBuildUp, SF) or
(null <- Sp = [P|Rp] then
data_request(I) => a(data_source,P) then
data_report(I,Ds) <= a(data_source,P) then
null <- NewSBuildUp = [Ds|SBuildUp] then
a(data_retriever(I,Rp,NewSBuildUp,SF),X))

a(data_source, P)::
data_request(F,D) <= a(data_collector,X) then
data_report(F,Ds)=>a(data_collector,X)<-denovoanalysis(F,D,Ds)

a(data_comparer, C)::
data_tocompare(Lst_dtas_file,Sp,SdF) <= a(data_coordinator,X) then
data_compared(Lst_dtas_file,Df) => a(data_coordinator,X) <-
				threeway_check(Lst_dtas_file,SdF,Df) 

 

Emergency Responses

STARTFE

STARTFE describes how an evacuation plan starts. An emergency coordinator alerts members to go to a specific destination. Each member finds a route to reach the destination.

 


//  Written by Gaia Trecarichi on 25/09/2007 
//
//  The firefighter coordinator retrieves a list of available firefighters, 
//  FFL, in order to send an alert message to each of them. 


a(firefighter_coordinator,FFC) ::=
( a(firefighter_coordinator(FFL),FFC) <-- obtainFFList(FFL))
or
null


//  The role involves a recursion over the list FFL so that a destination meeting
//  point (MP) can be assigned and an alert message can be sent to each 
//  firefighter FFL_H, in FFL. 
//  After having sent the messages to all the firefighters, the FFC assumes 
//  the role firefighter_coordinator3. 

a(firefighter_coordinator(FFL),FFC)::=
(( alert(MP) => a(firefighter,FFL_H) <-- FFL=[FFL_H|FFL_T] and 
	     assign_mp(MP, FFL_H) then
	     a(firefighter_coordinator(FFL_T),FFC) )
or 
( null <-- FFL=[] ) ) then 
a(firefighter_coordinator3,FFC)

//  In this role the FFC receives a confirmation (or disconfirmation) of reached
//  (not reached) destination MP from a given firefighter 
//  Id ('action_performer2' and 'replanner' are roles assumed by the firefighter role)
//  and the role recurses. If a disconfirmation is received, the FFC assigns to 
//  the firefighter Id a new destination - NewMP -  which is then embedded in 
//  the alert message sent back.

a(firefighter_coordinator3,FFC)::=
( (confirm(Id,MP) <= a(action_performer2(_,_,_,_),Id)) then 
a(firefighter_coordinator3,FFC) ) 
or 
(disconfirm(Id,MP) <= a(replanner(_,_,_),Id)  then
(alert(NewMP) => a(firefighter,Id) <-- assign_newDest(MP,NewMP,Id)) then
a(firefighter_coordinator3,FFC) )

//  The firefighter, FF, receives from the firefighter coordinator, FFC,
//  an alert message stating that the destination MP has to be reached.
//  Once the message is received, the firefighter, FF, assumes the role of 
//  route_finder.

a(firefighter,FF)::=
( alert(MP) <= a(firefighter_coordinator(_),FFC)
or 
alert(MP) <= a(firefighter_coordinator3,FFC) )  then
	a(route_finder(MP,FFC),FF) 


//  If the firefighter, FF, is not yet at the location Dest that must be reached
//  a vehicle will be needed together with the name of a digital service 
//  able to provide a route. 
//  A message for requesting a route between two locations (Pos and Dest) is 
//  then sent to the route service RS.
//  Once the firefighter FF receives the requested path together with its 
//  sub-paths through a message sent by the route service RS, he/her stores 
//  the path in its local memory and assumes the role action_performer 
//  in order to communicate the move action to the simulator which in turn 
//  will check its feasibility 

a(route_finder(Dest,FFC),Id) ::=
( request_route(Pos,Dest,Vehicle) => a(route_service,RS) <-- 
	at(Pos) and 
	not(Pos=Dest) and set_vehicle(Vehicle) and
	get_route_serviceID(RS) ) then
(route(From,To,Path,SubPaths) <= a(route_service,RS) then
 a(action_performer(move(From,To,Path,Vehicle),FFC),Id) <-- 
 decompose(Path,SubPaths,Vehicle) )


//  This role is entered by the firefighter when the simulator sends an 
//  illegal_action as a result.
//  It is similar to the previous role except for the fact that
//  - a list of banned subpaths is sent to the route service
//  - a disconfirmation is sent to the coordinator if no free paths leads to 
//  the destination.
//  Note: in the future this role will be embedded in the "route_finder" role.

a(replanner(S,OldDetails,FFC),Id) ::=
( request_route(Location,To,V,BanSubPaths) => a(route_service,RS) <-- 
at(Location) and
get_final_location(OldDetails,To) and
get_vehicle(OldDetails,V) and
get_BanSubPaths(BanSubPaths) and
get_route_serviceID(RS) ) then
(route(From,To,Path,NewDetails) <= a(route_service,RS) then
( a(action_performer(move(From,To,Path,V),FFC),Id) <-- 
  Path = [H|T] and 
  ass_breakdown(Path,NewDetails,V) )
 or
( (disconfirm(Id,To) => a(firefighter_coordinator3,FFC) <-- 
 Path=[]) then 
 a(firefighter,Id) ))


//  The route service, RS, after having received a route request from a route 
//  finder (or replanner) Id, selects a path from node From to node To, 
//  split the path in sub-paths and sends them back to the route finder Id.
//  The route service role then recurses to be able to accept other requests.
//  The route service can receive two types of messages from a route finder: 
//	- A message asking for a path from A to B (a vehicle is also specified);
//	- A message asking for a path from A to B (a vehicle is also specified) 
//        not including certain sub-paths (i.e., the blocked subpaths).
		      
a(route_service,RS)::=
( request_route(From,To,Vehicle) <= a(route_finder(_,_),Id) then    
(route(From,To,Path,SubPaths) => a(route_finder(_,_),Id) <-- 
	get_route(From,To,Vehicle,Path) and
	get_subpaths(Vehicle,Path,SubPaths)) then
 a(route_service,RS) )
or
( request_route(From,To,Vehicle,BanSubPaths) <= 
a(replanner(_,_,_),Id) then
(route(From,To,Path,SubPaths) => a(replanner(_,_,_),Id) <-- 
	get_route(From,To,Vehicle,BanSubPaths,Path) and
	get_subpaths(Vehicle,Path,SubPaths)) then
a(route_service,RS) )

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%% Agent coordinates its actions with the Simulator's Controller %%
//%% This file should be imported by every interaction (.inst file)%%
//%%    that needs to send actions to the simulator's controller   %%
//%%%%%%%%%%%%%%%% Written by Nardine on 21/08/2007 %%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

a(action_performer(Action,FFC),Id) ::=
a(action_performer2(S,Details,Details,FFC),Id) 
<--  simulator(S) and breakdown(Action,Details).

a(action_performer2(S,OldDetails,Details,FFC),Id) ::=

( Action => a(action_coordinator,S) <-- Details=[Action|Tail] then
Result <= a(action_coordinator,S) then
( a(replanner(S,OldDetails,FFC),Id) 
    <-- member(Result,[illegal_action(_),indecipherable(_)]) and 
	update_BanSubPath(Action)
or
a(action_performer2(S,OldDetails,Tail,FFC),Id) 
    <-- member(Result,[ok,pick,drop]) and performed_action(Action)
) )
or
(action_completed => a(action_coordinator,S) <-- Details=[] then 

(confirm(Id,To) => a(firefighter_coordinator3,FFC) <-- 
 get_final_location(OldDetails,To) and update_position(To) ) )

a(action_coordinator,S) ::=
(action_completed <= a(action_performer2(_,_,_,_),Id))
or
( update_action_results(Id,Action,Result)
  <-- Action <= a(action_performer2(_,_,_,_),Id) then
Result => a(action_performer2(_,_,_,_),Id) then
a(action_coordinator,S) )

 

CENSUS

CENSUS describes the phase during which an emergency peer registers information on people present at a certain location into a database.

 


//  Written by Lorenzo Vaccari

r(censuscurator,initial)
r(dbcurator,necessary,1)

//   The emergency peer enters this role to obtain the info 
//  (Name Type, Location, etc. ) related to a person and to send a 
//  relative message to the dbcurator (the peer who
//  actually will store the info into the DB). 
//  A success (failure) message is received if things went well (wrong) 

a(censuscurator, ID1):: 
update(Name,Type,Location,GPS,Status,Notes) => a(dbcurator, ID2) <- 
obtain(List, Name,Type,Location,GPS,Status,Notes)
then
success(Id) <= a(dbcurator, ID2)
or
(failure(Msg) <= a(dbcurator, ID2)
then
null <- proceed(Msg))


//  The peer who stores info into a DB enters this role.

a(dbcurator, ID2)::
update(Name,Type,Location,GPS,Status,Notes) <=  a(censuscurator, ID1)
then
success(Id) => a(censuscurator, ID1) <- updateDb(Name,Type,Location,GPS,Status,Notes,Id)
or
failure(Msg) => a(censuscurator, ID1) <- lastError(Msg)

 

BUSHANDLING

BUSHANDLING describes the phase during which an emergency peer (firefighter) needs a certain number of buses and, while they arrive, send them to specific destinations.

 


//  Written by Gaia Trecarichi on 19/09/2007
//
//  After having counted the number of people at the meeting point (MP) and
//  evaluated the criticality (danger level at that MP) the firefighter request 
//  a certain number of bus (No_bus) the firefighter will then receive from its 
//  coordinator the quantity of buses (NB) that will arrive and a 
//  list of refuge centers (DCL) where the buses can go after people are loaded.

a(firefighter(MP),FF)::
request_bus(MP,No_bus) => a(firefighter_coordinator,FFC)  <- 
    count(People) and get(Criticality) and 
bus_needed(People,Criticality,No_bus) and 
get_coordinator_ID(FFC) then
confirm_bus_arrival(NB,DCL) <= a(firefighter_coordinator,FFC) then 
		a(wait_for_bus(NB,DCL),FF) <- set_destination(DCL) then
		a(firefighter(MP),FF)				

//  The coordinator receives the request of buses, decides how many buses 
//  will send (No_bus) and assigns to each of them a destination
//  Then, he will send a confirmation message to the bus requester
		
a(firefighter_coordinator,FFC)::
request_bus(MP,Quantity) <= a(firefighter(_),FF) then
confirm_bus_arrival(No_bus,Destinations) =>  a(firefighter(_),FF)  <- 
check_for_bus(Quantity,No_bus) and assign(No_bus,Destinations) 

//  The bus requester enter this role after having received a confirmation of 
//    bus arrival from the coordinator.
//  He expects buses arriving in a quantity of  No_expected and has a list of 
//    destinations where to send each of them.
//  Once a certain number (No_Bus) of buses arrives at the location (MP), 
//    a list (ABL) containing details for each bus is given.
//  The list could merely be a list of bus identifiers.
//  The firefighter will assign to the arrived buses a certain number of 
//    destinations (Next_DCL) taken from the list DCL and
//    will start the buses (give a directive to the bus drivers ). 
//    He will then, wait for the other remaining buses.

a(wait_for_bus(No_expected,DCL),FF)::

( a(start_bus(ABL,Next_DCL),FF) <- DCL = [DCL_H| DCL_T] and 
bus_at_location(MP, No_Bus, ABL) and 
assign_dest(No_Bus,DCL,Next_DCL,Rest_DCL) then 
a(wait_for_bus(No_expected - No_Bus,Rest_DCL),FF) ) or 
null <- empty(DCL)

//  This role is needed when the firefighter has to start the bus. 
//  To each bus is assigned a destination (ABL is equal to DCL in lenght) 
//    and once the driver of each bus is identified, a directive to him/her 
//    is sent.

a(start_bus(ABL,DCL),FF)::
( drive_to(DCL_H) => a(bus_driver,BD)  <- ABL=[ABL_H|ABL_T] and
DCL=[DCL_H|DCL_T] and
driver_of(ABL_H,BD) then
a(start_bus(ABL_T,DCL_T),FF))	   
or			
null <- empty(ABL)


//  The bus driver, once the directive is received, get the route and 
//    move towards the destination. 
//    (here the bus_driver could jump to a "route_finder" role as defined 
//    in the interaction model "startFE")

a(bus_driver,BD)::
drive_to(Destination) <= a(start_bus(_,_),FF) then
 a(perfom(move(Location, Destination, Path, bus)), BD) <- at(Location) 
 and get_route(Location,Destination,Path)

 

RECONNAISSANCE

RECONNAISSANCE describes the phase during which an emergency peer (firefighter) needs to close a meeting point due to the increasing level of water measured at that meeting point and its neighbourhood.

 


//  Written by Gaia Trecarichi on 28/06/2007 - modified on 20/12/2007

r(firefighter,initial)
r(firefighter_coordinator,necessary,1)

//  The firefighter first measures the water level (WL_local) at the 
//  meeting point (MP) and then ask its coordinator
//  to give details on the water level at the closest areas (WL_adj_nodes). 
//  Based on this info, a parameter (Criticality) is computed in order to 
//  decide if it is the case to close the meeting point or not. 
//  If the MP is closed a message is sent to the coordinator.

a(firefighter,FF)::
update&request_WL_info(MP, WL_local) => a(firefighter_coordinator,FFC) 
     <- at(MP) and measure_local_WL(MP, WL_local) and 
	get_coordinator_ID(FFC) then
emergency_WL_info(MP, WL_adj_nodes) <= a(firefighter_coordinator,FFC) then
	null <- compute(WL_local, WL_adj_nodes, Criticality) then	
(a(perfom(close(MP)),FF) <- greater(Criticality,MaxCriticality) then	
   update_on_MP_state(closed) => a(firefighter_coordinator,FFC)) or 	
a(firefighter,FF) 


//  The firefighter coordinator receives a message from the firefighter to 
//  update info on water level at meeting point MP and to send info on water 
//  levels at its adjacent points.
//  The coordinator can also receives an "update_on_MP_state(closed)" message 
//  from the firefighter.

a(firefighter_coordinator,FFC)::
((update&request_WL_info(MP, WL_local) <= a(firefighter,FF) then 
emergency_WL_info(MP, WL_adj_nodes) => a(firefighter,FF) <- 
update_WL_info(MP,WL_local) and gather_WL_adj_area(MP, WL_adj_nodes)) or 
update_on_MP_state(closed) <= a(firefighter,FF) ) then
a(firefighter_coordinator,FFC)

 

WMS Service

The GIS agency service requestor, R, initiates the coordination task by entering the GA_SR role. According to this role the agent R assumes the role ga_sr and asks for the capabilities of the services provider. It uses the service address (MapFile) and the software version of the client request (Version). After that, the service requestor waits until the service provider returns the list of its capabilities. In our case it waits for the list of the available services (AvailableServices), the list of the available layers (AvailableLayers), the format of the returned file (Format), and the geographic coverage (map extent) of the available services (XMin_ME, YMin_ME, Xmax_ME, YMax_ME). In the second step the agent R asks to the service provider for a map. It selects some of the available geographic layers (selectLayers(AvailableLayers,Layers)), defines the map dimension (needMap(Width,Height)) and selects an area from the available geographic extension (selectBoundingBox(XMin_ME, YMin_ME, XMax_ME, YMax_ME, XMin_BB, YMin_BB, XMax_BB, YMax_BB)). The third operation is the request of the map legend for the selected layers.

The GIS agency service provider, P, assumes the role ga_sp and waits for one of the following requests: requestCapabilities, requestMap and requestLegend. In the former case, after receiving the request from the service requestor, it builds its capabilities (getCapabilities(MapFile, Version, AvailableServices, AvailableLayers, Format, Xmin_ME, YMin_ME, Xmax_Me, YMax_ME)) and passes them to the requestor. In the second request the service provider builds a digital map (getMap constraint) and passes it to the service requestor. In third case the service provider agent provides a legend for a collection of requested layers.


 LCC protocol for WMS Service
// 
// Lorenzo Vaccari
// 24th April 2007

r(ga_sr,initial)
r(ga_sp,necessary,1)


a(ga_sr,R):: 
requestCapabilities(MapFile,Version)=>a(ga_sp,P) <- needCapabilities(MapFile,Version) then
returnCapabilities(AvailableServices,AvailableLayers,Format,
		XMin_ME,YMin_ME,XMax_ME,YMax_ME)) <= a(gs_sp,P) then
requestMap(MapFile,Version,Layers,Width,Height,Format,Xmin_BB,YMin_BB,Xmax_BB,YMax_BB)) => 
a(ga_sp,P) <- selectLayers(AvailableLayers,Layers) and needMap(Width, Height) and
      selectBoundingBox(XMin_ME,YMin_ME,XMax_ME,YMax_ME,
			Xmin_BB,YMin_BB,Xmax_BB,YMax_BB)
returnMap(Map)<=a(ga_sp,P) then
requestLegend(MapFile,Version,Layers)=>a(ga_sp,P) then
returnLegend(Legend) <= a(ga_sp,P)


a(ga_sp,P) :: 
(
requestCapabilities(MapFile,Version)<=a(ga_sr,R) then
returnCapabilities(AvailableServices,AvailableLayers,Format,
			XMin_ME,YMin_ME,XMax_ME,YMax_ME)) <= a(gs_sr,R) 
    <- getCapabilities(MapFile,Version,AvailableServices,AvailableLayers,
			Format,XMin_ME,YMin_ME,XMax_ME,YMax_ME) 
) or
(
requestMap(MapFile,Version,Layers,Width,Height,Format,
		Xmin_BB,YMin_BB,Xmax_BB,YMax_BB)) => a(ga_sr,R) then
returnMap(Map)<=a(ga_sr,R) 
	    <- getMap(mapFile,Version,Request,Layers,Width,Height,Format,
		       Xmin_BB,YMin_BB,Xmax_BB,YMax_BB,Map) then
) or
(
requestLegend(MapFile,Version,Layers) <= a(ga_sr,R) then
returnLegend(Legend) => a(ga_sr,R)
		   <- getLegend(MapFile,Version,Layers,Legend)
)  
		      

 

Gazetteer Service

The Gazetteer requestor "R" initiates the coordination task by entering the gaz_requestor role. According to this role the agent R assumes the role "gaz_requestor" and asks for a list of toponyms that contains an input string ("Top"). The agent waits until the provider returns the list of toponym. Then it selects ("SelectToponym") one toponym and asks the geographic position of the toponym ("getTopByIDRespose(IDTop)"). After receinving the position it shows the lcoation to the user ("showToponymLocation"). If the toponym does not exists into the database, the IM returns an error ("error(IDTop)").

The gazetter provider "Z" assumes the role "gaz_requestor" and waits for a search request ("getTopRequest(Top)"). After receiving the request it searches for the string into its database ("searchFor(Top,LT)") and returns the list of toponyms that contains the string. Then it waits for a geographic position request and finally returns the geographic position of the selected toponym ("transform(IDTop,Loc)")


// LCC protocol for Gazetteer Service
// LCC code for local gazetteer. No coordinate
// transformation 
//
// Lorenzo Vaccari 
// 24th April 2007

r(gaz_requestor,initial)
r(gaz_provider,necessary,1)

a(gaz_requestor,R)::
getTopRequest(Top) => a(gaz_provider,Z) <- locate(Top) then	
( getTopResponse(LT) <= a(gaz_provider,Z) 
	then
	getTopByIDRequest(IDTop) => a(gaz_provider,Z) <- selectToponym(LT,IDTop) 
	then
	( getTopByIDResponse(Loc) <= a(gaz_provider,Z)
	 then
	 null <- showToponymLocation(Loc)
	)
	or
    error(IDTop) <=  a(gaz_provider,Z)
) 
or
notFound(Top) <= a(gaz_provider,Z) 

a(gaz_provider,Z)::
getTopRequest(Top) <= a(gaz_requestor,R) then
( getTopResponse(LT) => a(gaz_requestor,R) <- searchFor(Top,LT) 
 then
 getTopByIDRequest(IDTop) <= a(gaz_requestor,R) 
 then	
  getTopByIDResponse(Loc) => a(gaz_requestor,R) <- transform(IDTop,Loc)
   or 
  error(IDTop) =>  a(gaz_requestor,R)
) 
or
notFound(Top) => a(gaz_requestor,R) 

 

Playing Blackjack

 


//  Written By Paolo Besana
// -----------------------------------------------------------------------------------
// Player clauses

a(player(TotalMoney, LeftMoney),IDplr)::
null <- wager(Wager,TotalMoney) 
then
openingcards(Cards) <= a(dealer_starter(_,_), IDdlr)  
then
dealercard(OpenCard) <= a(dealer_starter(_,_), IDdlr)
then
a(player_strategy(Cards, OpenCard, Wager), IDplr).
then
(
 (
  win(Prize) <= a(dealer_end(_,_),IDdlr)
  then
  null <- LeftMoney = TotalMoney + Prize
 )
 or
 (
  ask(Amount) <= a(dealer_end(_,_),IDdlr)
  then
  null <- LeftMoney = TotalMoney - Amount
 )
 or
(
 push() <= a(dealer_end(_,_), IDdlr)
)

a(player_strategy(Cards,OpenCard,Wager,Depth), IDplr) ::
(
 bust(Cards,Wager) => a(dealer_waiter, IDdlr) <- 
				       greaterThan(sum(Cards), 21)
)
or
(
null <- makeDecision(Cards, OpenCard, Wager, Decision)
then
(
 (
  a(player_hit(Cards, NewCard), IDplr) <- equal(Decision, hit)
  then
  a(player_strategy([NewCard|Cards], OpenCard, Wager, Depth+1), IDplr)
 )	 
 or
 (
  a(player_double_down(Cards,Wager),IDplr) <- 
		equal(Decision, double_down)
 )
 or
 (
  surrender(Wager) => a(dealer_waiter(_), IDdlr) <- 
		      equal(Decision, surrender)
 )
 or
 (
  stand(Cards,Wager) => a(dealer_waiter, IDdlr) 
 )
)
)




a(player_hit(Cards, NewCard), IDplr) ::
hit() => a(dealer_waiter(_), IDdlr) 
then
card(Card) <= a(dealer_waiter(_), IDdlr)
then
a(player_strategy([Card|Cards], OpenCard, Wager), IDplr)


a(player_double_down(Cards,Wager),IDplr) ::
 double_down() => a(dealer_waiter(_), IDdlr) 
 then
 card(Card) <= a(dealer_waiter(_), IDdlr)
 then
 null <- NewCards = [Card|Cards]
 then
 (
   bust(NewCards,2*Wager) => a(dealer_waiter, IDdlr) <- 
			     greaterThan(sum(NewCards), 21)
   or
   stand(NewCards, 2*Wager) => a(dealer_waiter, IDdlr)
 )	 

% -----------------------------------------------------------------------------------
% Dealer clauses

a(dealer(Players, Cards), IDdlr)::
null <- Cards = [OpenCard|TailCards1] and 
	TailCards1 = [HiddenCards|TailCards2]
then
a(dealer_starter([OpenCard,HiddenCard], Players, 
			TailCards2, NewCards), IDdlr) 
then
a(dealer_waiter(NewCards, RestOfCards, Players, PlayerResults), IDdlr) 
then
a(dealer_game([OpenCard,HiddenCard], MyNewCards, Cards), IDdlr)
then
a(dealer_end(MyNewCards, PlayerResults), IDdlr)	


a(dealer_starter([OpenCard,HiddenCard], Players, Cards, NewCards), IDdlr) ::
(
 null <- Players = [IDP|PlayersTail]
 then
 openingcards([Card1, Card2]) => a(player,IDP) <- 
		      Cards = [Card1|TailCard1] and 
 TailCards1 = [Card2|RemainingCards]
 then
 dealercard(OpenCard) => a(player, IDP) 
 then 
 a(dealer_starter([OpenCard,HiddenCard], PlayersTail, 
			RemainingCards, NewCards), IDdlr)
)
or
(
null <- Players == [] and NewCards = RemainingCards
)


a(dealer_waiter(Cards, RestOfCards, Players, PlayerResults), IDdlr) ::
(
 null <- playerRemaining(Players,PlayerResults)
 then
 hit() <= a(player_hit(_,_,_), IDP) 
 then
 card(Card) => a(player_hit(_,_,_), IDP) <- Cards = [Card|RemainingCards]
 then 
 a(dealer_waiter(RemainingCards,RestOfCards, Players,PlayerResults)
)
or
(
 null <- playerRemaining(Players,PlayerResults)
 then
 bust(Cards,Wager) <= a(player_strategy(_,_), IDP) 
 then
 a(dealer_game(Cards, RestOfCards, Players, 
		      [(IDP,bust,_,Wager)|PlayerResults]), IDdlr)
)
or 
( 
 null <- playerRemaining(Players,PlayerResults)
 then
 stand(Cards, Wager) <= a(player_strategy(_,_), IDP) 
 then
 a(dealer_game(Cards, RestOfCards, Players, 
		      [(IDP,stand,Cards,Wager)|PlayerResults]), IDdlr)
)
or
( 
 null <- playerRemaining(Players,PlayerResults)
 then
 double_down() <= a(player_double_down(_,_), IDP) 
 then
 card(Card) => a(player_double_down(_,_), IDP) <- 
	       Cards = [Card|RemainingCards]
 then
 (
  bust(Cards,Wager) <= a(player_double_down(_,_), IDP)
  then
  a(dealer_game(RemainingCards, RestOfCards, Players, 
		[(IDP,bust,Cards,Wager)|PlayerResults]), IDdlr)
 )
 or
 (
  stand(Cards, Wager) <= a(player_double_down(_,_), IDP) 
  then
  a(dealer_game(Cards, RestOfCards, Players, 
		       [(IDP,stand,Cards,Wager)|PlayerResults]), IDdlr)
 )
)
or
(
 null <- playerRemaining(Players,PlayerResults)
 then
 surrender(Wager) <= a(player_strategy(_,_), IDP) 
 then
 a(dealer_game(Cards, RestOfCards, Players, 
		      [(IDP,surrender,_,Wager)|PlayerResults])
)
or
(
 null <- not playerRemaining(Players,PlayerResults) and 
	     (RestOfCards = Cards)
)




a(dealer_game(MyCards, MyNewCards, Cards),IDdlr)::
(
 null <- greaterThan(sum(Cards), 21) and MyNewCards = MyCards
)
or 
(
 null <- greaterThan(sum(MyCards), 17) and 
      evaluate_stand(MyCards) and MyNewCards = MyCards
)
or
(
 a(dealer_game([NewCard|MyCards], MyNewCards, TailCards), IDdlr) <- 
	Cards = [NewCard|TailCards] 
)
	

a(dealer_end(MyCards,PlayerResults),IDdlr) ::
null <- PlayerResults = [(IDP, Res, Cards, Wager) | PlayerTail]
then
(
 ask(Wager) => a(player(_), IDP) <- Res == bust
 or
 ask(Wager/2) => a(player(_), IDP) <- (Res == surrender)
 or
 ask(Wager) => a(player(_), IDP) <- (Res == stand) and 
	    lessOrEqualThan(sum(MyCards), 21)  and 
 graterThan(sum(MyCards), sum(Cards))	 
 or
 push() => a(player(_), IDP) <- (Res == stand) and 
	(sum(MyCards) == sum(Cards))
 or
 win(Wager) => a(player(_), IDP) <- (Res == stand) and 
	    greaterThan(sum(MyCards), 21)
 or
 win(2*Wager/3) => a(player(_), IDP) <- (Res == stand) and 
		lessThan(sum(MyCards), sum(Cards))
)
then 
a(dealer_end(MyCards,PlayerTail),IDdlr)


Dialogue Games

A sending agent, Id, sends an inform request to a receiving agent, Pid, about some proposition that Id believes to be true and Id does not believe Pid has any knowledge of the truth of that proposition.

A receiving agent, Pid, receives an inform request about some proposition from a sending agent, Id, is entitled to believe that the proposition is true.

[More details]

FIPA Inform Communicative Act


//  Written by Jarred McGinnis
//
//  LCC Specification for FIPA Inform as agent clauses

a(inform_ca_cender, Id)::
	inform(p) => a(inform_ca_receiver,Pid) <- believe(Id,p) and
	not(believe(Id,(bif(Pid,p) or uif(Pid,p))))

a(inform_ca_receiver, Pid)::
	assert(believe(Pid,p)) <- inform(p) <= a(inform_ca_sender,Id)

FIPA Query Interaction Protocol

In the FIPA Query Interaction Protocol (IP), a sending agent, Id, sends a query request to a receiving agent, Pid, to perform some kind of inform action. The receiving agent, Pid, can answer the query with either:

  • inform: gives the information requested
  • failure: the agent is unable to answer due to an error
  • not_understood: the query is not understood
  • the agent refuses to answer the query.

[More details]

//  Written by Jarred McGinnis
//
//  LCC Specification for FIPA query protocol 

a(query_ip_initiator, Id)::
	a(query_ca_sender,Id) then
	(
		a(inform_ca_receiver,Id) or
		a(failure_ca_receiver,Id) or
		a(not_understood_ca_receiver,Id) or
		a(refuse_ca_receiver,Id)
	)

a(query_ip_responder, Pid)::
	a(query_ca_receiver,Pid) then
	(
		a(inform_ca_sender,Pid) or
		a(failure_ca_sender,Pid) or
		a(not_understood_ca_sender,Pid) or
		a(refuse_ca_sender,Pid)
	)

FIPA Contract Net Interaction Protocol

In the FIPA Contract Net Interaction Protocol, the initiator, Id, takes the role of a manager which wishes to have some task performed by other agent(s). A receiving agent may either respond with a proposal, refuse, or not understand the task. The initiator can then either accept or refuse the proposal. The receiving agent then informs the initiator if the task is completed or sends a failure message. Alternatively, the initiator can cancel the task.

[More details]

//  Written by Jarred McGinnis
//
//  LCC Specification for FIPA contract net protocol 

a(contract_net_ip_initiator,Id)::
	(
		a(cfp_ca_sender,Id) or
		a(refuse_ca_receiver,Id) or
		a(not_understood_ca_receiver,Id)
	)
	then
	(
		a(accept_proposal_ca_sender,Id) or
		a(reject_proposal_ca_sender,Id)
	)
	then
	(
		a(inform_ca_receiver,Id) or
		a(failure_ca_receiver,Id) or
		a(cancel_ca_sender,Id)
	)

a(contract_net_ip_responder,Id)::
	(
		a(cfp_ca_sender,Id) or
		a(refuse_ca_sender,Id) or
		a(not_understood_ca_sender,Id)
	)
	then
	(
		a(accept_proposal_ca_receiver,Id) or
		a(reject_proposal_ca_receiver,Id)
	)
	then
	(
		a(inform_ca_sender,Id) or
		a(failure_ca_sender,Id) or
		a(cancel_ca_receiver,Id)
	)

Information Seeking Dialogue Game

A seeker, A, asks a provider, B, a question, P. The provider then sends a reply, which entitles the seeker to either assert the truth of P, the negation of P, or, for whatever reason, the provider cannot answer the question. The seeker the either accepts the provider's response or challenges the response, given that P or its negation is asserted. The provider replies to a challenge with an assertion of the support of an argument for the proposition challenged by the seeker. [More details]


Initial agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for the initial agent roles in an information seeking dialogue game 

a(seeker(P,B),A)::
	question(P) => a(provider(P,A),B) then
	(
		assert(P) <= a(provider(P,A),B) then
		a(challenger([P],B),A)
	)
	or
	(
		assert(not(P)) <= a(provider(P,A),B) then
		a(challenger([not(P)],B),A)
	)
	or
	assert(U) <= a(provider(P,A),B)

a(provider(P,A),B)::
	question(P) <= a(seeker(P,B),A) then
	(
		assert(P) => a(seeker(P,B),A) then
		a(defender([P],A),B)
	)
	or
	(
		assert(not(P)) => a(seeker(P,B),A) then
		a(defender([not(P)],A),B)
	)
	or
	assert(U) => a(seeker(P,B),A)


Recursive agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for tbe recursive agent roles in an information seeking dialogue game

a(challenger(List,B),A)::
	null <- (List = []) or
	(
		accept(R) => a(defender(List,A),B) <- (List = [R|T]) then
		a(challenger(T,B),A)
	)
	or
	(
		challenge(R) => a(defender(List,A),B) <- (List = [R|T]) then
		assert(S) <= a(defender(List,A),B) then
		a(challenger(S,B),A) then a(challenger(T,B),A)
	)

a(defender(List,A),B)::
	null <- (List = []) or
	(
		(List = [R|T] <- accept(R) => a(defender(List,B),A) then
		a(challenger(T,A),B)
	)
	or
	(
		(List = [R|T]) <- challenge(R) => a(defender(List,B),A) then
		assert(S) => a(defender(List,B),A) <- support(R,S) then
		a(defender(S,A),B) then a(defender(T,A),B)
	)

Persuasion Dialogue Game

A persuader, A, issues a message to a listener, B, indicating it believes that a proposition P is true, and asserts P. B accepts P if its acceptance attitude allows, else B either asserts the negation of p if it is allowed to, or else challenges P. If B has challenged, then either A asserts the support for p, or repeat the same process fo each element of the support of P. If B does not challenge, then it issues either an acceptance of a reject of P, depending upon the status of P for it. [More details]


Initial agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for the initial agent roles in a persuation dialogue game

a(persuader(P,B),A)::
	know(P) => a(listener(P,A),B) then
	assert(P) => a(listener(P,A),B) then
	a(defender([P],B),A)


a(listener(P,A),B)::
	know(P) => a(persuader(P,B),A) then
	assert(P) => a(persuader(P,B),A) then
	a(challenger([P],A),B)


Recursive agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for the recursive agent roles in a persuation dialogue game

a(defender(List,A),B)::
	null <- (List = []) or
	(
		(
			(List = [R|T]) <- accept(R) <= a(challenger(List,B),A)
			or
			(List = [R|T]) <- reject(R) <= a(challenger(List,B),A)
		) then
		a(defender(T,A),B)
	)
	or
	(
		(List = [R|T]) <- challenge(R) <= a(challenger(List,B),A) then
		assert(S) => a(challenger(List,B),A) <- support(R,S) then
		a(defender(S,A),B) then a(defender(T,A),B)
	)
	or
	(
		(List = [R|T]) <- assert(not(R)) <= a(challenger(List,B),A) then
		a(challenger([not(R)],A),B) then a(defender(T,A),B)
	)

a(challenger(List,B),A)::
	null <- (List = []) or
	(
		(
			accept(R) => a(defender(List,A),B) <- (List = [R|T])
			or
			reject(R) => a(defender(List,A),B) <- (List = [R|T])
		) then
		a(challenger(T,B),A)
	)
	or
	(
		challenge(R) => a(defender(List,A),B) <= (List = [R|T]) then
		assert(S) => a(defender(List,A),B) then
		a(challenger(S,B),A) then a(challenger(T,B),A)
	)
	or
	(
		assert(not(R)) => a(defender(List,A),B) <- (List = [R|T]) then
		a(defender([not(R)],B),A) then a(challenger(T,B),A)
	)

Inquiry Dialogue Game

A seeker, B, offers prove(P) for a proposition, inviting a provider, A, to join it in the search for a proof of P. A asserts the logical implication Q -> P for some Q, or asserts unknown. B accepts the implication Q -> P if its acceptance attitude allows, or challenges it. A replies to a challenge with the assertion of the support of an argument for the last proposition challenged by B. B asserts Q, or the implication R -> Q for some R. If at any point one of the propositions is not acceptable to an agent, it issues a reject, and the dialogue ends successfully. [More details]


Initial agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for the intial agent roles in an inquiry dialogue game

a(seeker(P,A),B)::
	prove(P) => a(provider(P,B),A) then
	(
		(
			assert(implies(Q,P)) <= a(provider(P,B),A) then
			a(challenger([implies(Q,P)],[P,implies(Q,P)],A),B)
		)
		or
		assert(unknown) <= a(provider(P,B),A)
	)

a(provider(P,B),A)::
	prove(P) <= a(seeker(P,A),B) then
	(
		(
			assert(implies(Q,P)) <= a(seeker(P,A),B) then
			a(defender([implies(Q,P)],[P,implies(Q,P)],B),A)
		)
		or
		assert(unknown) <= a(seeker(P,A),B)
	)

Recursive agent roles


//  Written by Jarred McGinnis
//
//  LCC Specification for the recursive agent roles in an inquiry dialogue game

a(challenger(List,ArgSet,A),B)::
	(a(provider2(ArgSet,A),B) <- (List = [])) or
	(
		accept(R) => a(defender(List,ArgSet,B),A) <- (List=[R|T]) then
		a(challenger(T,ArgSet,A),B)
	)
	or
	(
		challenger(R) => a(defender(List,ArgSet,B),A) <- (List=[R|T]) then
		assert(S) <= a(defender(List,ArgSet,B),A) then
		a(challenger(S,[S|ArgSet],A),B) then
		a(challenger(T,[S|ArgSet],A),B)
	)
	or
	reject(R) => a(defender(List,ArgSet,B),A) <- (List=[R|T])

a(defender(List,ArgSet,B),A)::
	(a(seeker2(ArgSet,B),A) <- (List = [])) or
	(
		(List = [R|T]) <- accept(R) <= a(challenger(List,ArgSet,A),B) then
		a(defender(T,ArgSet,B),A)
	)
	or
	(
		(List = [R|T]) <- defender(R) <= a(challenger(List,ArgSet,A),B) then
		assert(S) <= a(challenger(List,ArgSet,A),B) <- support(R,S) then
		a(defender(S,[S|ArgSet],B),A) then
		a(defender(T,[S|ArgSet],B),A)
	)
	or
	(List = [R|T]) <- reject(R) <= a(challenger(List,ArgSet,A),B) 

a(provider2(Arg,A),B)::
	(
		assert(Q) => a(seeker2(Arg,B),A) <- know(Q) then
		(
			accept([Q|Arg]) <= a(seeker2(Arg,B),A) then
			accept([Q|Arg]) => a(seeker2(Arg,B),A) or
			reject([Q|Arg]) => a(seeker2(Arg,B),A)
		)
		or
		reject([Q|Arg]) <= a(seeker2(Arg,B),A)
	)
	or
	(
		assert(implies(R,Q)) => a(seeker2(Arg,B),A) <- implies(R,Q) then
		a(defender([implies(R,Q)|Arg],A),B)
	)
	or
	assert(unknown) => a(seeker2(Arg,B),A)


a(seeker2(Arg,B),A)::
	(
		assert(Q) => a(provider2(Arg,A),B) <- know(Q) then
		(
			accept([Q|Arg]) <= a(provider2(Arg,A),B) then
			accept([Q|Arg]) => a(provider2(Arg,A),B) or
			reject([Q|Arg]) => a(provider2(Arg,A),B)
		)
		or
		reject([Q|Arg]) <= a(provider2(Arg,A),B)
	)
	or
	(
		assert(implies(R,Q)) => a(provider2(Arg,A),B) <- implies(R,Q) then
		a(challenger([implies(R,Q)|Arg],B),A)
	)
	or
	assert(unknown) => a(provider2(Arg,A),B)

Example OK Components

We provide here a collection of examples of OK components taken from our test cases.

Bioinformatics

YeastDataSourceOKC.java

YeastDataSourceOKC is the parent class of data providers, namely, ModBase, SAM and SWISS. The implementation of each data provider must implement the method for look-up.


package org.openk.okc.bioinfo.okc;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;

import org.openk.core.OKC.impl.OKCFacadeImpl;
import org.openk.core.module.interpreter.Argument;


public abstract class YeastDataSourceOKC extends OKCFacadeImpl {
	
	class YeastFileFilter implements FilenameFilter {
		
		private String yeastID;
		
		public YeastFileFilter(String yeastid){
			yeastID = yeastid;
		}
	    
		public boolean accept(File dir, String name) {
	        return (name.startsWith(yeastID));
	    }
	}
	
	//@MethodSemantic(
	//	language="tag",
	//		args={"yeast_gene_ORF","protein_3D_structure_model"}
	//)
	public abstract boolean lookup(Argument Yid, Argument Fnames, Argument Ds);
	
	protected String[] filesStartingWith(String dir, String prefix){
		File basedir = new File(dir);
		return basedir.list(new YeastFileFilter(prefix));

	}
	
	protected String fileNameOnly(String filename){
		File f = new File(filename);
		return f.getName();	
	}
	
	protected void readFile(String filename, StringBuffer filecontent) throws IOException{
        BufferedReader in = new BufferedReader(new FileReader(filename));
        String str;
        while ((str = in.readLine()) != null) {
        	filecontent.append(str+"\n");
        }
        filecontent.append("@#@#@#@\n"); // file separator
        in.close();
	}
}

MODBASESourceOKC.java

package org.openk.okc.bioinfo.okc;

import java.io.IOException;

import javax.swing.JOptionPane;

import org.openk.core.module.interpreter.Argument;

public class MODBASESourceOKC extends YeastDataSourceOKC {
	private final String datadir = "/bio-info-kernel/yeast/modbase/";
	
	@Override
	public boolean lookup(Argument Yid, Argument Fnames, Argument Ds){
		// filename
		// Q0045.randomnumber[].pdb
		String homedir = System.getProperty("user.home");
		String[] filenames = filesStartingWith(homedir+datadir, (String)Yid.getValue());
		JOptionPane.showMessageDialog(null, "MODBASEOKC:"+filenames[0]+"("+filenames.length+")");
		StringBuffer lstFiles = new StringBuffer();
		StringBuffer lstFilenames = new StringBuffer();
		for (String filename: filenames){
			try {
				readFile(homedir+datadir+filename,lstFiles);
				lstFilenames.append(fileNameOnly(filename)+"\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		Ds.setValue(lstFiles.toString());
		JOptionPane.showMessageDialog(null, lstFiles.substring(0,80));
		Fnames.setValue(lstFilenames.toString());
		return true;
	}
	

}

SAMSourceOKC.java

package org.openk.okc.bioinfo.okc;

import java.io.IOException;

import javax.swing.JOptionPane;

import org.openk.core.module.interpreter.Argument;



public class SAMSourceOKC extends YeastDataSourceOKC {
	
	private final String datadir = "/bio-info-kernel/yeast/sam/";
	
	@Override
	public boolean lookup(Argument Yid, Argument Fnames, Argument Ds){
		// I go to a local directory where the data are
		// The name of the file corresponds to the yeast ID:
		// Q0045.t2k.undertaker-align.pdb
		// where Q0045 is the Yeast ID. the rest is just file type
		String homedir = System.getProperty("user.home");
		String filename = homedir+datadir+Yid.getValue()+".t2k.undertaker-align.pdb";
		JOptionPane.showMessageDialog(null, "SAMOKC:"+filename);
		StringBuffer lstFiles = new StringBuffer();
		StringBuffer lstFilenames = new StringBuffer();
		try {
			readFile(filename,lstFiles);
			lstFilenames.append(fileNameOnly(filename)+"\n");
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		Fnames.setValue(lstFilenames.toString());
		Ds.setValue(lstFiles.toString());
		JOptionPane.showMessageDialog(null, lstFiles.toString().substring(0, 50)+"\n...\n"+lstFiles.toString().length());
		return true;
	}
}

SWISSSourceOKC.java

package org.openk.okc.bioinfo.okc;

import java.io.IOException;

import javax.swing.JOptionPane;

import org.openk.core.module.interpreter.Argument;

public class SWISSSourceOKC extends YeastDataSourceOKC {
	
	private final String datadir = "/bio-info-kernel/yeast/swiss/";
	
	@Override
	public boolean lookup(Argument Yid, Argument Fnames, Argument Ds){
		// filename
		// Q0045_SOMECODE_SOMEOTHERCODE.pdb
		String homedir = System.getProperty("user.home");
		String[] filenames = filesStartingWith(homedir+datadir, (String)Yid.getValue());
		JOptionPane.showMessageDialog(null, "SWISSOKC: "+filenames[0]+" ("+filenames.length+")");
		StringBuffer lstFiles = new StringBuffer();
		StringBuffer lstFilenames = new StringBuffer();
		for (String filename: filenames){
			try {
				readFile(homedir+datadir+filename,lstFiles);
				lstFilenames.append(fileNameOnly(filename)+"\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		JOptionPane.showMessageDialog(null, lstFiles.substring(0, 80)+"\n...\n"+lstFiles.length());
		Ds.setValue(lstFiles.toString());
		Fnames.setValue(lstFilenames.toString());
		return true;
	}
}