Università degli Studi di L’Aquila
DALI
Logic Programming Language
Dali: un linguaggio logico per Agenti
e Sistemi Multiagente
“Un agente e’ una entita’ software situata in un
ambiente,capace di azioni autonome allo scopo
di raggiungere i propri obiettivi”
Caratteristiche di DALI:
• Classi di eventi e loro interazione:
• Eventi esterni
• Eventi interni
• Eventi del presente
• Eventi del passato
DALI
• Azioni
• Interfogliamento delle attivita’
• Priorita’ nelle azioni
• Priorita’ negli eventi
• Gestione dei goals nel planning
• Memoria
Dali: gli eventi esterni e del presente
“E' la relazione con l'ambiente a determinare la
configurazione del sistema cognitivo di un organismo”
(Maturana)
Stage 1: reazione all’evento
Funzione: si innesca la reazione
all’evento secondo le direttive specificate
dalla regola reattiva contenuta nel
programma logico DALI.
suona_la_svegliaE:>mi_alzoA
Stage 2: dopo la reazione, l’ agente e’ capace
di ricordare l’evento esterno.
Funzione: ragionamento su cosa e’ accaduto
nel passato.
sono_pigro:-suona_la_svegliaP
not(mi_alzoP)
sono_pigroI:> prendo_un_giorno_di_ferieA
Un evento del presente fa’ in modo che il
processo di reazione ad un evento interno venga
‘anticipato’ da un processo di ragionamento
(tipico degli eventi interni). Cio’ garantisce la
distinzione tra ragionamento sugli eventi e
reazione agli eventi!
arriva_qualcuno:-suona_il_campanelloN.
arriva_qualcunoI:>mi_vestoA.
mi_vesto:< sono_svestitoP.
suona_il_campanelloE:>apro_la_portaA
Gli eventi esterni vengono processati sulla base
della loro priorita’ (alta o normale).
Gli eventi ad alta priorita’ hanno precedenza
assoluta sugli altri.
Dali: gli eventi interni
“Gli agenti riflettono”
Un evento interno e’ una conclusione raggiunta
dall’agente alla quale l’agente
reagisce similarmente ad un evento esterno!
Le conclusioni interne scatenano la proattivita’
dell’agente!
Stage1: le condizioni di innesco (eventi interni o
esterni a cui l’agente ha reagito,azioni
compiute,conoscenza,…) sono tutte true, si
scatena la reazione
Stage2: dopo la reazione, l’agente e’
capace di ricordare l’evento interno
cucino:-acceso_gasP,
metto_pentola_sul_gasP,
minuti_cottura(25),passati_minuti(25).
cucinoI:>tolgo_pentola_dal_gasA,spengo_gasA.
Il “comportamento” di un evento interno e’
determinato dalle direttive dell’utente:
• ogni quanto tempo tentare l’evento;
• quante volte ad un evento si deve
reagire:
• forever
• una volta, due volte,...
e quando:
• in assoluto
• quando “cambia” una determinata
condizione di innesco
• fino a quando (forever, fino ad un certo
tempo, fino ad una certa condizione)
Un evento interno puo’ corrispondere ad una
azione.
Piu’ eventi interni possono essere correlati
scatenando inferenze successive!
Dali: gli eventi interni
(1)
“Concatenare il pensiero e dedurre...”
sintomo1('demo1/knowledge/log.txt',H1,Time):-findall(str(AT,D),clause(log(_,_,_,AT,_,_,D,_),_),L),
length(L,Lu),Lu>5,remove_duplicates(L,L1),
member(M,L1),arg(1,M,H1),arg(2,M,Time),
carica_fileP('demo1/knowledge/log.txt',_).
sintomo1('demo1/knowledge/log.txt',H1,Time):-findall(str(AT,D),clause(log(_,_,_,AT,_,_,D,_),_),L),
length(L,Lu),Lu>5,remove_duplicates(L,L1),
member(M,L1),arg(1,M,H1),arg(2,M,Time),
intervalloP(_).
sintomo1I(X,H1,Time):>write(sintomo_uno(X,H1,Time)),nl.
sintomo2(T):-carica_fileP(_,_),datime(T),arg(4,T,H),H>=9.
sintomo2(T):-carica_fileP(_,_),datime(T),arg(4,T,H),H=<8.
sintomo2I(T):>write(sintomo_due(T)),nl.
sintomo3(X):-carica_fileP(X,_),datime(T),arg(4,T,H),H<9,H>8.
sintomo3(_):-intervalloP(_),datime(T),arg(4,T,H),H<9,H>8.
sintomo3I(X):>write(sintomo_tre(X)),nl,
clause(agent(A),_),
messageA(manager,inform(changed_time(X),A)).
Dali: gli eventi interni
(2)
“Concatenare il pensiero e dedurre...”
attacco1(P,date(A,Me,G),time(O,M)):-sintomo2P(T),
arg(1,T,A),arg(2,T,Me),arg(3,T,G),
arg(4,T,O),arg(5,T,M),
clause(log(_,_,P,_,_,_,date(A,Me,G),time(O,M1,_)),_),M-2=<M1,M1<M+3.
attacco1I(P,date(A,Me,G),time(O,M)):>clause(agent(Ag),_),
messageA(manager,send_message(attacco1(P,date(A,Me,G),time(O,M,00)),Ag)).
attacco2(X,H,D):-sintomo1P(X,H,D).
attacco2I(X,H,D):>clause(agent(A),_),trasf(X,K),trasf(H,H1),
clause(log(_,_,_,H,_,_,D,T),_),
messageA(manager,send_message(attacco2(H1,D,T,K),A)).
attacco3(H,D,_):-informP(avviso_attacco(H,D,_),_),ntrasf(H,H1),clause(log(_,_,H1,_,_,_,_,_),_).
attacco3I(H,D,_):>clause(agent(A),_),
messageA(manager,send_message(attacco3(H,D,_),A)).
Dali: i goals
“”
Dali possiede due tipi di goals:
• goals che l’agente tenta di perseguire:
Sono legati agli eventi interni. Quando un
agente invoca un goal, attiva l’evento interno
corrispondente che tenta le precondizioni. Se
quest’ultime diventano vere, si attiva il piano.
• goals
che
“eseguiti”
l’agente
verifica
se
Quando un agente trova un goal da “testare”
verifica se vi e’ il corrispondente evento del
passato o un fatto.
I goals da ottenere sono trattati
come eventi interni. Se raggiunti,
sono ricordati dall’ agente come
eventi del passato.
goE:>put_shoesG.
put_shoes:-put_right_shoeG,
put_left_shoeG,
right_shoe_onP,left_shoe_onP.
put_shoesI:>left_and_right_shoes_onA,
retractall(past(_,_,_)).
put_right_shoe:put_right_sockG,right_sock_onP.
put_right_shoeI:>right_shoe_onA.
put_left_shoe:-put_left_sockG,left_sock_onP.
put_left_shoeI:>left_shoe_onA.
put_right_sock:-have_right_sockP.
put_right_sockI:>right_sock_onA.
put_left_sock:-have_left_sockP.
put_left_sockI:>left_sock_onA.
STRIPS e DALI: planning
“L’idea dello STRIPS planner e’ dividi e conquista:per creare un piano
per ottenere un insieme di goals,occorre creare un piano per ottenere un
goal ed un piano per ottenere il resto”
Facciamo la spesa...con DALI
vaiE:>sono_a_casaA,compra_tuttoG.
compra_tutto:procura_bananaG,procura_latteG,vai_a_casaG,
pago_bananaP,pago_latteP,sono_a_casaP.
compra_tutto:procura_chiodiG,vai_a_casaG,pago_chiodiP,sono_a_casa
P.
compra_tuttoI:>acquisto_tuttoA.
procura_banana:vai_al_supermercatoG,compra_bananaG,
sono_al_supermercatoP,compro_bananaP.
procura_bananaI:>pago_bananaA.
...
procura_chiodi:-vai_alla_ferramentaG,compra_chiodiG,
sono_in_ferramentaP,compro_chiodiP.
procura_chiodiI:>pago_chiodiA.
vai_al_supermercato:sono_a_casaP,isa(supermercato_aperto).
vai_al_supermercato:sono_in_ferramentaP,isa(supermercato_aperto).
vai_al_supermercatoI:>sono_al_supermercatoA.
vai_alla_ferramenta:-sono_al_supermercatoP.
vai_alla_ferramenta:-sono_a_casaP.
vai_alla_ferramentaI:>sono_in_ferramentaA.
vai_a_casa:-sono_in_ferramentaP.
vai_a_casa:-sono_al_supermercatoP.
vai_a_casaI:>sono_a_casaA.
compra_banana:-sono_al_supermercatoP.
compra_bananaI:>compro_bananaA.
...
compra_chiodi:-sono_in_ferramentaP.
compra_chiodiI:>compro_chiodiA.
Dali: la comunicazione e le azioni
“”
Atomi azione rappresentano in DALI le azioni. Le azioni hanno:

