• Non ci sono risultati.

Ragionamenti su di un algoritmo

N/A
N/A
Protected

Academic year: 2022

Condividi "Ragionamenti su di un algoritmo"

Copied!
55
0
0

Testo completo

(1)

Specifica, progetto e verifica della correttezza di algoritmi

iterativi

Il metodo delle asserzioni

(2)

Ragionamenti su di un algoritmo

Ragionare sulla specifica di un algoritmo data con pre e post-condizioni serve a:

• (a posteriori) verificare la correttezza dell’algoritmo

• (a priori) costruire un algoritmo, a partire

da un’idea circa la soluzione, in modo che

sia corretto

(3)

Il metodo delle asserzioni (Floyd)

Divisione (n, m) Pre. n ≥ 0, m > 0

Post. ritorna q, r t.c. n = m q + r, 0 ≤ r < m r ← n

q ← 0

while r ≥ m do

r ← r − m q ← q + 1 { n = m q + r, 0 ≤ r }

{ n = m (q+1) + r − m, 0 ≤ r − m}

Asserzioni:

descrivono relazioni tra i valori delle

variabili, che devono valere

quando il controllo

raggiunge un certo

(4)

Le triple di Hoare

• Un comando ha la forma

C ::= x ← E | C ; C | if B then C |

if B then C else C | while B do C |

• Se ϕ e ψ sono asserzioni allora

ϕ C ψ ⇔ se i valori delle variabili soddisfano

ϕ prima di C e C termina, allora soddisfano ψ dopo C

tripla

(5)

Le triple di Hoare

Le triple di Hoare sono espressioni della logica formale, ma voi potete usare

asserzioni informali, purché

non ambigue!!!

(6)

Asserzioni per gli assegnamenti

{ x + ∆ > 0 } x ← x + ∆ { x > 0 }

{ ϕ (E)} (E può contenere x) x ← E

{ ϕ (x)}

{ ϕ ( E ) } x E { ϕ ( x ) } Assioma

(7)

Asserzioni per le sequenze

{y ≥ z}

y ← y – z {y ≥ 0}

x ← y {x ≥ 0}

{ ϕ } C 1

{ χ } (oppure χ′ se χ ⇒ χ′ ) C 2

{ ψ }

} {

; } {

} { }

{ } { }

