În informatică teoretică , problema SAT sau problema de satisfacție booleană este problema deciziei , care, dată fiind logica formulei propoziționale , determină dacă există o atribuire de variabile propoziționale care face formula adevărată.
Această problemă este foarte importantă în teoria complexității . A fost scoasă la lumină de teorema lui Cook , care stă la baza teoriei completitudinii NP și a problemei P = NP . Problema SAT are, de asemenea, multe aplicații, în special în ceea ce privește satisfacerea constrângerilor , planificarea clasică, verificarea modelelor , diagnosticarea și chiar configuratorul unui PC sau al sistemului de operare al acestuia: revenim la formulele propoziționale și folosim un rezolvator SAT .
Formulele logicii propoziționale sunt construite din variabile propoziționale și din conectorii booleni "și" ( ), "sau" ( ), "nu" ( ). O formulă este satisfăcătoare (spunem și satisfăcătoare ) dacă există o atribuire de variabile propoziționale care face formula logică adevărată. De exemplu :
Un literal este o variabilă propozițională (literal pozitiv) sau negarea unei variabile propoziționale (literal negativ). O clauză este o disjuncție a formei în care sunt literali.
O formulă de calcul propozițională este în formă normală conjunctivă (sau formă clauzală sau CNF înseamnă Forma normală conjunctivă ) dacă este o conjuncție de clauze.
ExempluFie setul de variabile și formula . , Și sunt clauze cu două literale de fiecare clauză. Conjuncția lor este o formă conjunctivă normală.Dacă formula propozițională nu este în formă normală conjunctivă, o putem transforma într-o formă normală conjunctivă echivalentă cu dimensiuni cel mult exponențiale în formula inițială. Îl putem transforma, de asemenea, într-o formă conjunctivă normală echisatisfăcătoare de dimensiune liniară în formula inițială.
Considerăm restricțiile sintactice ale problemei SAT.
Problema SAT este o problemă NP - completă conform teoremei lui Cook . În special, nu se cunoaște niciun algoritm determinist polinomial care să îl rezolve. În mod similar, deoarece orice formulă se poate transforma într-o formă conjunctivă normală echisatisfăcătoare de dimensiune liniară în formula inițială, problema CNF-SAT este, de asemenea, NP-completă .
Problema 3 - SAT este, de asemenea, NP - completă. Pentru a demonstra dificultatea NP a 3-SAT, este suficient să se demonstreze că problema CNF-SAT este polinomial reductibilă la 3 - SAT. Reducerea transformă fiecare clauză cu în .
Problema 2-SAT este restricționarea problemei SAT la formele normale conjunctive cu cel mult 2 litere per clauză. Această problemă este în clasa P . Sub presupunerea , nu este complet NP. Există mai mulți algoritmi polinomiali deterministi pentru a rezolva problema 2-SAT.
Algoritmul lui Aspvall, Plass și Tarjan Algoritmul ia o formulă conjunctivă de formă normală cu cel mult 2 litere per clauză. O clauză de ordinul doi este echivalentă cu implicațiile și . Pentru a rezolva 2-SAT, construim un grafic cu două direcții (numit grafic 2-SAT) conform următoarelor două reguli:Christos Papadimitriou a arătat în 1994 că problema 2-SAT este NL-completă .
Problema satisfiabilitate a unui set de clauze Horn propoziționale (adică, cu cel mult un literal pozitiv de clauza) este în clasa P . Mai precis, există un algoritm liniar în mărimea clauzelor care rezolvă problema satisfacției. Este P-complet (pentru reducerea spațiului logaritmic ).
Teorema lui Schaefer oferă condiții necesare și suficiente pentru ca o variantă a problemei SAT să fie în clasa P sau NP - completă . Găsim rezultatele complexității referitoare la 3-SAT (NP-complet), 2-SAT (în P), HORN-SAT (în P) ca aplicații ale acestei teoreme.
Cea mai evidentă metodă pentru a rezolva o problemă SAT este să parcurgeți tabelul de adevăr al problemei, dar complexitatea este apoi exponențială în comparație cu numărul de variabile.
Pentru a dovedi satisfacția CNF , este suficient să alegeți o variabilă și să demonstrați recursiv satisfacția lui sau . Procedura este recursiv mai ușoară, deoarece cu sau poate fi adesea simplificată. Apelul recursiv construiește un arbore binar de căutare .
În general, există clauze de unitate la fiecare nod (CNF este de formă ), care permit reducerea spațiului de căutare.
Exemplu Luați în considerare CNF: . A doua clauză ( ) este unitară și permite obținerea imediată . Putem înlocui valorile din acest CNF. Asta da : . Din nou, avem o clauză unitară și obținem . Apoi, prin propagare , obținem .În acest exemplu, am găsit valorile celor trei variabile fără a extinde măcar arborele de căutare. În general, spațiul de căutare poate fi redus foarte mult. Pe de altă parte, dacă o variabilă apare întotdeauna pozitiv în CNF , atunci putem pune deoarece este satisfăcătoare dacă și numai dacă este satisfăcătoare (și la fel dacă variabila apare negativ). Astfel, în exemplul anterior, apare doar negativ și atribuirea poate fi realizată. Rețineți că această atribuire face posibilă accelerarea descoperirii unei soluții, dar că soluțiile ar putea exista prin efectuarea atribuirii opuse. DPLL Algoritmul (Davis, Putnam, Davis, Logemann, Loveland) se bazează pe aceste idei.
Alegerea variabilei care trebuie dezvoltată este foarte importantă pentru performanța algoritmilor SAT. În general, alegem variabilele care apar cel mai des, dacă este posibil în clauzele de mărime 2.
Clauze de învățare prin conflictePrincipiul solvenților CDCL (Conflict-Driven Clause Clause Learning) este acela de a utiliza un mecanism pentru a învăța noi clauze în timpul unei căutări, apoi de a utiliza la maximum informațiile învățate în speranța de a îmbunătăți timpul de căutare. Din punct de vedere practic, această metodologie este foarte eficientă în rezolvarea problemelor concrete. Învățarea clauzelor este după cum urmează: atunci când apare un conflict în timpul căutării, adică atunci când se arată că o atribuire parțială este incompatibilă cu setul de clauze, putem izola un subset al acestor atribuiri și un subset al acestor clauze, care sunt responsabile pentru conflict (atribuțiile nu sunt în concordanță cu clauzele). Învățarea clauzelor face două lucruri. În primul rând, evită repetarea acelorași erori de mai multe ori în arborele de căutare. În al doilea rând, clauza învățată va intra în conflict cu starea arborelui de căutare. Prin urmare, va fi necesar să efectuați un backtracking pentru a vă asigura că cel puțin unul dintre aceste litere este adevărat.
Există diferite metode pentru a genera noi clauze dintr-o inconsecvență locală.
Metoda naivăSă instanța de rezolvat să aibă următoarea formulă :
și interpretarea parțială definită prin: . Această interpretare duce la un conflict, deoarece implică asta , în timp ce implică asta . Pentru a genera o clauză care reprezintă acest conflict, este posibil să se ia negarea de interpretare : . Cu toate acestea, această metodă are un dezavantaj major: dimensiunea clauzei este în întregime determinată de întreaga interpretare. Cu toate acestea, anumite părți ale interpretării pot fi complet independente de conflictul pe care cineva dorește să îl reprezinte. De fapt, să adăugăm formulele la instanță : și să fie interpretarea curentă . Conflictul apare din primele două clauze și deci din valorile lui și . Cu toate acestea, clauza generată de negarea interpretării va lua în considerare toate variabilele, cu excepția . Ca urmare, clauza va fi inutilă de lungă.
Analiza conflictelorCând se folosește această metodă, se creează un grafic pentru a reprezenta originea propagării, numit grafic de implicație. Nodurile reprezintă literali adevărați. Există două tipuri de noduri: noduri pătrate a căror valoare literală provine dintr-o alegere arbitrară și noduri rotunde a căror valoare provine dintr-o propagare. Informațiile sunt, de asemenea, asociate cu fiecare nod: nivelul nodului în cauză. Acest nivel este definit de numărul literelor alese înainte de efectuarea propagării dacă a existat propagare. În caz contrar, nivelul este definit de numărul literelor alese, inclusiv literalul curent. Arcurile interconectează literele care fac parte dintr-o clauză de propagare. Destinația unui arc este literalul propagat, sursa (sursele) fiind celelalte litere din clauză. Să instanța de rezolvat să aibă următoarea formulă :
însoțită de interpretarea pe care nivelurile de diferite valori literale sunt specificate precum și literal care duce la incoerență: . Apoi, este posibil să trageți graficul următor din acesta.
Datorită acestui grafic, este posibil să se creeze o clauză care să reprezinte cauza conflictului. Metoda utilizată este următoarea: începem prin a crea rezolvarea clauzelor care duc la un conflict. Apoi, atâta timp cât există mai mult de un literal al nivelului actual, se creează o nouă rezolvare între rezolvarea curentă și cauza unuia dintre literalele nivelului actual. În exemplul nostru, acest lucru va da (unde reprezintă rezoluția dintre clauză și clauză )
Backtracking necronologicOdată ce clauza a fost învățată, aceasta va fi utilizată pentru restabilire. Ideea din spatele revenirii non-cronologice este că se va face o revenire astfel încât starea atribuțiilor să fie astfel încât să rămână doar un literal neatribuit. Astfel, datorită clauzei învățate, va fi posibilă continuarea diferitelor propagări atunci când acest lucru nu mai este posibil fără ea.
Dacă luăm exemplul prezentat în secțiunea de analiză a conflictelor, clauza învățată ne oferă două litere. Nivelurile variabilelor corespunzătoare sunt: variabilă = 3, variabilă = 2. Pentru a ști la ce nivel este necesar să vă întoarceți, trebuie să vă uitați la cel mai profund nivel (nivelul este mai adânc decât nivelul ) dintre variabilele unui nivel mai mare decât nivelul actual. Deoarece clauza învățată conține doar două litere, există un singur nivel diferit de nivelul curent: nivelul 2. Prin urmare, se efectuează o revenire până la acest nivel și, prin urmare, se lasă ca interpretare . Cu toate acestea, cu o astfel de interpretare, clauza învățată conține o singură variabilă neatribuită: în timp ce cealaltă este afectată în așa fel încât literalul să fie fals. Aceasta implică necesitatea propagării variabilei la valoarea false.
Deși în acest exemplu, revenirea se face doar la un nivel, este posibil ca acesta să crească mai multe niveluri simultan. Într-adevăr, imaginați-vă că putem adăuga N niveluri între nivelul 2 și nivelul 3, unde toate variabilele care apar acolo sunt variabile noi. Deoarece aceste niveluri nu ar avea niciun impact asupra vechiului nivel 3, revenirea ar crește brusc aceste niveluri N + 1.
Abordări prospectiveAbordarea prospectivă constă în explorarea arborelui de cercetare pentru a descoperi anumite sarcini. Astfel, având în vedere un CNF , având în vedere o variabilă neinstanțiată, CNF-urile și sunt căutate . Dacă cele două CNF conduc la instanțierea aceleiași variabile cu aceeași valoare, atunci instanțierea se poate face din CNF .
Exemplu Luați în considerare CNF . Suntem interesați aici de variabilă și prospectăm variabila . Luați în considerare sarcina . Obținem și, prin urmare, atribuirea (deoarece această variabilă apare doar pozitiv). Luați în considerare sarcina . Obținem și, prin urmare, clauza de atribuire prin unitate. În toate cazurile, această atribuire este obținută și, prin urmare, este posibilă de la CNF .Amintiți-vă că complexitatea problemei SAT provine din dimensiunea exponențială a arborelui de căutare în comparație cu numărul de variabile. Prospectarea face posibilă reducerea considerabilă a acestui număr de variabile de la rădăcină (sau de la orice nod al arborelui) cu o complexitate suplimentară relativ scăzută în vederea reducerii arborelui de căutare.
Program dinamicSamer și Szeider au propus un program dinamic algoritm FTP în care lățimea arborelui graficului asociată cu formula care urmează să fie testată. Avantajul acestui algoritm este că poate face și contorizarea evaluărilor și, prin urmare, rezolva problema #SAT. De asemenea, poate fi paralelizat . Este implementat în instrumentul gpuSAT (paralelizarea este implementată prin GPU).
Pornind de la o alocare a tuturor variabilelor, încercăm să modificăm anumite evaluări pentru a reduce numărul de clauze nesatisfăcute. Acest algoritm suferă de mai multe defecte: poate cădea în minime locale și nu este în măsură să dovedească nesatisfacție, dar este foarte eficient în probleme nestructurate (adică deseori probleme generate aleatoriu). În caz de eșec după o lungă perioadă de timp, este posibil să alegeți o nouă alocare aleatorie pentru a evita minimele locale.
Este posibil să reduceți (traduceți) unele probleme de inteligență artificială la problema SAT pentru a rezolva în mod eficient aceste probleme.
Diagnosticul sistemelor statice constă în determinarea dacă un sistem se comportă la dat vina observarea intrărilor și ieșirilor sistemului. Modelul sistemului poate fi tradus într-un set de constrângeri (disjuncții): pentru fiecare componentă a sistemului, se creează o variabilă care este evaluată ca fiind adevărată dacă componenta are un comportament anormal ( Ab normal ). Observațiile pot fi traduse și printr-un set de disjuncții. Alocarea găsită de algoritmul de satisfacție este un diagnostic.
Problema clasică de planificare este de a găsi o secvență de acțiuni care să conducă de la o stare a sistemului la un set de stări. Având în vedere o lungime maximă a planului și un set de variabile de stare booleene utilizate pentru a descrie starea sistemului, creăm variabile propoziționale pentru orice variabilă . Variabila este adevărată dacă variabila de stare este adevărată după numărul acțiunii . De asemenea, creăm variabile pentru orice și orice acțiune . Variabila este adevărată dacă numărul acțiunii este . Apoi este posibil să se transforme modelul sistemului într-un set de clauze. De exemplu, dacă acțiunea face ca variabila să treacă la adevărat atunci când este falsă , atunci CNF va conține o clauză (care este tradusă prin clauză ). Alocarea găsită de algoritmul de satisfacție poate fi imediat tradusă într-un plan.
Planificarea clasică prin SAT este foarte eficientă dacă știm lungimea n a planului . Dacă această valoare nu este cunoscută, se pot căuta planuri pentru o valoare incrementală, care este uneori costisitoare (în special deoarece CNF nu este satisfăcător până la n - 1).
O abordare similară a fost utilizată pentru verificarea modelului . Principala diferență este că verificarea modelului se aplică traiectoriilor de lungime infinită spre deosebire de planificare. Cu toate acestea, dacă spațiul de stare al sistemului este finit, orice traiectorie infinită se bucură într-un anumit punct și putem limita dimensiunea traiectoriilor pe care este necesar să le verificăm. Modelul verificarea mărginite profită de această proprietate pentru a transforma problema de verificare de model într - o serie de probleme satisfiabilitate.
Complexitatea problemei SAT este o componentă esențială a securității oricărui sistem criptografic.
De exemplu, o funcție hash securizată constituie o cutie neagră care poate fi formulată în timp și spațiu finit ca o conjuncție de clauze normale, ale căror variabile booleene corespund direct valorilor posibile ale datelor de intrare ale funcției. și fiecare dintre biții de rezultat trebuie să răspundă la un test de egalitate boolean cu biții de date ai oricărui bloc de date de intrare. Funcțiile securizate de hash sunt utilizate în special în sistemele de autentificare (cunoașterea datelor secrete de intrare utilizate pentru a produce valoarea hash) și semnătură (împotriva oricărei modificări „ușoare” sau falsificări a datelor de intrare, care sunt cunoscute împreună cu funcția hash în sine și rezultatul acestuia).
Securitatea funcției hash depinde de posibilitatea recuperării unui bloc de date de intrare arbitrar (posibil diferit de blocul de date secret pentru care a fost obținută o anumită valoare hash) făcând posibilă egalizarea valorii binare returnate de funcția hash. O metodă de explorare sistematică a tuturor valorilor posibile ale datelor de intrare și pentru care funcția hash este aplicată ca un oracol, face posibilă satisfacerea problemei unei valori hash egale cu cea căutată, dar complexitatea ei algoritmică va să fie exponențial (în funcție de dimensiunea maximă de biți a datelor de intrare a funcției hash)
Încercarea de a egaliza o valoare hash cu variabile de intrare de valoare necunoscută este o problemă SAT (și întrucât, în practică, datele de intrare pentru funcția hash constă din mai mulți biți, va fi o problemă n -SAT cu n destul de mare (și în orice caz mai mare sau egal cu 3) Știm atunci că această problemă este reductibilă în timp polinomial la o problemă 3 - SAT, care este NP-completă.
Securitatea funcției hash va fi puternic legată de faptul imposibilității de a o reduce mai simplu (decât de un algoritm NP-complet de suficientă complexitate) prin reducerea formei conjunctive a clauzelor care o definesc pur și simplu, pentru a izola subseturi de variabile de intrare de dimensiuni mai mici, dar suficiente pentru a determina o parte din rezultatul funcției hash a cărei ordine n va fi apoi mult mai mică și să nu mai trebuiască să exploreze doar valorile posibile ale acestor numai subseturi de variabile pentru a satisface condiția de egalitate a rezultatului, fără a fi nevoie să testați toate celelalte variabile a căror valoare poate fi setată în mod arbitrar la anumite valori determinate de un algoritm mai simplu (învățarea clauzelor, abordări prospective de mai sus).
Problema SAT poate fi utilizată ca subrutină pentru a rezolva problema de satisfacție logică modală.
Există extensii la problema SAT.
Martin Davis și Hilary Putnam își oferă algoritmul pentru problema SAT în 1960, apoi îmbunătățit de George Logemann și Donald Loveland (în) ( Algoritm Davis-Putnam-Logemann-Loveland ). Momentul a fost dat atunci când Stephen Cook a folosit-o ca paradigmă a problemelor NP-complete . Un alt impuls a fost dat în 2002, când a început competiția SAT între software-ul de rezolvare a problemelor SAT.