Sempre successo se non hanno precondizioni

Hanno successo solo quando la condizione e’ true, se hanno precondizioni.
L’interprete DALI, quando una azione e’ true,la pone in coda in attesa di essere ripresa
ed eseguita. Cio’ permette il controllo sulle azioni ed evita che una azione venga
compiuta quando il contesto non lo permette (servire una birra se le birre sono finite!).
Quando cio’ accade l’azione viene rimessa in coda in attesa che il contesto la renda
ammissibile. Se questo non accade l’agente la elimina.
Nel linguaggio logico DALI le azioni sono ettichettate con una A e possono essere:
• una azione semplice (scritta sullo schermo o su un file)
• un messaggio inviato ad altri agenti (con il suffisso message)
LE AZIONI POSSONO AVERE PRIORITA’ ALTA O NORMALE!
suona_il_campanelloE(gino)):>apro_la_portaA,
messageA(gino,send_message(ciao,pippo)).
Dali: gli eventi del passato
“"risolvere" un problema equivale a "comprenderlo"; e "comprendere"
significa, in ultima analisi, ricondurre la situazione presente a una
situazione gia' nota del passato”
Eventi esterni e del presente
Eventi interni
Azioni
Goals
Il periodo di tempo in cui un evento del
passato viene “ricordato” e’ anch’esso definito
dalle direttive dell’utente:
• forever
• fino ad un certo tempo (until_time)
• fino a quando si verifica una
condizione (until_cond)
Reazione
sunny_weatherE :> open_the_windowA.
EVENTI
DEL
PASSATO
rainy_weatherE:>close_the_windowA
open_the_window:<close_the_windowP
close_the_window:< open_the_windowP
data
Dali: la architettura multiagente
LINDA PRIMITIVE
COMMUNICATION
Agente
DALI 3
Agente
DALI 2
Agente
DALI 1
Tuples Space
GUSCIO DALI
Elabora,estrae e
gestisce gli eventi, le
azioni, le regole e la
comunicazione
dell’agente DALI in
esso contenuto
Agente
DALI n
PROGRAMMA LOGICO
DALI
Descrive il
comportamento
dell’agente utilizzando
la sintassi del
linguaggio logico DALI
La architettura di un agente DALI
Pre-processing
Comunicazione
Processing
Eventi
Azioni
Goals
Comunicazione
file.txt
I files di un agente DALI
file.ple
file.txt
File.plf
file.pl
Le liste del file ple
[invitation,sega_la_legna,set,get,notify,call,ack,reply,return].
[go_by_car,wait_ack(DestAgent,TimeStamp,SeqId,AckContent),
wait_reply(DestAgent,TimeStamp,SeqId,VarName,VarValue),…].
[go_by_car,take_the_bus,ask_susan_to_join,aiuto(X),
message(To,set(A,T,SeqId,VarName,VarValue)),
message(To,get(A,T,SeqId,VarName)),…].
[go_by_car].
Condizioni
[].
Eventi del presente
[].
Goals da ottenere
[].
Goals da testare
[].
Fatti da ricordare
Eventi esterni
Eventi interni
Azioni
Il ‘naming’ del file pl
eve(predator_attacks(var_X)):-once(try_to_escape(var_X)).
try_to_escape(var_X):-a(fly(var_X)).
try_to_escape(var_X):-a(run(var_X)).
cd(fly(var_X)):-evp(bird(var_X)),not(evp(abnormal(var_X))).
Le direttive del file plf
action(Azione,normal).
action(Azione,high).
external_event(Evento_esterno,normal).
past_event(Evento/Azione,20).
mod(Evento_esterno,check).
internal_event(Evento_interno,3,forever,true,until_co
nd/until_date(Condizione/Data)).
internal_event(Evento_interno,3,1,change([]),forever).
La comunicazione in DALI
Percezione ed azione
Un agente è un oggetto attivo con la capacità di percepire,
ragionare ed agire.
Assumiamo che:
• un agente ha una KB ed un meccanismo per fare inferenza sulla
sua conoscenza
• un agente ha la
CAPACITA’ di COMUNICARE
parte PERCEZIONE
(ricevere messaggi)
parte AZIONE
(inviare messaggi)
Cooperare o competere?
La comunicazione permette agli agenti di coordinare le loro azioni ed il
loro comportamento.
La coordinazione è una proprietà di un sistema di agenti che compiono
una certa attività in un ambiente condiviso.
La COOPERAZIONE è una coordinazione tra agenti non antagonisti
mentre la NEGOZIAZIONE è una coordinazione tra agenti competitivi o
interessati a se stessi.
COORDINAZIONE
Cooperazione
Competizione
Planning
Negoziazione
Obiettivo



