Ripasso di teoria ed esercizi in preparazione al terzo compito

Ripasso di teoria
ed esercizi
in preparazione
al terzo compito
***DATA***
Teoria: domande “tipo” per il terzo compitino
1. Metaprogrammazione: In cosa consiste la metaprogrammazione?
Quali sono alcuni campi di applicazione tipici per la metaprogrammazione? Quali sono i vantaggi dell’uso di metainterpreti in Prolog? Qual è la differenza tra il metainterprete
banale, il metainterprete vaniglia ed il metainterprete che
riprogramma la funzione di selezione? In cosa consiste il forward reasoning? Che differenza c’è tra backward e forward
reasoning? In cosa consiste la adduzione? In che modo è
possibile implementare meccanismi di ereditarietà tra teorie?
In cosa consiste il “ragionamento approssimato”?
2. Tecniche di AI per problem solving: Cosa si intende con
euristica? In che modo può essere rappresentato un problema
in Prolog, in modo da adottare tecniche di AI per risolverlo?
Quali sono le tecniche di ricerca sullo spazio degli stati? In
cosa differiscono? Come si possono implementare in Prolog?
Cosa si intende con euristica? Cosa sono gli “and/or” graph?
Come si può applicare l’euristica ai grafi and/or? Illustrare
lo schema generale di un programma Prolog che utilizza di
alberi di ricerca per giochi. Illustrare l’algoritmo minimax.
Problem solving
Dato un problema bisogna rappresentarlo e risolverlo.
Il problema si può rappresentare tramite le configurazioni del
problema stesso, ovvero i possibili stati in cui il problema si può
trovare. Lo spazio degli stati è rappresentabile come un grafo
in cui i nodi sono le configurazioni e gli archi sono le azioni che
fanno muovere da una configurazione ad un’altra. Dovranno
essere anche rappresentati lo stato iniziale e lo stato finale.
Con la rappresentazione a grafo, trovare una soluzione corrisponde
a trovare un cammino dallo stato iniziale allo stato finale.
Il bersaglio
Data una parola di senso compiuto, modificarla (eventualmente
ripetutamente) in uno dei seguenti modi al fine di ottenere un’altra
parola di senso compiuto (stato finale):
– aggiungere una lettera in un punto qualunque della parola
(purché la parola ottenuta sia sempre di senso compiuto e non
sia più lunga di 8 lettere);
– rimuovere una lettera da un punto qualunque della parola
(purché la parola ottenuta sia sempre di senso compiuto e non
sia più corta di 3 lettere);
– cambiare una lettera della parola.
Il bersaglio
Rappresentazione del problema: ogni configurazione consiste
nella lista di lettere che compongono la parola.
Stato iniziale: [c, a, r, t, a] (verra’ dato come parametro
in input alla strategia di ricerca)
Stato finale: final([m, o, s, t, r, o]).
Configurazioni intermedie: liste di lettere accettabili secondo
le regole del gioco.
Il bersaglio
Mosse possibili: aggiungere e togliere lettere rispettando i vincoli
imposti dal problema.
move(Parola, NuovaParola) :letter(X),
insert(X, Parola, NuovaParola),
senso_compiuto(NuovaParola).
move(Parola, NuovaParola) :remove(Parola, NuovaParola),
senso_compiuto(NuovaParola).
Il bersaglio
move(Parola, NuovaParola) :letter(X),
exchange(X, Parola, NuovaParola),
senso_compiuto(NuovaParola).
Vanno definiti tutti i predicati usati in “move”.
Il bersaglio
Tecniche di ricerca adottabili: quelle viste a lezione.
• Depth-first search strategy (con e senza controllo di cicli).
• Breadth-first strategy.
Euristica applicata alla ricerca
Idea: ridurre lo spazio di ricerca con valutazioni empiriche basate
sulla natura del problema.
Locale: Hill climbing; globale: best-first search.
Non ci saranno esercizi sulla parte di implementazione in Prolog
di algoritmi che integrano l’euristica nella strategia di ricerca.
Potranno però esserci dei problemi sulla modellazione di euristiche per risolvere efficaciemente un dato problema.
Il bersaglio con euristica
Potremmo assumere che il costo di una mossa sia sempre 1,
quindi c(N, N’) = 1 per ogni coppia di configurazioni (N, N’) tali
che esiste una mossa da N a N’.
La difficoltà di una configurazione è la distanza di quella configurazione dallo stato finale, quindi f(N) = difficoltà della configurazione N = distanza dalla configurazione finale.
La distanza di due configurazioni nel gioco del bersaglio la calcoliamo come somma delle lettere diverse a parità di posizione.
Se una configurazione è più lunga dell’altra, si somma il numero
di lettere in cui le due lunghezze differiscono.
Il bersaglio con euristica
f([m,o,s,t,o]) = 2
f([c,a,r,t,a]) = 5
f([m,a,s,t,r,o]) = 1
Metainterpreti
Realizzare un meta-interprete che modifica la strategia con cui
vengono usate le clausole in un programma, utilizzando le clausole in ordine inverso (dal basso, ovvero dall’ultima clausola che
compare nel programma definente il predicato in oggetto, verso
l’alto, ovvero verso la prima clausola che compare nel programma
per definire il predicato in oggetto).
Inversione delle clausole
solve_revert_clauses(Programma, Goal):asserisci_clausole_invertite(Programma),
call(Goal).
asserisci_clausole_invertite([]).
asserisci_clausole_invertite([H|Tail]) :asserta(H),
asserisci_clausole_invertite(Tail).
Metainterpreti
Realizzare un meta-interprete che modifica l’algoritmo di unificazione. Il nuovo algoritmo deve soddisfare le seguenti specifiche:
• due costanti non unificano mai (anche se sono uguali);
• nel caso in cui i termini da unificare siano entrambi variabili,
o il termine da unificare sia una variabile ed il termine che
unifica sia una costante, l’unificazione avviene normalmente.
Si noti che se il termine da unificare è una costante ed il
termine che unifica è una variabile l’unificazione fallisce;
Metainterpreti
• nel caso in cui i due termini siano entrambi composti, l’unificazione
avviene se i funtori ed il numero di argomenti sono identici, e
gli argomenti unificano a due a due applicando ricorsivamente
le suddette regole.
Unificazione ridefinita
solve_unif(true) :- !.
solve_unif((A, B)) :- solve_unif(A), solve_unif(B), !.
solve_unif(Goal) :functor(Goal, F, A),
functor(Templ, F, A),
clause(Templ, Body),
unificano_termini(Goal, Templ),
solve_unif(Body).
Unificazione ridefinita
unificano_termini(Goal, Templ) :Goal =.. [_|Arg],
Templ =.. [_|Arg1],
unificano(Arg, Arg1).
unificano([], []).
unificano([H|Tail], [H1|Tail1]) :var(H),
H = H1,
unificano(Tail, Tail1).
Unificazione ridefinita
unificano([H|Tail], [H1|Tail1]) :compound(H), compound(H1),
H =.. [A|Arg], H1=..[A|Arg1],
unificano(Arg, Arg1),
unificano(Tail, Tail1).