Pagine

sabato 15 febbraio 2025

A passeggio con l'informatica #19 – Intelligenza delle macchine: è vera intelligenza?

di Enrico Nardelli

Continuando il discorso sulle macchine cognitive iniziato nel post precedente, osserviamo che si tende a considerare i dati elaborati dalle macchine cognitive come un qualcosa di oggettivo e assoluto, sulla base dell’etimologia di “dato” (che deriva dal latino datum = ciò che è stato dato) quando in realtà esso, in quanto rappresentazione di un fenomeno, ne costituisce solo un modello, uno dei tanti possibili. Quindi, nell’atto di scegliere un dato c’è già un’idea di interpretazione, che è soggettiva e che guida le modalità con le quali chi poi leggerà il dato gli darà un senso. L'esempio che tutti conoscono è quello della bottiglia, che può essere mezza vuota o mezza piena. Anche se usiamo un linguaggio più scientifico, posso descrivere questa bottiglia come un recipiente del volume di un litro contenente mezzo litro di acqua (bottiglia mezza piena) o contenente mezzo litro di aria (mezza vuota). Sto descrivendo lo stesso fenomeno, ma focalizzo il lettore su due interpretazioni differenti. La selezione di un certo insieme di dati è quindi l’atto fondamentale su cui si basa la successiva interpretazione. Si tratta di un meccanismo ben noto sia ai professionisti dell’informazione, che spesso lo usano per guidare chi legge verso una certa interpretazione, sia a chi per mestiere cerca di capire cosa sia davvero accaduto in certe occasioni, che si trova spesso di fronte resoconti contrastanti di una stessa vicenda da parte dei testimoni oculari.

Una seconda osservazione rilevante è che, data l’enorme quantità di dati digitali utilizzabili e la disponibilità di sofisticate tecniche di apprendimento automatico (machine learning), sembra non ci sia più bisogno di teorie, ovvero di quadri interpretativi coerenti per i fenomeni, perché l’opera di invenzione di queste teorie può essere sostituita dall’attività di macchine cognitive che, macinando senza fatica terabyte e terabyte di dati con sofisticate analisi statistiche, scopriranno per noi tutte le teorie necessarie. Quest’opinione, lanciata nel 2008 da Chris Anderson, direttore responsabile di Wired (una delle prime riviste che hanno affrontato il tema dell’impatto del digitale sulla società), sosteneva appunto che con il diluvio di dati disponibili non ci sarebbe più stato bisogno della teoria. L’ipotesi ha avuto nel 2016 una netta confutazione scientifica da parte degli informatici Christian Calude e Giuseppe Longo, che hanno matematicamente dimostrato come al crescere della quantità dei dati aumenta il numero di correlazioni che possono essere trovate in essi. Dal momento che questo è vero anche se i dati sono stati generati in modo casuale, ne discende che una correlazione trovata semplicemente applicando tecniche statistiche senza essere guidata da un modello interpretativo (cioè, da una teoria) non ha un significato intrinseco. Le macchine cognitive quindi, con le loro enormi capacità di analisi dati, possono certamente arricchire il metodo scientifico, ma non potranno mai sostituirlo.

Le macchine cognitive sono sicuramente utili al progresso della società umana e, data la velocità di avanzamento della tecnologia, è ragionevole aspettarsi che su un piano cognitivo puramente razionale le loro capacità analitico-deduttive saranno presto insuperate. Questo, però, non vuol dire che la cosiddetta “singolarità tecnologica” verrà presto raggiunta. Con questo termine si intende il momento in cui una macchina cognitiva diventa più intelligente di un essere umano, prefigurando quindi la sottomissione della nostra specie. Si tratta di una paura ancestrale, quella della macchina che si ribella al suo creatore, presente nella letteratura fin dal medievale mito ebraico del golem, passando per il racconto di Karel Capek, che ha dato origine al moderno uso della parola “robot", per arrivare alla fantascienza e ai moderni resoconti sui mass media, originati, questi ultimi, da personaggi molto noti in ambito tecnologico quali Ray Kurzweil ed Elon Musk.

La realtà è ben diversa. L’intelligenza delle macchine e l’intelligenza umana sono due cose piuttosto differenti, anche se hanno una qualche sovrapposizione. Il problema è che usando il termine intelligenza, che per tutta la storia dell’umanità ha sempre indicato quella umana, accoppiato all’aggettivo artificiale, tendiamo a evocare l’idea che si tratti di intelligenza umana artificialmente realizzata mediante automi. In altre parole, il termine “intelligenza artificiale” induce a credere che esso descriva più di quello che effettivamente è. Invece, come detto, si tratta solo dell’aspetto legato alle capacità analitico-deduttive puramente razionali, ovvero alla possibilità di calcolare nuovi dati logicamente implicati dai dati sotto esame. Ho articolato questa riflessione in un articolo in cui ho suggerito (in modo un po’ provocatorio, perché non penso che, a questo punto, si possa davvero cambiare modo di dire) di usare l’espressione “intelligenza meccanica” invece che “intelligenza artificiale”, per meglio concentrare l’attenzione sul fatto che si sta parlando comunque di capacità meccaniche, anche se estremamente sofisticate. In quest’ambito, come abbiamo già avuto prova nel campo dei giochi da tavolo, le macchine cognitive sono superiori alle capacità umane, così come le macchine industriali hanno superato l’uomo per quanto riguarda le capacità fisiche.

Discuteremo nel prossimo post alcune caratteristiche dell’intelligenza umana che appaiono difficilmente ottenibili mediante le macchine.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 12 febbraio 2025.

sabato 8 febbraio 2025

A passeggio con l'informatica #18 – Macchine cognitive

di Enrico Nardelli

Avendo terminato con il post precedente un rapido excursus sui concetti fondamentali più rilevanti dell’informatica come disciplina scientifica, in questa seconda parte iniziamo una serie di riflessione sul suo impatto su persone e società.

L’attuale società digitale è pervasa da macchine cognitive, che realizzano cioè operazioni di natura cognitiva. Sottolineo che con tale termine non sto assegnando a queste macchine un’intrinseca capacità cognitiva simile a quella degli esseri umani, ma solo che le funzioni che esse meccanicamente svolgono sono analoghe a quelle di elaborazione puramente logico-razionale che svolgono le persone. È inoltre opportuno aggiungere che negli individui, avvenendo tali elaborazioni in una mente incarnata in un corpo fisico, è difficile, se non impossibile in certe situazioni, farle accadere su un piano esclusivamente logico-razionale.