dotare il linguaggio di un robusto protocollo di
comunicazione capace di fornire agli agenti opportune
primitive per cooperare
assicurare un 'filtro' sui messaggi in ingresso ed in uscita
in modo da proteggere le entità software da atti
comunicativi dannosi
introdurre un livello di meta-ragionamento per agevolare
l’interpretazione dei messaggi
Nuova architettura degli agenti Dali
Filtro comunicazione
Filtro comunicazione
Metaragionamento
Metaragionamento
Messaggi
Interprete
Interprete
Progr.
Logico
Dali
Progr.
Logico
Dali
L’architettura DALI precedente ha subito notevoli variazioni passando
da un unico strato a tre strati consistenti in :



filtro sulla comunicazione e protocollo;
applicazione del meta ragionamento con supporto di ontologie;
interprete
Difendere gli agenti…


In un progetto di cooperazione tra agenti intelligenti è necessario
tenere il più possibile sotto controllo il processo di comunicazione.
Un agente, se non opportunamente ‘difeso’, può essere soggetto a
danneggiamenti della
base di conoscenza o delle regole
comportamentali.
Talvolta, però, può accadere che un agente invii ad un altro un
messaggio con contenuto sbagliato arrecando volontariamente o
involontariamente un enorme danno. Come riconoscere un
messaggio giusto da uno sbagliato?
Il filtro Dali



