Qualche tempo fa ho inventato un teorema. Confesso: la cosa è molto strana. Innanzi tutto, non è che i teoremi vengano in mente così, come se niente fosse. Per giunta io non sono un matematico: il mio rapporto d’amore con la matematica si è interrotto bruscamente quando ho lasciato la ricerca scientifica, più di trentacinque anni fa. Però in questo caso si trattava di un teorema così bello, paffuto, rotondo e facile, che poteva venire in mente anche a uno come me. Per prima cosa vorrei enunciarlo, poi cercherò di parlare delle riflessioni che ne sono seguite.

Partiamo dalla seguente domanda: che cos’è un algoritmo? Quasi tutti lo sanno, ormai: un algoritmo è un procedimento di calcolo. Per essere più precisi: un algoritmo è un procedimento finito, che utilizza un certo linguaggio, e che quando viene eseguito in modo pedissequo trasforma un determinato input in un determinato output. Non importa quale sia il linguaggio: C, java, pascal, quello che volete. Ci sono altri aspetti critici che distinguono un algoritmo dalla lista della spesa, ma le cose importanti, per quello che mi interessa qui, sono due: il linguaggio in cui è scritto qualsiasi algoritmo dispone di un numero finito di simboli, ed è composto da un numero finito di istruzioni. Questo significa che, dato un certo (qualsiasi) linguaggio, gli algoritmi che è possibile scrivere con quel linguaggio sono un’infinità numerabile.

Un esempio di corrispondenza biunivoca

Un insieme è composto da un’infinità numerabile di elementi se è possibile creare una corrispondenza biunivoca tra gli elementi stessi e i numeri interi. Qui scattano alcune delle numerose trappole logiche così affascinanti quando si ha a che fare con gli infiniti. Una corrispondenza biunivoca è una relazione in cui si associa a ogni elemento di un insieme uno e un solo elemento di un altro insieme, in modo tale che a ogni elemento del secondo insieme corrisponda esattamente un elemento del primo. E’ possibile creare una corrispondenza biunivoca tra due insiemi se e solo se essi sono equipotenti (cioè contengono lo stesso numero di elementi). Tradotto per i non matematici: entro in una classe in cui ci sono degli studenti e dei banchi. Se vedo che ci sono dei banchi vuoti, devo concludere che i banchi sono più numerosi degli studenti. Viceversa, se vedo degli studenti in piedi, evidentemente i banchi non bastano e gli studenti sono più numerosi dei banchi. Se non ci sono né banchi vuoti né studenti in piedi, devo concludere che il numero degli studenti è esattamente uguale al numero dei banchi. L’associazione tra gli studenti e i banchi è un esempio di corrispondenza biunivoca. Vorrei notare che la si può realizzare in molti modi. Ad esempio, siccome so che Andrea non fa che chiacchierare con il suo vicino di banco Luigi, obbligo Luigi a cambiare banco e al suo posto metto Daniela. Ho creato una corrispondenza biunivoca diversa, ma in ogni caso non ci sono studenti in piedi o banchi vuoti. In sostanza: la possibilità di creare una corrispondenza biunivoca tra due insiemi sembrerebbe esistere se e soltanto se i due insiemi contengono esattamente lo stesso numero di elementi, e in effetti è così se gli insiemi sono finiti.

Per quello che so, fu Galileo il primo a notare che nel caso di insiemi infiniti la faccenda non è così semplice. Ad esempio: consideriamo l’insieme di tutti gli interi e l’insieme degli interi pari. Posso creare una corrispondenza in cui associo 1 con 2, 2 con 4, 3 con 6, 4 con 8… in generale, ogni numero con il suo doppio. Ogni numero ha un doppio, questo è evidente; d’altra parte ogni doppio può essere diviso per due. In sostanza: la corrispondenza è biunivoca, anche se sembrerebbe proprio che i numeri pari siano meno numerosi di tutti i numeri!

Georg Cantor (1845 – 1918)