Si tratta di una vera e propria rivoluzione, la “rivoluzione informatica”, che ho caratterizzato come la terza “rivoluzione dei rapporti di potere”, e di cui parlo estesamente nel mio libro La rivoluzione informatica: conoscenza, consapevolezza e potere nella società digitale, perché per la prima volta nella storia dell’umanità complesse funzioni cognitive di tipo logico-razionale vengono svolte da macchine. Questa terza rivoluzione “rompe” il potere dell’intelligenza umana, realizzando artefatti che possono meccanicamente replicare azioni cognitive che erano finora caratteristiche esclusive dell’uomo.

Per certi versi queste macchine ricordano quelle che, nel corso della rivoluzione industriale, hanno reso possibile la trasformazione della società da contadina a industriale: tali macchine industriali sono degli amplificatori della forza fisica dell’uomo. In questo caso abbiamo macchine di natura diversa ed enormemente più potenti: queste della rivoluzione informatica sono macchine che amplificano le funzioni cognitive delle persone, vale a dire dispositivi che potenziano le capacità di quell’organo la cui funzione costituisce il tratto distintivo dell’essere umano.

Abbiamo una rivoluzione tecnica, cioè l’elaborazione più veloce dei dati, ma anche una rivoluzione sociale, cioè la generazione di nuova conoscenza. Il potere che viene scardinato, in questo caso, è quello dell’intelligenza umana. L’umanità è sempre stata, in tutta la sua storia, signora e padrona delle sue macchine. Per la prima volta questa supremazia rischia di essere messa in crisi: abbiamo delle macchine che esibiscono comportamenti che, quando vengono attuati dagli esseri umani, sono considerati manifestazioni di intelligenza.

Abbiamo iniziato con cose semplici, come mettere in ordine delle liste di nomi, ma adesso possiamo riconoscere se un frutto è maturo o se un tessuto presenta difetti, per citare un paio di esempi resi possibili da quella parte dell’informatica che va sotto il nome di intelligenza artificiale. Certe attività cognitive non sono più dominio esclusivo dell’umanità: lo vediamo nei vari giochi da scacchiera (dama, scacchi, go, …), un tempo unità di misura per l’intelligenza e nei quali ormai il computer batte regolarmente i campioni del mondo. Lo vediamo in tutta una serie di attività lavorative, un tempo appannaggio esclusivo delle persone, nelle quali sono ormai abitualmente utilizzati i cosiddetti bot, sistemi informatici basati su tecniche di apprendimento automatico (machine learning).

Infine, sono arrivati i sistemi di intelligenza artificiale generativa (tipo ChatGPT, per intenderci) di cui tutti ormai hanno sentito parlare, che esibiscono una competenza nella conversazione con gli esseri umani che è oggettivamente stupefacente. Purtroppo, tale competenza può essere macchiata da errori o imprecisioni di cui è difficile accorgersi, se non conosciamo già la risposta corretta. Accade che questi sistemi esibiscono una competenza eccellente con le parole che descrivono il mondo ma non posseggono davvero competenza sul mondo, non hanno una vera comprensione del significato delle parole che usano, nonostante le apparenze. In altri termini, noi proiettiamo su quanto questi sistemi producono il significato che è dentro di noi: la vera intelligenza è nel cervello di chi legge e non nei sistemi di intelligenza artificiale generativa.

Rimandando a successivi post una discussione più approfondita sul ruolo che tali sistemi possono giocare in futuro, è interessante quindi accennare a un paio di problemi che si applicano a tutte le macchine cognitive, anche a queste versioni più sofisticate.

Il primo è che allo stato attuale le macchine cognitive non hanno né flessibilità né adattabilità per cambiare il loro modo di operare al mutare delle condizioni di contesto. È vero che gli approcci basati su tecniche di apprendimento automatico consentono di rilevare cambiamenti nel loro ambiente e di adattare le loro azioni, però questo spazio di adattamento ha limiti severi. Tutti i possibili scenari futuri devono essere stati in qualche modo previsti dai progettisti. Le persone sono intrinsecamente in grado di apprendere ciò che non sanno, mentre le macchine cognitive possono apprendere solo ciò per cui sono state progettate. Le persone hanno imparato, attraverso milioni di anni di evoluzione, ad adattarsi flessibilmente a cambiamenti imprevisti nell’ambiente, mentre le macchine della conoscenza possono – ancora una volta – adattarsi solo ai cambiamenti previsti. Non possiamo quindi lasciarle operare da sole, a meno che non siano in contesti in cui c’è la certezza che tutto è stato tenuto in considerazione.

Il secondo è che le macchine cognitive sono del tutto distaccate da cosa significhi essere persone. Qualcuno lo vede come un pregio, per me è un enorme difetto. Io ritengo che non esista la possibilità di determinare un unico modo migliore di prendere le decisioni. Quelli che pensano che mediante l’intelligenza artificiale si possa governare la società umana nel modo migliore per tutti sono degli illusi (o hanno interessi nascosti). Da che esiste la società umana è compito della politica determinare la sintesi tra le esigenze contrastanti che sempre esistono in ogni consesso. E tale sintesi non può prescindere dal nostro essere umani. L’unica intelligenza che può prendere decisioni appropriate in questo contesto è l’intelligenza incarnata delle persone, non quella artificiale delle macchine cognitive.

Questo non implica che non ci sia un ruolo per le macchine cognitive. Il loro uso dovrebbe rimanere confinato a quello di potenti assistenti personali, che ci alleviano la pesantezza del lavoro intellettuale di routine, aiutandoci a non fare errori a causa della fatica o di sviste. Ma le persone devono sempre avere il controllo e le decisioni finali, soprattutto quelle che – direttamente o indirettamente – hanno conseguenze rilevanti per altre persone, devono sempre essere prese da esseri umani.

Ne riparleremo in post futuri.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 5 febbraio 2025.

sabato 1 febbraio 2025

A passeggio con l'informatica #17 – Bit che si riproducono

di Enrico Nardelli

Nel precedente post (Dati o programmi? Questo è il problema) abbiamo discusso come, a livello del linguaggio di programmazione che la macchina fisica è in grado di eseguire direttamente attraverso i suoi circuiti elettronici, non vi sia una distinzione intrinseca tra cosa costituisce un’istruzione e cosa un dato. Solo le istruzioni dell’Unità di Controllo della macchina a registri, che sono quelle poste all’interno dei cerchi della seconda figura del post n.4 (Come funziona un computer), sono intrinsecamente delle istruzioni. Quello che comunemente chiamiamo “programma” (indipendentemente se sia in linguaggio simbolico o in linguaggio macchina) è, al livello fisico direttamente eseguibile, solo una sequenza di bit zero e uno.

Questo costituisce un vantaggio, perché ci permette di elaborare i programmi trattandoli semplicemente come dati, ma può costituire anche una debolezza, se delle sequenze di bit che erano state considerate dei dati vengono invece interpretate come istruzioni e sono eseguite. Quest’ultimo è infatti il meccanismo con cui i virus informatici si diffondono: in assenza di opportune contromisure, vengono trasferiti da un computer a un altro come se fossero dei dati e poi vengono eseguiti.