Come riconoscere un messaggio giusto da uno
sbagliato? Il filtro adottato in DALI cerca di rispondere,
per quanto possibile, a questo quesito.
Quando un messaggio viene recepito, esso viene
sottoposto ad un check fornito da una struttura
altamente modificabile dall’utente ed adeguabile al
contesto.
Tale struttura controlla che i campi del messaggio
rispondano ai vincoli imposti dal programmatore,
altrimenti il messaggio viene cancellato non
producendo alcun effetto.
I vincoli sui messaggi in ingresso
Le direttive sul filtro sono contenute nel file
‘communication.txt’ accessibile direttamente dall’utente.
Ciò evita di dover cambiare ogni volta il codice
dell’interprete.
told(Ag,tipo_messaggio(_)):constraint1,constraint2,...,constraintn.
I vincoli sui messaggi in ingresso
told(Sender_agent,send_message(Evento_esterno)):not(evp(inaffidabile(Sender_agent))),
interessato_a(Evento_esterno).
told(Sender_agent,execute_proc(Procedure)):not(evp(inaffidabile(Sender_agent))),
conosco(Procedura).
told(Sender_agent,query_ref(Proposizione,3)):not(evp(inaffidabile(Sender_agent))),
carina(Sender_agent).
I vincoli sui messaggi in uscita
Le condizioni di filtro dei messaggi in uscita sono contenute
sempre nel file ‘communication.txt’ ma hanno ‘tell’ come
suffisso:
tell(To,From,type_message(_)):constraint1,...,constraintn.
tell(To,_,send_message(_)):not(evp(enemy(To))).
Applicazione del meta-ragionamento e delle
ontologie


In un sistema multi-agente dove più entità software
cooperano alla realizzazione di un obiettivo, come ad
esempio la sicurezza di un settore, non tutti i componenti
parlano la stessa lingua ma, anche all’interno della stessa
lingua, non tutti utilizzano le stesse parole per esprimere
un dato concetto.
In questo caso si può istruire l’agente ad applicare un
processo di ‘ragionamento’ che lo induca a capire se la
situazione che sta incontrando è riconducibile ad una già
conosciuta.
Cosa è una ontologia
Una ONTOLOGIA è una specifica degli oggetti, concetti e
relazioni in una area di interesse.
Una ontologia include:

proposizioni vere o false indipendentemente da un certo
individuo;

Proprietà di singoli individui ;

Relazioni tra coppie di individui o più individui.
dove per individuo si intende qualsiasi cosa: gente, colori,
emozioni, numeri,…
L’utilizzo di una ontologia
Supponiamo di avere la seguente regola reattiva.
caso1E(X):>azione1A(X),azione2A(X).


Se l’agente sà che caso1 è semanticamente equivalente a
caso2, può rispondere all’evento esterno caso2 pur
conoscendo soltanto caso1.
Che caso1 sia equivalente a caso2 può essere una
informazione data a run-time dall’agente che invia il
messaggio al destinatario oppure può essere contenuto
nell’ ontologia associata all’agente che riceve il messaggio.
Il livello di meta-ragionamento


Il ragionamento su una asserzione o chiamata ad evento
esterno è stato ottenuto tramite la procedura ‘meta’
agganciata tra lo strato superiore di check e quello
inferiore dell’interprete vero e proprio.
Tale procedura è contenuta nel file ‘communication.txt’ e
può essere modificata dall’utente senza intaccare il codice
dell’interprete. Ciò permette di aggiungere potenzialità a
livello di meta-ragionamento in un agente senza avere
conoscenze troppo approfondite sull’intero sistema.
Come è fatto il meta-ragionamento…
meta(Initial_term,Final_term,Agent_Sender):clause(agent(Agent_Receiver),_),
functor(Initial_term,Functor,Arity),Arity=0,
((ontology(Agent_Sender,Functor,Equivalent_term);
ontology(Agent_Sender,Equivalent_term,Functor));
(ontology(Agent_Receiver,Functor,Equivalent_term);
ontology(Agent_Receiver,Equivalent_term,Functor))),
Final_term=Equivalent_term.
meta(Initial_term,Final_term,Agent_Sender):functor(Initial_term,Functor,Arity),Arity=2,
symmetric(Functor),Initial_term=..List,
delete(List,Functor,Result_list),
reverse(Result_list,Reversed_list),
append([Functor],Reversed_list,Final_list),
Final_term=..Final_list.
piove
cade_acqua
ama(pippo,pina)
ama(pina,pippo)
Come è fatto il meta-ragionamento…
Insert name of Receiver
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert name of Sender
|: pino.
Insert message
|: confirm(ama(pippo,gina),pino).
Insert name of Receiver
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert name of Sender
|: anne.
Insert message
|: query_ref(ama(gina,X),anne).
Pippo
Anne
send_message_to(anne,
inform(query_ref(ama(gina,fdvar_6),1),
motivation(no_values),pippo),italian,[])
send_message_to(anne,
inform(query_ref(ama(gina,fdvar_7),1),
values([ama(pippo,gina)]),pippo),italian,[])
Protocollo di comunicazione


Ci sono diversi protocolli attraverso i quali gli agenti
possono comunicare. Uno di essi è il protocollo FIPA
(http://www.fipa.org/) che è basato sul concetto di
messaggio. I messaggi sono inviati avanti ed indietro tra un
agente sender ed un agente receiver ed hanno una
specifica strutturazione.
FIPA disciplina tutti gli atti comunicativi e definisce anche
quali messaggi il receiver può inviare in risposta ad un dato
messaggio
Il protocollo FIPA
Seguendo il protocollo di base FIPA, l'unità di
comunicazione di DALI ha assunto la seguente
struttura:





receiver: nome dell'agente che riceve il messaggio (lo stesso del
file di attivazione);
language: il linguaggio per mezzo del quale il messaggio è
espresso;
ontology: l'ontologia adottata dall'agente sender per
interpretare il messaggio;
sender: nome dell'agente che invia il messaggio;
content: contenuto del messaggio.
Primitive Dali e primitive FIPA