Chi si occupò con impressionante intelligenza di questo problema fu un matematico dell’ottocento che si chiamava Georg Cantor. Non posso evidentemente discutere qui i risultati di Cantor. Giusto per riassumere la faccenda: Cantor definì come equipotenti due insiemi infiniti tra i quali è possibile costruire una corrispondenza biunivoca. Nel senso di Cantor, i numeri pari sono equipotenti ai numeri interi. Cantor scoprì che anche le frazioni sono equipotenti ai numeri interi. Si potrebbe sospettare che tutti gli insiemi infiniti siano equipotenti tra loro, ma non è così. Cantor scoprì che i numeri reali sono più numerosi dei numeri interi e delle frazioni, infinitamente più numerosi…

Questo è davvero strano, visto che le frazioni sono un insieme denso (come dicono i matematici). Anche in questo caso, credo che la cosa sia abbastanza semplice da spiegare. Se prendiamo due frazioni, ne esiste sempre un’altra che è intermedia tra le due: basta prendere la loro media. La media di due frazioni è anch’essa una frazione; in sostanza, si direbbe che le frazioni siano infinitamente vicine tra di loro… e quindi, i numeri reali dove stanno? Vorrei notare che il risultato di Cantor è davvero sbalorditivo: i numeri reali sono infinitamente più numerosi delle frazioni, ma non sembrerebbe che ci sia posto per loro. Per arrivare a questa conclusione Cantor utilizzò un metodo detto metodo diagonale. Si tratta di uno dei risultati più brillanti raggiunti dalla matematica di tutti i tempi, eppure è così semplice che basta ricordarsi l’aritmetica delle medie per capirlo. L’idea è la seguente.

Consideriamo solo i numeri reali compresi tra 0  e 1. Si tratta in sostanza di numeri che è possibile esprimere nella forma:

0,281095634…

La dimostrazione “diagonale” di Cantor

Dove le cifre dopo la virgola sono infinite e, nel caso generale, non presentano nessuna regolarità. Adesso facciamo finta che l’insieme di questi numeri sia equipotente ai numeri interi. Se questo è vero, deve essere possibile costruire una tabella composta da infinite righe, una per ogni intero, che nelle sue (infinite) colonne riporta le cifre decimali dei nostri numeri reali compresi tra 0 e 1. Quello che dimostrò Cantor è che esiste certamente almeno un numero reale (nell’intervallo che stiamo considerando) che non è compreso nella tabella, e questo comunque si tenti di costruire la tabella stessa. Trascuriamo lo zero e la virgola, che in questo caso non sono rilevanti. I numeri reali di cui ci stiamo occupando diventano successioni infinite di cifre comprese tra 0 e 9. Adesso consideriamo la diagonale di questa tabella, e costruiamo una successione infinita di cifre decimali con la seguente regola:

la cifra nella posizione N è 7 se quello che appare nella riga N, colonna N è diverso da 7; altrimenti tale cifra è 4.

Avrei potuto usare altri valori, ma questo non è significativo. Quello che importa è che in questo modo è possibile costruire una successione infinita di cifre (dunque un numero reale compreso tra 0 e 1) che è diverso da tutti quelli riportati almeno per l’ennesima cifra, e che quindi non può essere tra quelli elencati nella tabella!

Gli output sono (infinitamente) più numerosi degli algoritmi!

Adesso torniamo agli algoritmi. Ho già detto che essi costituiscono un’infinità numerabile, ed è quindi possibile costruire una tabella con infinite righe che li elenca tutti. Capirlo è semplice: ciascun algoritmo include un numero finito di simboli, che possiamo ordinare in un modo qualsiasi. Giusto per dare concretezza al discorso, immaginiamo che tali simboli siano esattamente 26; a ciascuno di essi associamo una lettera dell’alfabeto inglese, da a a z. A questo punto possiamo cominciare a scrivere gli algoritmi che includono un solo simbolo, ordinati alfabeticamente, poi aggiungiamo quelli che includono due simboli, anch’essi ordinati alfabeticamente, e così via. Per semplificare il discorso, consideriamo solo gli algoritmi che prendono in input un numero intero, e restituiscono un valore logico (vero o falso). In sostanza è come se approvassero o disapprovassero i numeri che diamo loro in pasto. Ad esempio: 1 -> no, 2 -> no, 3 -> sì, 4 -> no, 5 -> no, 6 -> sì… potrebbe essere un algoritmo che restituisce vero solo se l’input è un multiplo di 3. La tabella riporterà, nelle sue infinite colonne, gli output (sì o no) corrispondenti a ciascun numero intero in input. A questo punto possiamo applicare il procedimento diagonale di Cantor: costruiamo un output in cui, alla posizione N, appare se l’algoritmo N, in corrispondenza dell’input N, restituiva no, e viceversa. Si tratta di una successione infinita di sì e di no, del tutto equivalente a quella che restituiscono gli algoritmi della tabella, che però non può corrispondere all’output di nessuno di essi.