Questa natura duale posseduta dalle sequenze di bit, insieme al fatto che – proprio a causa di tale dualità – una stessa sequenza di bit può essere interpretata in entrambi i modi e può quindi manipolare se stessa, conferisce all’informatica un potere di riproduzione di cui l’unica altra manifestazione esistente in natura è quella posseduta dai sistemi biologici.

Illustriamo questo potere di riproduzione con un automa molto semplice. Descrivo prima il suo semplice repertorio di istruzioni e poi presento un programma che, nonostante la semplicità dell’automa, è in grado di riprodurre se stesso. La prima istruzione del repertorio è un’istruzione di assegnazione del tipo

P=100;

che assegna a P il valore 100. Notiamo che ogni istruzione è terminata da un punto e virgola (;). Questo è solo un esempio di uso dell’istruzione, un altro potrebbe essere

Q=3;

che assegna a Q il valore 3. Abbiamo poi un’istruzione di stampa del tipo

stampa P;

che, avendo eseguito l’istruzione di assegnazione precedentemente descritta, produce come risultato

100

Chiaramente l’istruzione «stampa Q;» avrebbe invece prodotto «3»: osservate che in questo caso abbiamo usato le doppie parentesi angolari aperte («) e chiuse (») per denotare con precisione nel corpo del testo le istruzioni di cui parliamo o il loro effetto, mentre prima le avevamo presentate ognuna isolata su una riga. L’automa possiede anche una variante di tale istruzione di stampa, cioè

stampa “P”;

la cui esecuzione non produce più la stampa del valore eventualmente assegnato a P ma produce come risultato letteralmente quanto è contenuto tra i doppi apici, cioè

P

(analogamente «stampa “Q”;» produrrebbe «Q»). Osserviamo a questo punto che l’istruzione di stampa può avere più oggetti da stampare, come per esempio accade con

stampa P Q;

che produce

100    3

e con

stampa “P=” P;

che invece produce

P=100

Infine, l’automa possiede una convenzione di ripetizione, in base alla quale, ad esempio

3|X;

costituisce un modo abbreviato di rappresentare

X; X; X;

Abbiamo pertanto che il programma (fatto da due istruzioni che per semplicità scriviamo sulla stessa riga)

P=3|X; stampa P;

produce in uscita

X; X; X;

mentre il programma

P=3|X; stampa “P=” P;

produce in uscita

P=X; X; X;

Siamo pronti a questo punto a presentare e discutere il programma che riproduce se stesso, che è costituito da queste due sole istruzioni, presentate di seguito sulla stessa riga

P=2|stampa “P=2|” P;      stampa “P=2|” P;

Determiniamo cosa fa l’automa quando esegue questo programma. Con la prima istruzione assegna a P – in base alla convenzione di ripetizione sopra descritta – il valore «stampa “P=2|” P; stampa “P=2|” P;». Con la seconda istruzione produce in uscita il valore «P=2|» seguito dal valore appena assegnato a P, cioè

P=2|stampa “P=2|” P; stampa “P=2|” P;

L’esecuzione del programma ha quindi prodotto in uscita una copia esatta di se stesso! Notate che lo spazio tra le due istruzioni nel primo caso (il testo del programma) è maggiore del secondo (il risultato della sua esecuzione) solo per motivi di chiarezza tipografica.

Abbiamo ottenuto un comportamento che, a livello astratto, è esattamente lo stesso comportamento che realizza una sequenza di DNA durante la replicazione, processo chiave per la riproduzione biologica. Nel nostro caso, otteniamo la “riproduzione dei bit” e questo aspetto dell’informatica costituisce forse il più importante dei suoi apporti concettuali al panorama della cultura scientifica.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 29 gennaio 2025.

sabato 25 gennaio 2025

A passeggio con l'informatica #16 – Dati o programmi? Questo è il problema

di Enrico Nardelli

In questo ultimo post dedicato alla presentazione dei concetti fondamentali dell’informatica iniziamo ad affrontare quello che forse è il contributo più rilevante da un punto di vista culturale apportato da questa disciplina alla visione del mondo.

I concetti di algoritmo, linguaggio, automa, che – insieme agli altri – abbiamo esplorato nei precedenti post di questa serie, fanno parte del bagaglio concettuale di un informatico e sono gli strumenti intellettuali che un informatico usa per modellare e interpretare il mondo. Essi possono essere impiegati con successo per fornire descrizioni complementari a quelle fornite da altre scienze, per esprimere il punto di vista informatico sui fenomeni, arricchendo così la capacità di comprendere la realtà intorno a noi.

Nel post n.5 (Come istruire un computer) avevamo presentato un semplice programma scritto in linguaggio simbolico per una semplicissima macchina a registri (MR). Avevamo poi commentato che tale automa, per poter eseguire effettivamente il programma ha bisogno di una sua traduzione in linguaggio macchina. Come abbiamo infatti spiegato nel precedente post (Dalla virtualizzazione al cloud), il livello della macchina fisica è l’unico che può concretamente eseguire i programmi e ha bisogno di un linguaggio al suo livello (si veda la figura del post).

Nella figura sottostante, dove a sinistra vi sono le istruzioni e a destra i dati, viene presentata la versione in linguaggio macchina del programma presentato nel post n.5.

Rimandando alla sezione 4.2.2 del volume La rivoluzione informatica per una spiegazione di dettaglio di come tale programma viene ottenuto dalla versione in linguaggio simbolico, qui lo prendiamo così com’è perché ci serve per iniziare a discutere un concetto molto rilevante dell’informatica, cioè la natura duale che ha la rappresentazione per l’esecutore.

Infatti, ciò che c’è scritto nelle celle di memoria della MR non ha un’intrinseca caratterizzazione come dato o come istruzione. Nell’esempio di programma in linguaggio simbolico per MR presentato nella figura del post n.5 (Come istruire un computer) abbiamo distinto la zona di memoria con il programma e quella con i dati a solo scopo didattico. In quell’esempio noi, in quanto esseri umani, possiamo distinguere se ciò che leggiamo in una cella è un’istruzione o un dato, ma dal punto di vista della macchina stessa questa distinzione in realtà non esiste.

Consideriamo la seconda figura del post n.4 (Come funziona un computer): in tale figura, c’è scritto che la MR “legge l’istruzione all’indirizzo IC”, quando in realtà la MR sta leggendo semplicemente una sequenza di “0” e “1” e non ha – diversamente da noi esseri umani – alcuna consapevolezza che ciò che legge sia un’istruzione. Soltanto l’azione espressa in basso nella stessa figura, “esegui istruzione letta”, assegnerà l’effettiva natura di istruzione a quella sequenza binaria.

