Lezione 06 · Algebra booleana¶
Cosa impari
- cos'è una variabile booleana e perché il calcolatore ragiona con 0 e 1;
- gli operatori AND, OR, NOT (e NAND, NOR, XOR, XNOR) con le loro tabelle di verità;
- le proprietà dell'algebra di Boole, comprese le leggi di De Morgan;
- a costruire la tabella di verità di un'espressione rispettando la precedenza degli operatori;
- a riconoscere espressioni equivalenti, complementari e duali.
Un calcolatore deve saper fare i conti, ma anche ragionare: decidere se una condizione è vera o falsa e dedurne nuove verità. L'algebra di Boole è lo strumento matematico che rende possibile questo ragionamento automatico. È la base dei circuiti del processore e delle condizioni che scrivi negli if di Python.
Il ragionamento logico¶
La logica studia le regole del ragionamento. Un esempio classico è il sillogismo di Aristotele: da due premesse si deduce una conclusione.
Tutti gli uomini sono mortali, tutti i Greci sono uomini, quindi tutti i Greci sono mortali.
Lo schema è: se A implica B, e B implica C, allora A implica C. Anche il ragionamento matematico funziona così: se X > Y e Y > Z, allora X > Z.
Ragionare significa due cose:
- elaborare dei fatti (verità) sul mondo;
- dedurre nuove verità applicando regole logiche, cioè degli algoritmi.
L'aritmetica è facile da automatizzare (esistevano già calcolatrici meccaniche come la Pascalina). Il ragionamento logico è più difficile. Nel 1847 George Boole notò che anche il ragionamento sui fatti si può scrivere come un'algebra, con operazioni e regole simili a quelle dei numeri.
Dai fatti agli insiemi¶
I fatti si esprimono con predicati, cioè frasi vere o false:
- "Marco è un mammifero" → vero (Marco appartiene all'insieme dei mammiferi);
- "Marco è un cavallo" → falso.
Indichiamo con:
- Ø l'insieme vuoto: i fatti che non esistono, cioè le cose false;
- 1 l'insieme totale (l'"universo"): i fatti veri;
- + l'unione di insiemi (⋃);
- * l'intersezione di insiemi (⋂).
| Unione (+) | Intersezione (*) |
|---|---|
| Ø + Ø = Ø | Ø * Ø = Ø |
| Ø + 1 = 1 | Ø * 1 = Ø |
| 1 + Ø = 1 | 1 * Ø = Ø |
| 1 + 1 = 1 | 1 * 1 = 1 |
Se leggi Ø come 0, queste operazioni sembrano la somma e il prodotto dei numeri. C'è una sola eccezione: 1 + 1 = 1 (non 2). La conclusione è importante: la logica si può trattare come un'algebra, e quindi si può automatizzare.
Variabili booleane¶
Un'algebra booleana lavora su variabili booleane (o logiche), che possono assumere solo due valori:
| Valore | Significato |
|---|---|
| 1 | vero, true, on, chiuso |
| 0 | falso, false, off, aperto |
È adatta a descrivere eventi binari: una lampadina è accesa (1) o spenta (0). In Python conosci già il tipo bool, con i valori True e False.
Definizione di algebra di Boole¶
Prendiamo un insieme V che contiene almeno gli elementi 0 e 1. È un'algebra di Boole se su V sono definite tre operazioni:
- somma logica
+(operazione binaria: prende due elementi e ne restituisce uno); - prodotto logico
•(operazione binaria); - complemento o inversione
¬(operazione unaria: prende un solo elemento).
e se valgono questi assiomi:
| Assioma | Per la somma | Per il prodotto |
|---|---|---|
| commutativa | x + y = y + x | x • y = y • x |
| distributiva | x • (y + z) = x • y + x • z | x + (y • z) = (x + y) • (x + z) |
| elemento neutro | x + 0 = x | x • 1 = x |
| complemento | x + ¬x = 1 | x • ¬x = 0 |
Una distributiva \"strana\"
La seconda proprietà distributiva, x + (y • z) = (x + y) • (x + z), non vale con i numeri normali. Nell'algebra di Boole invece è vera: verificala con la tabella di verità negli esercizi qui sotto.
Altre proprietà¶
Dagli assiomi si ricavano altre proprietà utili per semplificare le espressioni.
| Proprietà | Per la somma | Per il prodotto |
|---|---|---|
| associativa | x + (y + z) = (x + y) + z | x • (y • z) = (x • y) • z |
| idempotenza | x + x = x | x • x = x |
| minimo e massimo | x + 1 = 1 | x • 0 = 0 |
| assorbimento | x + (x • y) = x | x • (x + y) = x |
| De Morgan | ¬(x + y) = ¬x • ¬y | ¬(x • y) = ¬x + ¬y |
Ad esempio l'assorbimento della somma si dimostra così: x + x • y = x • 1 + x • y = x • (1 + y) = x • 1 = x.
Le leggi di De Morgan¶
Le leggi di De Morgan dicono come si nega una somma o un prodotto: si negano i singoli termini e si scambia + con •. Verifichiamo la prima con la tabella di verità:
| x | y | x + y | ¬(x + y) | ¬x | ¬y | ¬x • ¬y |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 0 | 1 | 0 | 0 |
| 1 | 0 | 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 1 | 0 | 0 | 0 | 0 |
Le due colonne in grassetto sono uguali riga per riga: le due espressioni sono equivalenti.
De Morgan in Python
not (a or b) è uguale a (not a) and (not b). Ti serve quando vuoi negare una condizione in un if: "non (minore di 20 o maggiore di 40)" diventa "maggiore o uguale a 20 e minore o uguale a 40".
Diverse algebre di Boole¶
La stessa struttura si può interpretare in modi diversi: algebra binaria, algebra degli insiemi, algebra delle proposizioni, algebra delle reti (circuiti).
| Algebra di Boole | Algebra delle proposizioni | Algebra binaria |
|---|---|---|
| insieme V = | {falso, vero} | {0, 1} |
somma + |
disgiunzione OR | somma logica OR |
prodotto • |
congiunzione AND | prodotto logico AND |
complemento ¬ |
negazione NOT | negazione NOT |
| minimo 0 | contraddizione (falso) | zero |
| massimo 1 | tautologia (vero) | uno |
Le proposizioni sono frasi che possono essere vere o false. Esempio:
- (a) "In questo momento sta piovendo";
- (b) "In questo momento non sta piovendo": b = NOT a;
- © "Sta piovendo oppure non sta piovendo": c = a OR (NOT a) = vero sempre. È una tautologia;
- (d) "Sta piovendo e non sta piovendo": d = a AND (NOT a) = falso sempre. È una contraddizione.
Gli operatori logici¶
Gli operatori (o connettivi) logici combinano variabili booleane e restituiscono ancora un valore booleano.
AND, OR, NOT¶
AND (congiunzione, simboli • o ∧, spesso sottinteso: ab = a • b): è vero se e solo se entrambi gli operandi sono veri.
OR (disgiunzione o inclusione, simboli + o ∨): è vero se almeno uno degli operandi è vero.
NOT (negazione, simbolo ¬): restituisce il valore opposto.
| a | b | a ∧ b (AND) | a ∨ b (OR) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 |
| a | ¬a (NOT) |
|---|---|
| 0 | 1 |
| 1 | 0 |
Non confondere i simboli
• non è il prodotto aritmetico e + non è la somma aritmetica: in logica 1 + 1 = 1.
NAND, NOR, XOR, XNOR¶
| a | b | NAND = ¬(a ∧ b) | NOR = ¬(a ∨ b) | XOR | XNOR |
|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | 0 | 1 |
| 0 | 1 | 1 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 | 0 | 1 |
- NAND e NOR sono AND e OR seguiti da NOT.
- XOR (OR esclusivo) è vero quando gli operandi sono diversi: "o l'uno o l'altro, ma non entrambi".
- XNOR è vero quando gli operandi sono uguali.
Operatori bit a bit¶
Gli stessi operatori si possono applicare a due stringhe di bit, posizione per posizione (in inglese bitwise). Ogni operatore corrisponde a una porta logica, il componente base dei circuiti digitali.
Controlla colonna per colonna: nell'AND esce 1 solo dove entrambi i bit sono 1; nell'OR esce 0 solo dove entrambi sono 0; il NOT inverte ogni bit.
Tool · Operatori bit a bit
Scrivi due parole di bit e confronta AND, OR, XOR, NAND, NOR e NOT colonna per colonna.
Funzioni booleane e tabella di verità¶
Una funzione booleana F(x₁, …, xₙ) prende n variabili booleane e restituisce 0 o 1. Il modo più completo per descriverla è la tabella di verità: elenca tutte le combinazioni dei valori in ingresso e il valore della funzione per ciascuna.
Quante righe?
Con n variabili ci sono 2ⁿ combinazioni, quindi 2ⁿ righe: 2 variabili → 4 righe, 3 variabili → 8 righe, 4 variabili → 16 righe.
Esempio: superare l'esame¶
Uno studente supera l'esame se vale almeno una di queste condizioni:
- supera l'esonero e la prova orale;
- è sufficiente allo scritto di un appello regolare e supera la prova orale.
Assegniamo una variabile a ogni evento: a = esonero superato, b = scritto regolare superato, c = orale superato. Con 3 variabili ci sono 2³ = 8 combinazioni. La funzione "superamento esame" è S(a, b, c) = (a + b) • c:
| a | b | c | S |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 (–) |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 1 |
S = 1 solo se lo studente supera l'orale e almeno una tra esonero e scritto.
Valore don't care
La riga a = 0, b = 0, c = 1 in realtà non può capitare: all'orale si accede solo dopo aver superato una prova scritta. Per questa combinazione il valore di S si può lasciare non specificato. Si chiama don't care e si indica con il simbolo –.
Espressioni logiche¶
Una funzione booleana si può scrivere anche come espressione logica, combinando con gli operatori:
- variabili booleane;
- le costanti 0 (falso) e 1 (vero);
- altre espressioni.
Esempi: (a + b) • c, oppure ab + c(d + ae).
Insiemi funzionalmente completi¶
AND, OR e NOT formano un insieme funzionalmente completo: con questi tre operatori si può scrivere qualunque funzione logica. Grazie alle leggi di De Morgan bastano anche solo {AND, NOT} oppure {OR, NOT}. Ad esempio a + b = ¬(¬a • ¬b).
Precedenza degli operatori¶
Come in aritmetica la moltiplicazione viene prima della somma, anche in logica c'è un ordine:
- le parentesi;
- NOT (¬);
- AND (∧, •);
- OR (∨, +).
Python usa lo stesso ordine: not prima di and, and prima di or.
Dall'espressione alla tabella di verità¶
Prendiamo F(a, b, c) = a ∧ b ∨ ¬c. Si procede così:
- si contano le variabili diverse (qui 3: a, b, c);
- si scrivono tutte le 2³ = 8 combinazioni;
- si aggiunge una colonna per ogni operazione, nell'ordine di precedenza: prima ¬c, poi a ∧ b, infine l'OR tra le due.
| a | b | c | a ∧ b | ¬c | F = (a ∧ b) ∨ ¬c |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 | 1 |
| 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 1 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 | 1 |
Puoi far costruire la stessa tabella a Python. Tre cicli for annidati generano le 8 combinazioni; int() trasforma True/False in 1/0.
print('a b c | a∧b ¬c | F')
for a in range(2):
for b in range(2):
for c in range(2):
a_e_b = int(a and b)
non_c = int(not c)
F = int(a_e_b or non_c)
print(a, b, c, '|', a_e_b, ' ', non_c, ' |', F)
Prova a cambiare la riga di F con un'altra espressione, ad esempio int((a or b) and c): ottieni la tabella dell'esame.
Tool · Tabella di verità
Scrivi un'espressione e il tool costruisce la tabella con una colonna per ogni operazione, nell'ordine di precedenza. Con Confronta con verifichi se due espressioni sono equivalenti o complementari: prova le leggi di De Morgan, NOT (a AND b) contro NOT a OR NOT b.
Equivalenti, complementari, duali¶
Espressioni equivalenti. F1 e F2 sono equivalenti se hanno lo stesso valore per ogni combinazione degli ingressi: ad ingressi uguali, uscite uguali. Esempio: x + ¬x • y e x + y.
| x | y | x + ¬x • y | x + y |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 |
Espressioni complementari. F1 e F2 sono complementari se hanno valori opposti per ogni combinazione: dove una vale 1 l'altra vale 0, e viceversa. Esempio: F1 = ab e F2 = a NAND b.
Espressioni duali. La duale di un'espressione si ottiene scambiando + con • e 0 con 1 (le variabili e le negazioni restano come sono). Esempio: la duale di x + 0 = x è x • 1 = x. Per questo nelle tabelle delle proprietà ogni regola per la somma ha una "gemella" per il prodotto.
Duale non vuol dire complementare
La duale di a + b è a • b, che non è il suo complemento: con a = 1, b = 0 vale a + b = 1 e a • b = 0, ma con a = b = 1 valgono entrambe 1.
Errori frequenti negli esercizi¶
| Errore | Cosa succede | Come si corregge |
|---|---|---|
| scrivere 1 + 1 = 2 o 1 + 1 = 0 | risultato sbagliato | in logica (OR) 1 + 1 = 1 |
| dimenticare righe nella tabella | tabella incompleta | con n variabili servono 2ⁿ righe: elencale in ordine, come numeri binari 000, 001, 010, … |
| calcolare a ∧ b ∨ ¬c come a ∧ (b ∨ ¬c) | colonna F sbagliata | prima NOT, poi AND, poi OR; usa colonne intermedie |
| De Morgan senza scambiare gli operatori: ¬(x + y) = ¬x + ¬y | espressione non equivalente | nega i termini e scambia + con • |
| confondere OR e XOR | errore sulla riga 1, 1 | OR(1,1) = 1, XOR(1,1) = 0 |
Esercizi¶
Esercizio 1 · Operazioni bit a bit. Date le stringhe A = 10110010 e B = 01100111, calcola A AND B, A OR B e NOT A.
Soluzione
Verifica con Python, confrontando i caratteri uno alla volta:
Esercizio 2 · Tabella di verità. Costruisci la tabella di verità di F(a, b, c) = (a ∨ ¬b) ∧ (b ∨ c), con le colonne intermedie. Per quante combinazioni F vale 1?
Soluzione
| a | b | c | ¬b | a ∨ ¬b | b ∨ c | F |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 0 | 0 | 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 0 | 0 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 | 0 | 0 |
| 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 0 | 0 | 1 | 1 | 1 |
| 1 | 1 | 1 | 0 | 1 | 1 | 1 |
F vale 1 in 4 combinazioni.
Esercizio 3 · Dal testo alla funzione. Il cancello di un garage si apre (A = 1) se il proprietario preme il telecomando (t) e il codice del telecomando è valido (k), oppure se viene premuto il pulsante di emergenza (e). Scrivi l'espressione logica di A, costruisci la tabella di verità e verifica con la seconda distributiva che A = (t + e) • (k + e).
Soluzione
A(t, k, e) = t • k + e
| t | k | e | t • k | A |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 1 |
Il cancello si apre in 5 combinazioni su 8. Per la seconda proprietà distributiva, e + (t • k) = (e + t) • (e + k), cioè (t + e) • (k + e) per la commutativa. Verifica che le due colonne coincidono: