Pourquoi les invariants sont-ils importants en informatique

16

Je comprends «invariant» dans son sens littéral. Je les reconnais également lorsque je tape du code. Mais je ne pense pas comprendre l'importance de ce terme dans le contexte de l'informatique.

Chaque fois que je lis des conversations \ livres blancs sur la conception de langages de programmeurs célèbres \ informaticiens, le terme "invariant" continue d'apparaître comme un jargon; et c'est la partie que je ne comprends pas. Qu'est-ce qui est si spécial à ce sujet?

Antony Thomas
la source
J'utilise beaucoup d'assertions ... pas tant pour garantir l'exactitude que pour réduire la probabilité de bugs.
Job

Réponses:

7

Un algorithme est un processus reproductible. S'il est répétable, il doit avoir des attributs qui ne changent pas avec la répétition. Ce sont vos invariants. Les invariants sont combinés avec et / ou opèrent sur les données (potentiellement) variables qui seront introduites dans votre algorithme.

Ainsi, tout l'intérêt de la programmation est d'identifier ce qui ne varie pas - c'est essentiellement votre programme.

Dans un programme orienté objet, il existe une notion selon laquelle chaque objet doit bien faire une seule chose. Cela signifie essentiellement que (pour la POO basée sur une classe), une classe définit les invariants pour un seul algorithme, ainsi que les espaces réservés (variables) pour toutes les données de variantes dont ses objets pourraient avoir besoin. Idéalement, en OO, vous isoleriez ce qui varie autant que possible, de sorte que chaque objet soit principalement invariant.

Matthew Flynn
la source
27

La notion d'invariant est fortement liée aux «effets secondaires». Je crois qu'il a été promu par l'approche «Design by Contract (DbC)» de Bertrand Meyer pour la conception de logiciels.

DbC enrichit les types de données abstraits (épine dorsale des classes) avec 3 notions importantes, préconditions, postconditions, invariants . Cela s'explique facilement en se référant aux procédures, donc je vais essayer d'expliquer en référence avec cela:

  1. Une précondition représente les données d'entrée de condition qu'une procédure doit respecter pour appeler cette procédure. Cette condition préalable doit être respectée et imposée par le client de cette procédure particulière. Le concepteur de la procédure peut cependant se défendre contre des clients qui ne respectent pas la condition préalable en affirmant cette condition comme premières lignes de la procédure. Par exemple, avoir une méthode double divide(double dividend, double divisor)peut être une condition préalable divisor != 0.

  2. Une postcondition représente la condition a sur les données de sortie après le retour de la procédure; il appartient entièrement au concepteur de la procédure de respecter cette postcondition à condition que celle-ci ait été respectée; dans un style de programmation de défense avant le retour, la postcondition peut être affirmée.

  3. Un invariant peut être considéré à la fois comme une condition préalable et une postcondition, mais avec une compréhension différente de la précondition et de la postcondition des concepts ci-dessus. Un invariant dit essentiellement que si l'entrée a une condition particulière remplie avant l'appel de la procédure, alors cette condition particulière est valide après l'appel de la procédure. Par exemple, un invariant valide pour une procédure boolean search(int term, int array[])pourrait dire que l'état d' arrayavant l'appel est le même qu'après l'appel.

L'application des invariants aux procédures (et pas seulement aux procédures) est une grande chose car elle réduit les effets secondaires ; cela est utile car les effets secondaires sont un grand mal dans la programmation. Une procédure particulière peut changer l'état des arguments d'entrée, ou changer l'état de certaines variables globales, ou dépendre de certaines variables globales; cela peut conduire à des situations désagréables où deux appels identiques sur la même procédure (avec la même entrée) peuvent produire des sorties différentes. Cela conduit à connaître l'historique des appels et est très difficile à déboguer, en particulier dans un contexte multithreading.

m3th0dman
la source
2

Un invariant est une propriété logique qui est préservée par certaines opérations.

  • Vous avez besoin d'invariants pour raisonner sur les boucles. Puisque vous ne savez pas à l'avance combien d'itérations il y aura (ou vous n'auriez pas besoin d'une boucle), chaque itération doit conserver l'invariant, afin qu'à la fin vous puissiez prouver une propriété utile sur la boucle.

  • Vous avez besoin d'invariants pour raisonner sur les propriétés des données encapsulées. Souvent, les diverses données à l'intérieur d'un module ou d'un objet doivent satisfaire certaines propriétés pour un fonctionnement correct (par exemple, une liste représentant un ensemble doit toujours être triée). Vous voulez que chaque fonction ou méthode opérant sur les données préserve ces propriétés, elles sont donc également invariantes.

starblue
la source
0

D'après ce que je sais, l'importance de l'invariant vient du fait que c'est le bloc de construction pour prouver qu'un algorithme calcule une certaine fonction. Par exemple, vous avez développé un nouvel algorithme de tri, mais comment pouvez-vous être sûr qu'il trie vraiment avec chaque entrée ou avec chaque sortie correcte. L'étape suivante consiste à construire des invariants qui correspondent au flux de l'algorithme et à prouver qu'il trie à l'aide des invariants.

Emilian Branzelov
la source
0

Dans le contexte du système de type d'un langage de programmation, un type invariant est un type non convertible. Par exemple, en Java, lors de la surcharge d'une méthode, tous les paramètres sont invariants, tandis que le type de retour est covariant (peut être le même ou un sous-type).

MebAlone
la source