Il nuovo interprete Dali vede il protocollo di comunicazione
come due librerie. Ciò permette di associare ad un agente
protocolli diversi senza modificare il codice interno
dell’interprete variando semplicemente due files:
‘communication.txt’ dove si trova il check ed il file
‘communication_fipa.pl’ che contiene le primitive di
comunicazione.
Dali ha adottato, al momento, diverse tipologie di messaggi
FIPA aggiungendone alcuni fuori dal protocollo data la
particolarità degli agenti Dali. Il protocollo FIPA, infatti,
disciplina la comunicazione tra agenti che cooperano allo
svolgimento di obiettivi visti come sequenze di azioni.
Send_message (DALI)



Permette ad un agente Dali di inviare un messaggio ad un altro
agente allo scopo di attivare una regola reattiva tramite un
evento esterno.
Un evento esterno nel linguaggio Dali è un messaggio o uno
stimolo ambientale di cui l’agente prende atto e a cui risponde
applicando la corrispondente regola reattiva nel suo programma
logico, se la possiede.
La sintassi del send_message per inviare un evento esterno da
modulo utente è:
send_message(Evento_esterno, Agente_sender)
Send_message (DALI)
predator_attacksE(X):>once(try_to_escape(X)).
try_to_escape(X):-flyA(X).
try_to_escape(X):-runA(X).
fly(X):<birdP(X),not(abnormalP(X)).
New message
Insert name of addressee
|: animal.
…
Insert message
|: confirm(bird(duck),pippo).
New message
…
Insert From
|: pippo.
Insert message
make(run(penguin),96328)
make(fly(duck),147492)
|:send_message(predator_attacks(duck),pippo).
Propose (FIPA)



Identifica l’azione di sottomettere da parte di un agente ad un
altro la proposta di compiere una certa azione date alcune
precondizioni.
Le precondizioni sono inserite all’interno di una lista aggregata
al messaggio.
La nuova strutturazione permette ad un agente Dali di chiedere
ad un altro l’esecuzione di una singola azione, senza invocare
alcuna regola, purchè questa azione sia conosciuta dall’agente e
quindi inserita all’interno del programma logico.
Propose



L’accettazione della proposta di compiere una azione è legata alla
verifica delle condizioni relative al messaggio. Se esse sono vere,
l’agente che ha ricevuto il propose, invierà un messaggio all’agente
proponente dicendo di accettare la proposta, altrimenti la rifiuterà.
Ogni azione Dali è sottoposta alla verifica delle precondizioni
all’azione interne al programma logico.
La sintassi del propose per il modulo utente è:
propose(Action,[condizione1,…,condizionen], Agente_sender)
Accept-proposal (FIPA)


Identifica l’atto di accettare la proposta di compiere una azione
da parte di un agente ed è strettamente legato all’atto
comunicativo propose.
Questo comando è interno al processo di comunicazione e la
sua sintassi è:
message(Ag_receiver,
accept_proposal(Azione_accettata,
[condizione1…,condizionen], Agente_sender))
dove le condizioni possono essere delle eventuali richieste
insite nell’accettazione della proposta.
Reject-proposal (FIPA)


Identifica l’atto di rifiutare la proposta di compiere una azione
da parte di un agente ed è strettamente legato all’atto
comunicativo propose.
Questo comando è interno al processo di comunicazione e la
sua sintassi è:
message(Agente_receiver,
reject_proposal(Azione_rifiutata,
[ragione1,…,ragionen], Agente_sender))
dove le ragioni possono essere delle eventuali motivazioni
del rifiuto della proposta.
Failure (FIPA)



Identifica l’atto di dire ad un altro agente che una azione è
stata tentata ma il tentativo è fallito.
Ciò accade quando, pur avendo accettata la proposta di
compiere una azione, un agente verifica che le condizioni
interne al programma logico non la permettono.
La sintassi di tale primitiva è:
message(Agente_receiver,failure(Azione_fallita,mot
ivation(Motivo), Agente_sender))
Propose
dangerE:>once(ask_for_help).
ask_for_help:-call_policeA.
call_police:<have_a_phoneP.
ask_for_help:-screamA.
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
send_message_to(pippo,
reject_proposal(call_police,[],
pippo),italian,[])
|: propose(call_police,[near_home],pippo).
Propose
dangerE:>once(ask_for_help).
ask_for_help:-call_policeA.
call_police:<have_a_phoneP.
ask_for_help:-screamA.
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: gino.
Insert message
|: propose(call_police,[],gino).
send_message_to(pippo,
failure(call_police,
motivation(false_conditions),
pippo),italian,[])
Propose
dangerE:>once(ask_for_help).
ask_for_help:-call_policeA.
call_police:<have_a_phoneP.
ask_for_help:-screamA.
…
|: confirm(have_a_phone,pippo).
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: anne.
Insert message
|: propose(call_police,[],anne).
send_message_to(anne,
accept_proposal(call_police,[],
pippo),italian,[])
make(call_police,78653)
Cancel (FIPA)




