rustsat-cadical 0.7.5

Interface to the SAT solver CaDiCaL for the RustSAT library.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
#ifndef _options_hpp_INCLUDED
#define _options_hpp_INCLUDED

/*------------------------------------------------------------------------*/

// In order to add a new option, simply add a new line below. Make sure that
// options are sorted correctly (with '!}sort -k 2' in 'vi').  Otherwise
// initializing the options will trigger an internal error.  For the model
// based tester 'mobical' the policy is that options which become redundant
// because another one is disabled (set to zero) should have the name of the
// latter as prefix.  The 'O' column determines the options which are
// target to 'optimize' them ('-O[1-3]').  A zero value in the 'O' column
// means that this option is not optimized.  A value of '1' results in
// optimizing its value exponentially with exponent base '2', and a value
// of '2' uses base '10'.  The 'P' column determines simplification
// options (disabled with '--plain') and 'R' which values can be reset.

// clang-format off

#define OPTIONS \
\
/*      NAME         DEFAULT, LO, HI,O,P,R, USAGE */ \
\
OPTION( arena,             1,  0,  1,0,0,1, "allocate clauses in arena") \
OPTION( arenacompact,      1,  0,  1,0,0,1, "keep clauses compact") \
OPTION( arenasort,         1,  0,  1,0,0,1, "sort clauses in arena") \
OPTION( arenatype,         3,  1,  3,0,0,1, "1=clause, 2=var, 3=queue") \
OPTION( backbone,          1,  0,  2,0,0,1, "binary clause backbone") \
OPTION( backboneeffort,   20,  0,1e5,0,0,1, "binary effort in per mile") \
OPTION( backbonemaxrounds,1e3, 0,1e5,0,0,1, "backbone rounds limit") \
OPTION( backbonerounds,  100,  0,1e5,0,0,1, "backbone rounds limit") \
OPTION( backbonethresh,    5,  0,1e9,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( binary,            1,  0,  1,0,0,1, "use binary proof format") \
OPTION( block,             0,  0,  1,0,1,1, "blocked clause elimination") \
OPTION( blockmaxclslim,  1e5,  1,2e9,2,0,1, "maximum clause size") \
OPTION( blockminclslim,    2,  2,2e9,0,0,1, "minimum clause size") \
OPTION( blockocclim,     1e2,  1,2e9,2,0,1, "occurrence limit") \
OPTION( bump,              1,  0,  1,0,0,1, "bump variables") \
OPTION( bumpreason,        1,  0,  1,0,0,1, "bump reason literals too") \
OPTION( bumpreasondepth,   1,  1,  3,0,0,1, "bump reason depth") \
OPTION( bumpreasonlimit,  10,  1,2e9,0,0,1, "bump reason limit") \
OPTION( bumpreasonrate,  100,  1,2e9,0,0,1, "bump reason decision rate") \
OPTION( check,             0,  0,  1,0,0,0, "enable internal checking") \
OPTION( checkassumptions,  1,  0,  1,0,0,0, "check assumptions satisfied") \
OPTION( checkconstraint,   1,  0,  1,0,0,0, "check constraint satisfied") \
OPTION( checkfailed,       1,  0,  1,0,0,0, "check failed literals form core") \
OPTION( checkfrozen,       0,  0,  1,0,0,0, "check all frozen semantics") \
OPTION( checkproof,        3,  0,  3,0,0,0, "1=drat, 2=lrat, 3=both") \
OPTION( checkwitness,      1,  0,  1,0,0,0, "check witness internally") \
OPTION( chrono,            1,  0,  2,0,0,1, "chronological backtracking") \
OPTION( chronoalways,      0,  0,  1,0,0,1, "force always chronological") \
OPTION( chronolevelim,   1e2,  0,2e9,0,0,1, "chronological level limit") \
OPTION( chronoreusetrail,  1,  0,  1,0,0,1, "reuse trail chronologically") \
OPTION( compact,           1,  0,  1,0,1,1, "compact internal variables") \
OPTION( compactint,      2e3,  1,2e9,0,0,1, "compacting interval") \
OPTION( compactlim,      1e2,  0,1e3,0,0,1, "inactive limit per mille") \
OPTION( compactmin,      1e2,  1,2e9,0,0,1, "minimum inactive limit") \
OPTION( condition,         0,  0,  1,0,1,1, "globally blocked clause elim") \
OPTION( conditioneffort, 100,  1,1e5,0,0,1, "relative efficiency per mille") \
OPTION( conditionint,    1e4,  1,2e9,0,0,1, "initial conflict interval") \
OPTION( conditionmaxeff, 1e7,  0,2e9,1,0,1, "maximum condition efficiency") \
OPTION( conditionmaxrat, 100,  1,2e9,1,0,1, "maximum clause variable ratio") \
OPTION( conditionmineff,   0,  0,2e9,1,0,1, "minimum condition efficiency") \
OPTION( congruence,        1,  0,  1,0,1,1, "congruence closure") \
OPTION( congruenceand,     1,  0,  1,0,0,1, "extract AND gates") \
OPTION( congruenceandarity,1e6,2,5e7,0,0,1, "AND gate arity limit") \
OPTION( congruencebinaries,1,  0,  1,0,0,1, "extract binary and strengthen ternary clauses") \
OPTION( congruenceite,     1,  0,  1,0,0,1, "extract ITE gates") \
OPTION( congruencexor,     1,  0,  1,0,0,1, "extract XOR gates") \
OPTION( congruencexorarity,4,  2, 31,0,0,1, "XOR gate arity limit") \
OPTION( congruencexorcounts,1, 1,5e6,0,0,1, "XOR gate round") \
OPTION( cover,             0,  0,  1,0,1,1, "covered clause elimination") \
OPTION( covereffort,       4,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( covermaxclslim,  1e5,  1,2e9,2,0,1, "maximum clause size") \
OPTION( covermaxeff,     1e8,  0,2e9,1,0,1, "maximum cover efficiency") \
OPTION( coverminclslim,    2,  2,2e9,0,0,1, "minimum clause size") \
OPTION( covermineff,       0,  0,2e9,1,0,1, "minimum cover efficiency") \
OPTION( decompose,         1,  0,  1,0,1,1, "decompose BIG in SCCs and ELS") \
OPTION( decomposerounds,   2,  1, 16,1,0,1, "number of decompose rounds") \
OPTION( deduplicate,       1,  0,  1,0,1,1, "remove duplicated binaries") \
OPTION( deduplicateallinit,0,  0,  1,0,1,1, "remove duplicated clauses once before solving") \
OPTION( eagersubsume,      1,  0,  1,0,1,1, "subsume recently learned") \
OPTION( eagersubsumelim,  20,  1,1e3,0,0,1, "limit on subsumed candidates") \
OPTION( elim,              1,  0,  1,0,1,1, "bounded variable elimination") \
OPTION( elimands,          1,  0,  1,0,0,1, "find AND gates") \
OPTION( elimbackward,      1,  0,  1,0,0,1, "eager backward subsumption") \
OPTION( elimboundmax,     16, -1,2e6,1,0,1, "maximum elimination bound") \
OPTION( elimboundmin,      0, -1,2e6,0,0,1, "minimum elimination bound") \
OPTION( elimclslim,      1e2,  2,2e9,2,0,1, "resolvent size limit") \
OPTION( elimdef,           0,  0,  1,0,0,1, "mine definitions with kitten") \
OPTION( elimdefcores,      1,  1,100,0,0,1, "number of unsat cores") \
OPTION( elimdefticks,    2e5,  0,2e9,1,0,1, "kitten ticks limit") \
OPTION( elimeffort,      1e3,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( elimequivs,        1,  0,  1,0,0,1, "find equivalence gates") \
OPTION( elimint,         2e3,  1,2e9,0,0,1, "elimination interval") \
OPTION( elimites,          1,  0,  1,0,0,1, "find if-then-else gates") \
OPTION( elimlimited,       1,  0,  1,0,0,1, "limit resolutions") \
OPTION( elimmaxeff,      2e9,  0,2e9,1,0,1, "maximum elimination efficiency") \
OPTION( elimmineff,      1e7,  0,2e9,1,0,1, "minimum elimination efficiency") \
OPTION( elimocclim,      1e2,  0,2e9,2,0,1, "occurrence limit") \
OPTION( elimprod,          1,  0,1e4,0,0,1, "elim score product weight") \
OPTION( elimrounds,        2,  1,512,1,0,1, "usual number of rounds") \
OPTION( elimsubst,         1,  0,  1,0,0,1, "elimination by substitution") \
OPTION( elimsum,           1,  0,1e4,0,0,1, "elimination score sum weight") \
OPTION( elimxorlim,        5,  2, 27,1,0,1, "maximum XOR size") \
OPTION( elimxors,          1,  0,  1,0,0,1, "find XOR gates") \
OPTION( emadecisions,    1e5,  1,2e9,0,0,1, "window decision rate") \
OPTION( emagluefast,      33,  1,2e9,0,0,1, "window fast glue") \
OPTION( emaglueslow,     1e5,  1,2e9,0,0,1, "window slow glue") \
OPTION( emajump,         1e5,  1,2e9,0,0,1, "window back-jump level") \
OPTION( emalevel,        1e5,  1,2e9,0,0,1, "window back-track level") \
OPTION( emasize,         1e5,  1,2e9,0,0,1, "window learned clause size") \
OPTION( ematrailfast,    1e2,  1,2e9,0,0,1, "window fast trail") \
OPTION( ematrailslow,    1e5,  1,2e9,0,0,1, "window slow trail") \
OPTION( exteagerreasons,   1,  0,  1,0,0,1, "eagerly ask for all reasons (0: only when needed)") \
OPTION( exteagerrecalc,    1,  0,  1,0,0,1, "after eagerly asking for reasons recalculate all levels (0: trust the external tool)") \
OPTION( externallrat,      0,  0,  1,0,0,1, "external lrat") \
OPTION( factor,            0,  0,  1,0,1,1, "bounded variable addition") \
OPTION( factorcandrounds,  2,  0,2e9,0,0,1, "candidates reduction rounds") \
OPTION( factorcheck,       1,  0,  2,0,0,1, "API checks that variables have been declared (1 = only with factor on, 2 = always)") \
OPTION( factordelay,       4,  0, 12,0,0,1, "delay bounded variable addition between eliminations") \
OPTION( factoreffort,     50,  0,1e6,0,0,1, "relative effort per mille") \
OPTION( factoriniticks,  300,  1,1e6,0,0,1, "initial effort in millions") \
OPTION( factorsize,        5,  2,2e9,0,0,1, "clause size limit") \
OPTION( factorthresh,      7,  0,100,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( factorunbump,      1,  0,  1,0,1,1, "extension variable with lowest importance [1: as in kissat]") \
OPTION( fastelim,          1,  0,  1,0,1,1, "fast BVE during preprocessing") \
OPTION( fastelimbound,     8,  1,1e3,1,0,1, "fast BVE bound during preprocessing") \
OPTION( fastelimclslim,  1e2,  2,2e9,2,0,1, "fast BVE resolvent size limit") \
OPTION( fastelimocclim,  100,  1,2e9,2,0,1, "fast BVE occurence limit during preprocessing") \
OPTION( fastelimrounds,    4,  1,512,1,0,1, "number of fastelim rounds") \
OPTION( flush,             0,  0,  1,0,1,1, "flush redundant clauses") \
OPTION( flushfactor,       3,  1,1e3,0,0,1, "interval increase") \
OPTION( flushint,        1e5,  1,2e9,0,0,1, "initial limit") \
OPTION( forcephase,        0,  0,  1,0,0,1, "always use initial phase") \
OPTION( frat,              0,  0,  2,0,0,1, "1=frat(lrat), 2=frat(drat)") \
OPTION( idrup,             0,  0,  1,0,0,1, "incremental proof format") \
OPTION( ilb,               0,  0,  2,0,0,1, "ILB (incremental lazy backtrack) (0: no, 1: assumptions only, 2: everything)") \
OPTION( incdecay,          1,  0,  4,0,0,1, "decay clauses when doing incremental clauses" ) \
OPTION( incdecayint,     1e6,  1,2e9,0,0,1, "decay interval when doing incremental clauses" ) \
OPTION( inprobeint,      100,  1,2e9,0,0,1, "inprobing interval" ) \
OPTION( inprobing,         1,  0,  1,0,1,1, "enable probe inprocessing") \
OPTION( inprocessing,      1,  0,  1,0,1,1, "enable general inprocessing") \
OPTION( instantiate,       0,  0,  1,0,1,1, "variable instantiation") \
OPTION( instantiateclslim, 3,  2,2e9,0,0,1, "minimum clause size") \
OPTION( instantiateocclim, 1,  1,2e9,2,0,1, "maximum occurrence limit") \
OPTION( instantiateonce,   1,  0,  1,0,0,1, "instantiate each clause once") \
OPTION( lidrup,            0,  0,  1,0,0,1, "linear incremental proof format") \
LOGOPT( log,               0,  0,  1,0,0,0, "enable logging") \
LOGOPT( logsort,           0,  0,  1,0,0,0, "sort logged clauses") \
OPTION( lrat,              0,  0,  1,0,0,1, "use LRAT proof format") \
OPTION( lucky,             1,  0,  1,0,0,1, "lucky phases") \
OPTION( luckyassumptions,  1,  0,  1,0,0,1, "lucky phases with assumptions") \
OPTION( luckyearly,        1,  0,  1,0,0,1, "lucky phases before preprocessing") \
OPTION( luckylate,         1,  0,  1,0,0,1, "lucky phases after preprocessing") \
OPTION( minimize,          1,  0,  1,0,0,1, "minimize learned clauses") \
OPTION( minimizedepth,   1e3,  0,1e3,0,0,1, "minimization depth") \
OPTION( minimizeticks,     1,  0,  1,0,0,1, "increment ticks in minimization") \
OPTION( otfs,              1,  0,  1,0,0,1, "on-the-fly self subsumption") \
OPTION( phase,             1,  0,  1,0,0,1, "initial phase") \
OPTION( preprocessinit,  2e6,  0,2e9,2,0,1, "initial preprocessing base limit" ) \
OPTION( preprocesslight,   1,  0,  1,0,1,1, "lightweight preprocessing" ) \
OPTION( probe,             1,  0,  1,0,1,1, "failed literal probing" ) \
OPTION( probeeffort,       8,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( probehbr,          1,  0,  1,0,0,1, "learn hyper binary clauses") \
OPTION( probethresh,       0,  0,100,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( profile,           2,  0,  4,0,0,0, "profiling level") \
QUTOPT( quiet,             0,  0,  1,0,0,0, "disable all messages") \
OPTION( radixsortlim,     32,  0,2e9,0,0,1, "radix sort limit") \
OPTION( randec,            0,  0,  1,0,0,1, "random decisions") \
OPTION( randecfocused,     1,  0,  1,0,0,1, "random decisions in focused mode") \
OPTION( randecinit,       1e3, 2,2e9,0,0,1, "inital random decision interval") \
OPTION( randecint,       500,  0,2e9,0,0,1, "random conflict length") \
OPTION( randeclength,     10,  1,1e9,0,0,1, "length random decisions phases") \
OPTION( randecstable,      0,  0,  1,0,0,1, "random decisions in stable mode") \
OPTION( realtime,          0,  0,  1,0,0,0, "real instead of process time") \
OPTION( recomputetier,     1,  0,  1,0,0,1, "recompute tiers") \
OPTION( reduce,            1,  0,  1,0,0,1, "reduce useless clauses") \
OPTION( reduceinit,      300,  1,1e6,0,0,1, "initial interval") \
OPTION( reduceint,        25,  2,1e6,0,0,1, "reduce interval") \
OPTION( reduceopt,         1,  0,  2,0,0,1, "0=prct,1=sqrt,2=max") \
OPTION( reducetarget,     75, 10,1e2,0,0,1, "reduce fraction in percent") \
OPTION( reducetier1glue,   2,  1,2e9,0,0,1, "glue of kept learned clauses") \
OPTION( reducetier2glue,   6,  1,2e9,0,0,1, "glue of tier two clauses") \
OPTION( reluctant,         1,  0,  1,0,0,1, "stable reluctant doubling restarts") \
OPTION( reluctantint,   1024,  0,2e9,0,0,1, "reluctant doubling period") \
OPTION( reluctantmax,1048576,  0,2e9,0,0,1, "maximum reluctant doubling period") \
OPTION( rephase,           1,  0,  2,0,0,1, "enable resetting phase (0=no,1=always,2=stable-only)") \
OPTION( rephaseint,      1e3,  1,2e9,0,0,1, "rephase interval") \
OPTION( report,reportdefault,  0,  1,0,0,1, "enable reporting") \
OPTION( reportall,         0,  0,  1,0,0,1, "report even if not successful") \
OPTION( reportsolve,       0,  0,  1,0,0,1, "use solving not process time") \
OPTION( restart,           1,  0,  1,0,0,1, "enable restarts") \
OPTION( restartint,        2,  1,2e9,0,0,1, "restart interval") \
OPTION( restartmarginfocused,10,0,25,0,0,1, "focused slow fast margin in percent") \
OPTION( restartmarginstable ,25,0,25,0,0,1, "stable slow fast margin in percent") \
OPTION( restartreusetrail, 1,  0,  1,0,0,1, "enable trail reuse") \
OPTION( restoreall,        0,  0,  2,0,0,1, "restore all clauses (2=really)") \
OPTION( restoreflush,      0,  0,  1,0,0,1, "remove satisfied clauses") \
OPTION( reverse,           0,  0,  1,0,0,1, "reverse variable ordering") \
OPTION( score,             1,  0,  1,0,0,1, "use EVSIDS scores") \
OPTION( scorefactor,     950,500,1e3,0,0,1, "score factor per mille") \
OPTION( seed,              0,  0,2e9,0,0,1, "random seed") \
OPTION( shrink,            3,  0,  3,0,0,1, "shrink conflict clause (1=binary-only,2=minimize-on-pulling,3=full)") \
OPTION( shrinkreap,        1,  0,  1,0,0,1, "use a reap for shrinking") \
OPTION( shuffle,           0,  0,  1,0,0,1, "shuffle variables") \
OPTION( shufflequeue,      1,  0,  1,0,0,1, "shuffle variable queue") \
OPTION( shufflerandom,     0,  0,  1,0,0,1, "not reverse but random") \
OPTION( shufflescores,     1,  0,  1,0,0,1, "shuffle variable scores") \
OPTION( stabilize,         1,  0,  1,0,0,1, "enable stabilizing phases") \
OPTION( stabilizeinit,   1e3,  1,2e9,0,0,1, "stabilizing interval") \
OPTION( stabilizeonly,     0,  0,  1,0,0,1, "only stabilizing phases") \
OPTION( stats,             0,  0,  1,0,0,1, "print all statistics at the end of the run") \
OPTION( stubbornIOfocused, 0,  0,  1,0,0,1, "force phases to I/O in focused mode every once in a while (requires rephase==2)") \
OPTION( subsume,           1,  0,  1,0,1,1, "enable clause subsumption") \
OPTION( subsumebinlim,   1e4,  0,2e9,1,0,1, "watch list length limit") \
OPTION( subsumeclslim,   1e2,  0,2e9,2,0,1, "clause length limit") \
OPTION( subsumeeffort,   1e3,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( subsumelimited,    1,  0,  1,0,0,1, "limit subsumption checks") \
OPTION( subsumemaxeff,   1e8,  0,2e9,1,0,1, "maximum subsuming efficiency") \
OPTION( subsumemineff,     0,  0,2e9,1,0,1, "minimum subsuming efficiency") \
OPTION( subsumeocclim,   1e2,  0,2e9,1,0,1, "watch list length limit") \
OPTION( subsumestr,        1,  0,  1,0,0,1, "subsume strengthen") \
OPTION( sweep,             1,  0,  1,0,1,1, "enable SAT sweeping") \
OPTION( sweepclauses,   1024,  0,2e9,1,0,1, "environment clauses") \
OPTION( sweepcomplete,     0,  0,  1,0,0,1, "run SAT sweeping to completion") \
OPTION( sweepcountbinary,  1,  0,  1,0,0,1, "count binaries to environment") \
OPTION( sweepdepth,        2,  0,2e9,1,0,1, "environment depth") \
OPTION( sweepeffort,     1e2,  0,1e4,0,0,1, "relative effort in ticks per mille") \
OPTION( sweepfliprounds,   1,  0,2e9,1,0,1, "flipping rounds") \
OPTION( sweepmaxclauses, 3e5,  2,2e9,1,0,1, "maximum environment clauses") \
OPTION( sweepmaxdepth,     3,  1,2e9,1,0,1, "maximum environment depth") \
OPTION( sweepmaxvars,   8192,  2,2e9,1,0,1, "maximum environment variables") \
OPTION( sweeprand,         0,  0,  1,0,0,1, "randomize sweeping environment") \
OPTION( sweepthresh,       5,  0,100,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( sweepvars,       256,  0,2e9,1,0,1, "environment variables") \
OPTION( target,            1,  0,  2,0,0,1, "target phases (1=stable only)") \
OPTION( terminateint,     10,  0,1e4,0,0,1, "termination check interval") \
OPTION( ternary,           1,  0,  1,0,1,1, "hyper ternary resolution") \
OPTION( ternaryeffort,     8,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( ternarymaxadd,   1e3,  0,1e4,1,0,1, "max clauses added in percent") \
OPTION( ternaryocclim,   1e2,  1,2e9,2,0,1, "ternary occurrence limit") \
OPTION( ternaryrounds,     2,  1, 16,1,0,1, "maximum ternary rounds") \
OPTION( ternarythresh,     6,  0,100,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( tier1limit,       50,  0,100,0,0,1, "limit of tier1 usage in percentage") \
OPTION( tier1minglue,      0,  0,100,0,0,1, "lowest tier1 limit") \
OPTION( tier2limit,       90,  0,100,0,0,1, "limit of tier2 usage in percentage") \
OPTION( tier2minglue,      0,  0,100,0,0,1, "lowest tier2 limit") \
OPTION( transred,          1,  0,  1,0,1,1, "transitive reduction of BIG") \
OPTION( transredeffort,  1e2,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( transredmaxeff,  1e8,  0,2e9,1,0,1, "maximum efficiency") \
OPTION( transredmineff,    0,  0,2e9,1,0,1, "minimum efficiency") \
QUTOPT( verbose,           0,  0,  3,0,0,0, "more verbose messages") \
OPTION( veripb,            0,  0,  4,0,0,1, "odd=check-deletions, >2 drat") \
OPTION( vivify,            1,  0,  1,0,1,1, "vivification") \
OPTION( vivifycalctier,    0,  0,  1,0,0,1, "recalculate tier limits") \
OPTION( vivifydemote,      0,  0,  1,0,1,1, "demote irredundant or delete directly") \
OPTION( vivifyeffort,     50,  0,1e5,1,0,1, "overall efficiency per mille") \
OPTION( vivifyflush,       1,  0,  1,1,0,1,  "flush subsumed before vivification rounds") \
OPTION( vivifyinst,        1,  0,  1,0,0,1, "instantiate last literal when vivify") \
OPTION( vivifyirred,       1,  0,  1,0,0,1, "vivification of irredundant clauses") \
OPTION( vivifyirredeff,    3,  1,100,1,0,1, "irredundant efficiency per mille") \
OPTION( vivifyonce,        0,  0,  2,0,0,1, "vivify once: 1=red, 2=red+irr") \
OPTION( vivifyretry,       0,  0,  5,0,0,1, "re-vivify clause if vivify was successful") \
OPTION( vivifyschedmax,  5e3, 10,2e9,0,0,1, "maximum schedule size") \
OPTION( vivifythresh,     20,  0,100,1,0,1, "delay if ticks smaller thresh*clauses") \
OPTION( vivifytier1,       1,  0,  1,0,0,1, "vivification tier1") \
OPTION( vivifytier1eff,    4,  0,100,1,0,1, "relative tier1 effort") \
OPTION( vivifytier2,       1,  0,  1,0,0,1, "vivification tier2") \
OPTION( vivifytier2eff,    2,  1,100,1,0,1, "relative tier2 effort") \
OPTION( vivifytier3,       1,  0,  1,0,0,1, "vivification tier3") \
OPTION( vivifytier3eff,    1,  1,100,1,0,1, "relative tier3 effort") \
OPTION( walk,              1,  0,  1,0,0,1, "enable random walks") \
OPTION( walkeffort,       80,  1,1e5,1,0,1, "relative efficiency per mille") \
OPTION( walkfullocc,      0,   0,  1,1,0,1, "use Kissat's full occurrences instead of the single watched") \
OPTION( walkmaxeff,      1e7,  0,2e9,1,0,1, "maximum efficiency (in 1e3 ticks)") \
OPTION( walkmineff,        0,  0,1e7,1,0,1, "minimum efficiency") \
OPTION( walknonstable,     1,  0,  1,0,0,1, "walk in non-stabilizing phase") \
OPTION( walkredundant,     0,  0,  1,0,0,1, "walk redundant clauses too") \
OPTION( warmup,            1,  0,  1,0,0,1, "warmup before walk using propagation") \

// Note, keep an empty line right before this line because of the last '\'!
// Also keep those single spaces after 'OPTION(' for proper sorting.

// clang-format on

/*------------------------------------------------------------------------*/

// Some of the 'OPTION' macros above should only be included if certain
// compile time options are enabled.  This has the effect, that for instance
// if 'LOGGING' is defined, and thus logging code is included, then also the
// 'log' option is defined.  Otherwise the 'log' option is not included.

#ifdef LOGGING
#define LOGOPT OPTION
#else
#define LOGOPT(...) /**/
#endif

#ifdef QUIET
#define QUTOPT(...) /**/
#else
#define QUTOPT OPTION
#endif

/*------------------------------------------------------------------------*/

namespace CaDiCaL {

struct Internal;

/*------------------------------------------------------------------------*/

class Options;

struct Option {
  const char *name;
  int def, lo, hi;
  int optimizable;
  bool preprocessing;
  const char *description;
  int &val (Options *);
};

/*------------------------------------------------------------------------*/

// Produce a compile time constant for the number of options.

static const size_t number_of_options =
#define OPTION(N, V, L, H, O, P, R, D) 1 +
    OPTIONS
#undef OPTION
    + 0;

/*------------------------------------------------------------------------*/

class Options {

  Internal *internal;

  void set (Option *, int val); // Force to [lo,hi] interval.

  friend struct Option;
  static Option table[];

  static void initialize_from_environment (int &val, const char *name,
                                           const int L, const int H);

  friend Config;

  void reset_default_values ();
  void disable_preprocessing ();

public:
  // For library usage we disable reporting by default while for the stand
  // alone SAT solver we enable it by default.  This default value has to
  // be set before the constructor of 'Options' is called (which in turn is
  // called from the constructor of 'Solver').  If we would simply overwrite
  // its initial value while initializing the stand alone solver,  we will
  // get that change of the default value (from 'false' to 'true') shown
  // during calls to 'print ()', which is confusing to the user.
  //
  static int reportdefault;

  Options (Internal *);

  // Makes options directly accessible, e.g., for instance declares the
  // member 'int restart' here.  This will give fast access to option values
  // internally in the solver and thus can also be used in tight loops.
  //
private:
  int __start_of_options__; // Used by 'val' below.
public:
#define OPTION(N, V, L, H, O, P, R, D) \
  int N; // Access option values by name.
  OPTIONS
#undef OPTION

  // It would be more elegant to use an anonymous 'struct' of the actual
  // option values overlayed with an 'int values[number_of_options]' array
  // but that is not proper ISO C++ and produces a warning.  Instead we use
  // the following construction which relies on '__start_of_options__' and
  // that the following options are really allocated directly after it.
  //
  inline int &val (size_t idx) {
    assert (idx < number_of_options);
    return (&__start_of_options__ + 1)[idx];
  }

  // With the following function we can get rather fast access to the option
  // limits, the default value and the description.  The code uses binary
  // search over the sorted option 'table'.  This static data is shared
  // among different instances of the solver.  The actual current option
  // values are here in the 'Options' class.  They can be accessed by the
  // offset of the static options using 'Option::val' if you have an
  // 'Option' or to have even faster access directly by the member function
  // (the 'N' above, e.g., 'restart').
  //
  static Option *has (const char *name);

  bool set (const char *name, int); // Explicit version.
  int get (const char *name);       // Get current value.

  void print ();        // Print current values in command line form
  static void usage (); // Print usage message for all options.

  void optimize (int val); // increase some limits (val=0..31)

  static bool is_preprocessing_option (const char *name);

  // Parse long option argument
  //
  //   --<name>
  //   --<name>=<val>
  //   --no-<name>
  //
  // where '<val>' is as in 'parse_option_value'.  If parsing succeeds,
  // 'true' is returned and the string will be set to the name of the
  // option.  Additionally the parsed value is set (last argument).
  //
  static bool parse_long_option (const char *, string &, int &);

  // Iterating options.

  typedef Option *iterator;
  typedef const Option *const_iterator;

  static iterator begin () { return table; }
  static iterator end () { return table + number_of_options; }

  void copy (Options &other) const; // Copy 'this' into 'other'.
};

inline int &Option::val (Options *opts) {
  assert (Options::table <= this &&
          this < Options::table + number_of_options);
  return opts->val (this - Options::table);
}

} // namespace CaDiCaL

#endif