1 | /* =========FOR INTERNAL USE ONLY. NO DISTRIBUTION PLEASE ========== */ |
---|
2 | |
---|
3 | /********************************************************************* |
---|
4 | Copyright 2000-2004, Princeton University. All rights reserved. |
---|
5 | By using this software the USER indicates that he or she has read, |
---|
6 | understood and will comply with the following: |
---|
7 | |
---|
8 | --- Princeton University hereby grants USER nonexclusive permission |
---|
9 | to use, copy and/or modify this software for internal, noncommercial, |
---|
10 | research purposes only. Any distribution, including commercial sale |
---|
11 | or license, of this software, copies of the software, its associated |
---|
12 | documentation and/or modifications of either is strictly prohibited |
---|
13 | without the prior consent of Princeton University. Title to copyright |
---|
14 | to this software and its associated documentation shall at all times |
---|
15 | remain with Princeton University. Appropriate copyright notice shall |
---|
16 | be placed on all software copies, and a complete copy of this notice |
---|
17 | shall be included in all copies of the associated documentation. |
---|
18 | No right is granted to use in advertising, publicity or otherwise |
---|
19 | any trademark, service mark, or the name of Princeton University. |
---|
20 | |
---|
21 | |
---|
22 | --- This software and any associated documentation is provided "as is" |
---|
23 | |
---|
24 | PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS |
---|
25 | OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A |
---|
26 | PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR |
---|
27 | ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, |
---|
28 | TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. |
---|
29 | |
---|
30 | Princeton University shall not be liable under any circumstances for |
---|
31 | any direct, indirect, special, incidental, or consequential damages |
---|
32 | with respect to any claim by USER or any third party on account of |
---|
33 | or arising from the use, or inability to use, this software or its |
---|
34 | associated documentation, even if Princeton University has been advised |
---|
35 | of the possibility of those damages. |
---|
36 | *********************************************************************/ |
---|
37 | #include <iostream> |
---|
38 | #include <fstream> |
---|
39 | #include <cstdlib> |
---|
40 | #include <cstdio> |
---|
41 | #include <cstring> |
---|
42 | |
---|
43 | #include <set> |
---|
44 | #include <vector> |
---|
45 | #include <dirent.h> |
---|
46 | #include "SAT.h" |
---|
47 | |
---|
48 | using namespace std; |
---|
49 | |
---|
50 | const int MAX_LINE_LENGTH = 65536; |
---|
51 | const int MAX_WORD_LENGTH = 64; |
---|
52 | |
---|
53 | //This cnf parser function is based on the GRASP code by Joao Marques Silva |
---|
54 | void read_cnf(SAT_Manager mng, char * filename ) |
---|
55 | { |
---|
56 | // cout <<"read cnf "<<endl; |
---|
57 | char line_buffer[MAX_LINE_LENGTH]; |
---|
58 | char word_buffer[MAX_WORD_LENGTH]; |
---|
59 | set<int> clause_vars; |
---|
60 | set<int> clause_lits; |
---|
61 | int line_num = 0; |
---|
62 | |
---|
63 | if(opendir(filename)){ |
---|
64 | cerr << "Can't open input file, it's a directory" << endl; |
---|
65 | exit(1); |
---|
66 | } |
---|
67 | |
---|
68 | ifstream inp (filename, ios::in); |
---|
69 | if (!inp) { |
---|
70 | cerr << "Can't open input file" << endl; |
---|
71 | exit(1); |
---|
72 | } |
---|
73 | while (inp.getline(line_buffer, MAX_LINE_LENGTH)) { |
---|
74 | ++ line_num; |
---|
75 | if (line_buffer[0] == 'c') { |
---|
76 | continue; |
---|
77 | } |
---|
78 | else if (line_buffer[0] == 'p') { |
---|
79 | int var_num; |
---|
80 | int cl_num; |
---|
81 | |
---|
82 | int arg = sscanf (line_buffer, "p cnf %d %d", &var_num, &cl_num); |
---|
83 | if( arg < 2 ) { |
---|
84 | cerr << "Unable to read number of variables and clauses" |
---|
85 | << "at line " << line_num << endl; |
---|
86 | exit(3); |
---|
87 | } |
---|
88 | SAT_SetNumVariables(mng, var_num); //first element not used. |
---|
89 | } |
---|
90 | else { // Clause definition or continuation |
---|
91 | char *lp = line_buffer; |
---|
92 | do { |
---|
93 | char *wp = word_buffer; |
---|
94 | while (*lp && ((*lp == ' ') || (*lp == '\t'))) { |
---|
95 | lp++; |
---|
96 | } |
---|
97 | while (*lp && (*lp != ' ') && (*lp != '\t') && (*lp != '\n')) { |
---|
98 | *(wp++) = *(lp++); |
---|
99 | } |
---|
100 | *wp = '\0'; // terminate string |
---|
101 | |
---|
102 | if (strlen(word_buffer) != 0) { // check if number is there |
---|
103 | int var_idx = atoi (word_buffer); |
---|
104 | int sign = 0; |
---|
105 | |
---|
106 | if( var_idx != 0) { |
---|
107 | if( var_idx < 0) { var_idx = -var_idx; sign = 1; } |
---|
108 | clause_vars.insert(var_idx); |
---|
109 | clause_lits.insert( (var_idx << 1) + sign); |
---|
110 | } |
---|
111 | else { |
---|
112 | //add this clause |
---|
113 | if (clause_vars.size() != 0 && (clause_vars.size() == clause_lits.size())) { //yeah, can add this clause |
---|
114 | vector <int> temp; |
---|
115 | for (set<int>::iterator itr = clause_lits.begin(); |
---|
116 | itr != clause_lits.end(); ++itr) |
---|
117 | temp.push_back (*itr); |
---|
118 | SAT_AddClause(mng, & temp.begin()[0], temp.size() ); |
---|
119 | } |
---|
120 | else {} //it contain var of both polarity, so is automatically satisfied, just skip it |
---|
121 | clause_lits.clear(); |
---|
122 | clause_vars.clear(); |
---|
123 | } |
---|
124 | } |
---|
125 | } |
---|
126 | while (*lp); |
---|
127 | } |
---|
128 | } |
---|
129 | if (!inp.eof()) { |
---|
130 | cerr << "Input line " << line_num << " too long. Unable to continue..." << endl; |
---|
131 | exit(2); |
---|
132 | } |
---|
133 | // assert (clause_vars.size() == 0); //some benchmark has no 0 in the last clause |
---|
134 | if (clause_lits.size() && clause_vars.size()==clause_lits.size() ) { |
---|
135 | vector <int> temp; |
---|
136 | for (set<int>::iterator itr = clause_lits.begin(); |
---|
137 | itr != clause_lits.end(); ++itr) |
---|
138 | temp.push_back (*itr); |
---|
139 | SAT_AddClause(mng, & temp.begin()[0], temp.size() ); |
---|
140 | } |
---|
141 | clause_lits.clear(); |
---|
142 | clause_vars.clear(); |
---|
143 | // cout <<"done read cnf"<<endl; |
---|
144 | } |
---|
145 | |
---|
146 | |
---|
147 | void handle_result(SAT_Manager mng, int outcome, char * filename ) |
---|
148 | { |
---|
149 | string result = "UNKNOWN"; |
---|
150 | switch (outcome) { |
---|
151 | case SATISFIABLE: |
---|
152 | cout << "Instance Satisfiable" << endl; |
---|
153 | //following lines will print out a solution if a solution exist |
---|
154 | for (int i=1, sz = SAT_NumVariables(mng); i<= sz; ++i) { |
---|
155 | switch(SAT_GetVarAsgnment(mng, i)) { |
---|
156 | case -1: |
---|
157 | cout <<"("<< i<<")"; break; |
---|
158 | case 0: |
---|
159 | cout << "-" << i; break; |
---|
160 | case 1: |
---|
161 | cout << i ; break; |
---|
162 | default: |
---|
163 | cerr << "Unknown variable value state"<< endl; |
---|
164 | exit(4); |
---|
165 | } |
---|
166 | cout << " "; |
---|
167 | } |
---|
168 | result = "SAT"; |
---|
169 | break; |
---|
170 | case UNSATISFIABLE: |
---|
171 | result = "UNSAT"; |
---|
172 | cout << "Instance Unsatisfiable" << endl; |
---|
173 | break; |
---|
174 | case TIME_OUT: |
---|
175 | result = "ABORT : TIME OUT"; |
---|
176 | cout << "Time out, unable to determine the satisfiability of the instance"<<endl; |
---|
177 | break; |
---|
178 | case MEM_OUT: |
---|
179 | result = "ABORT : MEM OUT"; |
---|
180 | cout << "Memory out, unable to determine the satisfiability of the instance"<<endl; |
---|
181 | break; |
---|
182 | default: |
---|
183 | cerr << "Unknown outcome" << endl; |
---|
184 | } |
---|
185 | cout << "Random Seed Used\t\t\t\t" << SAT_Random_Seed(mng) << endl; |
---|
186 | cout << "Max Decision Level\t\t\t\t" << SAT_MaxDLevel(mng) << endl; |
---|
187 | cout << "Num. of Decisions\t\t\t\t" << SAT_NumDecisions(mng)<< endl; |
---|
188 | cout << "( Stack + Vsids + Shrinking Decisions )\t\t" <<SAT_NumDecisionsStackConf(mng); |
---|
189 | cout << " + " <<SAT_NumDecisionsVsids(mng)<<" + "<<SAT_NumDecisionsShrinking(mng)<<endl; |
---|
190 | cout << "Original Num Variables\t\t\t\t" << SAT_NumVariables(mng) << endl; |
---|
191 | cout << "Original Num Clauses\t\t\t\t" << SAT_InitNumClauses(mng) << endl; |
---|
192 | cout << "Original Num Literals\t\t\t\t" << SAT_InitNumLiterals(mng) << endl; |
---|
193 | cout << "Added Conflict Clauses\t\t\t\t" << SAT_NumAddedClauses(mng)- SAT_InitNumClauses(mng)<< endl; |
---|
194 | cout << "Num of Shrinkings\t\t\t\t" << SAT_NumShrinkings(mng)<< endl; |
---|
195 | cout << "Deleted Conflict Clauses\t\t\t" << SAT_NumDeletedClauses(mng)-SAT_NumDelOrigCls(mng) <<endl; |
---|
196 | cout << "Deleted Clauses\t\t\t\t\t" << SAT_NumDeletedClauses(mng) <<endl; |
---|
197 | cout << "Added Conflict Literals\t\t\t\t" << SAT_NumAddedLiterals(mng) - SAT_InitNumLiterals(mng) << endl; |
---|
198 | cout << "Deleted (Total) Literals\t\t\t" << SAT_NumDeletedLiterals(mng) <<endl; |
---|
199 | cout << "Number of Implication\t\t\t\t" << SAT_NumImplications(mng)<< endl; |
---|
200 | //other statistics comes here |
---|
201 | cout << "Total Run Time\t\t\t\t\t" << SAT_GetCPUTime(mng) << endl; |
---|
202 | // cout << "RESULT:\t" << filename << " " << result << " RunTime: " << SAT_GetCPUTime(mng)<< endl; |
---|
203 | cout << "RESULT:\t"<<result << endl; |
---|
204 | |
---|
205 | |
---|
206 | } |
---|
207 | |
---|
208 | void output_status(SAT_Manager mng) |
---|
209 | { |
---|
210 | cout << "Dec: " << SAT_NumDecisions(mng)<< "\t "; |
---|
211 | cout << "AddCl: " << SAT_NumAddedClauses(mng) <<"\t"; |
---|
212 | cout << "AddLit: " << SAT_NumAddedLiterals(mng)<<"\t"; |
---|
213 | cout << "DelCl: " << SAT_NumDeletedClauses(mng) <<"\t"; |
---|
214 | cout << "DelLit: " << SAT_NumDeletedLiterals(mng)<<"\t"; |
---|
215 | cout << "NumImp: " << SAT_NumImplications(mng) <<"\t"; |
---|
216 | cout << "AveBubbleMove: " << SAT_AverageBubbleMove(mng) <<"\t"; |
---|
217 | //other statistics comes here |
---|
218 | cout << "RunTime:" << SAT_GetElapsedCPUTime(mng) << endl; |
---|
219 | } |
---|
220 | |
---|
221 | void verify_solution(SAT_Manager mng) |
---|
222 | { |
---|
223 | int num_verified = 0; |
---|
224 | for ( int cl_idx = SAT_GetFirstClause (mng); cl_idx >= 0; |
---|
225 | cl_idx = SAT_GetNextClause(mng, cl_idx)) { |
---|
226 | int len = SAT_GetClauseNumLits(mng, cl_idx); |
---|
227 | int * lits = new int[len+1]; |
---|
228 | SAT_GetClauseLits( mng, cl_idx, lits); |
---|
229 | int i; |
---|
230 | for (i=0; i< len; ++i) { |
---|
231 | int v_idx = lits[i] >> 1; |
---|
232 | int sign = lits[i] & 0x1; |
---|
233 | int var_value = SAT_GetVarAsgnment( mng, v_idx); |
---|
234 | if( (var_value == 1 && sign == 0) || |
---|
235 | (var_value == 0 && sign == 1) ) break; |
---|
236 | } |
---|
237 | if (i >= len) { |
---|
238 | cerr << "Verify Satisfiable solution failed, please file a bug report, thanks. " << endl; |
---|
239 | exit(6); |
---|
240 | } |
---|
241 | delete [] lits; |
---|
242 | ++ num_verified; |
---|
243 | } |
---|
244 | cout <<"c "<< num_verified << " Clauses are true, Verify Solution successful."<<endl;; |
---|
245 | } |
---|
246 | |
---|
247 | int main(int argc, char ** argv) |
---|
248 | { |
---|
249 | SAT_Manager mng = SAT_InitManager(); |
---|
250 | if (argc < 2) { |
---|
251 | cerr << "Z-Chaff: Accelerated SAT Solver from Princeton. " << endl; |
---|
252 | cerr << "Copyright 2000-2004, Princeton University." << endl << endl;; |
---|
253 | cerr << "Usage: "<< argv[0] << " cnf_file [time_limit]" << endl; |
---|
254 | return 2; |
---|
255 | } |
---|
256 | cout << "Z-Chaff Version: " << SAT_Version(mng) << endl; |
---|
257 | cout << "Solving " << argv[1] << " ......" << endl; |
---|
258 | if (argc == 2) { |
---|
259 | read_cnf (mng, argv[1] ); |
---|
260 | } |
---|
261 | else { |
---|
262 | read_cnf (mng, argv[1] ); |
---|
263 | SAT_SetTimeLimit(mng, atoi(argv[2])); |
---|
264 | } |
---|
265 | |
---|
266 | /* if you want some statistics during the solving, uncomment following line */ |
---|
267 | // SAT_AddHookFun(mng,output_status, 5000); |
---|
268 | |
---|
269 | /* you can set all your parameters here, following values are the defaults*/ |
---|
270 | // SAT_SetMaxUnrelevance(mng, 20); |
---|
271 | // SAT_SetMinClsLenForDelete(mng, 100); |
---|
272 | // SAT_SetMaxConfClsLenAllowed(mng, 5000); |
---|
273 | |
---|
274 | /* randomness may help sometimes, by default, there is no randomness */ |
---|
275 | // SAT_SetRandomness (mng, 10); |
---|
276 | // SAT_SetRandSeed (mng, -1); |
---|
277 | int result = SAT_Solve(mng); |
---|
278 | if (result == SATISFIABLE) |
---|
279 | verify_solution(mng); |
---|
280 | handle_result (mng, result, argv[1]); |
---|
281 | return 0; |
---|
282 | } |
---|