A che serve, come si qualifica nello studio della computabilità? Serve a varie cose: serve alla MdT universale U, perché prende in input la CODIFICA di una macchina e il suo input. Altro utilizzo è quello dell’enumerazione: una volta codificate, posso enumerare tutte le stringhe binarie e capire se una stringa è decodificabile come MdT oppure se non è valida (in quel caso gli associamo una MdT fittizia con un solo stato e si ferma subito non avendo transizioni). Dalle enumerazioni posso costruire la tabella macchine-stringhe Mij con {…\appunti} e da essa ricavare la diagonale, che complementata forma Ld. Perché si è sicuri che esista almeno un linguaggio non ricorsivamente enumerabile? Fare un esempio di un linguaggio di questo tipo e giustificare il fatto che non è RE. Enumerando tutte le stringhe binarie e formando la tabella posso costruire il complemento della diagonale Ld, e questo linguaggio non corrisponde a nessun altro linguaggio accettabile da macchine di Turing (è diverso da ogni riga per almeno un elemento) e quindi ricorsivamente enumerabile. Ne consegue che Ld non è RE. Dare la definizione di linguaggio RIC e di linguaggio RE. Un linguaggio RE significa che esiste una MdT che lo accetta. Se un linguaggio è RE ma non RIC, quando la stringa in input non appartiene al linguaggio è indecidibile sapere se la macchina si fermerà oppure no. RIC significa che, oltre ad essere RE, per ogni stringa la MdT si ferma, sia che appartiene al linguaggio sia che non appartiene al linguaggio. Dare un esempio di linguaggio RE ma non RIC. Dire perché non appartiene alla classe RIC e giustificare la risposta. È il linguaggio universale per esempio, ovvero il linguaggio accettato dalla macchina universale U. Non può essere ricorsivo perché altrimenti vorrebbe dire che tutte le macchine di Turing dovrebbero fermarsi e rifiutare in caso di input non appartenente al linguaggio, cosa non possibile dato il problema dell’arresto, che è indecidibile. Dare la definizione di Extended Context Free Grammar e fare un esempio di produzione. Sono quelle grammatiche nelle quali nei corpi delle produzioni si possono usare espressioni regolari. Troviamo gli esempi sulle slide di laboratorio. Dare la definizione del linguaggio Ld. È un linguaggio RE? Ld = {wi | wi non appart L(Mi)} Notare che la stringa e la macchina hanno lo stesso indice, essendo sulla diagonale i = j. Infatti, sulla diagonale c’è la coppia (M, w) nella quale w però è la codifica di M, e ci si chiede se M accetta la codifica di se stessa. Il linguaggio di diagonalizzazione contiene le codifiche che non vengono accettate dalla macchina corrispondente (che nella tabella avevano 0), infatti per ottenere il paradosso serve la negazione. Non è RE proprio perché sono le stringhe che non hanno una macchina di Turing che le accetta. Si consideri una matrice che serve per definire la funzione caratteristica del linguaggio diagonale Ld. Con quale criterio le entità che caratterizzano le righe e le colonne sono elencate? Sono tutte le stringhe binarie, elencate in ordine di lunghezza della stringa e poi lessicograficamente, ponendo ogni stringa w come 1w (quindi epsilon sarà la prima, 0 diventa 10 e sarà la seconda, 1 diventa 11 e sarà la terza… e così via). Descrivere la macchina di Turing universale per sommi capi. È la macchina che prende in input la codifica di una MdT e una stringa quindi ; è una macchina multinastro che simula la macchina che prende in input usando 4 nastri, uno di input in cui c’è Cod(M)111w, uno che simula il nastro di input M dove verrà messa w, un altro in cui tiene lo stato attuale di M in unario, un altro ausiliario dove fa i calcoli. Perché U è detta macchina ‘universale’? Perché simula ogni macchina di Turing, compresa se stessa. Dare la definizione del linguaggio che U accetta, ovvero Lu. Lu = {(M, w) | w appart L(M)} in cui la coppia (M, w) è una stringa binaria codificata come Cod(M)111w. Lu è un linguaggio RIC? No, è un linguaggio RE perché non è detto che la macchina M che prende U in input si fermi, e dato che U la simula vale lo stesso problema indecidibile. Dire com’è fatta la struttura di un DPDA e a quale grammatica può essere associato? DFA + pila
Sezione 3.3: applicazione dell’ER in unix, analisi lessicale, ricerca di pattern.
Sezione 5.3 applicazioni delle CFG: parser, yacc, linguaggi di markup (XML). Ogni computazione può essere descritta come una derivazione di un sistema di riscrittura, ovvero una grammatica. Definizione di algoritmo da “The Art of…”, Gli algoritmi si possono tutti scrivere come grammatiche di tipo 0. Noam Chomsky (1928), linguista di formazione, si chiese quale fosse l’origine del fenomeno per il quale i bambini imparano così velocemente a parlare, nonostante i genitori si rivolgano ad essi per la maggiore in “motherese” (...). Ipotizzò quindi l’idea di una grammatica universale innata come base di ragionamento nel nostro cervello, questionando la possibilità dell’esistenza di un pensiero umano senza linguaggio. Ovviamente, studi più recenti hanno rilevato come base del nostro ragionamento una rete neurale profonda. Siamo infatti molto più propensi a riconoscere pattern, più che grammatiche. Ipotizzò comunque una grammatica formale generativa, ovvero un formalismo che descrive e genera tutti i linguaggi (sia umani, che di macchine). Così arrivò alla definizione di una gerarchia di grammatiche, oggi nota come “gerarchia di Chomsky”. Notare che ci sono grammatiche “al di fuori” dei quattro tipi, che non sono riconosciute da alcuna di essi. Ci sono due aspetti per i linguaggi, la grammatica e l’automa. La grammatica è una descrizione finita di un linguaggio, o anche un formalismo che, attraverso le sue produzioni, genera un linguaggio. Un automa è una dispositivo che accetta le stringhe di un linguaggio; anch’esso descrive in modo finito il linguaggio. Le grammatiche formali generative ci permettono di: tradurre un programma da un linguaggio all’altro (tipicamente, la compilazione di codice) -sono usate dal parser, un componente di un compilatore, per capire se un programma è legale in un certo linguaggio e ricostruirne la struttura sintattica. descrivere documenti elettronici -usate in un DTD per specificare classi di documenti XML nella comunicazione tra macchine (server e client web) Nei parser, i simboli dell’alfabeto (insieme finito e non vuoto) saranno dei token. Una stringa è invece una sequenza finita (ma che può essere vuota) di simboli dell’alfabeto CULTURA INFORMATICA -- C’è qualche differenza tra programma e codice? codice (code) una sequenza di simboli (atti a rappresentare "istruzioni") con cui un programmatore vuole influenzare il comportamento di un esecutore di programmi (tipicamente una macchina computazionale). Ci si può chiedere: è lessicalmente corretto? è sintatticamente corretto? è funzionalmente corretto? È efficace? è efficiente? Date le grammatiche (lessicali e sintattiche) del linguaggio in cui è scritto un codice (sorgente) può essere possibile la traduzione del codice in un altro linguaggio (di cui siano note le grammatiche). programma: un insieme di operazioni che un esecutore di programmi (tipicamente una macchina computazionale) esegue sulla base di un codice (codice macchina) in un certo ordine (anche dipendente dall’input). Può essere software o hardware. Ogni linguaggio di programmazione è caratterizzato da due grammatiche: lessicale e sintattica. La grammatica lessicale (o morfologica) è quella che ci permette di trasformare stringhe si simboli di T (charset UNICODE) in stringhe di “input elements” o tokens del linguaggio di programmazione. Input elements: identifiers (variabili, costanti), keywords (nomi riservati, tipo new, for if), literals (valori assegnati a variabili), separators (parentesi, punteggiatura), operators (=,>,<,…). elements” o tokens del (linguaggi) di programmazione. La grammatica lessicale di Java ci permette di mappare codice sorgente scritto in Java in codice tokenizzato, coi token dell’alfabeto della grammatica sintattica di Java.