Calcolare gli assegnamenti

Ieri sera alla riunione del Milano XP User Group abbiamo parlato di come “calcolare” gli assegnamenti, ovvero, come fare in modo che uno statement conservi un invariante e allo stesso tempo faccia progresso verso la fine del loop. Ad esempio, supponiamo di voler calcolare una tabella di quadrati, con la limitazione che non possiamo usare la moltiplicazione. (Perché no? Magari perché sul nostro processore la moltiplicazione è lenta). Abbiamo due variabili s e n che soddisfano l’invariante s = n2. Vogliamo incrementare n, e conservare l’invariante. In altre parole, vogliamo trovare un’espressione E che soddisfi

{ s = n2 } s, n := E, n+1 { s = n2 }

In pratica questa è un’equazione in cui l’incognita E è l’espressione che manca per completare il programma

  
  while n != N do
     s, n := E, n+1
     println "il quadrato di " n " è " s
  end

L’obiettivo è essere in grado di calcolare l’espressione E che mi serve, senza doverci “pensare”. Qual’è allora la procedura? Per dimostrare

{ P } x := E { Q }

devo dimostrare che P implica Q[x:=E], dove Q[x:=E] significa sostituire x con E all’interno di Q. Nel nostro caso:

   s = n2[s, n := E, n+1]
sse // applico la sostituzione
   E = (n+1)2
sse // svolgo il quadrato
   E = n2 + 2n + 1
sse // sfrutto l’invariante
   E = s + 2n + 1
sse // le moltiplicazioni sono vietate
   E = s + n + n + 1

Voilà: ho dimostrato che s=n2 implica s=n2[s, n := E, n+1] se scelgo E=s+n+n+1. Il programma desiderato è dunque

  
  while n != N do
     s, n := s+n+n+1, n+1
     println "il quadrato di " n " è " s
  end

Per saperne di più:

6 Responses to “Calcolare gli assegnamenti”

  1. Antonio Ganci Says:

    Interessante articolo, complimenti.
    Per renderlo più leggibile cambierei la notazione dell’assegnamento da:
    s, n := E, n + 1 in
    s := E
    n := n + 1
    (stessa cosa nella notazione matematica) lo rende IMHO più leggibile, tra l’altro lo stesso Astrachan dice che uno dei motivi per cui è poco diffuso l’uso degli invarianti è dovuto alla notazione matematica non molto chiara.

  2. matteo Says:

    Ma in linguaggi come Ruby l’assegnamento simultaneo esiste e si usa:

    x, y = y, x

    al posto di

    temp = x
    x = y
    y = temp

    Il fatto è che non tutti gli assegnamenti si possono eseguire in un ordine arbitrario senza conseguenze…

  3. Franco Lombardo Says:

    Matteo, alla tua affermazione In linguaggi come Ruby l’assegnamento simultaneo
    esiste e si usa
    vorrei rispondere:
    è anche per questo che la complessità di Ruby è elevata ed alcuni programmatori,
    come me, si rifiutano di utilizzarlo.
    Perché l’assegnamento simultaneo alza la complessità? A mio avviso perché il
    cervello umano, almeno il mio, è una macchina
    fondamentalmente sequenziale.

    Nel tuo esempio, quando applichi la prima sostituzione, giungi alla formula
    E=(n+1)2. Qui l’assegnamento simultaneo potrebbe
    disorientare per un attimo chi ti sta seguendo. Ci si potrebbe infatti chiedere
    se n a questo punto sia già stato incrementato oppure no.

    A mio parere l’esposizione sarebbe molto più comprensibile se partisse da
    {s=n2} s:=E {s=(n+1)2}

    A suffragare la mia convinzione che l’assegnamento simultaneo alzi, inutilmente,
    la complessità dell’argomento, penso possa esserci anche una considerazione di tipo teorico.
    Su questo terreno, però, non mi trovo a mio agio e probabilmente
    sto per dire delle grosse inesattezze: so che saprai correggimi se dovessi sbagliare.
    A dimostrazione della complessità dell’assegnamento simultaneo, dicevo, sta il
    fatto che la sua semantica non può essere compresa dall’insieme originale di assiomi
    proposti da Hoare nel suo lavoro originale,
    ma richiede, se non erro, l’introduzione di un nuovo schema di assiomi:

    {P(x0/E0, x1/E1,…,xn/En)}
    x0, x1,…,xn := E0, E1,…,En
    {P(x0, x1,…,xn)}

    Citerei quindi lo stesso Hoare. It seems likely that a language which can
    be described by a few “self-evident” axioms […] will be preferable to a language
    with many obscure axioms.
    Non che questo nuovo assioma sia particolarmente oscuro,
    però è comunque un assioma in più.

    Cambiando parzialmente argomento, nella riunione dell’XPUG Milano chiedevi suggerimenti per
    accostare la logica di Hoare ai metodi agili. Qualcosa si può trovare ancora nella
    già citata pubblicazione di Hoare, dove l’autore propugna l’adozione della verifica formale
    di correttezza dei programmi sia per alzare la qualità del software, sia per fornire una forma
    di documentazione automatica del codice. E’ quindi evidente l’analogia tra la logica di
    Hoare e la pratica dei test unitari.

  4. matteo Says:

    Ciao Franco, grazie per la risposta.

    La mia risposta di prima era troppo sbrigativa. Il fatto è che non è semplice spiegare questa tecnica in poche righe. Per ridurre al minimo il numero di regole da imparare, ho usato l’assegnamento simultaneo; altrimenti se usi la sequenza

    s := E ; n := n + 1

    ti tocca avere una regola per l’assegnamento e una per la sequenza.

    Lo schema di assiomi dell’assegnamento simultaneo è in realtà una generalizzazione di quello per l’assegnamento singolo. Devi solo fare il passaggio fra “sostituire una variabile con un espressione”, a “sostituire un vettore di variabili con le corrispondenti espressioni.”

    Non sono sicuro di capire perché trovi complicato l’assegnamento simultaneo; considera ad esempio il problema di scambiare il valore di due variabili x e y. A me sembra che la sequenza

    temp := x; x := y; y := temp

    sia più difficile da scrivere e da leggere di

    x,y := y,x

    Sono d’accordo con le tue considerazioni sull’utilità della logica.

  5. Franco Lombardo Says:

    Matteo, anche io sono stato forse troppo sbrigativo nel mio intervento. Quel che intendevo dire è che l’assegnamento simultaneo complica inutilmente quell’esempio, e io penso anche molti altri, mentre ovviamente rende più semplice lo scambio di valori tra variabili. Personalmente ritengo più comprensibili i due assiomi dell’assegnamento e della sequenza che l’assioma dell’assegnamento simultaneo, proprio per la già citata conformazione sequenziale del mio cervello (forse bacato).
    Tu dici che l’assioma dell’assegnamento simultaneo è una semplice generalizzazione di quello dell’assegnamento singolo. Io ho il sospetto che un logico potrebbe dimostrare l’indipendenza dei due assiomi, e quindi la sostanziale diversità tra essi. Ma questo è solo una mia ipotesi.

  6. Franco Lombardo Says:

    Matteo,
    mi sono reso conto di aver detto una grossa stupidata :-(
    Suppongo che dagli assiomi originali di Hoare non sia derivabile l’assioma dell’assegnamento multiplo. Ovviamente, però, prendendo per valido l’assioma dell’assegnamento multiplo si ha come caso particolare l’assegnamento semplice.

Leave a Reply