Questo è scritto nella voce wiki di Symbolic Execution , ma non riesco a trovare alcun riferimento per questo. Qualcuno può mostrarmi un puntatore? Grazie.
Questo è scritto nella voce wiki di Symbolic Execution , ma non riesco a trovare alcun riferimento per questo. Qualcuno può mostrarmi un puntatore? Grazie.
Risposte:
Non sono a conoscenza di un documento riguardante il confronto tra esecuzione simbolica e interpretazione astratta. Né penso che ne sia necessario uno. La lettura delle descrizioni originali di queste due tecniche dovrebbe essere sufficiente.
(Al contrario, se ci fosse una connessione inaspettata, varrebbe la pena descriverla. Ma dubito fortemente che sia così.)
L'idea principale dell'esecuzione simbolica è che, in un punto arbitrario dell'esecuzione, è possibile esprimere i valori di tutte le variabili come funzioni dei valori iniziali. L'idea principale di interpretazione astratta è che è possibile esplorare sistematicamente tutte le esecuzioni di un programma mediante una serie di approssimazioni eccessive. (Riesco a sentire diversi appassionati di intelligenza artificiale gemere alla precedente approssimazione.)
Pertanto, almeno nella formulazione originale, l'esecuzione simbolica non riguardava l'esplorazione di tutte le possibili esecuzioni. Puoi vederlo anche nel titolo: include la parola "test". Ma ecco di più dalla Sezione 8: "Per i programmi con alberi di esecuzione infiniti, i test simbolici non possono essere esaustivi e non è possibile stabilire alcuna prova assoluta di correttezza".
Al contrario, l'interpretazione astratta mira a esplorare tutte le esecuzioni. Per fare ciò, utilizza diversi ingredienti, uno dei quali è molto simile all'idea principale dell'esecuzione simbolica. Questi ingredienti sono (1) stati astratti, (2) unendo e allargando (quindi, "reticolo" nel titolo).
Stati astrattiLo stato concreto di un programma in un determinato momento è sostanzialmente un'istantanea del contenuto della memoria (incluso il codice del programma stesso e il contatore del programma). Questo ha molti dettagli, che è difficile da rintracciare. Quando si analizza una particolare proprietà, è possibile ignorare ampie parti dello stato concreto. Oppure potresti voler preoccuparti solo se una particolare variabile è negativa, zero o positiva, ma non preoccuparti del suo valore esatto. In generale, si desidera prendere in considerazione una versione astratta dello stato concreto. Affinché ciò funzioni, è necessario disporre di una proprietà di commutatività: se si prende uno stato concreto, si esegue un'istruzione e quindi si astratto lo stato risultante, si dovrebbe ottenere lo stesso risultato se si astratto lo stato iniziale, quindi eseguire lo stesso dichiarazione ma sullo stato astratto. Questo diagramma di commutatività appare in entrambi i documenti. Questa è l'idea comune Ancora una volta, l'interpretazione astratta è più generale, perché non impone come astrarre uno stato - dice solo che dovrebbe esserci un modo per farlo. Al contrario, l'esecuzione simbolica dice che usi espressioni (simboliche) che menzionano i valori iniziali.
Unire e allargare. Se l'esecuzione del programma raggiunge una determinata istruzione in due modi diversi, l'esecuzione simbolica non tenta di unire le due analisi. Questo è il motivo per cui la citazione sopra parla di alberi di esecuzione, piuttosto che di scarti. Ma ricorda che l'interpretazione astratta vuole coprire tutte le esecuzioni. Pertanto, chiede un modo per unire le analisi di due esecuzioni nel punto in cui hanno lo stesso contatore di programmi. (L'unione potrebbeessere molto stupido ({a} join {b} = {a, b}) in modo che equivalga a quello che fa l'esecuzione simbolica.) In generale, unirsi a se stesso non è sufficiente a garantire che alla fine si finirà di analizzare tutte le esecuzioni. (In particolare, il muto join menzionato in precedenza non funzionerà.) Si consideri un programma con un loop: "n = input (); per i nell'intervallo (n): dostuff ()". Quante volte dovresti andare in giro e continuare ad aderire? Nessuna risposta fissa funziona. Pertanto, è necessario qualcos'altro, che si sta allargando , che può essere visto come euristico. Supponi di aver fatto il giro del ciclo 3 volte e di aver appreso che "i = 0 o i = 1 o i = 2". Quindi dici: hmmm, ... allargiamo e ottieni "i> = 0". Ancora una volta l'interpretazione astratta non dice come fare l'ampliamento, ma semplicemente quali proprietà dovrebbe ampliare l'allargamento delle proprietà.
(Mi dispiace per questa lunga risposta: non ho davvero avuto il tempo di accorciarlo.)
Penso che ciò significhi in un senso molto superficiale. Il primo passo dell'interpretazione astratta è identificare una semantica di raccolta concreta. Piuttosto che descrivere l'evoluzione di un singolo stato, la raccolta di semantica descrive l'evoluzione di insiemi di stati. Poiché ragioni di esecuzione simbolica relative alle rappresentazioni di insiemi di stati, si può sostenere che rappresenta la semantica concreta del programma. Non sono a conoscenza di una corrispondenza più precisa elaborata.
Vedi Patrick Cousot. Metodi iterativi di costruzione ed approssimazione di punti fissi di monoteroni monotoni su un treillis, analisi di serie di programmi (metodi iterativi per la costruzione e approssimazione di punti fissi di operatori monotoni su reticoli, analisi statica del programma). Thèse ès Sciences Mathématiques, Université Joseph Fourier, Grenoble, Francia, 21 marzo 1978. https://cs.nyu.edu/~pcousot/publications.www/CousotTheseEsSciences1978.pdf (purtroppo in francese), pagina (3) da -27 a (3) -29