Ciò si capisce bene nella versione in linguaggio macchina del programma mostrato nella figura qua sopra. Infatti, in tale figura, nella cella di memoria di indirizzo 0 (che contiene un’istruzione) c’è scritta la sequenza “0000 00 0001”, ma anche nelle celle di memoria di indirizzo 15 e 16 (che contengono dati che il programma deve elaborare), c’è scritto lo stesso valore “0000 00 0001” (ricordate che gli spazi non contano). Nello stesso modo, nella cella 6 (istruzione) c’è scritto “0000 00 0000”, che è lo stesso valore scritto sia nella cella 10 che 17 (entrambi dati).

Questa osservazione implica che ogni dato gestito da una MR, o da qualunque calcolatore, ha in realtà una natura duale, potendo essere interpretato anche come un’istruzione per la macchina. Questa natura duale del dato fornisce all’informatica un potere di “riproduzione” che in precedenza era posseduto solo da sistemi biologici. È proprio questa natura duale il meccanismo concettuale di base per la costruzione dei virus informatici, che arrivano nei dispositivi digitali come dati e poi entrano in azione come programmi.

Nel prossimo post vedremo un esempio concreto di tale capacità di riproduzione.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 22 gennaio 2025.

sabato 18 gennaio 2025

A passeggio con l'informatica #15 – Dalla virtualizzazione al cloud

di Enrico Nardelli

Nella tappa n.5 di questa passeggiata con l’informatica (Come istruire un computer) avevamo visto come fornire a un computer le istruzioni che esso deve eseguire. In quel post avevamo presentato un semplicissimo esempio di programma con istruzioni scritte in un linguaggio di programmazione a livello simbolico (brevemente, linguaggio simbolico), chiarendo che l’effettiva esecuzione da parte di un automa richiede invece istruzioni espresse in linguaggio di programmazione a livello macchina (cioè, linguaggio macchina).

Da un punto di vista concettuale possiamo considerare il computer “come se” fosse in grado di eseguire direttamente il programma in linguaggio simbolico. Questa visione del computer lo considera quindi come una macchina virtuale in grado di eseguire direttamente le istruzioni del linguaggio simbolico. Poiché non lo è, per poter realizzare questo comportamento, deve essere fatta una traduzione del programma dal linguaggio simbolico a quello macchina.

La traduzione può avvenire in due modi, detti compilazione e interpretazione. La differenza tra i due è che con la compilazione il programma di livello simbolico viene interamente tradotto in quello di livello macchina e la sua esecuzione avviene dopo che l’intero processo di traduzione è terminato. Con l’interpretazione, invece, lo stesso programma viene tradotto un’istruzione per volta, che viene subito eseguita dalla macchina fisica. In alcuni casi è preferibile la compilazione, in altri l’interpretazione: entrambi gli approcci sono largamente usati. Si tratta della stessa differenza che c’è tra il traduttore di un libro, che vi consegna l’intero volume tradotto (compilazione) e l’interprete simultaneo, che invece esegue volta per volta la traduzione della frase pronunciata (interpretazione).

Se riprendete in considerazione la tappa n.5 vi rendete conto, però, che anche quel linguaggio simbolico era un po’ involuto, con termini non troppo chiarissimi (p.es., X Dim o Vai Y per indicare un’istruzione che verifica il contenuto della cella X e poi o lo decrementa o predispone la macchina per continuare con l’istruzione nella cella Y). Sarebbe bello quindi poter avere un linguaggio simbolico di alto livello, con istruzioni quasi vicine al senso comune e applicare lo stesso meccanismo di traduzione. In questo caso, il computer verrebbe considerato come una macchina virtuale in grado di eseguire direttamente programmi scritti in un linguaggio simbolico di alto livello, mentre in realtà il tutto passerebbe attraverso un processo di traduzione come precedentemente spiegato.

Questa visione concettuale di scatole cinesi (o di bamboline russe) viene illustrata, per la situazione appena descritta, nella figura sottostante.

Al livello più basso c’è la macchina fisica, cioè il livello dei circuiti elettronici, che sono in grado di eseguire fisicamente le operazioni logiche e aritmetiche. Quando si passa da questo livello a quello della macchina in grado di eseguire le istruzioni del linguaggio simbolico, si compie un processo di astrazione, si prescinde cioè da ciò che si ha fisicamente a disposizione, immaginando invece di avere qualcosa di più potente, cioè un calcolatore in grado di eseguire direttamente le istruzioni del linguaggio simbolico.

La macchina simbolica così definita non deve però essere fisicamente realizzata perché viene virtualmente ottenuta con il processo di traduzione delle istruzioni in linguaggio simbolico in quelle del linguaggio macchina, che vengono poi eseguite dalla macchina fisica.

Questo approccio viene anche chiamato virtualizzazione, proprio perché consente di avere a disposizione la macchina simbolica non mediante la sua effettiva costruzione fisica, ma attraverso la sua emulazione da parte di una macchina fisica, opportunamente istruita affinché produca i risultati che si sono chiesti alla macchina simbolica.

Nella realtà dell’informatica accade esattamente qualcosa di simile, estendendo ulteriormente questo meccanismo di virtualizzazione, come descritto in maggior dettaglio nel volume La rivoluzione informatica.

È utile ricordare che quando i calcolatori sono nati, nella prima metà del XX secolo, era disponibile solo il livello fisico, quello dei circuiti elettronici. Da subito, però, gli informatici hanno capito che la potenza concettuale di un esecutore automatico poteva essere impiegata per meccanizzare il processo di traduzione dall’espressione umana della procedura risolutiva a quella in grado di essere eseguita dalla macchina fisica. Oltre a consentire alle persone di operare al livello mentale più adeguato a loro, si evitavano in questo modo sia gli errori in cui fatalmente si incorre nel processo di traduzione sia quelli derivanti dal non esprimersi con lo strumento più adatto.

A partire dal secondo decennio del XXI secolo la virtualizzazione, che come abbiamo appena detto fa parte dell’informatica sin dalla sua nascita, ha assunto un ruolo sempre più importante. Infatti, la disponibilità capillare di una rete Internet ad alta velocità ha reso più conveniente, in tutta una serie di circostanze, non comprare direttamente macchine fisiche, cioè calcolatori – come si dice nell’ambiente – “di ferro”, che devono essere gestiti anche da un punto di vista fisico (protezione, spazio, climatizzazione, manutenzione, …), ma noleggiare macchine virtuali disponibili da qualche parte su Internet, appunto in the cloud, cioè “nella nuvola” (termine che deriva dal fatto che negli schemi di descrizione a livello aziendale dei sistemi informatici la parte della rete di comunicazione veniva convenzionalmente rappresentata da una nuvoletta).