Identifica la richiesta di cancellare una certa azione ordinata da
un agente.
Nel caso di un agente Dali con un numero di eventi ed azioni
limitate, la richiesta di compiere una azione viene eseguita in
tempi relativamente più brevi di quelli dell’arrivo di una richiesta
di cancellazione.
la cancellazione della azione avviene sia dalla coda ad alta
priorità che da quella a priorità normale.
La sintassi del comando è:
message(Agente_receiver,cancel(Azione_canc,
Ag_sender))
Cancel (FIPA)
dangerE:>once(ask_for_help).
ask_for_help:-call_policeA.
call_police:<have_a_phoneP.
ask_for_help:-screamA.
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: anne.
Insert message
|: cancel(call_police,[],anne).
Execute_proc (DALI)



Questo atto comunicativo riguarda la chiamata di semplici
procedure all’interno del programma logico Dali.
Il codice non si limita ad invocare il check ma fa riferimento allo
strato del meta-ragionamento ed alle ontologie.
La sintassi da modulo utente e’:
execute_proc(Procedura, Agente_sender)
Execute_proc (DALI)
scrivi(X):-write(X),nl.
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: execute_proc(scrivi(pippo),pippo).
pippo
Execute_proc (DALI)
scrivi(X):-write(X),nl.
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [scrivi].
Insert From
|: pippo.
Insert message
|: execute_proc(scrivo(pippo),pippo).
pippo
Ontologia
Query_ref (FIPA)



Indica l’atto di domandare ad un altro agente se conosce
uno o un insieme di fatti che dimostrano la proprietà
richiesta.
Come primo argomento il query_ref prende la proprietà
richiesta, come secondo accetta un numero che è il limite
sul numero di matching che un agente si aspetta di
ottenere.
La sintassi di questo atto comunicativo per il modulo utente
è:
query_ref(Proprietà,N,Agente_sender)
Query_ref (FIPA)
…
New message
Insert name of addressee
|: pippo.
…
Insert From
|: pino.
Insert message
|: confirm(vado(domani,montagna),pino).
New message
Insert name of addressee
|: pippo.
…
Insert From
|: anne.
Insert message
??? Non ho nell’ontologia che vado è simmetrico!
send_message_to(anne,
inform(query_ref(vado(montagna,
fdvar_1),1),
motivation(no_values),pippo),
italian,[])
send_message_to(anne,
inform(query_ref(vado(fdvar_3,mo
ntagna),1),values([vado(domani,
montagna)]),pippo),italian,[]) …
|: query_ref(vado(Y,montagna),1,anne).
past(inform(query_ref(vado(mon
tagna,fdvar_1),1),
motivation(no_values),
pippo), 479379, pippo).
Query_ref (FIPA)
…
New message
Insert name of addressee
|: pippo.
…
Insert From
|: pino.
Insert message
|: confirm(vado(domani,montagna),pino).
New message
Insert name of addressee
|: pippo.
…
Insert From
|: anne.
Insert message
symmetric(vado).
send_message_to(anne,
inform(query_ref(vado(montagna,f
dvar_4),1),
values([vado(domani,montagna)]),
pippo),italian,[])
|: query_ref(vado(Y,montagna),1,anne).
past(inform(query_ref(vado(mon
tagna,fdvar_4),1),
values([vado(domani,montagna)]
),pippo), 59946, pippo).
Inform (FIPA)



L’atto di chiedere ad un agente se conosce la proposizione
contenuta nell’agree.
La sintassi di questa primitiva prevede che la proposizione
di cui si domanda la conoscenza sia un atomo ground.
La sintassi da modulo utente è:
inform(Proposizione,Agente_sender)
Refuse (FIPA)


Indica l’atto di rifiutare qualcosa o una data azione.
Questo comando,interno al protocollo di comunicazione,
ha la seguente sintassi:
refuse(Cosa_rifiutata,Agente_sender)

Il codice del refuse prevede, dopo il check, la
memorizzazione come evento del passato del rifiuto.
Confirm (FIPA)



L’agente sender informa il receiver che una data
proposizione è vera. La proposizione viene asserita come
evento del passato.
A livello di codice abbiamo il richiamo al check e
l’asserzione, come evento del passato, della proposizione
contenuta nel confirm.
La sintassi del confirm da modulo utente è:
confirm(Proposizione,Agente_sender)
Confirm (FIPA)
…
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: anne.
Insert message
|: confirm(asserisci(questo),anne).
past(asserisci(questo), 255677,
anne).
Disconfirm (FIPA)



L’agente sender informa il receiver che una data
proposizione è falsa. La proposizione viene ritratta da
evento del passato.
A livello di codice abbiamo il richiamo al check e la
ritrazione, da evento del passato, della proposizione
contenuta nel disconfirm.
La sintassi del disconfirm da modulo utente è:
disconfirm(Proposizione,Agente_sender)
Confirm (FIPA)
…
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: anne.
Insert message
|: disconfirm(asserisci(questo),anne).
past(asserisci(questo), 255677,
anne).
Agree
Indica l’atto di domandare ad un altro agente se conosce un
fatto.

A livello di codice abbiamo il richiamo al check ed al livello del
meta ragionamento.


La sintassi del disconfirm da modulo utente è:
agree(Proposizione,Agente_sender)
Agree
…
New message
Insert name of addressee
|: pippo.
…
Insert From
|: anne.
Insert message
|: confirm(asserisci(questo),anne).
New message
Insert name of addressee
|: pippo.
…
Insert From
|: anne.
Insert message
|: agree(asserisci(questo),anne).
send_message_to(anne,
inform(agree(asserisci(questo)),val
ues(yes),pippo),italian,[])
past(inform(agree(asserisci(questo)
),values(yes),pippo), 53827, pippo).
Invio di messaggi FIPA


