Rapporto tra contratti e tipizzazione dipendente


31

Ho letto alcuni articoli su tipi dipendenti e contratti di programmazione. Dalla maggior parte di ciò che ho letto, sembra che i contratti siano controllati dinamicamente i vincoli e che i tipi dipendenti siano controllati staticamente.

Ci sono stati alcuni documenti che mi hanno fatto pensare che sia possibile avere contratti parzialmente controllati staticamente:

Con ciò, sembra esserci una notevole quantità di sovrapposizioni e la mia categorizzazione dei contratti rispetto ai tipi dipendenti inizia a scomparire.

C'è qualcosa di più profondo in entrambi i concetti che mi manca? O sono davvero solo categorie sfocate di rappresentare lo stesso concetto di base?

Risposte:


26

A livello pratico, i contratti sono affermazioni. Ti consentono di controllare le proprietà (senza quantificatore) delle singole esecuzioni di un programma. L'idea chiave alla base del controllo del contratto è l'idea della colpa - fondamentalmente, vuoi sapere chi è la colpa di una violazione del contratto. Può essere un'implementazione (che non calcola il valore promesso) o il chiamante (che ha passato una funzione del tipo sbagliato di valore).

L'intuizione chiave è che puoi rintracciare la colpa usando lo stesso meccanismo delle coppie di inclusione-proiezione nella costruzione del limite inverso della teoria dei domini. In sostanza, si passa dal lavorare con le asserzioni al lavorare con coppie di asserzioni, una delle quali incolpa il contesto del programma e l'altra incolpa il programma. Quindi, ciò consente di avvolgere le funzioni di ordine superiore con i contratti, poiché è possibile modellare la contraddizione dello spazio delle funzioni scambiando la coppia di asserzioni. (Vedi il documento di Nick Benton "Annullare la digitazione dinamica" , per esempio.)

I tipi dipendenti sono tipi. I tipi specificano le regole per affermare se determinati programmi sono accettabili o meno. Di conseguenza, non includono cose come la nozione di colpa, poiché la loro funzione è quella di impedire che programmi maleducati esistano in primo luogo. Non c'è nulla da incolpare poiché solo programmi ben formati sono persino espressioni grammaticali. Pragmaticamente, ciò significa che è molto facile usare tipi dipendenti per parlare di proprietà dei termini con quantificatori (es., Che una funzione funziona per tutti gli input).

Queste due viste non sono uguali, ma sono correlate. Fondamentalmente, il punto è che con i contratti, iniziamo con un dominio universale di valori e utilizziamo i contratti per ridurre le cose. Ma quando usiamo i tipi, proviamo a specificare in anticipo domini di valori più piccoli (con una proprietà desiderata). Quindi possiamo collegare i due tramite famiglie di relazioni orientate al tipo (cioè relazioni logiche). Ad esempio, vedi il recente "Blame for All" di Ahmed, Findler, Siek e Wadler , o "Il significato dei tipi: dalla intrinseca alla semantica estrinseca" di Reynolds .


Perché dici che i contratti sono quantificabili gratuitamente?
Radu GRIGore

3
Poiché in genere non è possibile utilizzare i test per stabilire proprietà delle funzioni universalmente quantificate, tutto qui.
Neel Krishnaswami,

3
A meno che i quantificatori non si estendano su domini finiti, nel qual caso possono essere visti come grandi congiunzioni e disgiunzioni. Oppure, se si desidera essere fantasiosi, è possibile verificare alcuni tipi di dichiarazioni quantificate, a condizione che i quantificatori si estendano ai tipi ricercabili di Martin Escardo (che possono essere infiniti).
Andrej Bauer

2
@Radu: chiamo cose come JML & co "logiche di programma". Le lingue di asserzione delle logiche dei programmi non si limitano ad essere termini dalla lingua dei programmi. Questo ti consente di escludere cose come asserzioni non terminali o con effetti collaterali, che non hanno una buona interpretazione logica. (Tuttavia, queste cose sono importanti per il controllo dei contratti - vedi il recente lavoro di Pucella e Tove all'ESOP sull'uso di contratti imperativi con stato per tenere traccia delle proprietà della linearità.)
Neel Krishnaswami

