La Parole semble s'être utilisée dans un certain nombre de contextes. Le mieux que je puisse comprendre, c'est qu'ils signifient une variable qui ne peut pas changer. N'est-ce pas à cela que servent les constantes/finales (sacrément Java!)?
Un invariant est plus "conceptuel" qu'une variable. En général, c'est une propriété de l'état du programme qui est toujours vraie. On dit qu'une fonction ou une méthode qui garantit que l'invariant est maintenu maintient l'invariant.
Par exemple, un arbre de recherche binaire peut avoir l'invariant que pour chaque nœud, la clé de l'enfant gauche du nœud est inférieure à la clé propre du nœud. Une fonction d'insertion correctement écrite pour cet arbre conservera cet invariant.
Comme vous pouvez le constater, ce n'est pas le genre de chose que vous pouvez stocker dans une variable: c'est plus une déclaration about le programme. En déterminant le type d'invariants que votre programme doit conserver, puis en examinant votre code pour vous assurer qu'il conserve réellement ces invariants, vous pouvez éviter les erreurs logiques dans votre code.
C'est une condition que vous savez être toujours vraie à un endroit particulier de votre logique et que vous pouvez vérifier lors du débogage pour déterminer ce qui a mal tourné.
Je les vois généralement plus en termes d'algorithmes ou de structures.
Par exemple, vous pourriez avoir un invariant de boucle qui pourrait être affirmé - toujours vrai au début ou à la fin de chaque itération. Autrement dit, si votre boucle était censée traiter une collection d'objets d'une pile à une autre, vous pourriez dire que | stack1 | + | stack2 | = c, en haut ou en bas de la boucle.
Si la vérification invariante échouait, cela indiquerait que quelque chose s'est mal passé. Dans cet exemple, cela pourrait signifier que vous avez oublié de pousser l'élément traité sur la pile finale, etc.
La magie de wikipedia: Invariant (informatique)
En informatique, un prédicat qui, s'il est vrai, restera vrai tout au long d'une séquence d'opérations spécifique, est appelé (an) invariant à cette séquence.
Comme l'indique cette ligne:
En informatique, un prédicat qui, s'il est vrai, restera vrai tout au long d'une séquence d'opérations spécifique, est appelé (an) invariant à cette séquence.
Pour mieux comprendre cet espoir, cet exemple en C++ aide.
Considérez un scénario dans lequel vous devez obtenir des valeurs et en obtenir le nombre total dans une variable appelée count
et les ajouter dans une variable appelée sum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
Le code pour ce qui précède serait quelque chose comme ça,
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
Que fait le code ci-dessus?
1) Lit l'entrée de cin
et les place dans x
2) Après une lecture réussie, incrémentez count
et sum = sum + x
3) Répétez 1-2 jusqu'à ce que la lecture s'arrête (c'est-à-dire ctrl + D)
L'invariant doit être True [~ # ~] toujours [~ # ~] . Donc, au début, vous commencez votre code avec juste cela
while(cin>>x){
}
Cette boucle lit les données de l'entrée standard et les stocke dans x. Bel et bien. Mais le invariant devient faux parce que la première partie de notre invariant n'a pas été suivie (ou maintenue vraie).
// we have read count grades so far, and
Facile! compte d'incrément.
Donc ++count;
ferait du bien !. Maintenant, notre code devient quelque chose comme ça,
while(cin>>x){
++count;
}
Même maintenant, notre invariant (un concept qui doit être VRAI) est faux parce que maintenant nous ne satisfaisons pas la deuxième partie de notre invariant.
// sum is the sum of the first count grades
Que faire maintenant?
Ajoutez x
à sum
et stockez-le dans sum
(sum+=x
) et la prochaine fois cin>>x
lira une nouvelle valeur dans x.
Maintenant, notre code devient quelque chose comme ça,
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
code:
while(cin>>x){
++count;
sum+=x;
}
Ah !. Maintenant, l'invariant de boucle est True toujours et le code fonctionne bien.
L'exemple ci-dessus a été tiré et modifié de le livre Accelerated C++ par Andrew-koening et Barbara-E
Quelque chose qui ne change pas dans un bloc de code
Suite à ce qu'il est, les invariants sont très utiles pour écrire du code propre, car sachant conceptuellement quels invariants doivent être présents in votre code vous permet de décider facilement comment organiser votre code pour atteindre ces objectifs. Comme mentionné précédemment, ils sont également utiles dans le débogage, car vérifier si l'invariant est maintenu est souvent un bon moyen de voir si la manipulation que vous essayez d'effectuer fait réellement ce que vous voulez.
Il s'agit généralement d'une quantité qui ne change pas sous certaines opérations mathématiques. Un exemple est un scalaire, qui ne change pas sous les rotations. En imagerie par résonance magnétique, par exemple, il est utile de caractériser une propriété tissulaire par un invariant rotationnel, car alors son estimation ne dépend idéalement pas de l'orientation du corps dans le scanner.
L'invariant ADT spécifie les relations entre les champs de données (variables d'instance) qui doivent toujours être vraies avant et après l'exécution de toute méthode d'instance.
Il existe un excellent exemple d'un invariant et pourquoi il est important dans le livre Java Concurrency in Practice .
Bien que centré sur Java, l'exemple décrit du code qui est responsable du calcul des facteurs d'un entier fourni. L'exemple de code tente de mettre en cache le dernier nombre fourni et les facteurs qui ont été calculés pour améliorer les performances. Dans ce scénario, il existe un invariant qui n'était pas pris en compte dans l'exemple de code qui a laissé le code sensible aux conditions de concurrence dans un scénario simultané.