Parallelamente alla funzionalità di ricevere messaggi
seguendo il protocollo FIPA, gli agenti Dali sono in grado di
inviare messaggi aderenti al suddetto protocollo.
La sintassi dell’invio del query_ref è:
send(To,query_ref(X,N,Ag)):tell(To,Ag,query_ref(X,N)),send_m(To,query_ref(X,
N,Ag)).
Generare un agente Dali


In questa nuova versione di DALI si è deciso di attivare
un agente per mezzo di un file di testo che contiene i dati
necessari.
La stringa rende anche automatico il processo di
attivazione di un agente permettendo di rigenerare
automaticamente il processo o di delegare il compito ad
altre entità software.
agent('dali
examples/agent',pino,'pino_ontology.txt',italian,[lira,comm
unication_fipa,communication],liraMode(local,classpath,ho
st,port,agent_name,ClassJavaName)).
esempi
The Dali Interpreter
Initialization of server:
Aprire la shell di Sicstus Prolog e caricare il file ‘active_server.pl’.
Initialization of user module:
Aprire una shell di Sicstus Prolog e caricare il file ‘active_user.pl’.Il modulo si mettera’ in
attesa dei dati relativi all’invio di un messaggio. I dati richiesti saranno:
-
Il nome dell’agente destinatario del messaggio;
Il linguaggio in cui viene espresso il contenuto del messaggio: italian, english,...
L’ontologia adottata;
Il nome dell’agente che invia il messaggio;
Il contenuto del messaggio;
Insert name of addressee|: pippo.
Insert Language|: italian.
Insert Ontology|: [].
Insert From|: pino.
Insert message|:send_message(rain,pino).
Insert name of addressee|: pippo.
Insert Language|: italian.
Insert Ontology|: [piove,cade_acqua].
Insert From|: pino.
Insert message|:send_message(rain,pino).
The Dali Interpreter
La sintassi dei messaggi corrrisponde a quella del protocollo adottato: FIPA nel nostro caso!
Qualche esempio:
- Chiamare una regola reattiva con il send_message:
send_message(arriva(X),gino)
- Comunicare un fatto ad un agente con il confirm:
- Proporre una azione con il propose:
confirm(piove(oggi),pippo).
propose(vai_alla_stazione,mamma).
- Invocare una procedura all’interno del programma logico con execute_proc:
execute_proc(aggiorna(Y),pluto).
The Dali Interpreter
Inizializzazione di un agente Dali:
Aprire una shell di Sicstus Prolog e caricare il file ‘lida.pl’.
L’interprete chiederà il nome del file di inizializzazione dell’ agente Dali:
Inserire il percorso ed il nome del file di inizializzazione:
|:’pippo.txt’.
Il file di inizializzazione è un file di estensione txt che contiene la stringa con i dati dell’agente
Dali da generare:
agent('dali demo/anne',anne,'anne_ontology.txt',
italian,[communication,communication_fipa],no).
Dali examples
Anne
invitationE:>once(go_out).
go_out:-go_by_carA.
go_by_car:<clause(car_available,_).
go_out:-take_the_busA.
go_by_carI:>ask_susan_to_joinA.
agent('dali demo/anne',anne,'anne_ontology.txt',
italian,[communication,communication_fipa],no).
File name: anne.txt
Directives for the interpreter
action(go_by_car,normal).
action(take_the_bus,normal).
action(ask_susan_to_join,normal).
action(copri(_172364),normal).
external_event(invitation,normal).
external_event(piove,normal).
external_event(arriva,normal).
past_event(invitation,20).
past_event(piove,20).
past_event(arriva,20).
past_event(go_by_car,20).
past_event(take_the_bus,20).
past_event(ask_susan_to_join,20).
past_event(copri(_171544),20).
internal_event(go_by_car,3,forever,t
rue,until_cond(past(go_by_car))).
Dali examples
File name: anne.txt
USER
MODULE
make(take_the_bus,_)
make(go_by_car,_)
make(ask_susan_to_join,_)
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.Insert message
|: confirm(car_available,pino).
New message
Insert name of addressee
|: …
Insert message
|:send_message(invitation,pino).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|:send_message(invitation,pino).
Dali examples
File name: animal.txt
Directives for the interpreter
Animal
predator_attacksE(X):>once(try_to_escape(X)).
try_to_escape(X):-flyA(X).
try_to_escape(X):-runA(X).
fly(X):<birdP(X),not(abnormalP(X)).
make(run(penguin),_)
make(fly(duck),_)
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology|:
[].
Insert From
|: pino.
Insert message
|: confirm(bird(penguin),pino).
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|:
confirm(abnormal(penguin),pino).
action(fly(_228740),normal).
action(run(_228740),normal).
external_event(predator_attacks,
normal).
past_event(predator_attacks,20).
past_event(fly(_228039),20).
past_event(run(_228039),20).
Dali examples
Planner
goE:>put_shoesG.
put_shoes:-put_right_shoeG,put_left_shoeG,
right_shoe_onP,left_shoe_onP.
put_shoesI:>left_and_right_shoes_onA,
retractall(past(_,_,_)).
put_right_shoe:-put_right_sockG,right_sock_onP.
put_right_shoeI:>right_shoe_onA.
put_left_shoe:-put_left_sockG,left_sock_onP.
put_left_shoeI:>left_shoe_onA.
put_right_sock:-have_right_sockP.
put_right_sockI:>right_sock_onA.
put_left_sock:-have_left_sockP.
put_left_sockI:>left_sock_onA.
File name:shoes.txt
Directives for the interpreter
action(left_and_right_shoes_on,normal).
action(right_shoe_on,normal).
action(left_shoe_on,normal).
action(right_sock_on,normal).
action(left_sock_on,normal).
external_event(go,normal).
past_event(go,20).
past_event(put_shoes,20).
past_event(put_right_shoe,20).
past_event(put_left_shoe,20).
past_event(put_right_sock,20).
past_event(put_left_sock,20).
past_event(left_and_right_shoes_on,20).
past_event(right_shoe_on,20).
past_event(left_shoe_on,20).
past_event(right_sock_on,20).
past_event(left_sock_on,20).
internal_event(put_shoes,3,forever,true,u
ntil_cond(past(put_shoes)))...
USER
MODULE
Dali examples
make(right_sock_on,_)
make(right_shoe_on,_)
make(left_sock_on,_)
make(left_shoe_on,_)
make(left_and_right_shoes_on,_)
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|: confirm(have_left_sock,pino).
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|: confirm(have_right_sock,pino).
New message
Insert name of addressee
|: pippo.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|: send_message(go,pino).
Dali examples
Anne e l’ontologia
grandinaE:>compro_un_ombrelloA,
corro_a_casaA.
make(compro_un_ombrello,34890)
make(corro_a_casa,34890)
Eliminated message:not exists meta_rule for
send_messagee(go,pino)
From:pino:nb-kasko-eagle:1032
make(compro_un_ombrello,119343)
make(corro_a_casa,119343)
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|: send_message(grandina,pino).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [grandina].
Insert From
|: pino.
Insert message
|: send_messagee(cade_grandine,pino).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [grandina].
Insert From
|: pino.
Insert message
|:send_message(cade_grandine,pino).
Dali examples
PIPPO
File name: pippo.txt
:-dynamic isa/3.
conosciE(X):messageA(pluto,agree(conosco(X),1,pippo)).
isa(ama(pippo,iole),45566,pippo).
send_message_to(pluto,
inform(query_ref(ama(pippo,fdvar_2),1),
values([ama(pippo,iole)]),pippo),italian,[]).
PLUTO
File name: pluto.txt
amaE(X):messageA(pippo,query_ref(ama(X,Y),1,pluto)).
send_message_to(pippo,query_ref(ama(pippo,
fdvar_2),1,pluto),italian,[])
Dali examples
PIPPO
File name: pippo.txt
:-dynamic isa/3.
conosciE(X):messageA(pluto,agree(conosco(X),1,pippo)).
isa(ama(pippo,iole),45566,pippo).
send_message_to(pluto,agree(conosco(iol
e),pippo),italian,[])
send_message_to(pluto,agree(conosco(iol
e),pippo),italian,[])
PLUTO
File name: pluto.txt
amaE(X):messageA(pippo,query_ref(ama(X,Y),1,pluto)).
send_message_to(pippo,inform(agree(con
osco(iole)),values(no),pluto),italian,[])
send_message_to(pippo,inform(agree(con
osco(iole)),values(yes),pluto),italian,[])
New message
Insert name of addressee
|: pluto.
…
Insert message
|: confirm(conosco(iole),pippo).
Dali examples
PIPPO
ANNE
Eliminated message:not exists meta_rule for
propose(take_the_bus,pippo)
From:pippo:nb-kasko-eagle:1032
send_message_to(pippo,reject_proposal(take_t
he_bus,[],anne),italian,[])
send_message_to(pippo,accept_proposal(take_
the_bus,[],anne),italian,[])
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: propose(take_the_bus,pippo).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: propose(take_the_bus,[piove],pippo).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pino.
Insert message
|: confirm(piove,pino).
Dali examples
PIPPO
ANNE
send_message_to(pippo,accept_proposal(take_
the_bus,[],anne),italian,[])
make(take_the_bus,224766)
send_message_to(pippo,accept_proposal(go_by
_car,[],anne),italian,[])
send_message_to(pippo,failure(go_by_car,moti
vation(false_conditions),anne),italian,[])
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|:propose(take_the_bus,[piove],pippo).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: propose(go_by_car,[piove],pippo).
Dali examples
PIPPO
ANNE
Anne
send_message_to(pippo,accept_proposal(go_by
_car,[],anne),italian,[])
make(go_by_car,312094)
make(ask_susan_to_join,312109)
Pippo
past(failed_action(go_by_car,motivation(false
_conditions),anne), 197047, anne).
past(accepted_proposal(go_by_car,[],anne),
240344, anne).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: confirm(car_available,pippo).
New message
Insert name of addressee
|: anne.
Insert Language
|: italian.
Insert Ontology
|: [].
Insert From
|: pippo.
Insert message
|: propose(go_by_car,[piove],pippo).
Scarica

Università degli Studi di L`Aquila