Votre axiome n'est pas vraiment un axiome, il manque des hypothèses. Des présentations simples de la logique Hoare manipulent des formules de la forme où P et P ' sont des formules logiques et C est une commande. Vous devez vous assurer que C est bien formé . Dans des langages simples comme ceux souvent utilisés pour une première introduction à la logique Hoare, la bonne forme est syntaxique: il s'agit généralement de vérifier que C{P}C{P′}PP′CCCse conforme à une grammaire sans contexte, et peut-être que les variables libres sont dans un ensemble autorisé. Si le langage comprend des constructions qui ont une exactitude sémantique, telles que les accès aux éléments du tableau, vous devez ajouter des hypothèses pour exprimer cette exactitude sémantique.
Formellement, vous pouvez ajouter des jugements pour exprimer la correction d'expressions et de commandes. Si les expressions n'ont pas d'effets secondaires, elles n'ont pas besoin de post-conditions, seulement de conditions préalables. Par exemple, vous pouvez écrire des règles de bonne forme telles que
et n'autorisent que des expressions bien formées dans les commandes:
{P[x←E]}
{P}E wf{P∧0≤E<length(A)}A[E] wf{P}E1 wf{P}E2 wf{P}E1+E2 wf
{P[x←E]}E wf{P[x←E]}x:=E{P}
Une approche différente consiste à traiter toutes les expressions comme bien formées, mais à faire en sorte que toute expression impliquant un calcul mal formé ait une valeur spéciale . Dans les langues avec vérification des limites d'exécution, e r r o r signifie «ce programme a déclenché une exception fatale». Vous suivriez alors si un programme s'est trompé via un prédicat logique E r r o r ; un programme n'est valable que si vous pouvez prouver que sa postcondition implique ¬ E r r o r .
errorerrorError¬Error
{P[x←E]}x:=E{P∨Error}P[x←E]⟹E↛error{P[x←E]}x:=E{P}
Une autre approche consiste à considérer un triple de Hoare comme valable uniquement si le programme se termine correctement. Il s'agit de l'approche habituelle pour les programmes non terminés: la postcondition se maintient lorsque la commande se termine, ce qui peut ne pas toujours se produire. Si vous traitez les erreurs d'exécution comme non terminées, vous balayez tous les problèmes de correction sous le capot. Vous devrez toujours prouver l'exactitude du programme d'une manière ou d'une autre, mais ce n'est pas nécessairement dans la logique Hoare si vous préférez un autre formalisme pour cette tâche.
Soit dit en passant, noter que l'expression de ce qui se produit lorsqu'une variable composée telle qu'un tableau est modifié est plus complexe que ce que vous avez écrit. Supposons que était, disons, je s S o r t e d ( A ) : la substitution A [ i ] ← E ne changerait pas P , mais l'affectation A [ i ] ← P pourrait invalider P . Même si vous limitez la syntaxe des prédicats pour ne parler que des atomes, considérez l'affectation A [ A [ 0PIsSorted(A)A[i]←EPA[i]←PP sous la condition préalable A [ 0 ] = 2 ∧ A [ 1 ] = 3 : vous ne pouvez pas faire une simple substitution pour obtenir la postcondition correcte A [ 0 ] = 1 ∧ A [ 1 ] = 1 , vous devez évaluer A [ 0 ] (ce qui peut être difficile en général, car la précondition peut ne pas spécifier une seule valeur possible pour AA[A[0]−1]:=A[0]A[0]=2∧A[1]=3A[0]=1∧A[1]=1A[0] ). Vous devez effectuer la substitution sur le tableau lui-même: A ← A [ i ← E ] . Les notes de cours de Mike Gordonont une bonne logique Hoare de présentation avec des tableaux (mais sans vérification d'erreur).A[0]A←A[i←E]
length
àA
?length
été renomméA_length
.) Deuxièmement, nous avons besoin d'axiomes de "création" de tableaux commeint[] a = int[length] {a_length==length}
. Je pense que cela devrait suffire.