Chiudo questa sezione ricordando che lo stesso meccanismo di virtualizzazione che ha permesso lo sviluppo del cloud ci consente di “far rivivere” modelli di calcolatori ormai fuori commercio o che non sono più in grado di funzionare fisicamente, consentendo a loro emulatori, cioè macchine virtuali che si appoggiano su macchine funzionanti, di eseguire il software che ancora esiste per essi ma che non è più in grado di essere eseguito né da tali modelli né direttamente dalle macchine moderne.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 15 gennaio 2025.

sabato 11 gennaio 2025

A passeggio con l'informatica #14 – Il galateo della comunicazione tra automi

di Enrico Nardelli

Con questa tappa concludiamo la sezione dedicata a discutere i principali elementi dello scenario di elaborazioni realizzate mediante la partecipazione di più agenti, ormai attualissimo a causa dell’ubiquità di Internet, e denominato computazione distribuita. Dopo il post introduttivo a questa tematica, abbiamo affrontato i tre concetti fondamentali della cooperazione, sincronizzazione e consenso. Questo post di chiusura affronta un aspetto più tecnologico ma altrettanto rilevante, quello dei protocolli di comunicazione.

Sotto questo nome sono comprese tutte le regole che definiscono come due o più esecutori si coordinano per scambiare informazioni. Non essendo persone in carne e ossa che, se parlano uno stesso linguaggio e fanno parte di una stessa comunità sociale, hanno appreso nel corso della loro esperienza di vita le regole per interagire con gli altri, devono essere istruiti fino all’ultimo dettaglio.

In un certo senso, i protocolli di comunicazione sono come i vari galatei di conversazione che vi sono nei diversi ambienti sociali. Nel mondo delle corti reali, assai diffuse a livello europeo nel XVIII secolo, era previsto, ad esempio, che fossero il re o la regina a rivolgere per primi la parola a chi veniva presentato. Durante la conversazione bisognava usare i termini appropriati e, nel congedarsi, non bisognava girare le spalle. Quando i nostri figli sono piccoli gli insegniamo a salutare quando si entra in un ambiente dove vi sono altre persone e a non interrompere gli adulti quando parlano (o, almeno, a farlo con modi opportuni).

I protocolli di comunicazione degli automi dell’informatica svolgono concettualmente la stessa funzione e hanno avuto un ruolo fondamentale fin dagli albori di questa tecnologia.

Sono sostanzialmente fatti di due parti. La prima è un insieme di regole che specificano la successione dei passi di interazione. Un esempio banale della vita normale: prima si saluta, poi si chiede come va, poi si fa una specifica domanda, poi si ringrazia, infine si saluta. La seconda è un insieme di regole che definiscono la struttura delle comunicazioni scambiate. Continuando l’esempio di prima, si può specificare che il saluto sia abbreviato e costituito solo dal termine di saluto (“ciao” oppure “salve”) o strutturato con “termine di saluto” (p.es: buongiorno) seguito dal “titolo” (p.es. dottoressa) seguito dal “nome completo” (p.es.: Paola Rossi).

Tra i protocolli moderni più famosi usati nell’informatica, di cui anche molti non informatici hanno sentito parlare, ci sono:

  • HypertText Transfer Protocol (= protocollo per il trasferimento di ipertesti – HTTP) che è alla base dello scambio di pagine web;
  • Transmission Control Protocol (= protocollo per il controllo della trasmissione – TCP) che è uno dei protocolli fondamentali per la gestione delle comunicazioni su Internet;
  • Internet Protocol (= protocollo di Internet – IP) che è il protocollo che consente alle diverse reti di comunicazione di scambiarsi dati per realizzare l’Internet che conosciamo;
  • File Transfer Protocol (= protocollo per il trasferimento di file – FTP) che costituisce il protocollo di base per trasferire file generici da una macchina all’altra sulla rete.

Ad esempio il protocollo HTTP prevede, come regole che specificano l’interazione, che chi voglia ricevere una pagina web invii una richiesta alla macchina che la possiede (trascurando i dettagli di come questa richiesta venga inviata) e che tale macchina risponda con la pagina o un messaggio di errore. Per quanto riguarda la struttura delle comunicazioni scambiate, sia la richiesta che la risposta hanno un formato testuale, cioè sono rappresentate mediante la codifica ASCII (ne abbiamo parlato nel post sulla rappresentazione dei dati).

La richiesta deve avere, semplificando, la seguente struttura:

  • un metodo di richiesta (scelto tra un elenco predefinito),
  • un indirizzo della pagina (il termine preciso è “identificatore univoco di risorsa”, in inglese uniform resource identifier = URI),
  • l’indicatore della versione del protocollo,
  • eventuali informazioni aggiuntive (sono gli header di richiesta = intestazioni della richiesta),
  • un corpo del messaggio (che può essere vuoto).

La risposta deve avere il seguente formato:

  • una riga di stato, che contiene un codice a 3 cifre che caratterizza il successo della risposta o una condizione di errore (il famoso “codice 404”, che quasi tutti avranno incontrato almeno una volta nella loro esperienza di navigazione su Internet e che corrisponde alla situazione di “pagina non trovata”, descrive appunto una condizione di errore) o situazioni intermedie che qui non trattiamo,
  • informazioni aggiuntive relative al tipo di macchina che risponde e al tipo di contenuto restituito (sono gli header di risposta = intestazioni della risposta),
  • il contenuto della risposta (ovviamente in caso di successo).

Con il prossimo post apriremo la trattazione di un nuovo tema, quello della virtualizzazione, che è sempre state presente nell’informatica fin dai suoi albori, ma che recentemente ha conosciuto, sotto la forma della tecnologia del cloud, un’esplosione senza precedenti.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione l'8 gennaio 2025.

sabato 21 dicembre 2024

A passeggio con l'informatica #13 – Raggiungere un accordo non è mai facile

di Enrico Nardelli

In questa tappa affrontiamo il terzo dei problemi rilevanti per la computazione distribuita, quello del consenso. Anche in questo caso lo introduciamo con un esempio ispirato alla vita d’ufficio.

Lo scenario considerato è quindi quello di due colleghi, Anna e Bruno, che devono presentarsi insieme dal capo-ufficio per sostenere una causa comune. Poiché sono consapevoli del fatto che andando insieme avranno maggiori opportunità di farsi valere, mentre se va uno solo dei due una punizione è certa, hanno già concordato il possibile giorno e ora in cui incontrarsi davanti alla porta del capo. A questo punto devono solo decidere se realizzare o no questo piano. Allo scopo si scambiano messaggi: il problema però è che qualche messaggio può perdersi a causa di guasti o malfunzionamenti degli strumenti che usano, che non prevedono una “ricevuta di consegna”, cioè una conferma ricevuta dal mittente che il messaggio è arrivato al destinatario. Ciò non deve sorprendere perché, anche in un’epoca di sistemi digitali, non sempre si ha la certezza che un messaggio di posta elettronica sia stato effettivamente consegnato al destinatario. Questo vuol dire, ad esempio, che dopo che Anna ha inviato un messaggio a Bruno, non può avere la certezza che esso sia arrivato e può soltanto attendere una risposta o inviarlo di nuovo. In altre parole, Anna non può distinguere la situazione in cui il suo messaggio è andato perso dalla situazione in cui è la risposta di Bruno che si è persa. Solo quando le giunge la risposta di Bruno può dedurre che il suo messaggio è arrivato. Ma a questo punto è Bruno che si trova in una situazione di incertezza: non è sicuro che la sua risposta sia stata consegnata ad Anna.