2
Questo perché ho scritto male il cognome di Tov. Vedi "Contratti con stato per tipi di affine", ccs.neu.edu/home/tov/pubs/affine-contracts
Neel Krishnaswami

13

Il problema (abbastanza astratto) che entrambi i tipi e i contratti attaccano è "Come garantire che i programmi abbiano determinate proprietà?". C'è una tensione intrinseca qui tra la capacità di esprimere una classe più ampia di proprietà e la capacità di verificare che un programma abbia o meno una proprietà. I sistemi di tipo solitamente garantiscono una proprietà molto specifica (il programma non si arresta in modo anomalo in determinati modi) e dispongono di un algoritmo di controllo del tipo. D'altro canto, i contratti consentono di specificare una gamma molto ampia di proprietà (ad esempio, l'output di questo programma è un numero primo) ma non viene fornito con un algoritmo di controllo.

Tuttavia, il fatto che non esista un algoritmo di controllo del contratto (che funziona sempre) non significa che non ci siano quasi algoritmi di controllo del contratto (che tendono a funzionare nella pratica). Ti consiglio di guardare Spec # e il plugin Jessie di Frama-C . Entrambi funzionano esprimendo "questo programma obbedisce a questo contratto" come una dichiarazione nella logica del primo ordine tramite la generazione delle condizioni di verifica e quindi chiedendo a un SMTrisolutore per andare prova a trovare una prova. Se il risolutore non riesce a trovare una prova, allora il programma è sbagliato o, beh, il risolutore non è riuscito a trovare una prova esistente. (Ecco perché si tratta di un algoritmo di controllo del contratto "quasi"). Esistono anche strumenti basati sull'esecuzione simbolica, il che significa approssimativamente che "questo programma obbedisce a questo contratto" è espresso come un insieme di proposizioni (in qualche logica). Vedi, ad esempio, jStar .

Il lavoro di Flanagan cerca di trarre il meglio da entrambi i mondi in modo da poter controllare rapidamente le proprietà simili a un tipo e poi lavorare per il resto. Non ho molta familiarità con i tipi ibridi, ma ricordo l'autore affermare che la sua motivazione era quella di trovare una soluzione che richiedesse meno annotazioni (rispetto al suo precedente lavoro su ESC / Java). In un certo senso, tuttavia, esiste una certa integrazione tra tipi e contratti in ESC / Java (e Spec #): quando si controllano i contratti, al risolutore viene detto che il controllo del tipo è riuscito in modo da poter visualizzare tali informazioni.


7

I contratti possono essere controllati staticamente. Se guardi il vecchio lavoro di Dana Xu su ESC / Haskell , è stata in grado di implementare il controllo completo del contratto in fase di compilazione, basandosi solo su un proverore di teoremi per l'aritmetica. La risoluzione è risolta da un semplice limite di profondità se ricordo correttamente:


6

Sia i contratti che i tipi consentono di rappresentare le specifiche in stile Hoare (condizioni pre / post) sulle funzioni. Entrambi possono essere controllati staticamente al momento della compilazione o dinamicamente in fase di esecuzione.

I tipi dipendenti consentono di codificare una gamma molto ampia di proprietà nel sistema dei tipi, i tipi di proprietà che i programmatori del contratto si aspettano. Questo perché possono dipendere dai valori del tipo. I tipi dipendenti hanno la tendenza a essere controllati staticamente, anche se credo che i documenti che hai citato guardino approcci alternativi.

Alla fine, c'è poca differenza. Penso che sia più che i tipi dipendenti siano una logica in cui è possibile esprimere le specifiche mentre i contratti sono una metodologia di programmazione in cui si esprimono le specifiche.


È un po 'fuorviante affermare che le annotazioni in stile Hoare possono essere verificate staticamente. Se la logica è FO, come è di solito, allora il problema è sicuramente indecidibile. Ma sì, so che intendevi dire che si può provare e persino riuscire in molte situazioni.
Radu GRIGore

1
Avevo l'impressione che la generazione della prova potesse essere indecidibile, ma il controllo di una prova dovrebbe esserlo. Molte lingue tipicamente dipendenti si basano sull'utente per fornire il valore di prova dell'abitazione del tipo di teorema.
Jason Reich

Hai ragione. Ma vivo nel mondo automatizzato, dove di solito non viene richiesta una prova all'utente .
Radu GRIGore,
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.