Cours d'algorithmique 10 / Intranet 1 19 décembre 2006 Cours d’Algorithmique Logique de Hoare (fin) : Les boucles et les invariants.
19 décembre 2006Cours d'algorithmique 10 / Intranet2 Trier et chercher, recherche textuelle Trier et chercher, recherche textuelle Listes et arbres Listes et arbres Le back-track Le back-track Arbres équilibrés Arbres équilibrés Récursivité et induction sur la structure Récursivité et induction sur la structure Divide and conquer, algorithmes gloutons Divide and conquer, algorithmes gloutons Minimax, alpha-beta Minimax, alpha-beta Dérécursion Dérécursion Divers problèmes particuliers Divers problèmes particuliers Logique de Hoare Logique de Hoare Programmation dynamique Programmation dynamique Complexité et calculabilité Complexité et calculabilité Les grandes lignes du cours
19 décembre 2006Cours d'algorithmique 10 / Intranet3 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
19 décembre 2006Cours d'algorithmique 10 / Intranet4 Logique de Hoare L’exemple qui nous sert à illustrer la notion d’invariant : L’exemple qui nous sert à illustrer la notion d’invariant : – PRE : V, D N – POST: Q, R N telles V = Q * D + R et R < D. C’est la spécification de la division euclidienne ! C’est la spécification de la division euclidienne ! I I
19 décembre 2006Cours d'algorithmique 10 / Intranet5 Logique de Hoare Exemple : V = 17, D = 5 V = 17, D = 5, Q = 0 Q <- 0 ; R <- V ; while R >= D Q <- Q + 1 ; Q <- Q + 1 ; R <- R - D R <- R - D V = 17, D = 5, Q = 0, R = 17 V = 17, D = 5, Q = 1, R = 17 V = 17, D = 5, Q = 1, R = 12 Y a-t-il quelque-chose de commun entre les différentes itérations ? OUI : V = Q * D + R V = 17, D = 5, Q = 2, R = 12 V = 17, D = 5, Q = 2, R = 7
19 décembre 2006Cours d'algorithmique 10 / Intranet6 Logique de Hoare Exemple : V = 17, D = 5 V = 17, D = 5, Q = 0 Q <- 0 ; R <- V ; while R >= D Q <- Q + 1 ; Q <- Q + 1 ; R <- R - D R <- R - D V = 17, D = 5, Q = 0, R = 17 Y a-t-il quelque-chose de commun entre les différentes itérations ? OUI : V = Q * D + R V = 17, D = 5, Q = 2, R = 7 V = 17, D = 5, Q = 3, R = 7 V = 17, D = 5, Q = 3, R = 2 A la fin : V = Q * D + R et R < D
19 décembre 2006Cours d'algorithmique 10 / Intranet7 Logique de Hoare Les valeurs de V, D, Q, R peuvent changer. Les valeurs de V, D, Q, R peuvent changer. Mais la relation V = Q * D + R reste toujours vérifiée. Mais la relation V = Q * D + R reste toujours vérifiée. C’est ce qu’on appelle un « invariant » ! C’est ce qu’on appelle un « invariant » ! Un invariant est un prédicat qui : 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 !) (Les tests ne font pas d’affectation !)
19 décembre 2006Cours d'algorithmique 10 / Intranet8 Logique de Hoare Pour écrire un corps de boucle, il faut connaître l’invariant de la boucle ! 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 ». 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. 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 » ! Ceci revient à connaître « l’invariant » ! e e
19 décembre 2006Cours d'algorithmique 10 / Intranet9 Logique de Hoare Quel est l’invariant ? Quel est l’invariant ? Avant le « i » tour de boucle, nous avons fait les tours de boucle de « 1 » à « i – 1 ». 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 ». Nous avons donc sommé dans « s » les valeurs de « 1 » à « i – 1 ». Invariant : s = j Invariant : s = j s <- 0 ; i <- 1 ; while ( i <= n ) do s <- s + i ; s <- s + i ; i <- i + 1 i <- i + 1 e j = 1 i – 1
19 décembre 2006Cours d'algorithmique 10 / Intranet10 Logique de Hoare Règle pour le programme while C do : Règle pour le programme while C do : Nous dirons que « I » est l’invariant ! Nous dirons que « I » est l’invariant ! La condition { I, C } { I } vérifie que « I » est bien invariant ! ! ! La condition { I, C } { I } vérifie que « I » est bien invariant ! ! ! La post-condition { I, C } est évidente ! La post-condition { I, C } est évidente ! Il suffit alors que { I } soit vrai au début ! Il suffit alors que { I } soit vrai au début ! { I } while C do { I, C } { I, C } { I }
19 décembre 2006Cours d'algorithmique 10 / Intranet11 Logique de Hoare Dans la pratique, nous avons une post-condition Q et le code while C do : Dans la pratique, nous avons une post-condition Q et le code while C do : Quel prédicat « I » faut-il choisir comme invariant ? Quel prédicat « I » faut-il choisir comme invariant ? C’est l’utilisateur qui doit faire une proposition ! C’est l’utilisateur qui doit faire une proposition ! Nouvelle syntaxe : while C do inv I Nouvelle syntaxe : while C do inv I { ??? } while C do { Q } { ???, C } { ??? }
19 décembre 2006Cours d'algorithmique 10 / Intranet12 Logique de Hoare Règle pour le programme while C do inv I : Règle pour le programme while C do inv I : Nous devons prouver que I, C => Q ! Nous devons prouver que I, C => Q ! Nous calculons la pré-condition « F » de { F } { I } ! Nous calculons la pré-condition « F » de { F } { I } ! Nous prouvons que I, C => F ! Nous prouvons que I, C => F ! A ce moment, nous connaissons la pré-condition « I » ! A ce moment, nous connaissons la pré-condition « I » ! { F } { I } I, C => F I, C => Q { I } while C do inv I { Q }
19 décembre 2006Cours d'algorithmique 10 / Intranet13 Logique de Hoare Règle pour le programme while C do inv I : Règle pour le programme while C do inv I : Attention, il y a deux obligations de preuve ! Attention, il y a deux obligations de preuve ! Elles sont semi-automatisables. Elles sont semi-automatisables. Un prouveur peut ne pas trouver la preuve ! Un prouveur peut ne pas trouver la preuve ! Un prouveur ne saura jamais dire si elle n’existe pas ! ! ! Un prouveur ne saura jamais dire si elle n’existe pas ! ! ! { F } { I } I, C => F I, C => Q { I } while C do inv I { Q }
19 décembre 2006Cours d'algorithmique 10 / Intranet14 Logique de Hoare U N P R E M I E R E X E M P L E
19 décembre 2006Cours d'algorithmique 10 / Intranet15 Logique de Hoare POST : POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; Q <- Q + 1 ; R <- R – D R <- R – D inv I inv I Q = { V = D * Q + R, 0 <= R < D }
19 décembre 2006Cours d'algorithmique 10 / Intranet16 Logique de Hoare POST : POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; Q <- Q + 1 ; R <- R – D R <- R – D inv I inv I Q = { V = D * Q + R, 0 <= R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } Sans problème : I, C => Q
19 décembre 2006Cours d'algorithmique 10 / Intranet17 Logique de Hoare POST : POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; Q <- Q + 1 ; R <- R – D R <- R – D inv I inv I Q = { V = D * Q + R, 0 <= R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } Sans problème : I, C => Q F = { V = D * Q + R, D <= R } { V = D * Q + R, 0 <= R } { V = D * Q + R – D, 0 <= R – D } Après simplification !
19 décembre 2006Cours d'algorithmique 10 / Intranet18 Logique de Hoare { F } { I } I, C => Q { I } while C do inv I { Q } I, C => F { V = D * Q + R, 0 = D } !!!!!!=> { V = D * Q + R, D <= R }
19 décembre 2006Cours d'algorithmique 10 / Intranet19 Logique de Hoare POST : POST : R <- V ; Q <- 0 ; while ( R >= D ) do Q <- Q + 1 ; Q <- Q + 1 ; R <- R – D R <- R – D inv I inv I Q = { V = D * Q + R, 0 <= R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } et { R < D } = { V = D * Q + R, 0 <= R } Sans problème : I, C => Q F = { V = D * Q + R, D <= R } { V = D * Q + R, 0 <= R } { V = D * Q + R – D, 0 <= R – D } I = { V = D * Q + R, 0 <= R } Sans problème : I, C => F { V = D * 0 + R, 0 <= R } { V = D * 0 + V, 0 = 0 } PRE : PRE :
19 décembre 2006Cours d'algorithmique 10 / Intranet20 Logique de Hoare U N D E U X I E M E E X E M P L E
19 décembre 2006Cours d'algorithmique 10 / Intranet21 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) }
19 décembre 2006Cours d'algorithmique 10 / Intranet22 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) } = { pgcd( x, 0 ) = pgcd( a, b ) } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ) } Sans problème : I, C => Q
19 décembre 2006Cours d'algorithmique 10 / Intranet23 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) } = { pgcd( x, 0 ) = pgcd( a, b ) } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ) } Sans problème : I, C => Q F = { pgcd( y, x % y ) = pgcd( a, b ) } { pgcd( x, y ) = pgcd( a, b ) } { pgcd( m, y ) = pgcd( a, b ) } { pgcd( m, x%y ) = pgcd( a, b ) }
19 décembre 2006Cours d'algorithmique 10 / Intranet24 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 }
19 décembre 2006Cours d'algorithmique 10 / Intranet25 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) } = { pgcd( x, 0 ) = pgcd( a, b ) } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), x >= y } Sans problème : I, C => Q
19 décembre 2006Cours d'algorithmique 10 / Intranet26 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) } = { pgcd( x, 0 ) = pgcd( a, b ) } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } Sans problème : I, C => Q F = { pgcd( y, x % y ) = pgcd( a, b ) } { pgcd( x, y ) = pgcd( a, b ), x >= y } {..., m >= y } {..., m >= x % y } = { pgcd( x, y ) = pgcd( a, b ), x >= y }
19 décembre 2006Cours d'algorithmique 10 / Intranet27 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 )
19 décembre 2006Cours d'algorithmique 10 / Intranet28 Logique de Hoare x <- a ; y <- b ; while ( y <> 0 ) do m <- y ; m <- y ; y <- x % y ; y <- x % y ; x <- m x <- m inv I inv I POST : POST : Q = { x = pgcd( a, b ) } = { pgcd( x, 0 ) = pgcd( a, b ) } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } = { pgcd( x, y ) = pgcd( a, b ), y = 0 } Sans problème : I, C => Q F = { pgcd( y, x % y ) = pgcd( a, b ) } { pgcd( x, y ) = pgcd( a, b ), x >= y } {..., m >= y } {..., m >= x % y } Sans problème : I, C => F I = { pgcd( x, y ) = pgcd( a, b ), x >= y } { pgcd( a, b ) = pgcd( a, b ), a >= b } = { a >= b } PRE : PRE : = { pgcd( x, y ) = pgcd( a, b ), x >= y }
19 décembre 2006Cours d'algorithmique 10 / Intranet29 Logique de Hoare U N T R O I S I E M E E X E M P L E
19 décembre 2006Cours d'algorithmique 10 / Intranet30 Logique de Hoare s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; s <- s + c ; c <- c + 1 c <- c + 1 inv I inv I POST : POST : i = 1 c – 1 = { c <= n + 1, s = i } Sans problème : I, C => Q Q = { s = i } = { s = i, c n } i = 1 n c – 1
19 décembre 2006Cours d'algorithmique 10 / Intranet31 Logique de Hoare s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; s <- s + c ; c <- c + 1 c <- c + 1 inv I inv I POST : POST : i = 1 c – 1 = { c <= n + 1, s = i } Sans problème : I, C => Q Q = { s = i } = { s = i, c n } i = 1 n c – 1 F = { c <= n, s = i } I =... i = 1 c – 1 Après simplification !
19 décembre 2006Cours d'algorithmique 10 / Intranet32 Logique de Hoare s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; s <- s + c ; c <- c + 1 c <- c + 1 inv I inv I POST : POST : i = 1 c – 1 = { c <= n + 1, s = i } Sans problème : I, C => Q Q = { s = i } = { s = i, c n } i = 1 n c – 1 F = { c <= n, s = i } I =... i = 1 c – 1 Sans problème : I, C => F
19 décembre 2006Cours d'algorithmique 10 / Intranet33 Logique de Hoare s <- 0 ; c <- 1 ; while ( c <= n ) do s <- s + c ; s <- s + c ; c <- c + 1 c <- c + 1 inv I inv I POST : POST : i = 1 c – 1 = { c <= n + 1, s = i } Sans problème : I, C => Q Q = { s = i } = { s = i, c n } i = 1 n c – 1 F = { c <= n, s = i } I =... i = 1 c – 1 Sans problème : I, C => F i = 1 c – 1 I = { c <= n + 1, s = i } i = 1 1 – 1 { 1 = 0 } PRE : PRE :
19 décembre 2006Cours d'algorithmique 10 / Intranet34 Logique de Hoare s <- 1 ; c <- 2 ; while ( c <= n ) do i = 1 c – 1 I = { c <= n + 1, s = i } i = 1 2 – 1 { 2 = 1 } PRE : PRE : Une autre initialisation : Une autre initialisation : POST : POST : Q = { s = i } i = 1 n
19 décembre 2006Cours d'algorithmique 10 / Intranet35 Logique de Hoare s <- 6 ; c <- 2 ; while ( c <= n ) do i = 1 c – 1 I = { c <= n + 1, s = i } i = 1 2 – 1 { 2 = 1, 6 = 1 } = { FAUX } PRE : PRE : Une mauvaise initialisation : Une mauvaise initialisation : POST : POST : Q = { s = i } i = 1 n
19 décembre 2006Cours d'algorithmique 10 / Intranet36 Logique de Hoare s <- 6 ; c <- 2 ; while ( c <= n ) do i = 1 c – 1 I = { c <= n + 1, s = i } i = 1 2 – 1 { 2 = 1, 6 = 1 } = { n >= 1 } PRE : PRE : Une mauvaise initialisation : Une mauvaise initialisation : POST : POST : Q = { s = i } i = 1 n
19 décembre 2006Cours d'algorithmique 10 / Intranet37 Logique de Hoare s <- 6 ; c <- 2 ; while ( c <= n ) do i = 1 c – 1 I = { c <= n + 1, s = i } i = 1 2 – 1 { 2 = 1, 6 = 1 } = { n >= 3 } PRE : PRE : Une mauvaise initialisation : Une mauvaise initialisation : POST : POST : Q = { s = i } i = 1 n
19 décembre 2006Cours d'algorithmique 10 / Intranet38 POST : POST : Logique de Hoare Un mauvais invariant : Un mauvais invariant : Q = { s = i } = { s = i, c n } i = 1 n... while ( c <= n ) do s <- s + c + 3 ; s <- s + c + 3 ; c <- c + 1 c <- c + 1 inv I inv I i = 1 c – 1 = { c <= n + 1, s = i } i = 1 c – 1 Sans problème : I, C => Q
19 décembre 2006Cours d'algorithmique 10 / Intranet39 POST : POST : Logique de Hoare Un mauvais invariant : Un mauvais invariant : Q = { s = i } = { s = i, c n } i = 1 n... while ( c <= n ) do s <- s + c + 3 ; s <- s + c + 3 ; c <- c + 1 c <- c + 1 inv I inv I i = 1 c – 1 = { c <= n + 1, s = i } i = 1 c – 1 I =... F = { c <= n, s + 3 = i } i = 1 c – 1 Après simplification ! Sans problème : I, C => Q
19 décembre 2006Cours d'algorithmique 10 / Intranet40 Logique de Hoare I, C => F { c <= n + 1, s = i } et { c <= n } NON=> { c <= n + 1, s + 3 = i } i = 1 c – 1 i = 1 c – 1 // Sinon, nous aurions 3 = 0 !
19 décembre 2006Cours d'algorithmique 10 / Intranet41 POST : POST : Logique de Hoare Un mauvais invariant : Un mauvais invariant : Q = { s = (i + 3) } = { s = (i + 3), c <= n + 1, c > n } c > n } i = 1 n... while ( c <= n ) do s <- s + c + 3 ; s <- s + c + 3 ; c <- c + 1 c <- c + 1 inv I inv I i = 1 c – 1 = { c <= n + 1, s = (i + 3) } i = 1 c – 1 Sans problème : I, C => Q I =... F = { c <= n, s = (i + 3) } i = 1 c – 1 Après simplification ! Sans problème : I, C => F
19 décembre 2006Cours d'algorithmique 10 / Intranet42 Logique de Hoare Attention : Attention : Tout ceci n’empêche pas un programme de boucler ! Tout ceci n’empêche pas un programme de boucler ! Nous affirmons seulement que Nous affirmons seulement que – si le programme s’arrête, – alors il rend le résultat indiqué !