Perché gli invarianti sono importanti in Informatica


16

Capisco "invariante" nel suo senso letterale. Li riconosco anche quando scrivo il codice. Ma non credo di capire l'importanza di questo termine nel contesto dell'informatica.

Ogni volta che leggo conversazioni \ white paper sulla progettazione linguistica di famosi programmatori \ informatici, il termine "invariante" continua a comparire come un gergo; e questa è la parte che non capisco. Cosa c'è di così speciale?


Uso molte asserzioni ... non tanto per garantire la correttezza quanto per ridurre la probabilità di bug.
Giobbe

Risposte:


7

Un algoritmo è un processo ripetibile. Se è ripetibile, deve avere attributi che non cambiano con la ripetizione. Questi sono i tuoi invarianti. Gli invarianti sono combinati con e / o operano sui dati (potenzialmente) variabili che verranno inseriti nel tuo algoritmo.

Pertanto, il punto centrale della programmazione è identificare ciò che non varia: questo è essenzialmente il tuo programma.

Nel programma orientato agli oggetti, c'è l'idea che ogni oggetto dovrebbe fare bene una sola cosa. Ciò significa essenzialmente che (per OOP basato sulla classe) una classe definisce gli invarianti per un singolo algoritmo, insieme ai segnaposto (variabili) per qualsiasi dato variante che potrebbe essere necessario ai suoi oggetti. Idealmente in OO, isolare ciò che varia il più possibile, in modo che ogni oggetto sia per lo più invariante.


27

La nozione di invariante è fortemente legata agli "effetti collaterali". Credo che sia stato promosso dall'approccio "Design by Contract (DbC)" di Bertrand Meyer per la progettazione del software.

DbC arricchisce i tipi di dati astratti (spina dorsale delle classi) con 3 nozioni importanti, precondizioni, postcondizioni, invarianti . Si spiega facilmente quando si fa riferimento alle procedure, quindi cercherò di spiegare in riferimento ad esso:

  1. Una condizione preliminare rappresenta la condizione che i dati di input che una procedura deve rispettare per poter chiamare tale procedura. Questa condizione preliminare deve essere rispettata e applicata dal cliente di quella particolare procedura. Il progettista della procedura potrebbe tuttavia difendersi dai client che non rispettano il presupposto affermando tale condizione come prime righe della procedura. Ad esempio avere un metodo double divide(double dividend, double divisor)potrebbe essere un prerequisito divisor != 0.

  2. Una postcondizione rappresenta la condizione sui dati di output dopo il ritorno della procedura; è interamente compito del progettista delle procedure rispettare questo postcondizionamento purché sia ​​rispettato il presupposto; in uno stile di programmazione della difesa prima del ritorno, si può affermare la postcondizione.

  3. Un invariante può essere considerato sia una precondizione che una postcondizione, ma con una comprensione diversa della precondizione e della postcondizione dai concetti sopra. Un invariante dice sostanzialmente che se l'input ha una condizione particolare soddisfatta prima che la procedura fosse chiamata, allora quella particolare condizione è valida dopo che la procedura è stata chiamata. Ad esempio, un invariante valido per una procedura boolean search(int term, int array[])potrebbe dire che lo stato arrayprecedente alla chiamata è lo stesso di quello successivo alla chiamata.

Far rispettare gli invarianti sulle procedure (e non solo sulle procedure) è un'ottima cosa poiché riduce gli effetti collaterali ; questo è utile poiché gli effetti collaterali sono un grande male nella programmazione. Una particolare procedura potrebbe cambiare lo stato degli argomenti di input, o cambiare lo stato di alcune variabili globali o dipendere da alcune variabili globali; questo potrebbe portare a brutte situazioni in cui due chiamate identiche sulla stessa procedura (con lo stesso input) potrebbero produrre output diversi. Ciò porta a conoscere la cronologia delle chiamate ed è molto difficile eseguire il debug soprattutto in un contesto multithreading.


2

Un invariante è una proprietà logica che viene preservata da alcune operazioni.

  • Hai bisogno di invarianti per ragionare sugli anelli. Dal momento che non sai in anticipo quante iterazioni ci saranno (o non avresti bisogno di un ciclo), ogni iterazione deve preservare l'invariante, in modo che alla fine puoi dimostrare alcune proprietà utili sul ciclo.

  • Hai bisogno di invarianti per ragionare sulle proprietà dei dati incapsulati. Spesso i vari dati all'interno di un modulo o oggetto devono soddisfare determinate proprietà per il corretto funzionamento (ad esempio, un elenco che rappresenta un set deve sempre essere ordinato). Volete che ogni funzione o metodo che opera sui dati conservi queste proprietà, quindi sono anche invarianti.


0

Da quello che so l'importanza di invariante deriva dal fatto che è la base per dimostrare che un algoritmo calcola una determinata funzione. Ad esempio, hai sviluppato un nuovo algoritmo di ordinamento, ma come puoi essere così sicuro che si ordina davvero con ogni input o con ogni output corretto. Il prossimo passo è costruire invarianti che corrispondano al flusso dell'algoritmo e dimostrare che ordina gli invarianti.


0

Nel contesto del sistema di tipi di un linguaggio di programmazione, un tipo invariante è un tipo non convertibile. Ad esempio in Java, quando si sovraccarica un metodo, tutti i parametri sono invarianti, mentre il tipo restituito è covariante (può essere lo stesso o un sottotipo).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.