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.
// 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;
}
}