Come possono fare Anna e Bruno per risolvere questa situazione? Esiste un algoritmo che possa aiutarli ad avere la sicurezza che si sono messi d’accordo e nessun messaggio è andato perso? La risposta, sorprendente ma vera, è che, anche in questo semplicissimo scenario, non esiste un tale algoritmo.

Ne diamo la prova con il meccanismo della dimostrazione per assurdo. Con questo procedimento matematico si assume che qualcosa sia vero, poi si fa vedere che da questa assunzione deriva una contraddizione logica (ad esempio, si deriva che un’affermazione è contemporaneamente vera e falsa) e a questo punto si conclude che l’assunzione iniziale è assurda, cioè non vera.

Supponiamo, allora, che esista un algoritmo, che chiamiamo Accordo, che consente di mettersi d’accordo per realizzare il piano presentandosi entrambi dal capo-ufficio. Consideriamo poi lo scenario, che chiamiamo Possibile, in cui Accordo ha fatto effettivamente mettere d’accordo Anna e Bruno con lo scambio del numero minimo di messaggi. Consideriamo poi un secondo scenario, chiamato Alternativo, in cui Anna e Bruno si scambiano con l’algoritmo Accordo esattamente gli stessi messaggi scambiati nello scenario Possibile : nello scenario Alternativo però l’ultimo messaggio, che ipotizziamo sia stato inviato da Anna a Bruno, non raggiunge quest’ultimo perché viene perso. Dal punto di vista di Anna, non c’è differenza tra i messaggi che ha ricevuto nello scenario Possibile e quelli che ha ricevuto in quello Alternativo : quindi va all’appuntamento in entrambi gli scenari. Dal punto di vista di Bruno, nello scenario Alternativo gli è arrivato un messaggio in meno e l’algoritmo Accordo può far compiere a Bruno una di queste due azioni: (1) Bruno non va all’appuntamento, oppure (2) Bruno va all’appuntamento. Nel caso 1 si deduce che l’algoritmo Accordo è scorretto, perché Anna si presenta dal capo-ufficio mentre Bruno no: questa è una contraddizione con l’assunto iniziale che Accordo li faccia presentare entrambi e prova l’assurdità dell’esistenza di Accordo. Nel caso 2 si ottiene che Anna e Bruno hanno effettivamente scambiato nello scenario Alternativo un messaggio in meno per andare entrambi all’appuntamento, e questo contraddice l’ipotesi che Possibile sia lo scenario col numero minimo di messaggi. Anche nel caso 2, quindi, tale contraddizione prova l’assurdità dell’esistenza dell’algoritmo ottimo Accordo. Notate che potremmo assumere che l’ultimo messaggio sia quello inviato da Bruno ad Anna ma il ragionamento precedente rimarrebbe dello stesso tipo e le sue conclusioni ugualmente valide.

Questo è quello che ci dice la teoria. Nella pratica, quando due persone concordano un appuntamento in questo modo, man mano che si scambiano messaggi il loro livello di confidenza aumenta (anche in funzione del livello di conoscenza che ognuna di esse ha dell’affidabilità dell’altra) e, generalmente, quando una delle due parti ha ricevuto due messaggi dalla controparte, si ritiene ragionevolmente sicura che l’accordo sia stato raggiunto. È la situazione illustrata nella figura sottostante:

Quelli un po’ più diffidenti magari faranno un terzo scambio di messaggi, ma tendenzialmente si riterranno abbastanza sicuri di aver raggiunto il consenso. Ovviamente, quando la posta in gioco è alta e serve la certezza al 100% le persone usano il telefono, cioè la comunicazione sincrona, oppure meccanismi di comunicazione che certificano l’avvenuta consegna del messaggio.

Nel prossimo post prenderemo brevemente in esami i “protocolli di comunicazione” ovvero l’insieme di regole che definiscono come due esecutori si coordinano per scambiare informazioni.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 18 dicembre 2024.

sabato 14 dicembre 2024

A passeggio con l’informatica #12 – La sincronizzazione fra più esecutori

di Enrico Nardelli

Come descritto nel post introduttivo alla computazione distribuita, un secondo problema rilevante è quello della sincronizzazione, in cui i vari esecutori non devono coordinare il loro lavoro, che ognuno svolge in maniera autonoma, ma devono evitare di intralciarsi nell’uso di risorse che servono a tutti.

Lo discutiamo attraverso l’esempio di un ufficio in cui due impiegati, Rossi e Bianchi, devono ognuno controllare le proprie pratiche senza doversi coordinare nella loro gestione. Assumiamo per semplicità che il loro lavoro consista solo nel controllo, seguito dal rifiuto o dall’approvazione della pratica in esame. L’approvazione della pratica avviene suggellando la decisione attraverso un timbro particolare, fatto da due parti che si trovano in due posti diversi. Se i due impiegati non attuano una qualche forma di sincronizzazione, si possono trovare nella situazione in cui uno ha preso una parte del timbro, l’altro ha preso l’altra parte e nessuno dei due può approvare la pratica. Escludiamo strategie particolari che le persone potrebbero attuare in casi come questi, per esempio andando a trovare l’altro responsabile e concordando che uno dei due ceda la sua parte all’altro per fargli timbrare la sua pratica per poi ricevere indietro il timbro completo per approvare la propria.

Questo è il più semplice esempio possibile di sincronizzazione. Può essere risolto facendo eseguire a entrambi gli agenti uno stesso algoritmo, detto di Peterson, che non riporto interamente qua per la sua complessità formale, rimandando al mio libro La rivoluzione informatica per la sua spiegazione di dettaglio e fornendo nel seguito una descrizione intuitiva.

L’algoritmo assume che vi siano tre “variabili globali” che, nel contesto di un ufficio quale quello che stiamo considerando, possiamo considerare come tre bacheche che tutti gli impiegati possono leggere. Ogni bacheca è identificata da un nome: Rossi_vuole_timbrare, Bianchi_vuole_ timbrare, Adesso_è_il_turno_di. All’inizio dell’algoritmo in ognuna delle prime due bacheche è scritto FALSO, mentre ciò che è scritto sulla terza è irrilevante. L’algoritmo ripete in continuazione la sequenza di azioni descritta nel seguito.

