it-swarm.it

Cosa sono gli invarianti, come possono essere usati e l'hai mai usato nel tuo programma?

Sto leggendo Coders at Work, e in esso si parla molto di invarianti. Per quanto ho capito, un invariante è una condizione che detiene sia prima che dopo un'espressione. Sono, tra l'altro, utili nel dimostrare che il ciclo è corretto, se ricordo correttamente il mio corso di Logica.

La mia descrizione è corretta o ho perso qualcosa? Li hai mai usati nel tuo programma? E se sì, come hanno beneficiato?

54
gablin

In OOP, un invariante è un insieme di asserzioni che devono sempre essere vere durante la vita di un oggetto affinché il programma sia valido. Dovrebbe valere dalla fine del costruttore all'inizio del distruttore ogni volta che l'oggetto non sta eseguendo un metodo che cambia il suo stato.

Un esempio di invariante potrebbe essere che esattamente una delle due variabili membro dovrebbe essere nulla. O che se uno ha un determinato valore, allora l'insieme di valori consentiti per l'altro è questo o quello ...

A volte uso una funzione membro dell'oggetto per verificare che l'invariante sia valido. In caso contrario, viene sollevata un'affermazione. E il metodo viene chiamato all'inizio e all'uscita di ogni metodo che cambia l'oggetto (in C++, questa è solo una riga ...)

47
Xavier Nodet

Bene, le cose che vedo in questo thread sono tutte fantastiche, ma ho una definizione di "invariante" che è stata tremendamente utile per me al lavoro.

Un invariante è qualsiasi regola logica che deve essere rispettata durante l'esecuzione del programma che può essere comunicata a un essere umano, ma non al compilatore.

Questa definizione è utile perché suddivide le condizioni in due gruppi: quelli del compilatore di cui ci si può fidare con l'applicazione, e quelli che devono essere documentati, discussi, commentati o altrimenti comunicati ai contributori affinché possano interagire con la base di codice senza introdurre bug .

Inoltre, questa definizione è utile perché ti consente di utilizzare la generalizzazione, "Gli invarianti sono cattivi".

Ad esempio, il cambio in un'auto a cambio manuale è progettato per evitare un invariante. Se avessi voluto, avrei potuto costruire una trasmissione con una leva per ogni marcia. Questa leva può essere in avanti ("innestata") o indietro ("disinnestata"). In un tale sistema, ho creato un "invariante", che potrebbe essere documentato come tale:

"È fondamentale che l'ingranaggio attualmente innestato sia disinnestato prima di innestare un altro ingranaggio. Innestare due marce contemporaneamente provoca stress meccanici che lacerano la trasmissione. Disinnestare sempre l'ingranaggio attualmente innestato prima di innestarne un altro."

E così, si potrebbe incolpare trasmissioni interrotte sulla guida sciatta. Le auto moderne, tuttavia, usano un solo bastone che ruota attorno agli ingranaggi. È progettato in modo tale che, su una moderna auto con cambio a levetta, non è possibile innestare due marce contemporaneamente.

In questo modo, potremmo dire che la trasmissione è stata progettata per "rimuovere l'invariante", perché non consente di configurarsi meccanicamente in modo tale da violare la regola logica.

Ogni invariante di questo tipo che rimuovi dal tuo codice è un miglioramento, perché riduce il carico cognitivo di lavoro con esso.

15
Daniel Burbank

Basato sulla seguente citazione di Coders At Work ...

Ma una volta che conosci l'invariante che sta mantenendo, puoi vedere, ah, se manteniamo quell'invariante, avremo tempo di ricerca del registro.

... Immagino che "invariant" = "condizione che si desidera mantenere per garantire l'effetto desiderato".

Sembra che l'invariante abbia due sensi che differiscono in modo sottile:

  1. Qualcosa che rimane lo stesso.
  2. Qualcosa che stai cercando di mantenere lo stesso, al fine di raggiungere l'obiettivo X (come un "tempo di ricerca del registro" sopra).

Quindi 1 è come un'asserzione; 2 è come uno strumento per dimostrare la correttezza, le prestazioni o altre proprietà - penso. Vedi articolo di Wikipedia per un esempio di 2 (dimostrando la correttezza della soluzione al puzzle MU).

In realtà un terzo senso di invariante è:

.3. Cosa dovrebbe fare il programma (o modulo o funzione); in altre parole, il suo scopo.

Dallo stesso colloquio con Coders At Work:

Ma ciò che rende gestibile il grande software è avere alcuni invarianti globali o dichiarazioni di grande quadro su ciò che dovrebbe fare e ciò che le cose dovrebbero essere vere.

3
Jonathan Aquino

Un invariante (nel senso comune) indica alcune condizioni che devono essere vere ad un certo punto nel tempo o anche sempre mentre il programma è in esecuzione. per esempio. PreCondizioni e PostCondizioni possono essere utilizzate per affermare alcune condizioni che devono essere vere quando viene chiamata una funzione e quando ritorna. Gli invarianti di oggetti possono essere usati per affermare che un oggetto deve avere uno stato valido per tutto il tempo in cui esiste. Questo è il principio secondo il progetto.
Ho usato gli invarianti in modo informale usando i controlli nel codice. Ma più recentemente sto giocando con il codice libreria dei contratti per .Net che supporta direttamente gli invarianti.

3
softveda

Un invariante è come una regola o un presupposto che può essere utilizzato per dettare la logica del programma.

Ad esempio, supponiamo di avere alcune applicazioni software che tengono traccia degli account utente. Supponiamo inoltre che l'utente possa avere più account, ma per qualsiasi motivo è necessario distinguere tra account principale di un utente e account "alias".

Questo potrebbe essere un record DB o qualcos'altro, ma per ora supponiamo che ogni account utente sia rappresentato da un oggetto classe.

class userAccount {private char * pUserName; char privato * pParentAccountUserName;

...}

Un invariante potrebbe essere il presupposto che se pParentAccountUserName è NULL o vuoto, questo oggetto è l'account principale. Puoi utilizzare questo invariante per distinguere diversi tipi di account. Esistono probabilmente metodi migliori per distinguere diversi tipi di account utente, quindi tieni presente che questo è solo un esempio per mostrare come potrebbe essere usato un invariante.

1
Pemdas

Provenienti da un background fisico, in fisica abbiamo degli invarianti, che sono essenzialmente quantità che non variano durante un intero calcolo/simulazione. Ad esempio, in fisica, per un sistema chiuso l'energia totale è conservata. O ancora in fisica, se due particelle si scontrano, i frammenti risultanti devono contenere esattamente l'energia con cui hanno iniziato e esattamente lo stesso momento (una quantità vettoriale). Di solito non ci sono abbastanza invarianti per specificare totalmente il risultato. Ad esempio nella collisione a 2 parti, abbiamo quattro invarianti, tre componenti del momento e una componente di energia, ma il sistema ha sei gradi di libertà (sei numeri per descriverne lo stato). Gli invarianti dovrebbero essere conservati nell'errore di arrotondamento, ma la loro conservazione non dimostra che la soluzione sia corretta.

Quindi, in genere, queste cose sono importanti come controlli di integrità, ma da sole non possono dimostrare la correttezza.

1
Omega Centauri