A passeggio con l’informatica – 03. Automa e linguaggio (parte prima)

Quarta puntata del nostro viaggio

Nel post precedente abbiamo parlato di come rappresentare i dati. Una volta stabilita la rappresentazione va specificata la sequenza di istruzioni che vogliamo far compiere meccanicamente all’automa (o esecutore o agente) per eseguire l’elaborazione desiderata. Cos’è l’automa? Il termine è preso dalla lingua greca ed è la radice di termini quali “automatico” e “automatismo” che indicano appunto ciò che viene eseguito senza riflessione, senza coscienza e senza possibilità di deviare dalla strada tracciata. Come la rappresentazione digitale in sé non è un fatto recente, così non lo è l’automazione. Ricordiamo gli automi meccanici, che in Occidente sono stati ampiamenti studiati nell’età ellenistica, che copre approssimativamente gli ultimi trecento anni prima di Cristo. Da molti secoli l’umanità è in grado di costruire macchine per fare automaticamente dei calcoli (dette “macchine calcolatrici”) e quelle per automatizzare i calcoli aritmetici sono state sviluppate con una certa regolarità almeno a partire dal Seicento.

Per poter definire la sequenza di istruzioni (chiamata anche procedura o programma) da far eseguire all’automa dobbiamo però sapere quali sono le specifiche istruzioni che esso è in grado di eseguire, cioè le specifiche operazioni che è in grado di compiere. Un aspetto fondamentale da tener presente è che esse sono strettamente legate alla natura dell’esecutore stesso. Ecco quindi che definire l’automa di riferimento per le elaborazioni, cioè specificare l’insieme delle istruzioni che tale agente è in grado di eseguire e illustrare esattamente quali operazioni vengono compiute per eseguirle e chiarire in ogni dettaglio come questo possa essere ottenuto meccanicamente, è un passo preliminare alla concretizzazione di ogni processo di elaborazione delle rappresentazioni. Tale definizione va effettuata insieme alla definizione del linguaggio, chiamato linguaggio di programmazione, che verrà poi usato per descrivere, di volta in volta, le specifiche elaborazioni che l’esecutore dovrà attuare. Si può quindi dire che la definizione dell’automa e del suo linguaggio di programmazione sono due lati della stessa medaglia: non ha senso dotare un automa di un’operazione se non c’è un’istruzione nel relativo linguaggio che è in grado di invocarla e simmetricamente non ha senso inserire nel linguaggio un’istruzione che l’automa non è in grado di eseguire.

La caratterizzazione precisa di cosa costituisce un automa è un aspetto fondamentale dell’informatica, su cui la ricerca non ha ancora terminato le proprie indagini. Bisogna inoltre aggiungere che non tutti gli automi sono uguali, cioè non hanno tutti lo stesso “potere computazionale”. In altre parole non sono tutti in grado di effettuare le stesse elaborazioni. Va però chiarito subito che tutti i calcolatori elettronici oggi effettivamente usati sono basati su un modello di automa che è il più potente definibile.

Un automa di tipo molto semplice è l’automa a stati finiti, che può realizzare computazioni “ricordando” cosa è successo in passato. Questa memoria del passato si chiama “stato” e costituisce un concetto abbastanza intuitivo.

Ecco un esempio che è in grado di eseguire l’addizione tra numeri binari. Ricordiamo brevemente che nella rappresentazione in binario i numeri sono scritti utilizzando solo le due cifre “0” e “1” (da cui l’aggettivo “binario”).

Una cifra nella posizione meno significativa (la prima da destra) rappresenta direttamente uno dei due possibili valori “zero” o “uno”.

Il valore rappresentato da una cifra nella seconda posizione da destra si ottiene moltiplicando la cifra per due, ovvero per il numero di possibili valori rappresentati dalla cifra alla sua destra.

Il valore rappresentato da una cifra nella terza posizione da destra deve essere moltiplicato per quattro, ovvero per il numero di possibili valori rappresentati dalle due cifre nelle due posizioni alla sua destra. Così facendo si arriva, per esempio, a rappresentare il numero scritto in decimale come “20” con la rappresentazione binaria “10100”, dal momento che 1∙16 + 0∙8 + 1∙4 + 0∙2 + 0∙1 = 20.

L’addizione in binario funziona analogamente a quella in decimale tranne che, in binario, quando sommando due cifre si raggiunge (o si supera) il due, allora “si scrive 0 (oppure 1) con riporto 1”. Nella tabella viene rappresentato quello che avviene indicando tutte le possibili situazioni di cifre da sommare e con presenza o meno del riporto.

Possiamo adesso definire un automa a stati finiti che è in grado di sommare numeri binari di qualunque lunghezza. Per semplicità assumiamo che siano rappresentati con lo stesso numero di cifre. Forniamo all’automa i numeri binari una cifra per volta, in coppia, una cifra per ognuno dei due numeri, a partire dalla coppia di cifre più a destra. Ogni coppia di cifre fornite in ingresso (la coppia scritta sugli archi nella figura sotto) causa il passaggio da uno stato a un altro rappresentato dalla freccia su cui la coppia compare (gli stati sono rappresentati da cerchi e il “passaggio di stato” può avvenire anche dallo stato verso sé stesso) e produce in uscita una cifra del risultato (scritta sugli archi dopo la barra). Lo stato R0 rappresenta la situazione in cui la precedente addizione di due cifre ha prodotto un riporto di 0 e lo stato R1 rappresenta la situazione simmetrica con un riporto di 1. L’automa, rappresentato nella figura sotto, inizia nello stato R0, dal momento che all’inizio dell’addizione non c’è alcun riporto. Le 4 frecce uscenti da R0 rappresentano i 4 passaggi di stato determinati dalle 4 possibili coppie di cifre in ingresso, di cui uno solo determina un reale cambiamento dello stato da R0 a R1. Una volta effettuato il passaggio di stato corrispondente alla coppia in ingresso, questa viene eliminata e si prende in considerazione la coppia successiva. Quando non vi sono più coppie in ingresso l’addizione è terminata e sono state prodotte in uscita tutte le cifre del risultato.

Se il lettore avrà la pazienza di usare tale automa per effettuare la somma tra i due numeri binari 0101 (cioè sette) e 0011 (cioè tre) vedrà che con esso si calcola automaticamente, meccanicamente il risultato 1010 (cioè dieci).

Esistono però dei casi nei quali l’automa a stati finiti non è in grado di produrre un risultato, ovvero non ha un sufficiente potere computazionale. Un esempio semplice di una classe di problemi di questo genere è quella in cui l’automa può ricevere una sequenza arbitrariamente lunga di cifre, in cui appaiono solo “1” o “2”, usando “0” per indicare che la sequenza è finita, e in cui è necessario contare quanti “2” sono presenti nella specifica sequenza che è arrivata. Poiché non possiamo sapere a priori quanti “2” conterrà lo specifico esempio, non possiamo costruire l’automa che sia in grado risolvere qualunque istanza di un problema di questa classe.

Vedremo nella prossima puntata un tipo di automa che è il più generale e potente possibile e che è alla base di tutti i dispositivi informatici (PC, tablet, smartphone) che usiamo. Possiamo dunque star tranquilli che tutti i nostri dispositivi informatici sono sufficientemente potenti da un punto di vista computazionale, anche se possono essere più o meno veloci da un punto di vista tecnologico.


( I post di questa serie sono basati sul libro dell’Autore La rivoluzione informatica: conoscenza, consapevolezza e potere nella società digitale, al quale si rimanda per approfondimenti. I lettori interessati al tema possono anche dialogare con l’Autore, su questo blog interdisciplinare. )