L’impiegato che deve approvare la sua pratica dichiara che vuole timbrare, cioè scrive VERO sulla bacheca che inizia col suo nome, e scrive il nome dell’altro impiegato sulla bacheca che esprime di chi è il turno.

Dopo di questo, controlla se è contemporaneamente vero che l’altro impiegato vuole timbrare e che è il suo turno, e in caso positivo (chiamiamo “semaforo rosso” questa eventualità) si mette ad aspettare che questa situazione diventi falsa.

Quando ciò accade (cioè non vi è più il semaforo rosso) allora (1) va a prendere entrambi le parti del timbro, (2) approva la pratica, (3) rilascia entrambe le parti del timbro. Queste tre azioni vengono tecnicamente definite “sezione critica”, perché sono quelle che devono essere eseguite solo da un automa per volta, per non causare la situazione di blocco descritta all’inizio.

Successivamente all’esecuzione della sezione critica l’impiegato scrive FALSO sulla bacheca che inizia col suo nome e continua a controllare le sue pratiche.

Terminata la descrizione dell’algoritmo facciamo vedere che effettivamente la sezione critica può essere eseguita solo da un automa alla volta e che solo un automa alla volta può essere nello stato di attesa.

Assumiamo che Bianchi stia eseguendo la sua sezione critica e che Rossi sia in attesa. Allora Rossi potrà entrare nella sua sezione critica solo quando Bianchi uscirà dalla sua e scriverà FALSO sulla bacheca Bianchi_vuole_timbrare (rendendo così falsa la condizione che teneva Rossi in attesa, ovvero rimuovendo il semaforo rosso). Quando questo accade, Bianchi si trova a controllare pratiche e Rossi entra nella sezione critica: dopo un po’ anche Rossi uscirà dalla sua sezione critica e passerà a controllare pratiche.

Immaginiamo adesso che, mentre Bianchi continua a controllare pratiche, Rossi dichiari che vuole timbrare. Se Bianchi continua sempre a controllare pratiche allora Rossi non deve attendere (perché su Bianchi_vuole_timbrare c’è scritto FALSO) ed entra nella sua sezione critica. Se, in questa fase in cui Rossi è nella sua sezione critica, anche Bianchi dichiara di voler timbrare, allora troverà il semaforo rosso (perché su Rossi_vuole_timbrare c’è scritto VERO e inoltre sulla bacheca del turno c’è scritto che è il turno di Rossi) e rimarrà in attesa. Siamo quindi nella situazione precedentemente descritta, a parti invertite tra Rossi e Bianchi.

Vediamo invece che succede se, proprio subito dopo che Rossi ha dichiarato che vuol timbrare, anche Bianchi scrive VERO sulla bacheca Bianchi_vuole_timbrare. Allora non può accadere che entrambi vadano nello stato di attesa perché, anche se tentano di scrivere contemporaneamente sulla bacheca che esprime di chi è il turno potranno scrivere solo uno dopo l’altro e alla fine sulla bacheca ci sarà scritto o Bianchi o Rossi. Nel primo caso è Rossi che va in attesa e Bianchi entra nella sezione critica, nel secondo caso, avviene il contrario. Se invece il tentativo di scrittura sulla bacheca del turno, dopo aver dichiarato entrambi la volontà di timbrare non è contemporaneo ma avviene prima (ad esempio) quello di Rossi, allora sarà Rossi a entrare in attesa, ma solo momentaneamente, perché quando poi Bianchi arriva a scrivere sulla bacheca del turno renderà falsa la condizione che bloccava Rossi nello stato di attesa, consentendo a quest’ultimo di entrare nella sua sezione critica mentre lui (Bianchi) va in attesa.

Nel prossimo post esamineremo il terzo importante problema della computazione distribuita, quello del consenso.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione l'11 dicembre 2024.

martedì 10 dicembre 2024

A passeggio con l'informatica #11 – Come fanno più automi a mettersi d’accordo?

di Enrico Nardelli

Come abbiamo introdotto nel post precedente, stiamo considerando il caso di più agenti che devono eseguire collettivamente un’elaborazione. La comunicazione tra di essi in questo contesto avviene mediante lo scambio asincrono di messaggi. Ricordo che lo scambio asincrono è ciò che avviene con la posta elettronica, mentre lo scambio sincrono è il caso di una telefonata, che richiede la disponibilità contemporanea di entrambi gli interlocutori.

Dobbiamo inoltre precisare con esattezza le caratteristiche dell’insieme degli automi e della loro organizzazione. Per rimanere a un livello molto semplice (e rimandando al mio libro La rivoluzione informatica per maggiori dettagli) assumiamo che ogni esecutore sia identificabile tramite un diverso numero intero. Tutti gli automi eseguono lo stesso algoritmo, ma in ogni esecutore l’algoritmo può prendere decisioni diverse in base ai messaggi ricevuti e al suo identificatore.

Un ultimo elemento rilevante da definire è quale sia la struttura della rete di comunicazione disponibile per l’insieme di automi, cioè con quali altri agenti si possono scambiare i messaggi che sono necessari per realizzare il coordinamento. Ad esempio, un esecutore può parlare con tutti gli agenti o solo con un sottoinsieme? Trascurando i casi irrilevanti di automi che non parlano con alcun altro automa, sono possibili diverse scelte, da quelle assolutamente estreme (e quindi in qualche modo poco interessanti) in cui ogni agente parla solo con un altro agente (il caso a sinistra nella figura sotto) oppure in cui ogni agente parla con tutti gli altri agenti (a destra).

Un modello semplice ma comunque non banale di struttura della rete di comunicazione è quello del cosiddetto “anello”, in cui si immagina l’insieme degli agenti disposti a cerchio e ogni agente parla solo con chi gli sta a destra e a sinistra.

Il più semplice problema che si può affrontare, in tema di cooperazione, è quello della scelta di un “comandante” o “direttore”, per eventualmente in futuro guidare l’azione del collettivo.

All’inizio nessuno degli agenti dell’anello è il direttore. La soluzione corretta del problema si ha quando esattamente uno degli agenti è il comandante e lo rimane stabilmente, nel senso che il processo di elaborazione che ha portato alla sua scelta non gli fa più cambiare stato, e questa informazione è nota a tutti.

Un semplice algoritmo, detto di Chang-Roberts, per risolvere questo problema nelle ipotesi che stiamo considerando è fatto nel modo che adesso descriviamo. Ricordiamo che questo algoritmo viene eseguito da ogni agente.

