[10] | 1 | // /********************************************************************* |
---|
| 2 | // Copyright 2000-2004, Princeton University. All rights reserved. |
---|
| 3 | // By using this software the USER indicates that he or she has read, |
---|
| 4 | // understood and will comply with the following: |
---|
| 5 | // |
---|
| 6 | // --- Princeton University hereby grants USER nonexclusive permission |
---|
| 7 | // to use, copy and/or modify this software for internal, noncommercial, |
---|
| 8 | // research purposes only. Any distribution, including commercial sale |
---|
| 9 | // or license, of this software, copies of the software, its associated |
---|
| 10 | // documentation and/or modifications of either is strictly prohibited |
---|
| 11 | // without the prior consent of Princeton University. Title to copyright |
---|
| 12 | // to this software and its associated documentation shall at all times |
---|
| 13 | // remain with Princeton University. Appropriate copyright notice shall |
---|
| 14 | // be placed on all software copies, and a complete copy of this notice |
---|
| 15 | // shall be included in all copies of the associated documentation. |
---|
| 16 | // No right is granted to use in advertising, publicity or otherwise |
---|
| 17 | // any trademark, service mark, or the name of Princeton University. |
---|
| 18 | // |
---|
| 19 | // |
---|
| 20 | // --- This software and any associated documentation is provided "as is" |
---|
| 21 | // |
---|
| 22 | // PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS |
---|
| 23 | // OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A |
---|
| 24 | // PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR |
---|
| 25 | // ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, |
---|
| 26 | // TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. |
---|
| 27 | // |
---|
| 28 | // Princeton University shall not be liable under any circumstances for |
---|
| 29 | // any direct, indirect, special, incidental, or consequential damages |
---|
| 30 | // with respect to any claim by USER or any third party on account of |
---|
| 31 | // or arising from the use, or inability to use, this software or its |
---|
| 32 | // associated documentation, even if Princeton University has been advised |
---|
| 33 | // of the possibility of those damages. |
---|
| 34 | // *********************************************************************/ |
---|
| 35 | |
---|
| 36 | #ifndef __SAT_HEADER__ |
---|
| 37 | #define __SAT_HEADER__ |
---|
| 38 | |
---|
| 39 | #define SAT_Manager void * |
---|
| 40 | |
---|
| 41 | typedef long long long64; // this is for 32 bit unix machines |
---|
| 42 | // typedef long long64; // this is for Windows or 64 bit unix machines |
---|
| 43 | |
---|
| 44 | |
---|
| 45 | #ifndef _SAT_STATUS_ |
---|
| 46 | #define _SAT_STATUS_ |
---|
| 47 | enum SAT_StatusT { |
---|
| 48 | UNDETERMINED, |
---|
| 49 | UNSATISFIABLE, |
---|
| 50 | SATISFIABLE, |
---|
| 51 | TIME_OUT, |
---|
| 52 | MEM_OUT, |
---|
| 53 | ABORTED |
---|
| 54 | }; |
---|
| 55 | #endif |
---|
| 56 | |
---|
| 57 | #ifndef _CLS_STATUS_ |
---|
| 58 | #define _CLS_STATUS_ |
---|
| 59 | enum CLAUSE_STATUS { |
---|
| 60 | ORIGINAL_CL, |
---|
| 61 | CONFLICT_CL, |
---|
| 62 | DELETED_CL, |
---|
| 63 | }; |
---|
| 64 | #endif |
---|
| 65 | |
---|
| 66 | #ifndef UNKNOWN |
---|
| 67 | #define UNKNOWN 2 |
---|
| 68 | #endif |
---|
| 69 | |
---|
| 70 | // /*============================================================ |
---|
| 71 | // |
---|
| 72 | // This is the header for using the sat solver. A typical flow is |
---|
| 73 | // |
---|
| 74 | // 1. calling SAT_InitManager to get a new manager. You can pre-set |
---|
| 75 | // the number of variables upfront, or you can add it later by |
---|
| 76 | // SAT_AddVariable. |
---|
| 77 | // Variables are indexed from 1, NOT 0. |
---|
| 78 | // |
---|
| 79 | // 2. add clauses by calling SAT_AddClause. Clause is represented by |
---|
| 80 | // an array of integers. Each literal is represented by |
---|
| 81 | // 2 * VarIndex + Sign. The Sign is 0 for positive phased literals, |
---|
| 82 | // and 1 for negative phased literals. |
---|
| 83 | // For example, a clause (3 -5 11 -4 ) should be represented by |
---|
| 84 | // { 6, 11, 22, 9 } |
---|
| 85 | // Note: Each variable can occure no more than once in a clause. |
---|
| 86 | // if a variable occures in both phase, the clause is automatically |
---|
| 87 | // satisfied. If more than one occurance with same phase, they |
---|
| 88 | // should be combined. IT IS YOUR RESPONSIBILITY TO KEEP EACH |
---|
| 89 | // CLAUSE NON-REDUNDENT, or the solver will not function correctly. |
---|
| 90 | // |
---|
| 91 | // 3. zchaff support incremental SAT solving. Clauses can be added |
---|
| 92 | // or deleted from the database after each run. To accomplish |
---|
| 93 | // this, a clause is associated with a "Group ID". Each clause |
---|
| 94 | // has one Group ID. The group of clauses with the same GID can |
---|
| 95 | // be deleted from the database by calling SAT_DeleteClauseGroup |
---|
| 96 | // after each run. You need to call SAT_Reset to reset the state |
---|
| 97 | // of the solver before begining a new run. |
---|
| 98 | // As an example, the first 10 clauses are associated with GID 1, |
---|
| 99 | // We add another 2 clauses with GID 2. After solving this instance |
---|
| 100 | // with 12 clauses, we may want to delete the last 2 clauses and |
---|
| 101 | // add another 3 clauses. We call SAT_DeleteClauseGroup with GID |
---|
| 102 | // 2 and add the three clauses (these three clauses can have any |
---|
| 103 | // GID: either 1 if you don't want to delete them in the future, |
---|
| 104 | // 2 if you want to distinguish them from Group 1). Then you should |
---|
| 105 | // call SAT_Reset() to reset the state of the solver, and call |
---|
| 106 | // SAT_Solve() again to solve the new instance (a instance with |
---|
| 107 | // 13 clauses). |
---|
| 108 | // You should obtain free GID using SAT_AllocClauseGroupID. When |
---|
| 109 | // you call SAT_DeleteClauseGroup, the gid will be freed and can |
---|
| 110 | // be re-used when you call SAT_AllocClauseGroupID() again. |
---|
| 111 | // You can also merge two group of clauses into 1 by calling |
---|
| 112 | // corresponding functions. |
---|
| 113 | // |
---|
| 114 | // 4. Optionally, you may set the time limit and memory limit for |
---|
| 115 | // the solver, note: time and memory limits are not exact. |
---|
| 116 | // Also, you can set other paramenters like clause deletion |
---|
| 117 | // etc. |
---|
| 118 | // |
---|
| 119 | // 5. You can add hook function to do some extra work after |
---|
| 120 | // a certain number of decisions (branchings). A hook function |
---|
| 121 | // should accept input of a manager, and has no return value. |
---|
| 122 | // |
---|
| 123 | // 6. Calling SAT_Solve to solve the problem. it will return the |
---|
| 124 | // status of the solver. |
---|
| 125 | // |
---|
| 126 | // 7. If the problem is satisfiable, you can call SAT_GetVarAsgnment |
---|
| 127 | // to get a variable assignment which satisfy the problem. |
---|
| 128 | // |
---|
| 129 | // 8. You can also get some statistics from the solver, such as |
---|
| 130 | // run time, mem usage, etc. |
---|
| 131 | // |
---|
| 132 | // 9. Release the manager by calling SAT_ReleaseManager. |
---|
| 133 | // |
---|
| 134 | // You need to link the library libsat.a, also, though you can compile |
---|
| 135 | // your C program with c compiler when using this sat solver, you |
---|
| 136 | // still need c++ linker to link the library. |
---|
| 137 | // |
---|
| 138 | // Have fun. |
---|
| 139 | // The Chaff Team |
---|
| 140 | // (contact zfu@EE.Princeton.EDU |
---|
| 141 | // for any questions or suggestions) |
---|
| 142 | // 2004. 3. 10 |
---|
| 143 | // =============================================================*/ |
---|
| 144 | |
---|
| 145 | |
---|
| 146 | // Following are the main functions for the flow. |
---|
| 147 | |
---|
| 148 | // init a manager |
---|
| 149 | SAT_Manager SAT_InitManager(void); |
---|
| 150 | |
---|
| 151 | // get the version of the solver |
---|
| 152 | char * SAT_Version(SAT_Manager mng); |
---|
| 153 | |
---|
| 154 | // release a manager |
---|
| 155 | void SAT_ReleaseManager(SAT_Manager mng); |
---|
| 156 | |
---|
| 157 | // set the number of variables. |
---|
| 158 | void SAT_SetNumVariables(SAT_Manager mng, |
---|
| 159 | int num_vars); |
---|
| 160 | |
---|
| 161 | // add a variable. it will return the new var's index |
---|
| 162 | int SAT_AddVariable(SAT_Manager mng); |
---|
| 163 | |
---|
| 164 | // the following functions will allow/disallow the variable to be branched |
---|
| 165 | // user may want to branch only on certain variables (for example, primary |
---|
| 166 | // inputs of a circuit, if the CNF is generated from circuit). |
---|
| 167 | // By default, all variables are branchable, usually, if a variable is |
---|
| 168 | // unbranchable, it's value should be determined by all the branchable variables. |
---|
| 169 | // if that's not the case, then these variables may not get an assigned |
---|
| 170 | // value even if the solver says that the problem is satisfiable. |
---|
| 171 | // Notice, the solver determines if a problem is satisfiable by trying to assign |
---|
| 172 | // all the branchable variables. If all such variables can be assigned values |
---|
| 173 | // without causing conflict, then the instance is reported as satisfiable, even |
---|
| 174 | // if the instance is actually unsatisfiable because of unbranchable |
---|
| 175 | // variables being not dependent on branchable variables. |
---|
| 176 | void SAT_EnableVarBranch(SAT_Manager mng, int vid); |
---|
| 177 | |
---|
| 178 | void SAT_DisableVarBranch(SAT_Manager mng, int vid); |
---|
| 179 | // add a clause. a literal is a integer with value 2*V_idx + sign |
---|
| 180 | // gid is the group ID. by default, gid equals 0 . Note: group 0 |
---|
| 181 | // clauses can't be deleted. |
---|
| 182 | void SAT_AddClause(SAT_Manager mng, |
---|
| 183 | int * clause_lits, |
---|
| 184 | int num_lits, |
---|
| 185 | int gid = 0); |
---|
| 186 | |
---|
| 187 | // delete a clause group and learned clauses depending on them. |
---|
| 188 | void SAT_DeleteClauseGroup(SAT_Manager mng, |
---|
| 189 | int gid); |
---|
| 190 | |
---|
| 191 | // This will reset the solver so it will not keep the implications made before |
---|
| 192 | void SAT_Reset(SAT_Manager mng); |
---|
| 193 | |
---|
| 194 | // merge the clause group gid1 with gid2, return a new group which |
---|
| 195 | // contain both groups. |
---|
| 196 | int SAT_MergeClauseGroup(SAT_Manager mng, |
---|
| 197 | int gid1, |
---|
| 198 | int gid2); |
---|
| 199 | |
---|
| 200 | // Allocate a free clause group id. will be -1 if no more available. |
---|
| 201 | // current implementation allow 32 deletable group IDs ranging from |
---|
| 202 | // 1-32. Group 0 is the permanent group (i.e. can't delete). |
---|
| 203 | int SAT_AllocClauseGroupID(SAT_Manager mng); |
---|
| 204 | |
---|
| 205 | // followings are for clause gid manipulation |
---|
| 206 | int SAT_IsSetClauseGroupID(SAT_Manager mng, int cl_idx, int id); |
---|
| 207 | int SAT_SetClauseGroupID(SAT_Manager mng, int cl_idx, int id); |
---|
| 208 | int SAT_ClearClauseGroupID(SAT_Manager mng, int cl_idx, int id); |
---|
| 209 | // clauses belong to volatile group will always be deleted when |
---|
| 210 | // SAT_DeleteClauseGroup is called |
---|
| 211 | int SAT_GetVolatileGroupID(SAT_Manager mng); |
---|
| 212 | // clauses belong to global group will never be deleted |
---|
| 213 | int SAT_GetGlobalGroupID(SAT_Manager mng); |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | void SAT_SetTimeLimit(SAT_Manager mng, |
---|
| 217 | float runtime); |
---|
| 218 | |
---|
| 219 | // note: memory estimation is very rough, so allow 30% of error |
---|
| 220 | // in both SetMemLimit and EstimateMemUsage. Also, in the run |
---|
| 221 | // time, the memory usage could be temporarily 50% larger than |
---|
| 222 | // the limit (this occours when program reallocate memory because |
---|
| 223 | // of insufficiency in the initial allocation). |
---|
| 224 | void SAT_SetMemLimit(SAT_Manager mng, |
---|
| 225 | int num_bytes); |
---|
| 226 | |
---|
| 227 | |
---|
| 228 | int SAT_Solve(SAT_Manager mng); |
---|
| 229 | // enum SAT_StatusT |
---|
| 230 | // Get a variable's assignment. -1 means UNKNOWN or undicided |
---|
| 231 | int SAT_GetVarAsgnment(SAT_Manager mng, |
---|
| 232 | int v_idx); |
---|
| 233 | |
---|
| 234 | // this is used for randomness in decision making |
---|
| 235 | void SAT_SetRandomness(SAT_Manager mng, |
---|
| 236 | int n); |
---|
| 237 | // if the seed < 0, solver will use the day timer to |
---|
| 238 | // get a "psuedo real random" seed. |
---|
| 239 | void SAT_SetRandSeed(SAT_Manager mng, |
---|
| 240 | int seed); |
---|
| 241 | |
---|
| 242 | // add a hookfunction. This function will be called |
---|
| 243 | // every "interval" of decisions. You can add more than |
---|
| 244 | // one such hook functions. i.e. call SAT_AddHookFun more |
---|
| 245 | // than once. |
---|
| 246 | void SAT_AddHookFun(SAT_Manager mng, |
---|
| 247 | void (*fun)(void *), |
---|
| 248 | int interval); |
---|
| 249 | |
---|
| 250 | // /* ======================================================= |
---|
| 251 | // This function is for users who want to customize their own |
---|
| 252 | // decision making strategy. |
---|
| 253 | // |
---|
| 254 | // What you can do is add a hook function with interval of 1, |
---|
| 255 | // that function will be called before every decision. Inside |
---|
| 256 | // this hook function, use SAT_MakeDecision to make decision |
---|
| 257 | // with variable "vid" and "sign". sign = 1 means value of |
---|
| 258 | // the variable be 0. |
---|
| 259 | // |
---|
| 260 | // If there are no free variable left, problem is satisfied, |
---|
| 261 | // call SAT_MakeDecision with vid = 0 && sign = 0 will cause |
---|
| 262 | // solver exit with status "SATISFIABLE". |
---|
| 263 | // |
---|
| 264 | // Here is an example: |
---|
| 265 | // |
---|
| 266 | // void my_own_decision (SAT_Manager mng) |
---|
| 267 | // { |
---|
| 268 | // int n_var = SAT_NumVariables(mng); |
---|
| 269 | // int i; |
---|
| 270 | // for (i=1; i<n_var; ++i) { |
---|
| 271 | // if (SAT_GetVarAsgnment(mng, i)==UNKNOWN){ |
---|
| 272 | // SAT_MakeDecision(mng, i, 1); //make decision with value 0; |
---|
| 273 | // break; |
---|
| 274 | // } |
---|
| 275 | // } |
---|
| 276 | // if (i >= n_var) //every var got an assignment, no free var left |
---|
| 277 | // SAT_MakeDecision (mng, 0, 0); |
---|
| 278 | // } |
---|
| 279 | // ======================================================== */ |
---|
| 280 | void SAT_MakeDecision(SAT_Manager mng, |
---|
| 281 | int vid, |
---|
| 282 | int sign); |
---|
| 283 | |
---|
| 284 | // Following are statistics collecting functions |
---|
| 285 | int SAT_EstimateMemUsage(SAT_Manager mng); |
---|
| 286 | // time elapsed from last call of GetElapsedCPUTime |
---|
| 287 | float SAT_GetElapsedCPUTime(SAT_Manager mng); |
---|
| 288 | // current cpu time |
---|
| 289 | float SAT_GetCurrentCPUTime(SAT_Manager mng); |
---|
| 290 | // time spent on the whole solving process |
---|
| 291 | float SAT_GetCPUTime(SAT_Manager mng); |
---|
| 292 | |
---|
| 293 | int SAT_NumLiterals(SAT_Manager mng); |
---|
| 294 | |
---|
| 295 | int SAT_NumClauses(SAT_Manager mng); |
---|
| 296 | |
---|
| 297 | int SAT_NumVariables(SAT_Manager mng); |
---|
| 298 | |
---|
| 299 | int SAT_InitNumLiterals(SAT_Manager mng); |
---|
| 300 | |
---|
| 301 | int SAT_InitNumClauses(SAT_Manager mng); |
---|
| 302 | |
---|
| 303 | long64 SAT_NumAddedLiterals(SAT_Manager mng); |
---|
| 304 | |
---|
| 305 | int SAT_NumAddedClauses(SAT_Manager mng); |
---|
| 306 | |
---|
| 307 | int SAT_NumShrinkings(SAT_Manager mng); |
---|
| 308 | |
---|
| 309 | int SAT_NumDeletedClauses(SAT_Manager mng); |
---|
| 310 | |
---|
| 311 | int SAT_NumDelOrigCls(SAT_Manager mng); |
---|
| 312 | |
---|
| 313 | long64 SAT_NumDeletedLiterals(SAT_Manager mng); |
---|
| 314 | |
---|
| 315 | int SAT_NumDecisions(SAT_Manager mng); |
---|
| 316 | int SAT_NumDecisionsStackConf(SAT_Manager mng); |
---|
| 317 | int SAT_NumDecisionsVsids(SAT_Manager mng); |
---|
| 318 | int SAT_NumDecisionsShrinking(SAT_Manager mng); |
---|
| 319 | |
---|
| 320 | |
---|
| 321 | int SAT_Random_Seed(SAT_Manager mng); |
---|
| 322 | |
---|
| 323 | long64 SAT_NumImplications(SAT_Manager mng); |
---|
| 324 | |
---|
| 325 | int SAT_MaxDLevel(SAT_Manager mng); |
---|
| 326 | |
---|
| 327 | float SAT_AverageBubbleMove(SAT_Manager mng); |
---|
| 328 | // Following function will allow you to traverse all the |
---|
| 329 | // clauses and literals. Clause is represented by a index. |
---|
| 330 | // The original clauses' indice are not changed during the |
---|
| 331 | // whole process, while added clauses may get deleted, so |
---|
| 332 | // a certain index may not always represent the same |
---|
| 333 | // clause, also, a index may not always be valid. |
---|
| 334 | int SAT_GetFirstClause(SAT_Manager mng); |
---|
| 335 | |
---|
| 336 | // GetClauseType will get the clause's type. it can be |
---|
| 337 | // ORIGINAL_CL, CONFLICT_CL, PROBE_CL |
---|
| 338 | int SAT_GetClauseType(SAT_Manager mng, int cl_idx); |
---|
| 339 | |
---|
| 340 | // if there are no more clauses left, return value is -1. |
---|
| 341 | // the organization is like : |
---|
| 342 | // index 0 ... InitNumClauses - 1 are the original clauses |
---|
| 343 | // after that, they are added clauses. |
---|
| 344 | int SAT_GetNextClause(SAT_Manager mng, int cl_idx); |
---|
| 345 | |
---|
| 346 | int SAT_GetClauseNumLits(SAT_Manager mng, int cl_idx); |
---|
| 347 | |
---|
| 348 | // the lits array should have been pre-allocated enough memory |
---|
| 349 | // to store all the lits of a clause. Use SAT_GetClauseNumLits to find |
---|
| 350 | // out before-hand how much memory is required. |
---|
| 351 | void SAT_GetClauseLits(SAT_Manager mng, int cl_idx, int * lits); |
---|
| 352 | |
---|
| 353 | // Following functions dictate the run time behavior |
---|
| 354 | // Don't mess with them unless you know what you are doing |
---|
| 355 | void SAT_EnableConfClsDeletion(SAT_Manager mng); |
---|
| 356 | void SAT_DisableConfClsDeletion(SAT_Manager mng); |
---|
| 357 | void SAT_SetClsDeletionInterval(SAT_Manager mng, int freq); |
---|
| 358 | |
---|
| 359 | void SAT_SetMaxUnrelevance(SAT_Manager mng, int n); |
---|
| 360 | void SAT_SetMinClsLenForDelete(SAT_Manager mng, int n); |
---|
| 361 | void SAT_SetMaxConfClsLenAllowed(SAT_Manager mng, int n); |
---|
| 362 | |
---|
| 363 | // void SAT_AllowMultipleConflicts(SAT_Manager mng); |
---|
| 364 | // void SAT_AllowMultipleConfCls(SAT_Manager mng); |
---|
| 365 | // void SAT_SetLitPoolCompactRatio(SAT_Manager mng, float ratio); |
---|
| 366 | // void SAT_SetLitPoolExpantionRatio(SAT_Manager mng, float ration); |
---|
| 367 | |
---|
| 368 | // this function cleans all learned clauses in the database. |
---|
| 369 | // it can be called if you incrementally solving many instances and |
---|
| 370 | // the learned clauses occupy too much memory. By calling |
---|
| 371 | // this function, it essentially equal to a fresh restart, i.e. throw |
---|
| 372 | // away the learned clauses obtained so far. |
---|
| 373 | void SAT_CleanUpDatabase(SAT_Manager mng); |
---|
| 374 | |
---|
| 375 | // Followings are functions to facilitate the translation from |
---|
| 376 | // Circuit to a CNF representation. It will automatically generate |
---|
| 377 | // the necessary clauses to represent the gates. |
---|
| 378 | // Note: The input convension are the same as in AddClause, |
---|
| 379 | // e.g. 2 * Vid + Sign |
---|
| 380 | // NOTE: You need to make sure that the signals (a, b, c, o etc) are |
---|
| 381 | // distinctive. I.e. the two inputs to a AND2 gate are different |
---|
| 382 | // signals. Otherwise, the solver may behave incorrectly. Don't |
---|
| 383 | // add a gate that has signal a and a' as inputs. You should do |
---|
| 384 | // these kinds of special case simplifications by yourself. |
---|
| 385 | |
---|
| 386 | |
---|
| 387 | void SAT_GenClsAnd2(SAT_Manager mng, |
---|
| 388 | int a, |
---|
| 389 | int b, |
---|
| 390 | int o, |
---|
| 391 | int gid = 0); |
---|
| 392 | |
---|
| 393 | void SAT_GenClsAndN(SAT_Manager mng, |
---|
| 394 | int * inputs, |
---|
| 395 | int num_inputs, |
---|
| 396 | int o, |
---|
| 397 | int gid = 0); |
---|
| 398 | |
---|
| 399 | void SAT_GenClsOr2(SAT_Manager mng, |
---|
| 400 | int a, |
---|
| 401 | int b, |
---|
| 402 | int o, |
---|
| 403 | int gid = 0); |
---|
| 404 | |
---|
| 405 | void SAT_GenClsOrN(SAT_Manager mng, |
---|
| 406 | int * inputs, |
---|
| 407 | int num_inputs, |
---|
| 408 | int o, |
---|
| 409 | int gid = 0); |
---|
| 410 | |
---|
| 411 | void SAT_GenClsNand2(SAT_Manager mng, |
---|
| 412 | int a, |
---|
| 413 | int b, |
---|
| 414 | int o, |
---|
| 415 | int gid = 0); |
---|
| 416 | |
---|
| 417 | void SAT_GenClsNandN(SAT_Manager mng, |
---|
| 418 | int * inputs, |
---|
| 419 | int num_inputs, |
---|
| 420 | int o, |
---|
| 421 | int gid = 0); |
---|
| 422 | |
---|
| 423 | void SAT_GenClsNor2(SAT_Manager mng, |
---|
| 424 | int a, |
---|
| 425 | int b, |
---|
| 426 | int o, |
---|
| 427 | int gid = 0); |
---|
| 428 | |
---|
| 429 | void SAT_GenClsNorN(SAT_Manager mng, |
---|
| 430 | int * inputs, |
---|
| 431 | int num_inputs, |
---|
| 432 | int o, |
---|
| 433 | int gid = 0); |
---|
| 434 | |
---|
| 435 | void SAT_GenClsXor(SAT_Manager mng, |
---|
| 436 | int a, |
---|
| 437 | int b, |
---|
| 438 | int o, |
---|
| 439 | int gid = 0); |
---|
| 440 | |
---|
| 441 | void SAT_GenClsNot(SAT_Manager mng, |
---|
| 442 | int a, |
---|
| 443 | int o, |
---|
| 444 | int gid = 0); |
---|
| 445 | |
---|
| 446 | #endif |
---|