{

1 2

ψ ϕ

ψ χ

χ ϕ

C C

C C

} { } {

} { } {

ψ ϕ

ψ ψ

ψ ϕ

ϕ ϕ

C

C ′ ′ ⇒

⇒ ′

premesse

(8)

Asserzioni per la selezione

if x ≥ 0 then

z ← x {z = |x|}

else {x < 0}

z ← − x {z = |x|}

{z = |x|}

{ ϕ }

if B then { ϕ ∧ B}

C 1 { ψ } else { ϕ ∧ ¬ B}

C 2 { ψ } { ψ }

} {

else then

if } {

} {

} {

} {

} {

2 1

2

1 ψ

ϕ

ψ ϕ

ψ ϕ

C C

B

C B

C

B ∧ ¬

(9)

Asserzioni per le iterazioni

while y > 0 do

{ ??????? } z ← z + x 2 y ← y − 1

Cosa mettere in un punto

attraversato tante

volte?

(10)

Asserzioni per le iterazioni

{n = m ⋅ q + r, 0 r}

while r ≥ m do

{n = m ⋅ (q+1) + r – m, 0 r – m}

r ← r − m q ← q + 1

{n = m ⋅ q + r, 0 r < m}

Qualcosa che, pur cambiando i valori delle variabili, resti

sempre vero!

(11)

Asserzioni per le iterazioni

{n = m ⋅ q + r ∧ 0 r}

while r ≥ m do

{n = m⋅(q+1) + r – m ∧ 0 r ∧ r ≥ m}

r ← r − m q ← q + 1

{n = m ⋅ q + r ∧ 0 r ∧ r < m }

{ ϕ }

while B do

{ ϕ ∧ B}

C { ϕ } { ϕ ∧ ¬ B}

} {

} {

} { } {

B C

do B while

C B

¬

ϕ ϕ

ϕ ϕ

invariante

(12)

Gli invarianti di ciclo

invariante: asserzione vera prima di ogni esecuzione del corpo dell’iterazione

• l’invariante deve essere vero anche prima di entrare nel ciclo, dopo ogni esecuzione del corpo, all’uscita dal ciclo

L’ invariante è unico?

(13)

Gli invarianti di ciclo

• Un ciclo ha molti (infiniti) invarianti, per lo più triviali:

{0 = 0} è invariante di ogni ciclo

Qual è allora quello che mi

serve?

(14)

Gli invarianti di ciclo

• Un invariante è interessante se fa capire cosa avrà fatto il ciclo dopo la terminazione

• Quindi occorre che implichi la post-condizione del ciclo che desidero dimostrare

• A posteriori, trovare un invariante senza conoscere l’idea su cui si basa l’algoritmo è una strada in

salita!

(15)

(Ri)-costruire un algoritmo

• La via maestra per trovare un invariante: partire dall’idea su cui si basa l’algoritmo e ricostruirlo

Molto spesso l’invariante non è che una formulazione

precisa di quest’idea

(16)

Ricerca binaria

1. Definisci il problema

• Pre-condizioni: il vettore è ordinato

• Input: il valore cercato è 25

• Post-condizioni: ritorna l’indice del valore cercato (se presente).

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

20

1 8

(17)

Ricerca binaria

2. Individua l’invariante, pensando alla generica iterazione:

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

Inv. : La ricerca è limitata ad un sottovettore t.c. se il valore cercato è presente, allora si trova in quel

sottovettore

Valore cercato: 25

(18)

Ricerca binaria

3. Cerca un modo per avvicinare la soluzione mantenendo vero l’invariante

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

Passo: dividi il sottovettore in due parti (quasi) uguali;

Valore cercato: 43

Punto intermedio

Se si trova nel punto intermedio: stop

(19)

Ricerca binaria

3. Cerca un modo per avvicinare la soluzione mantenendo vero l’invariante

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

Passo: dividi il sottovettore in due parti (quasi) uguali;

Valore cercato: 25

Punto intermedio

Se il valore cercato è < di quello nel punto

intermedio, può essere solo nella parte sinistra

(20)

Ricerca binaria

3. Cerca un modo per avvicinare la soluzione mantenendo vero l’invariante

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

Passo: dividi il sottovettore in due parti (quasi) uguali;

Valore cercato: 54

Punto intermedio

Se il valore cercato è > di quello nel punto

intermedio, può essere solo nella parte destra

(21)

Ricerca binaria

4. Definisci in quale momento la computazione si deve fermare

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

• Quando si sia trovato il valore nel punto intermedio, ….

Valore cercato: 25 Punto intermedio

(22)

Ricerca binaria

4. Definisci in quale momento la computazione si deve fermare

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

• …. oppure quando il sottovettore cui limitiamo la ricerca sia ridotto al vettore vuoto

Valore cercato: 23 Dovrebbe essere qui in mezzo: ma questo

intervallo è vuoto

(23)

Ricerca binaria

5. Definisci le condizioni iniziali della ricerca

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

• Il sottovettore cui la ricerca è limitata coincide con l’intero vettore

Valore cercato: 25

(24)

Ricerca binaria

6. Stabilisci i dettagli della codifica

95 91

88 83

74 72

60 53

51 49

43 36

25 21

21 18

13 6

5 3

1 20

• Il sottovettore cui la ricerca è limitata è compreso tra le posizioni i e j incluse

i j

Il punto medio ha indice: (i + j) div 2

Se i > j allora il sottovettore è vuoto

(25)

Ricerca binaria

7. Procedi alla pseudocodifica, usando le asserzioni, e principalmente l’invariante, come commenti

RicercaBinaria (V, n)

Pre. V è un vettore ordinato, n il valore cercato

Post. Ritorna m in [1..lunghezza(V)] se V[m] = n, 0 altrimenti i ← 1, j ← lunghezza(V)

trovato ← false

while i ≤ j and not trovato do

{Inv. Se n in V allora n in V[i..j], se trovato = true allora V[m] = n } m ← (i+j) div 2

if n = V[m] then trovato ← true

else if n < V[m] then {considero V[i.. m − 1]} j ← m − 1

sottovettore considerato

(26)

Costruire un algoritmo in modo che sia corretto

• La via maestra: formulare precisamente l’idea su cui si basera’ l’algoritmo

Molto spesso la formulazione precisa di quest’idea è

proprio l’invariante

(27)

Come si inventa un ciclo?

inizializzazione

while condizione do

corpo dell’iterazione 1

2

3

1. Per scrivere l’inizializzazione si deve sapere cosa deve fare il ciclo

2. Per scrivere la condizione (guardia) si deve conoscere cosa farà il corpo

L’ordine giusto

è l’opposto!

(28)

La generica iterazione

• Per individuare correttamente l’invariante non ci si deve porre agli estremi (inizio o

fine del ciclo) ma in un ideale punto medio:

la generica iterazione

(29)

Ordinamento per selezione

parte ordinata tutti gli el. di questa parte sono maggiori di quelli nella parte ordinata

i

indice del primo

elemento della parte da ordinare

Idea

V [1..n]

(30)

Ordinamento per selezione

i

Invariante

V [1..n]

• V [1 .. i − 1] ordinato

• se x in V [i .. n] ed y in V [1 .. i − 1] allora x ≥ y

(31)

Ordinamento per selezione

i

Passo

V [1..n] V [k] sia il minimo valore in V [i .. n]

k

Scambiando V[i] con V[k] l’invariante si mantiene con i ← i + 1:

(32)

Ordinamento per selezione

i

Passo

V [1..n] V [k] sia il minimo valore in V [i .. n]

k

Scambiando V[i] con V[k] l’invariante si mantiene con i ← i + 1:

• V [1 .. i] ordinato

• se x in V [i + 1 .. n] ed y in V [1 .. i ] allora x ≥ y

(33)

Ordinamento per selezione

i+1

Passo

V [1..n]

Inoltre la lunghezza della porzione ordinata è

aumentata, mentre la lunghezza di quella da ordinare

è diminuita

(34)

Ordinamento per selezione

i

Guardia (test di controllo)

V [1..n]

L’iterazione deve proseguire fintanto che i < n.

Quando i = n, V[i] è il massimo in V[1..n]

(35)

Ordinamento per selezione

i = 1

Inizializzazione

V [1..n]

La parte già ordinata è vuota: V[1.. 0]

(36)

Ordinamento per selezione

Pseudocodifica

SelectSort (V)

Pre. V[1..n] vettore di valori su un insieme linearmente ordinato (es. gli interi) Post. permuta sul posto gli elementi di V in ordine non decrescente

i ← 1

while i < n do

{inv. V[1..i −1] ordinato, gli el. in V[i..n] maggiorizzano quelli in V[1..i −1]}

k ← indice del minimo in V[i..n]

scambia V[i] con V[k]

i ← i + 1

(37)

Ordinamento per inserzione

parte ordinata Nessuna assunzione!

i

indice del primo

elemento della parte da ordinare

Idea

V [1..n]

(38)

Ordinamento per inserzione

i

Invariante

V [1..n]

• V [1 .. i − 1] ordinato

(39)

Ordinamento per inserzione

i

Passo

V [1..n]

Come fare per mantenere l’invariante?

Cercherò “il posto” in cui V[i]

dovrebbe stare

(40)

Ordinamento per inserzione

i

Passo

V [1..n]

quindi k in 2..i è il massimo indice t.c.

V[k − 1] ≤ V[i] & k < i ⇒ V[k] > V[i]

k

V[1] ≤ V[i] , V[2] ≤ V[i] …, V[k − 1] ≤ V[i]

V[k] > V[i]

(41)

Ordinamento per inserzione

i

Passo

V [1..n]

k

temp ← V[i] Salviamo il valore di V[i]

(42)

Ordinamento per inserzione

i

Passo

V [1..n]

k

Facciamo “slittare” V[k..i − 1]

su V[k + 1..i]

(43)

Ordinamento per inserzione

i

Passo

V [1..n]

k

V[k] ← temp Poniamo in V[k] il valore

salvato di V[i]

(44)

Ordinamento per inserzione

i

Guardia

V [1..n]

Prosegui fintanto che i ≤ n

(45)

Ordinamento per inserzione

i = 2

Inizializzazione

V [1..n]

• Il vettore V[1..1] è trivialmente ordinato

• i è l’indice del primo elemento della parte da

(46)

Ordinamento per inserzione

Pseudocodifica

InsertSort (V)

Pre. V[1..n] vettore di valori su un insieme linearmente ordinato (es. gli interi) Post. permuta sul posto gli elementi di V in ordine non decrescente

i ← 2

while i ≤ n do {inv.: V[1..i −1] ordinato, sia U= V[1..i −1]}

temp ← V[i], k ← I

while k ≥ 2 and V[k-1] > temp do {inv.: V[1..k-1] V[k+1..i] = U, V[k+1..i] sono > di temp}

V[k] ← V[k – 1], k ← k – 1 V[k] ← temp

{V[1..i] ordinato}

(47)

Accumulatori ed invarianti

• Quello iterativo è un metodo di calcolo

incrementale: ci si avvicina al risultato un passo dopo l’altro

• Un accumulatore è una variabile il cui valore rappresenta l’approssimazione corrente

• L’invariante deve allora spiegare in che

senso l’accumulatore approssima il risultato

(48)

Moltiplicazione

per somme successive

Moltiplicazione (x, n) Pre. n intero positivo Post. ritorna xn

z ← 0, y ← n while y > 0 do

z ← z + x y ← y − 1 return z

2 X 3 = 2 + 2 + 2

A scuola:

moltiplicandi e

moltiplicatori

(49)

Moltiplicazione

per somme successive x x

x x

x + L + + + + L +

z xy

x x

x x

x + L + + + + L +

z + x x(y – 1 )

(50)

Moltiplicazione

per somme successive

Moltiplicazione (x, n) Pre. n intero positivo Post. ritorna xn

z ← 0, y ← n while y > 0 do

z ← z + x y ← y − 1 return z

accumulatore

contatore

{inv. xn = z + xy}

z + xy = (z + x) + x (y – 1)

(51)

Moltiplicazione alla russa

56 56

13

0 112

6

224 224

3

448 448

1

728 -

0

13 × 56

div 2

+ + +

=

Risultato = somma val.

della seconda colonna quando quelli sulla

prima sono

dispari

(52)

Moltiplicazione alla russa

 

= +

dispari se

1

2

pari se

2

a k

a a k

) (

2

2 k a b k b k b b a = ⇒ ⋅ = ⋅ = ⋅ +

b b

b k

b k

b a k

a = 2 + 1 ⇒ ⋅ = ( 2 + 1 ) ⋅ = ⋅ ( + ) +

 

+

⋅ +

+

+

= +

+ ( ) ( div 2 ) ( ) dispari pari

) (

2) div (

a b

b a

b z

a b

b a

b z

a

z

(53)

Moltiplicazione alla russa

MoltRussa (m, n)

Pre. n, m interi positivi Post. ritorna n m

a ← n, b ← m, z ← 0 while a > 0 do

if a dispari then z ← z + b a ← a div 2

b ← b + b return z

{inv. n m = z + a b}

contatore

accumulatore

(54)

Riassumendo

• Il metodo delle asserzioni

• Invarianti di ciclo

• Come verificare la correttezza di un algoritmo iterativo

• Come costruire un algoritmo iterativo in modo che sia corretto

• Accumulatori (e contatori) in rapporto agli

invarianti

(55)

Domande

Domanda: l’algoritmo di ordinamento per selezione e’ migliore dell’algoritmo di

ordinamento per inserzione?

Perche’?

Domanda: l’algoritmo MoltRussa e’

migliore dell’algoritmo Moltiplica?

Perche’?

Risposte: TRA QUALCHE LEZIONE…

Riferimenti

Documenti correlati

all’aumentare dell’energia abbiamo i valori sulla circonferenza complessa di raggio unitario, che sono tutti valori fisicamente permessi, e che corrispondono quindi a valori

Allianz Invest4Life è un contratto di assicurazione sulla vita con componente unit linked che, a fronte del versamento di un Premio unico, garantisce al Contraente, in caso di

Qualora l'Assicurato in seguito a Malattia improvvisa o ad Infortunio avvenuti nel corso del Viaggio, dovesse sostenere Spese mediche/farmaceutiche/ospedaliere

Accordo di collaborazione tra l’Istituzione Servizi sociali educativi e culturali dell’Unione dei comuni dell’Appennino bolognese e le Istituzioni scolastiche del

Se torniamo ora all’asta CD, da quanto abbiamo visto concludiamo che in C essa risente della forza pe y ; spezzata l’asta nel suo punto medio e richiedendo l’equilibrio dei

E sufficiente sottrarre al momento centrale di inerzia per il rettangolo intero i contributi dei due rettangoli ` AEF G ed IHCL utilizzando il teorema di Huygens-Steiner..

Tale studio deve essere presentato tramite un’opportuna modellazione via diagrammi UML (www.uml.org), che descriva l’architettura del simulatore e dei suoi componenti..

Quale può essere il numero esatto dei pezzi del puzzle di Melania, sapendo che è vicino a 1000.. Giustificare