web-dev-qa-db-fra.com

Qu'est-ce qu'un invariant?

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!)?

105
Dustman

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.

154
Jacob Baskin

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é.

26
moonshadow

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.

15
Michael Haren

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.

13
cero

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

Le invariant (encore une fois, c'est plus comme un concept):

// 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)

Invariant de boucle:

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

Comment garder l'invariant vrai?

Facile! compte d'incrément.

Donc ++count; ferait du bien !. Maintenant, notre code devient quelque chose comme ça,

while(cin>>x){
 ++count; 
 }

Mais

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;
 }

Allons vérifier

Si le code correspond à notre invariant

// 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

6
void

Quelque chose qui ne change pas dans un bloc de code

4
Chris

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.

2
Kaushik

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.

2
HassanTC

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.

1
meshal almotairi

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é.

enter image description here