Ogni esecutore inizia l’algoritmo o per sua spontanea decisione o perché gli arriva un messaggio dall’agente alla sua destra. Se un esecutore riceve un messaggio con identificatore minore del suo non fa niente. Se un esecutore riceve un messaggio con un identificatore maggiore del suo lo inoltra all’agente alla sua sinistra. Se un esecutore riceve un messaggio con il suo identificatore si proclama il direttore e lo annuncia all’agente alla sua sinistra. Se un esecutore riceve un messaggio con il risultato dell’elezione del direttore lo inoltra all’agente alla sua sinistra, a meno che non si tratti del suo identificatore. In ogni caso l’esecuzione dell’algoritmo in questo agente termina.

Un esempio di esecuzione nel caso di un insieme di 6 automi è mostrato nella figura più sotto, cui il numero all’interno di ogni cerchietto è l’identificatore e il numero accanto alla freccia rossa è il messaggio che viene inviato.

Nell’esempio, per facilità di illustrazione, tutti gli esecutori iniziano nello stesso momento, ma l’algoritmo è indipendente da questa assunzione. I vari passi della computazione sono mostrati uno alla volta procedendo da sinistra a destra e poi dall’alto in basso. Per ogni esecutore, quello successivo in senso orario nella figura è quello che l’algoritmo considera alla sua sinistra. L’ultima immagine rappresenta sinteticamente il fatto che l’agente 6, avendo ricevuto al passo precedente il messaggio con il suo identificatore, l’ha inoltrato come messaggio di scelta del direttore alla sua sinistra e ha ricevuto il messaggio di scelta del direttore dall’agente alla sua destra.

Possiamo convincerci che l’algoritmo sia corretto osservando che l’identificatore di valore massimo viene inoltrato da tutti gli esecutori fino a raggiungere quello identificato da esso (prime sei immagini), mentre ogni altro identificatore viene prima o poi fermato. Quindi uno solo degli agenti determinerà di essere il direttore e avviserà tutti gli altri (la settima immagine).

Ci possiamo porre il problema di quanti messaggi in tutto siano necessari per terminare questo algoritmo. Rimandando al testo La rivoluzione informatica per una discussione più approfondita, ricordo qui soltanto che, prendendo in considerazione solo il caso pessimo (come discusso nella puntata Ma quanto ci mette quest’algoritmo?), questo si ha quando gli identificatori degli automi sono sempre decrescenti, andando lungo l’anello in senso orario. In tal caso il numero di messaggi necessario è proporzionale a N2. Con un’analisi più sofisticata si può dimostrare che in media il numero di messaggi utilizzati da questo algoritmo è N∙(log N ). Questa è anche la complessità che il miglior algoritmo conosciuto per questo problema (si tratta di quello di Hirschberg-Sinclair) garantisce nel caso pessimo. Tale algoritmo è anche il migliore possibile, dal momento che si è dimostrato che qualunque algoritmo ha bisogno di inviare almeno N∙(log N ) messaggi.

Nel prossimo post affronteremo il secondo dei problemi più importanti che caratterizzano la computazione distribuita, quello della sincronizzazione.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 7 dicembre 2024.

sabato 30 novembre 2024

A passeggio con l'informatica #10 – Come mettere al lavoro più automi

di Enrico Nardelli

Come abbiamo accennato nella tappa n.6 di questo viaggio (Comprendere gli algoritmi non è difficile), l’informatica come disciplina scientifica nasce – da un punto di vista culturale – quando si comincia a considerare la possibilità di eseguire algoritmi in modo meccanico attraverso un automa. Successivamente, però, ci si rende conto che un’elaborazione può essere attuata anche con la partecipazione di più agenti, condizione che nel periodo attuale è evidente anche all’uomo della strada, a causa dell’onnipresenza di Internet. Tale tipo di situazione, denominata in generale “computazione distribuita”, presenta diversi aspetti. Nel corso delle prossime tappe esamineremo tre dei più importanti, che qui introduciamo brevemente.

Un primo aspetto è la cooperazione, che fa riferimento a un insieme di automi che devono effettuare collettivamente un’elaborazione e, quindi, cooperano nel raggiungimento di quest’obiettivo. Un po’ come quando un gruppo di persone deve realizzare un certo compito in collaborazione. Ad esempio, vi può essere una pratica d’ufficio che necessita di controlli su aspetti differenti, ognuno di competenza di un differente responsabile e da svolgere secondo un ordine stabilito. In tal caso si rende necessaria una comunicazione tra i differenti esecutori per coordinare le varie elaborazioni che ognuno svolge.

Un secondo è la sincronizzazione, in cui vi è la necessità di non intralciarsi nell’uso di risorse condivise, senza che necessariamente vi sia una cooperazione. Sempre per rimanere nel contesto dell’approvazione di pratiche d’ufficio, si immagini che ogni responsabile abbia le sue pratiche da approvare, senza doversi coordinare con gli altri per la decisione. Il processo di approvazione richiede però di mettere un timbro particolare su di essa. La particolarità del timbro è che è composto da due parti, ognuna conservata in un differente deposito. È quindi necessario che i vari responsabili si sincronizzino per evitare il caso di un responsabile che, dopo aver prelevato una parte del timbro, si trovi bloccato perché contemporaneamente un altro responsabile ha già prelevato l’altra parte dall’altro deposito.

Un terzo aspetto, il consenso, fa riferimento al fatto che sia le comunicazioni tra i vari agenti, sia il loro comportamento, possono essere soggetti a guasti o errori. Come facciamo quindi ad essere sicuri che le comunicazioni che abbiamo inviato siano effettivamente arrivate? Come essere sicure di aver ricevuto la risposta della controparte? Osserviamo che questo aspetto è estremamente rilevante nelle applicazioni pratiche, dove guasti, temporanei o permanenti, possono normalmente accadere, nonostante tutte le precauzioni che possono essere prese affinché questo non succeda.

Chiariamo infine che, per semplicità di presentazione, esaminiamo solo il caso di agenti fatti tutti nello stesso modo e quindi in grado di eseguire le istruzioni di uno stesso linguaggio. Inoltre assumiamo che essi abbiano tutti lo stesso livello gerarchico, ovvero non c’è uno che comanda e altri che obbediscono, e che eseguano tutti lo stesso algoritmo.

Considereremo quindi questi tre problemi, cooperazione, sincronizzazione e consenso, nei prossimi tre post, e concluderemo il nostro excursus nell’ambito della computazione distribuita con un post dedicato ai protocolli di comunicazione, che sono un ingrediente fondamentale di quella “rete delle reti”, più comunemente conosciuta come Internet, che è stata il fattore fondamentale per la diffusione dei sistemi digitali nella vita quotidiana di ogni persona.

--
Versione originale pubblicata da "Osservatorio sullo Stato digitale" dell'IRPA - Istituto di Ricerche sulla Pubblica Amministrazione il 27 novembre 2024.