420 likes | 589 Views
Cours d’Algorithmique. Logique de Hoare (fin) : Les boucles et les invariants. Les grandes lignes du cours. Trier et chercher, recherche textuelle Listes et arbres Le back-track Arbres équilibrés Récursivité et induction sur la structure Divide and conquer, algorithmes gloutons
E N D
Cours d’Algorithmique Logique de Hoare (fin) : Les boucles et les invariants. Cours d'algorithmique 10 / Intranet
Les grandes lignes du cours • Trier et chercher, recherche textuelle • Listes et arbres • Le back-track • Arbres équilibrés • Récursivité et induction sur la structure • Divide and conquer, algorithmes gloutons • Minimax, alpha-beta • Dérécursion • Divers problèmes particuliers • Logique de Hoare • Programmation dynamique • Complexité et calculabilité Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- W H I L E e t l e s I N V A R I A N T S D E B O U C L E Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • L’exemple qui nous sert à illustrer la notion d’invariant : • PRE : V , D e N • POST: Q , R e N telles V = Q * D + R et R < D . • C’est la spécification de la division euclidienne ! I I Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- Exemple : V = 17 , D = 5 Y a-t-il quelque-chose de commun entre les différentes itérations ? Q <- 0 ; R <- V ; while R >= D Q <- Q + 1 ; R <- R - D V = 17 , D = 5 , Q = 0 OUI : V = Q * D + R V = 17 , D = 5 , Q = 0 , R = 17 V = 17 , D = 5 , Q = 0 , R = 17 V = 17 , D = 5 , Q = 1 , R = 12 V = 17 , D = 5 , Q = 1 , R = 17 V = 17 , D = 5 , Q = 2 , R = 12 etc etc ! ! ! V = 17 , D = 5 , Q = 1 , R = 12 V = 17 , D = 5 , Q = 2 , R = 7 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- Exemple : V = 17 , D = 5 Y a-t-il quelque-chose de commun entre les différentes itérations ? Q <- 0 ; R <- V ; while R >= D Q <- Q + 1 ; R <- R - D V = 17 , D = 5 , Q = 0 OUI : V = Q * D + R V = 17 , D = 5 , Q = 0 , R = 17 C'est fini ! ! ! V = 17 , D = 5 , Q = 2 , R = 7 A la fin : V = Q * D + R et R < D V = 17 , D = 5 , Q = 3 , R = 7 V = 17 , D = 5 , Q = 3 , R = 2 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Les valeurs de V , D , Q , R peuvent changer. • Mais la relation V = Q * D + R reste toujours vérifiée. • C’est ce qu’on appelle un « invariant » ! • Un invariant est un prédicat qui : • est vrai à chaque début de boucle, • et à chaque fin de boucle, • c’est-à-dire début de la boucle suivante. (Les tests ne font pas d’affectation !) Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Pour écrire un corps de boucle, il faut connaître l’invariant de la boucle ! • Votre code sera exécuté par le « i » tour de boucle, quel que soit la valeur de « i ». • Pour savoir ce que vous devez faire au « i » tour de boucle, vous devez vous souvenir de ce que vous avez fait pendant les « i – 1 » premiers tours. • Ceci revient à connaître « l’invariant » ! e e Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Quel est l’invariant ? • Avant le « i » tour de boucle, nous avons fait les tours de boucle de « 1 » à « i – 1 ». • Nous avons donc sommé dans « s » les valeurs de « 1 » à « i – 1 ». • Invariant :s = S j s <- 0 ; i <- 1 ; while ( i <= n ) do s <- s + i ; i <- i + 1 e i – 1 j = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Règle pour le programme while C dog : • Nous dirons que « I » est l’invariant ! • La condition { I , C }g{ I } vérifie que « I » est bien invariant ! ! ! • La post-condition { I , ù C } est évidente ! • Il suffit alors que { I } soit vrai au début ! { I , C }g{ I } { I }while C dog{ I , ù C } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Dans la pratique, nous avons une post-condition Q et le code while C dog : • Quel prédicat « I » faut-il choisir comme invariant ? • C’est l’utilisateur qui doit faire une proposition ! • Nouvelle syntaxe : while C doginv I { ??? , C }g{ ??? } { ??? }while C dog{ Q } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Règle pour le programme while C doginv I : • Nous devons prouver que I , ù C => Q ! • Nous calculons la pré-condition « F » de { F } g { I } ! • Nous prouvons que I , C => F ! • A ce moment, nous connaissons la pré-condition « I » ! { F } g { I } I , ù C => Q I , C => F { I }while C doginv I { Q } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Règle pour le programme while C doginv I : • Attention, il y a deux obligations de preuve ! • Elles sont semi-automatisables. • Un prouveur peut ne pas trouver la preuve ! • Un prouveur ne saura jamais dire si elle n’existe pas ! ! ! { F } g { I } I , ù C => Q I , C => F { I }while C doginv I { Q } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- U N P R E M I E R E X E M P L E Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; R <- R – D inv I Q = { V = D * Q + R , 0 <= R < D } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; R <- R – D inv I Sans problème : I , ù C => Q = { V = D * Q + R , 0 <= R } Q = { V = D * Q + R , 0 <= R < D } = { V = D * Q + R , 0 <= R } et { R < D } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; R <- R – D inv I Après simplification ! F = { V = D * Q + R , D <= R } { V = D * Q + R – D , 0 <= R – D } Sans problème : I , ù C => Q { V = D * Q + R , 0 <= R } = { V = D * Q + R , 0 <= R } Q = { V = D * Q + R , 0 <= R < D } = { V = D * Q + R , 0 <= R } et { R < D } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- { F } g { I } I , ù C => Q I , C => F { I }while C doginv I { Q } { V = D * Q + R , 0 <= R } et { R >= D } !!!!!! => { V = D * Q + R , D <= R } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • PRE : { V = D * 0 + V , 0 <= V } = { V >= 0 } • POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; R <- R – D inv I { V = D * 0 + R , 0 <= R } I = { V = D * Q + R , 0 <= R } F = { V = D * Q + R , D <= R } Sans problème : I , C => F { V = D * Q + R – D , 0 <= R – D } Sans problème : I , ù C => Q { V = D * Q + R , 0 <= R } = { V = D * Q + R , 0 <= R } Q = { V = D * Q + R , 0 <= R < D } = { V = D * Q + R , 0 <= R } et { R < D } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- U N D E U X I E M E E X E M P L E Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : Q = { x = pgcd( a , b ) } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : Sans problème : I , ù C => Q = { pgcd( x , y ) = pgcd( a , b ) } Q = { x = pgcd( a , b ) } = { pgcd( x , 0 ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) , y = 0 } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : F = { pgcd( y , x % y ) = pgcd( a , b ) } { pgcd( m , x%y ) = pgcd( a , b ) } { pgcd( m , y ) = pgcd( a , b ) } Sans problème : I , ù C => Q { pgcd( x , y ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) } Q = { x = pgcd( a , b ) } = { pgcd( x , 0 ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) , y = 0 } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- I , C => F ? ? ? { pgcd( x , y ) = pgcd( a , b ) }et { y <> 0 } ??? => { pgcd( y , x % y ) = pgcd( a , b ) } Maths : x >= y et y <> 0 => pgcd( x , y ) = pgcd( y , x % y ) Nous devons renforcer l’invariant : { pgcd( x , y ) = pgcd( a , b ) , x >= y } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : Sans problème : I , ù C => Q = { pgcd( x , y ) = pgcd( a , b ) , x >= y } Q = { x = pgcd( a , b ) } = { pgcd( x , 0 ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) , y = 0 } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : F = { pgcd( y , x % y ) = pgcd( a , b ) } { . . . , m >= x % y } { . . . , m >= y } Sans problème : I , ù C => Q { pgcd( x , y ) = pgcd( a , b ) , x >= y } = { pgcd( x , y ) = pgcd( a , b ) , x >= y } Q = { x = pgcd( a , b ) } = { pgcd( x , 0 ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) , y = 0 } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- I , C => F { pgcd( x , y ) = pgcd( a , b ) , x >= y }et { y <> 0 } !!!!!! => { pgcd( y , x % y ) = pgcd( a , b ) } Maths : x >= y et y <> 0 => pgcd( x , y ) = pgcd( y , x % y ) Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • PRE : { pgcd( a , b ) = pgcd( a , b ) , a >= b } = { a >= b } x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; y <- x % y ; x <- m inv I • POST : I = { pgcd( x , y ) = pgcd( a , b ) , x >= y } F = { pgcd( y , x % y ) = pgcd( a , b ) } Sans problème : I , C => F { . . . , m >= x % y } { . . . , m >= y } Sans problème : I , ù C => Q { pgcd( x , y ) = pgcd( a , b ) , x >= y } = { pgcd( x , y ) = pgcd( a , b ) , x >= y } Q = { x = pgcd( a , b ) } = { pgcd( x , 0 ) = pgcd( a , b ) } = { pgcd( x , y ) = pgcd( a , b ) , y = 0 } Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- U N T R O I S I E M E E X E M P L E Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; c <- c + 1 inv I • POST : Sans problème : I , ù C => Q c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; c <- c + 1 inv I • POST : Après simplification ! c – 1 F = { c <= n , s = S i } i = 1 Sans problème : I , ù C => Q I = . . . c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; c <- c + 1 inv I • POST : c – 1 F = { c <= n , s = S i } Sans problème : I , C => F i = 1 Sans problème : I , ù C => Q I = . . . c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • PRE : 1 – 1 { 1 <= n + 1 , 0 = S i } = { n >= 0 } i = 1 s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; c <- c + 1 inv I • POST : c – 1 I = { c <= n + 1 , s = S i } i = 1 c – 1 F = { c <= n , s = S i } Sans problème : I , C => F i = 1 Sans problème : I , ù C => Q I = . . . c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Une autre initialisation : • POST : • PRE : 2 – 1 { 2 <= n + 1 , 1 = S i } = { n >= 1 } i = 1 s <- 1 ; c <- 2 ; while ( c <= n ) do . . . c – 1 I = { c <= n + 1 , s = S i } i = 1 n Q = { s = S i } i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Une mauvaise initialisation : • POST : • PRE : 2 – 1 { 2 <= n + 1 , 6 = S i } = { n >= 1 , 6 = 1 } = { FAUX } i = 1 s <- 6 ; c <- 2 ; while ( c <= n ) do . . . c – 1 I = { c <= n + 1 , s = S i } i = 1 n Q = { s = S i } i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Une mauvaise initialisation : • POST : • PRE : 2 – 1 { 2 <= n + 1 , 6 = S i } = { n >= 1 , 6 = 1 } = { n >= 1 } 1 1 i = 1 1 s <- 6 ; c <- 2 ; while ( c <= n ) do . . . c – 1 I = { c <= n + 1 , s = S i } i = 1 Nous corrigeons ! n Q = { s = S i } i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Une mauvaise initialisation : • POST : 4 • PRE : 2 – 1 3 4 { 2 <= n + 1 , 6 = S i } = { n >= 1 , 6 = 1 } = { n >= 3 } 6 i = 1 s <- 6 ; c <- 2 ; while ( c <= n ) do . . . c – 1 4 I = { c <= n + 1 , s = S i } i = 1 Une autre correction ! n Q = { s = S i } i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Un mauvais invariant : . . . while ( c <= n ) do s <- s + c + 3 ; c <- c + 1 inv I • POST : Sans problème : I , ù C => Q c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Un mauvais invariant : . . . while ( c <= n ) do s <- s + c + 3 ; c <- c + 1 inv I • POST : Après simplification ! c – 1 F = { c <= n , s + 3 = S i } i = 1 Sans problème : I , ù C => Q I = . . . c – 1 = { c <= n + 1 , s = S i } i = 1 n c – 1 Q = { s = S i } = { s = S i , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- I , C => F c – 1 { c <= n + 1 , s = S i } et { c <= n } NON => { c <= n + 1 , s + 3 = S i } i = 1 // c – 1 i = 1 Sinon, nous aurions 3 = 0 ! Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Un mauvais invariant : . . . while ( c <= n ) do s <- s + c + 3 ; c <- c + 1 inv I • POST : Après simplification ! c – 1 F = { c <= n , s = S (i + 3) } Sans problème : I , C => F i = 1 Sans problème : I , ù C => Q I = . . . c – 1 = { c <= n + 1 , s = S (i + 3) } i = 1 n c – 1 Q = { s = S (i + 3) } = { s = S (i + 3) , c <= n + 1 , c > n } i = 1 i = 1 Cours d'algorithmique 10 / Intranet
Logique de Hoare----------------------------------------------------------------- • Attention : • Tout ceci n’empêche pas un programme de boucler ! • Nous affirmons seulement que • si le programme s’arrête, • alors il rend le résultat indiqué ! Cours d'algorithmique 10 / Intranet