Io credo che questa cosa sia nota ai matematici, anche se personalmente non ne avevo mai sentito parlare. Sono convinto che non si possa essere creativi in un campo che non è il proprio; se ci si prova, il risultato sarà sbagliato oppure ovvio. In questo caso sono sicuro che la dimostrazione funziona (perbacco, è la dimostrazione di Cantor!), dunque si tratta per forza di un teorema ovvio. A mio parere, però, le sue implicazioni non sono del tutto banali. In sostanza, quello che il teorema dimostra è che ci sono output che nessun algoritmo potrà mai generare; non solo: tali output sono infinitamente più numerosi degli algoritmi stessi, un oceano sterminato di cui i poveri algoritmi non potranno mai neppure sognare di solcare le acque. Questa cosa, a mio parere, pone dei seri problemi rispetto al tentativo di creare una qualsiasi forma di pensiero artificiale attraverso programmi.

Vorrei chiarire bene la mia posizione. In materia religiosa sono agnostico; in particolare, non credo che esista qualcosa in noi capace di generare la nostra attività mentale, se non il nostro cervello. La relazione tra mente e cervello è davvero molto complicata, ma (ammesso che sia vera la premessa) il cervello è comunque un oggetto fisico, come tale riproducibile (certo, non con la tecnologia di oggi). Supponendo che non vi sia nulla di metafisico nel pensiero, nessuna res cogitans, nessun’anima trascendente, devo concludere che una tecnologia superiore alla nostra sarebbe in grado di costruire un oggetto artificiale che simula il cervello, dunque in grado di pensare: una mente artificiale. Questa mente, tuttavia, non potrebbe funzionare in modo algoritmico, in base al teorema che ho appena enunciato.

Mi si potrebbe obiettare: non lo sai, non lo puoi sapere. Che cosa ti fa pensare che i nostri pensieri (possibili) non siano in realtà limitati come gli output degli algoritmi della tabella? In fondo anche questi output sono infiniti, anche se sono infinitamente meno numerosi di tutti gli output possibili… Per esempio, sarebbe possibile creare un algoritmo in grado di pensare esattamente tutto ciò che ha pensato Einstein; sarebbe molto complicato, ne convengo, ma in fin dei conti Einstein è vissuto per un tempo finito, il numero dei pensieri che ha avuto non può che essere finito: per un algoritmo, un numero finito di output è uno scherzo (si fa per dire). Immaginiamo questo algoritmo meraviglioso che scopre la relatività ristretta e poi la estende fino a creare la relatività generale, che spiega l’effetto fotoelettrico, il moto browniano, che polemizza con (l’algoritmo) Niels Bohr e nel corso della polemica scopre l’entanglement quantistico… La sola idea mi riempie di ammirazione, ma che cosa succederebbe se chiedessi all’algoritmo che cosa avrebbe scoperto Einstein se fosse vissuto dieci anni di più? Magari avrebbe trovato l’idea magica in grado di unificare tutta la fisica, ma questo l’algoritmo non può saperlo. Quello che intendo dire è che la finitezza degli output che un cervello umano può produrre non è sufficiente per dire che esiste un algoritmo in grado di riprodurre tali output: è vero, ma solo dopo che uno è morto; finché siamo vivi, abbiamo sempre la possibilità di stupire tutti gli algoritmi del mondo. Ne dubitate? Ve ne ho appena dato la prova. Chi, tra quelli che mi conoscono, avrebbe mai immaginato che sarei stato capace di inventare un teorema? (A proposito: si dice inventare un teorema o scoprire un teorema?)