Phƣơng thức “ ” đƣợc hiểu là phƣơng thức giữ chỗ cho việc các cài đặt các ràng buộc thêm vào trong các phiên bản mở rộng của MiniSAT.
Với một bài toán SAT, giao diện đƣợc sử dụng nhƣ sau: Các biến đƣợc giới thiệu bằng cách gọi phƣơng thức . Từ những biến này, các mệnh đề đƣợc xây dựng và thêm vào với phƣơng thức . Các xung đột tầm thƣờng, ví dụ nhƣ 2 mệnh đề đơn vị và khi đƣợc thêm vào, có thể đƣợc phát hiện bởi phƣơng thức , và sẽ trả lại FALSE. Sau đó, trạng thái máy giải sẽ là không xác định và sẽ không đƣợc sử dụng nữa. Nếu không có xung đột tầm thƣờng nhƣ vậy trong quá trình thêm mệnh đề, phƣơng thức sẽ đƣợc gọi với một danh sách trống các giả định. Phƣơng thức sẽ trả lại FALSE nếu bài toán là UNSAT và trả lại TRUE nếu bài toán là SAT, trƣờng hợp này model có thể đƣợc đọc ra từ biến vec- tơ public “ ”.
Phƣơng thức s có thể đƣợc sử dụng trƣớc khi gọi phƣơng thức để làm đơn giản hóa các ràng buộc của bài toán. Trong cài đặt này, phƣơng thức đầu tiên sẽ thực hiện unit propagation, sau đó loại bỏ các ràng buộc đã thỏa mãn. Với phƣơng thức , việc đơn giản hóa đôi khi có thể phát hiện một xung đột, và do đó trả về FALSE và trạng thái máy giải sẽ là không xác định và sẽ không đƣợc sử dụng nữa.
Nếu máy giải trả về SAT, các ràng buộc mới có thể đƣợc thêm lặp lại nhiều lần vào cơ sở dữ liệu đang tồn tại và phƣơng thức sẽ chạy một lần nữa. Tuy nhiên, các dãy SAT khác có thể đƣợc giải bằng các sử dụng giả định đơn vị. Khi duyệt qua một danh sách không rỗng các giả định để gọi , máy giải tạm thời giả định các literal là true. Sau khi tìm đƣợc một model hay một mâu thuẫn, những giả định này bị loại bỏ, và máy giải đƣợc trả về một trạng thái có thể sử dụng đƣợc, kể cả khi phƣơng thức trả về FALSE, mà bây giờ nên đƣợc giải thích là UNSAT với giả định.
Để thực hiện điều này, gọi phƣơng thức trƣớc phƣơng thức là điều bắt buộc. Đó là cơ chế phát hiện xung đột dựa trên giả định – từ bây giờ trở đi đƣợc đề cập tới nhƣ là xung đột top-level. Xung đột này sẽ đặt máy giải vào trạng thái không xác định. Việc duyệt qua các giả định đơn vị có hiệu quả to lớn hơn là ta tƣởng.
4.3. Tổng quan về Minisat
Phần này sẽ xem xét các SAT solver thông thƣờng dựa trên thuật toán DPLL [26], bactrack thông qua phân tích xung đột và và ghi nhớ mệnh đề ( hay học mệnh đề), và suy diễn ràng buộc lý luận – boolean constraint propagation (BCP) sử dụng watched literals. Các SAT solver kiểu này đƣợc đề cập tới nhƣ SAT solver hƣớng xung đột.
Một SAT solver hƣớng xung đột cơ bản có thể đƣa ra các mệnh đề (với 2 literal hoặc hơn) và các phép gán.
Cơ chế suy luận duy nhất đƣợc sử dụng bởi một solver tiêu chuẩn là unit propagation. Ngay khi một mệnh đề trở thành unit sau phép gán hiện tại (tất cả các literal trừ một literal đƣợc gán false), literal còn lại sẽ đƣợc gán là true, có khả năng sẽ tạo nên nhiều mệnh đề đơn vị khác. Quá tình đƣợc tiếp tục cho đến khi không thể suy diễn thêm thông tin nào nữa.
Thủ tục tìm kiếm của một solver hiện đại là thủ tục phức tạp nhất. Trong quá trình thử, các biến đƣợc chọn và gán giá trị (phép giả định đƣợc tạo ra), cho đến khi quá trình suy diễn phát hiện một xung đột (tất cả literal của một mệnh đề là false). Khi đó, một mệnh đề xung đột đƣợc xây dƣng và thêm vào bài toán SAT. Các giải định sau đó đƣợc hủy bỏ bằng cách backtrack cho đến khi mệnh đề xung đột trở thành đơn vị mà từ đó mệnh đề đơn vị này đƣợc suy diễn và quá trình tìm kiếm tiếp tục.
Suy diễn (Propagation): Với mỗi literal, một danh sách các ràng buộc đƣợc giữ. Đây là những ràng buộc có thể suy diễn các thông tin đơn vị (các phép gán biến) nếu literal trở thành true. Với các mệnh đề, không một thông tin đơn vị nào có thể đƣợc suy diễn cho đến khi tất cả các literal trừ một literal vừa trở thành false. Hai literal chƣa đƣợc gán p và q của mệnh đề do đó đƣợc chọn, và sự tham chiếu tới mệnh đề sẽ lần lƣợt đƣợc thêm vào các danh sách của ⌐p và ⌐q. Các literal đƣợc nói là đƣợc
watched và các danh sách của các ràng buộc đƣợc đề cập tới nhƣ watcher list. Ngay khi một literal watched trở thành true, các ràng buộc đƣợc gọi để xem có thông tin nào có thể đƣợc suy diễn hay không, hoặc để chọn các literal chƣa bị gán mới để đƣợc
watched.
Học (Learning): Thủ tục học của MiniSAT dựa trên ý tƣởng của MarquesSilva
và Sakallah. Quá trình bắt đầu khi một ràng buộc trở nên xung đột dƣới phép gán hiện tại. Ràng buộc xung đột sau đó đƣợc truy vấn với một tập các phép biến khiến nó mâu thuẫn. Với một mệnh đề, đó sẽ là tất cả các literal của mệnh đề. Mỗi phép gán đƣợc biến trả về phải là một giả định của thủ tục tìm kiếm, hay một kết quả của phép suy diễn một ràng buộc nào đó. Các ràng buộc suy diễn đƣợc truy vấn lần lƣợt tập các phép gán biến khiến phép suy diễn xảy ra, tiếp tục quá trình phân tích ngƣợc. Thủ tục đƣợc lặp lại cho đến khi một vài điều kiện kết thúc đƣợc lấp đầy, đƣa đến một tập các phép gán biến mà đƣa đến xung đột. Một mệnh đề ngăn chặn phép gán cụ thể đó đƣợc thêm vào cơ sở dữ liệu mệnh đề. Mênh đề học đƣợc (learnt clause) này phải luôn luôn , trong quá trình xây dựng, đƣợc ngầm ý là ràng buộc ban đầu của bài toán.
Các mệnh đề học đƣợc phục vụ 2 mục đích: chúng hƣớng thủ tục backtrack và tăng tốc các xung đột trong tƣơng lại bằng cách lƣu trữ nguyên nhân xảy ra xung đột. Mỗi mệnh đề sẽ chỉ ngăn chặn một lƣợng nhất định các suy luận, nhƣng do các mệnh
đề đƣợc ghi lại sẽ tạo ra lẫn nhau và tham gia vào quá trình suy diễn đơn vị, hiệu quả ƣớc chừng của việc học có thể là rất lớn. Tuy nhiên, do tập các mệnh đề học đƣợc ngày càng tăng, quá trình suy diễn sẽ bị chậm lại. Do đó, số lƣợng các mệnh đề học đƣợc sẽ đƣợc giảm bớt định kỳ, chỉ giữ lại các mệnh đề có vẻ hữu dụng.
Tìm kiếm: Thủ tục tìm kiếm của các SAT solver hƣớng xung đột là một cái gì
đó ẩn. Mặc dù một định nghĩa đệ quy của thủ tục có thể súc tích hơn, nhƣng thủ tục này thƣờng đƣợc miêu tả (và cài đặt) theo cách lặp. Thủ tục sẽ bắt đầu bằng cách chọn một biến chƣa đƣợc gán (đƣợc gọi là biến quyết định) và gán một giá trị cho nó, cho là TRUE. Kết quả của việc gán sẽ đƣợc suy diễn, có thể dẫn tới việc gán nhiều biến khác. Tất cả các biến đƣợc gán nhƣ kết quả của việc gán đƣợc coi là cùng một mức quyết định (decision level), đếm từ 1 cho phép gán đầu tiên và tăng dần. Các phép gán đƣợc tạo ra trƣớc phép gán đầu tiên (mức quyết định 0) đƣợc gọi là top-level.
Tất cả các phép gán sẽ đƣợc lƣu trong một ngăn xếp theo thứ tự chúng đƣợc tạo ra; từ giờ trở đi sẽ gọi ngăn xếp này là trail. Trail đƣợc chia thành các mức quyết định và đƣợc sử dụng để đảo ngƣợc thông tin trong quá trình backtrack.
Pha quyết định sẽ tiếp tục cho đến khi tất cả các biến đƣợc gán, khi đó ta có đƣợc một model, hay một xung đột xảy ra. Trong khi xung đột, thủ tục học đƣợc gọi và mệnh đề xung đột sẽ đƣợc tạo ra. Trail sẽ đƣợc sử dụng để xóa bỏ mức quyết định, mỗi mức một lần, cho đến khi có chính xác một trong số các literal của mệnh đề học đƣợc trở nên chƣa đƣợc gán. Trong quá trình xử lý, mệnh đề xung đột không thể đi trực tiếp từ xung đột tới một mệnh đề với 2 hoặc nhiều hơn các literal chƣa gán.
Một phần quan trọng của thủ tục là tự khám phá của phƣơng thức . Giống CHAFF, MiniSAT sử dụng độ ƣu tiên động của biến để đƣa ra thứ tự cho các biến liên quan đến các xung đột gần nhất. Dƣới đây là thủ tục search [26]:
Loop
Propagate() - propagate unit clause
If not conflict then
If all variables assigned then Return SATISFIABLE Else
Decide() -pick a new variable and assign it
Else
Analyze() - analyze conflict and add a conflict clause
If top-leval conflict found then Return UNSATISFIABLE Else
Độ ƣu tiên của biến: Một kỹ thuật quan trọng đƣợc giới thiệu bởi CHAFF đó là sắp xếp biến dựa trên độ ƣu tiên động của biến. Thuật toán ban ban đầu dựa trên sắp xếp các literal, p và ⌐p sẽ đƣợc coi nhƣ nhau trong MiniSAT.
Mỗi biến có một độ ƣu tiên gắn với nó. Mỗi khi một biến có mặt trong một mệnh đề xung đột đƣợc ghi lại, độ ƣu tiên của nó tăng lên. Sau khi ghi lại xung đột, độ ƣu tiên của tất cả các biến trong hệ thống sẽ đƣợc nhân với một hằng số nhỏ hơn 1, do đó làm giảm độ ƣu tiên của các biến qua thời gian. Lƣợng gia tăng gần sẽ lớn hơn lƣợng gia tăng trƣơc đó. Tổng hiện tại sẽ quyết định độ ƣu tiên của biến.
MiniSAT sử dụng một ý tƣởng tƣơng tự cho mệnh đề. Khi một mệnh đề học đƣợc đƣợc sƣ dụng trong quá trình phân tích một xung đột, độ ƣu tiên của nó sẽ đƣợc bump. Các mệnh đề không hoạt động sẽ đƣợc loại bỏ định kỳ.
Loại bỏ ràng buộc: Cơ sở dữ liệu ràng buộc đƣợc chia ra thành 2 phần: ràng buộc của
bài toán và các mệnh đề học đƣợc. Tập các mệnh đề học đƣợc sẽ đƣợc loại bỏ định kỳ để gia tăng hiệu quả của việc suy diễn mệnh đề. Các mệnh đề học đƣợc đƣợc sử dụng bỏ bớt các nhánh phát sinh trong tƣơng lai của cây tìm kiếm, vì vậy khi loại bỏ các mệnh đề này có thể dẫn tới việc tạo ra không gian tìm kiếm lớn hơn.
Ràng buộc bài toán cũng có thể đƣợc loại bỏ nếu chúng thỏa mãn ở top-level. Phƣơng thức chịu trách nhiệm việc này.
Top-level solver: Một chiến lƣợc cụ thể đƣợc áp dụng bởi các SAT solver hƣớng
xung đột hiện đại là sử dụng việc tái khởi động (restart) để thoát khỏi các phần vô ích của cây tìm kiếm. Trong MiniSAT số lƣợng các mệnh đề học đƣợc ở một thời điểm sẽ biến đổi. Hơn nữa, phƣơng thức của giao diện lập trình ứng dụng hỗ trợ các phép gán tăng dần, điều mà không đƣợc giải quyết bởi đoạn mã giả trên.
4.4. Thực nghiệm
Hai kỹ thuật Glueminisat và Glucose đã đƣợc cài đặt thành hai SAT Solver là Glueminisat [7] và Glucose [8] .
4.4.1. Biên dịch Minisat
Để thực hiện biên dịch Minisat trên Ubuntu, ta thực hiện các bƣớc dƣới đây: - Tạo thƣ mục chứa Minisat: mkdir Minisat
- Download minisat-2.2.0.tar.gz:
wget http://minisat.se/downloads/minisat-2.2.0.tar.gz - Gõ câu lệnh : tar xvf minisat-2.2.0.tar.gz
- Gõ cd minisat
- Gõ cd core
- Gõ sudo apt-get install libghc-zlib-dev - Gõ make (Tạo đƣợc file chạy minisat)
- Tạo thƣ mục examples để lƣu lại các benchmark. Gõ mkdir examples
- Copy file minisat ở thƣ mục Minisat/core chuyển vào thƣ mục examples: Gõ cp ./core/minisat ./examples/
- Gõ 2 câu lệnh sau để thực hiện chạy minisat:
cd ~/minisat/examples/ ./minisat <Input-file>
4.4.2. Biên dịch GlueMinisat
Để thực hiện biên dịch GlueMinisat trên Ubuntu, ta thực hiện các bƣớc dƣới đây: - Download glueminisat-2.2.8:
wget http://glueminisat.nabelab.org/home/download/glueminisat-2.2.8.tar.gz - Giải nén: unzip glueminisat-2.2.8.zip
- Chạy file build.sh: Gõ ./build.sh (Tạo đƣợc file chạy Glueminisat) - Tạo thƣ mục examples để lƣu lại các benchmark. Gõ mkdir examples
- Copy file glueminisat-simp ở thƣ mục Glueminisat/binary chuyển vào thƣ mục examples: cp binary/glueminisat-simp examples/
- Gõ 2 câu lệnh sau để thực hiện chạy Glueminisat:
cd ~/glueminisat-2.2.8/examples/ ./glueminisat-simp <Input-file> 4.4.3. Biên dịch Glucose
Để thực hiện biên dịch Glucose trên Ubuntu, ta thực hiện các bƣớc dƣới đây: - Tạo thƣ mục Glucose:mkdir Glucose
- Download Glucose 2.0:
wget http://www.lri.fr/~simon/downloads/glucose-2-compet.tgz
- Gõ câu lệnh: tar -xf glucose-2-compet.tgz - Mở thƣ mục simp: Gõ cd simp/
- Gõ make rs (Tạo đƣợc file chạy Glucose)
- Copy file glucose_static từ thƣ mục simp sang thƣ mục Examples: cp simp/glucose_static Examples/
- Gõ 2 câu lệnh sau để thực hiện chạy Glucose:
cd ~/Gluecose/examples/ ./glucose_static <Input-file>
4.4.4. Bộ dữ liệu thực nghiệm (Benchmarks)
Bộ dữ liệu thực nghiệm SAT Solver là bộ các bài toán dƣới định dạng DIMACS CNF (.CNF), là đầu vào của các SAT Solver đƣợc xây dựng bởi cộng đồng SAT.
Các bộ dữ liệu thực nghiệm SAT đƣợc tham khảo tại [27].
4.4.5. Thực nghiệm
Để đánh giá hiệu quả của các kỹ thuật SAT Solving tiên tiến, tiến hành thực nghiệm Minisat, Glueminisat, Glucose trên “Bộ dữ liệu Slitherlink” đƣợc tham khảo tại [25] và “Bộ dữ liệu thực nghiệm chuẩn Aprove09” đƣợc tham khảo tại [24].
a. Bộ dữ liệu Slithelink
Bảng 4.1: Kết quả thực nghiệm Minisat, Glueminisat, Glucose trên Slitherlink STT Kích thƣớc Số biến Số clause
SAT Solver Restart Conflict Decision Propagations
1 16x16 544 3027 Minisat 2 195 1040 9841 Glueminisat 1 194 790 7257 Glucose 1 70 456 3954 2 20x20 840 4565 Minisat 3 253 2206 17981 Glueminisat 1 146 996 8092 Glucose 1 384 1726 15241 3 25x25 1300 7062 Minisat 5 534 6108 43584 Glueminisat 4 336 3225 26394 Glucose 4 695 5619 47843 4 30x30 1860 10306 Minisat 4 481 7897 58679 Glueminisat 3 362 4911 34474 Glucose 2 820 10988 83648
b. Bộ dữ liệu thực nghiệm chuẩn Aprove09
Bảng 4.2: Kết quả thực nghiệm Minisat, Glueminisat, Glucose trên Aprove 09 STT Tên Số
biến
Số clause
SAT Solver Restart Conflict Decision Thời gian chạy (giây) 1 Aprove 09-01 81870 151268 Minisat 9 1346 160739 0.372023 Glueminisat 1 217 11121 0.304 Glucose 1 178 11961 0.248015 2 Aprove 09-03 59231 119736 Minisat 7 966 166278 0.364022 Glueminisat 1 264 12644 0.200 Glucose 1 195 11594 0.248015 3 Aprove 09-05 14685 49032 Minisat 86 23738 47852 3.50822 Glueminisat 29 6376 13899 0.384 Glucose 44 9107 20607 0.712044 4 Aprove 09-06 77262 262886 Minisat 2047 1040139 1636929 1295.16 Glueminisat 5369 1781724 2588671 1043.385 Glucose 2583 1146245 1743095 755.647 5 Aprove 09-07 8567 28677 Minisat 129 45028 56908 9.42059 Glueminisat 44 12390 18217 0.748 Glucose 13 11231 16361 1.16407 6 Aprove 09-08 8564 28668 Minisat 207 67507 83018 13.0408 Glueminisat 46 30321 41574 12.471 Glucose 142 75165 97628 9.19657 7 Aprove 09-10 67186 238869 Minisat 8 1277 4108 0.784049 Glueminisat 4 1568 5143 1.140 Glucose 1 442 2242 0.508031 8 Aprove 09-11 20192 77131 Minisat 3 387 4782 0.080005 Glueminisat 1 247 3380 0.128 Glucose 2 762 5415 0.136008 9 Aprove 27495 100426 Minisat 9 1357 23704 0.276017
09-12 Glueminisat 2 1203 14286 0.256 Glucose 5 1019 10826 0.216013 10 Aprove 09-13 7606 6082 Minisat 3 255 2546 0.012 Glueminisat 0 162 800 0.048 Glucose 1 137 1234 0.036002 11 Aprove 09-15 94663 300532 Minisat 62 15933 54021 7.90049 Glueminisat 35 5639 22239 1.836 Glucose 53 8483 29084 2.56816