2013-05-07 26 views
45

Ho una domanda su come Z3 risolve in modo incrementale i problemi. Dopo aver letto alcune risposte, ho trovato quanto segue:Come funziona la risoluzione incrementale in Z3?

  1. Esistono due modi per utilizzare Z3 per la risoluzione incrementale: uno è la modalità push/pop (stack), l'altro utilizza le ipotesi. Soft/Hard constraints in Z3.
  2. In modalità pila, Z3 dimenticheranno tutti i lemmi apprese in globale (ho ragione?) portata anche dopo un "pop" locale Efficiency of constraint strengthening in SMT solvers
  3. In modalità ipotesi (non so il nome, che è il nome che mi viene in mente), z3 non semplificherà alcune formule, ad es propagazione del valore. z3 behaviour changing on request for unsat core

ho qualche confronto (siete invitati a chiedere per le formule, sono semplicemente troppo grandi per mettere sul rise4fun), ma qui ci sono le mie osservazioni: Su alcune formule, tra cui quantificatori, la modalità di assunzioni è Più veloce. Su alcune formule con molte variabili booleane (variabili di ipotesi), la modalità stack è più veloce della modalità assunzioni.

Sono implementati per scopi specifici? Come funziona la risoluzione incrementale in Z3?

risposta

7

Sì, ci sono essenzialmente due modalità incrementali.

In pila: utilizzando push(), pop() si crea un contesto locale, che segue una disciplina di stack. Le asserzioni aggiunte sotto un push() vengono rimosse dopo un pop corrispondente(). Inoltre, tutti i lemmi derivati ​​da una spinta vengono rimossi. Utilizzare push()/pop() per emulare il congelamento di uno stato e aggiungere ulteriori vincoli sullo stato congelato, quindi riprendere lo stato congelato. Ha il vantaggio che qualsiasi overhead di memoria addizionale (come i lemmi appresi) creato nell'ambito di un push() viene rilasciato. L'ipotesi di lavoro è che i lemmi appresi sotto una spinta non sarebbero più utili.

Assunzione base: usando lettere assunzione aggiuntivi passati per verificare()/check_sat() è possibile (1) estratto nuclei insoddisfacibile nel corso degli letterali assunzione, (2) guadagnare incrementalità locale senza lemmi della spazzatura raccolta che vengono derivate indipendentemente dalle ipotesi . In altre parole, se Z3 impara un lemma che non contiene nessuno dei presupposti letterali, si aspetta di non raccoglierli. Per utilizzare efficacemente i letterali di presupposto, dovresti aggiungerli anche alle formule. Quindi il compromesso è che le clausole usate con le assunzioni contengono una certa quantità di bloat. Ad esempio, se si desidera assumere localmente una formula (< = xy), aggiungere una clausola (=> p (< = xy)) e assumere p quando si chiama check_sat(). Si noti che l'ipotesi originale era un'unità. Z3 diffonde le unità in modo efficiente. Con la formulazione che utilizza i letterali di assunzione non è più un'unità al livello di base della ricerca. Ciò comporta un ulteriore sovraccarico. Le unità diventano clausole binarie, le clausole binarie diventano clausole ternarie, ecc.

La differenziazione tra funzionalità push/pop vale per il motore SMT predefinito di Z3. Questo è il motore che la maggior parte delle formule utilizzerà. Z3 contiene alcuni portfolio di motori. Ad esempio, per i problemi con il vettore di bit puro, Z3 può finire per utilizzare il motore basato su sat. L'incrementalità nel motore basato su sat è implementata in modo diverso rispetto al motore predefinito. Qui l'incrementalità è implementata usando i letterali di presupposto. Ogni asserzione che aggiungi nell'ambito di una spinta è asserita come implicazione (=> formula scope_literals). check_sat() all'interno di tale ambito dovrà occuparsi di valori letterali di assunzione. Sul rovescio della medaglia, qualsiasi conseguenza (lemma) che non dipende dall'ambito corrente è non garbage collection su pop().

In modalità di ottimizzazione, quando si asseriscono obiettivi di ottimizzazione o quando si utilizzano gli oggetti di ottimizzazione sull'API, è anche possibile richiamare il push/pop. Allo stesso modo con punti fissi. Per queste due funzionalità, push/pop sono essenzialmente utili per l'utente. Non c'è incrementalità interna. Il motivo è che queste due modalità utilizzano una pre-elaborazione sostanziale super-non incrementale.