-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathCoreSMTSolver.h
More file actions
1165 lines (1015 loc) · 45.3 KB
/
CoreSMTSolver.h
File metadata and controls
1165 lines (1015 loc) · 45.3 KB
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
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*********************************************************************
Author: Antti Hyvarinen <antti.hyvarinen@gmail.com>
OpenSMT2 -- Copyright (C) 2012 - 2016 Antti Hyvarinen
2008 - 2012 Roberto Bruttomesso
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
/****************************************************************************************[Solver.C]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef MINISATSMTSOLVER_H
#define MINISATSMTSOLVER_H
#define CACHE_POLARITY 0
#include "SMTSolver.h"
#include "THandler.h"
#include <cstdio>
#include <iosfwd>
#include <memory>
#include <sstream>
#include <vector>
#include "Vec.h"
#include "Heap.h"
#include "Alg.h"
#include "SolverTypes.h"
#include "Timer.h"
class Proof;
class ModelBuilder;
// Helper method to print Literal to a stream
std::ostream& operator <<(std::ostream& out, Lit l); // MB: Feel free to find a better place for this method.
// -----------------------------------------------------------------------------------------
// The splits
//
class SplitData
{
bool no_instance; // Does SplitData store the instance?
std::vector<vec<Lit>> constraints; // The split constraints
std::vector<vec<Lit>> learnts; // The learnt clauses
char* litToString(const Lit);
template<class C> char* clauseToString(const C&);
char* clauseToString(const vec<Lit>&);
int getLitSize(const Lit l) const;
void toPTRefs(std::vector<vec<PtAsgn> >& out, const std::vector<vec<Lit> >& in, const THandler &thandler) const;
public:
SplitData(bool no_instance = true)
: no_instance(no_instance)
{ assert(no_instance); }
template<class C> void addConstraint(const C& c)
{
constraints.emplace_back();
vec<Lit>& cstr = constraints.back();
for (int i = 0; i < c.size(); i++)
cstr.push(c[i]);
}
void addLearnt(Clause& c)
{
learnts.emplace_back();
vec<Lit>& learnt = learnts.back();
for (unsigned i = 0; i < c.size(); i++)
learnt.push(c[i]);
}
char* splitToString();
inline void constraintsToPTRefs(std::vector<vec<PtAsgn>>& out, const THandler& thandler) const { toPTRefs(out, constraints, thandler); }
inline void learntsToPTRefs(std::vector<vec<PtAsgn>>& out, const THandler& thandler) const { toPTRefs(out, learnts, thandler); }
};
inline int SplitData::getLitSize(const Lit l) const
{
int sz = 0;
if (sign(l)) sz++;
Var v = var(l);
int n = v+1;
while (n != 0) { n /= 10; sz++; }
return sz;
}
inline char* SplitData::litToString(const Lit l)
{
char* l_str;
asprintf(&l_str, "%s%d", sign(l) ? "-" : "", var(l)+1);
return l_str;
}
template<class C>
inline char* SplitData::clauseToString(const C& c)
{
char* c_str = (char*)malloc(1);
c_str[0] = 0;
char* c_old = c_str;
for (int i = 0; i < c.size(); i++)
{
char* l_str = litToString(c[i]);
c_old = c_str;
asprintf(&c_str, "%s%s ", c_old, l_str);
free(l_str);
free(c_old);
}
c_old = c_str;
asprintf(&c_str, "%s0", c_str);
free(c_old);
return c_str;
}
inline char* SplitData::splitToString()
{
int buf_cap = 1024;
int sz = 0;
char* buf = (char*) malloc(1024);
// The constraints
for (const vec<Lit>& c : constraints) {
for (Lit l : c) {
int n = getLitSize(l);
while (buf_cap < sz + n + 2) // Lit, space, and NULL
{
buf_cap *= 2;
buf = (char*) realloc(buf, buf_cap);
}
sprintf(&buf[sz], "%s%d ", sign(l) ? "-" : "", var(l)+1);
sz += n+1; // Points to the NULL
}
while (buf_cap < sz + 3) // 0, newline, and NULL
{
buf_cap *= 2;
buf = (char*) realloc(buf, buf_cap);
}
sprintf(&buf[sz], "0\n");
sz += 2;
}
for (const vec<Lit> & c : learnts) {
for (Lit l : c) {
int n = getLitSize(l);
while (buf_cap < sz + n + 2) // The size of lit, space, and NULL
{
buf_cap *= 2;
buf = (char*) realloc(buf, buf_cap);
}
sprintf(&buf[sz], "%s%d ", sign(l) ? "-" : "", var(l)+1);
sz += n+1; // points to the null
}
while (buf_cap < sz + 3) // The zero, newline, and the NULL
{
buf_cap *= 2;
buf = (char*) realloc(buf, buf_cap);
}
sprintf(&buf[sz], "0\n");
sz += 2; // Points to the NULL
}
buf = (char*) realloc(buf, sz+1);
return buf;
}
inline void SplitData::toPTRefs(std::vector<vec<PtAsgn> >& out, const std::vector<vec<Lit> >& in, const THandler& theory_handler) const
{
for (const vec<Lit>& c : in) {
out.emplace_back();
vec<PtAsgn>& out_clause = out[out.size()-1];
for (Lit l : c)
{
PTRef tr = theory_handler.varToTerm(var(l));
PtAsgn pta(tr, sign(l) ? l_False : l_True);
out_clause.push(pta);
}
}
}
template<class A, class B>
struct Pair { A first; B second; };
//=================================================================================================
// Solver -- the main class:
class CoreSMTSolver
{
friend class LookaheadScoreClassic;
friend class LookaheadScoreDeep;
protected:
SMTConfig & config; // Stores Config
THandler & theory_handler; // Handles theory
bool verbosity;
bool init;
public:
bool stop = false;
// Constructor/Destructor:
//
CoreSMTSolver(SMTConfig&, THandler&);
virtual ~CoreSMTSolver();
void initialize ( );
void clearSearch (); // Backtrack SAT solver and theories to decision level 0
// Problem specification:
//
protected:
void addVar_ (Var v); // Ensure that var v exists in the solver
virtual Var newVar(bool polarity, bool dvar);// (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
public:
void addVar(Var v); // Anounce the existence of a variable to the solver
bool addOriginalClause(const vec<Lit> & ps);
bool addEmptyClause(); // Add the empty clause, making the solver contradictory.
bool addOriginalClause(Lit p); // Add a unit clause to the solver.
bool addOriginalClause(Lit p, Lit q); // Add a binary clause to the solver.
bool addOriginalClause(Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
protected:
bool addOriginalClause_(const vec<Lit> & _ps); // Add a clause to the solver
public:
// Solving:
//
bool simplify (); // Removes already satisfied clauses.
void declareVarsToTheories(); // Declare the seen variables to the theories
bool solve ( const vec< Lit > & assumps ); // Search for a model that respects a given set of assumptions.
void crashTest (int, Var, Var); // Stress test the theory solver
void toDimacs (FILE* f, const vec<Lit>& assumps); // Write CNF to file in DIMACS-format.
void toDimacs (const char *file, const vec<Lit>& assumps);
void toDimacs (FILE* f, Clause& c, vec<Var>& map, Var& max);
// Convenience versions of 'toDimacs()':
void toDimacs (const char* file);
void toDimacs (const char* file, Lit p);
void toDimacs (const char* file, Lit p, Lit q);
void toDimacs (const char* file, Lit p, Lit q, Lit r);
// Variable mode:
//
void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
// Read state:
//
lbool value (Var x) const; // The current value of a variable.
lbool value (Lit p) const; // The current value of a literal.
lbool safeValue (Var x) const; // The current value of a variable. l_Undef if the variable does not exist.
lbool safeValue (Lit p) const; // The current value of a literal. l_Undef if the literal does not exist.
lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
int nAssigns () const; // The current number of assigned literals.
int nClauses () const; // The current number of original clauses.
int nLearnts () const; // The current number of learnt clauses.
int nVars () const; // The current number of variables.
int nFreeVars () const;
void fillBooleanVars(ModelBuilder & modelBuilder);
Proof const & getProof() const { assert(proof); return *proof; }
// Resource contraints:
//
void setConfBudget(int64_t x);
void setPropBudget(int64_t x);
void budgetOff();
void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver.
void clearInterrupt(); // Clear interrupt indicator flag.
// Memory management:
//
virtual void garbageCollect();
void checkGarbage(double gf);
void checkGarbage();
// External support incremental and backtrackable APIs
// MB: This is used (and needed) by BitBlaster; can be removed if BitBlaster is re-worked
void pushBacktrackPoint ( );
void popBacktrackPoint ( );
void reset ( );
inline void restoreOK ( ) { ok = true; conflict_frame = 0; }
inline bool isOK ( ) const { return ok; } // FALSE means solver is in a conflicting state
inline int getConflictFrame ( ) const { assert(not isOK()); return conflict_frame; }
template<class C>
void printSMTClause ( ostream &, const C& );
void printSMTClause ( ostream &, vec< Lit > &, bool = false );
void printSMTClause ( ostream &, vector< Lit > &, bool = false );
// Added Code
//=================================================================================================
// Extra results: (read-only member variable)
//
vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any). (moded to SMTSolver)
vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
// this vector represent the final conflict clause expressed in the assumptions.
// Mode of operation:
//
double var_decay; // Inverse of the variable activity decay factor. (default 1 / 0.95)
double clause_decay; // Inverse of the clause activity decay factor. (1 / 0.999)
double random_var_freq; // The frequency with which the decision heuristic tries to choose a random variable. (default 0.02)
bool luby_restart;
int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full).
bool rnd_pol; // Use random polarities for branching heuristics.
bool rnd_init_act; // Initialize variable activities with a small random value.
double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered.
int restart_first; // The initial restart limit. (default 100)
double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.1)
double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
bool expensive_ccmin; // Controls conflict clause minimization. (default TRUE)
int polarity_mode; // Controls which polarity the decision heuristic chooses. See enum below for allowed modes. (default polarity_false)
enum { polarity_true = 0, polarity_false = 1, polarity_user = 2, polarity_rnd = 3 };
int learntsize_adjust_start_confl;
double learntsize_adjust_inc;
// Statistics: (read-only member variable)
//
uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts, conflicts_last_update;
uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
#ifdef STATISTICS
opensmt::OSMTTimeVal search_timer;
opensmt::OSMTTimeVal branchTimer;
#endif
double learnts_size;
uint64_t all_learnts;
uint64_t learnt_theory_conflicts;
uint64_t top_level_lits;
// Splits
std::vector<SplitData> splits;
std::vector<vec<Lit>> split_assumptions;
protected:
Lit forced_split; // If theory solver tells that we must split the instance, a literal with unknown value is inserted here for the splitting heuristic
int processed_in_frozen; // The index in Theory's frozen vec until which frozennes has been processed
// Helper structures:
//
static inline VarData mkVarData(CRef cr, int l)
{
VarData d = {cr, l};
return d;
}
void virtual setAssumptions(vec<Lit> const& assumps);
struct Watcher
{
CRef cref;
Lit blocker;
Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
//=================================================================================================
// Added Code
Watcher() : cref(CRef_Undef), blocker(lit_Undef) {}
// Added Code
//=================================================================================================
bool operator==(const Watcher& w) const
{
return cref == w.cref;
}
bool operator!=(const Watcher& w) const
{
return cref != w.cref;
}
};
//=================================================================================================
// Added Code
// struct watcher_lt
// {
// const ClauseAllocator& ca;
// watcher_lt(const ClauseAllocator& ca_) : ca(ca_) {}
// bool operator () (const Watcher& x, const Watcher& y)
// {
// return ca[x.cref].size() < ca[y.cref].size();
// }
// };
// Added Code
//=================================================================================================
struct WatcherDeleted
{
const ClauseAllocator& ca;
WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
bool operator()(const Watcher& w) const
{
return ca[w.cref].mark() == 1;
}
};
struct VarOrderLt
{
const vec<double>& activity;
bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
VarOrderLt(const vec<double>& act) : activity(act) { }
};
friend class VarFilter;
struct VarFilter
{
const CoreSMTSolver& s;
VarFilter(const CoreSMTSolver& _s) : s(_s) {}
bool operator()(Var v) const { return s.assigns[v] == l_Undef && s.decision[v]; }
};
// Solver state:
//
bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
int conflict_frame; // Contains the frame (the assumption literal index+1) where conflict was detected. (Default is 0)
uint32_t n_clauses; // number of clauses in the problem
vec<CRef> clauses; // List of problem clauses.
vec<CRef> learnts; // List of learnt clauses.
vec<CRef> tmp_reas; // Reasons for minimize_conflicts 2
#ifdef PEDANTIC_DEBUG
vec<Clause*> debug_reasons; // Reasons for the theory deduced clauses
Map<Var,int,VarHash> debug_reason_map; // Maps the deduced lit to the clause used to deduce it
#endif
double cla_inc; // Amount to bump next clause with.
vec<double> activity; // A heuristic measurement of the activity of a variable.
double var_inc; // Amount to bump next variable with.
OccLists<Lit, vec<Watcher>, WatcherDeleted> watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
vec<lbool> assigns; // The current assignments (lbool:s stored as char:s).
vec<bool> var_seen;
vec<char> polarity; // The preferred polarity of each variable.
vec<char> decision; // Declares if a variable is eligible for selection in the decision heuristic.
protected:
#ifdef PEDANTIC_DEBUG
public:
vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
protected:
#else
vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
#endif
vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
vec<VarData> vardata; // Stores reason and level for each variable.
int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
Map<Var,int, VarHash> assumptions_order; // Defined for active assumption variables: how manyeth active assumption variable this is in assumptions
Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
double random_seed; // Used by the random variable selection.
double progress_estimate;// Set by 'search()'.
bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
ClauseAllocator ca{512*1024};
#ifdef CACHE_POLARITY
vec<char> prev_polarity; // The previous polarity of each variable.
#endif
// Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
// used, exept 'seen' wich is used in several places.
//
vec<char> seen;
vec<Lit> analyze_stack;
vec<Lit> analyze_toclear;
vec<Lit> add_tmp;
double max_learnts;
double learntsize_adjust_confl;
int learntsize_adjust_cnt;
SpUnit resource_units;
double resource_limit; // Time limit for the search in resource_units
double next_resource_limit; // The limit at which the solver needs to stop
// splitting state vars
SpType split_type;
bool split_on;
bool split_start;
int split_num;
SpUnit split_units;
double split_inittune; // Initial tuning in units.
double split_midtune; // mid-tuning in units.
double split_next; // When the next split will happen?
SpPref split_preference;
int unadvised_splits; // How many times the split happened on a PTRef that the logic considers ill-advised
// Resource contraints:
//
int64_t conflict_budget; // -1 means no budget.
int64_t propagation_budget; // -1 means no budget.
bool asynch_interrupt;
// Main internal methods:
//
virtual lbool solve_ (); // Main solve method (assumptions given in 'assumptions').
void updateSplitState(); // Update the state of the splitting machine.
bool scatterLevel(); // Are we currently on a scatter level.
bool createSplit_scatter(bool last); // Create a split formula and place it to the splits vector.
bool excludeAssumptions(vec<Lit>& neg_constrs); // Add a clause to the database and propagate
void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
virtual Lit pickBranchLit (); // Return the next decision variable.
virtual void newDecisionLevel (); // Begins a new decision level.
void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined.
bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise.
CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause.
virtual void cancelUntil (int level); // Backtrack until a certain level.
void analyze (CRef confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
lbool search (int nof_conflicts, int nof_learnts); // Search for a given number of conflicts.
bool okContinue (); // Check search termination conditions
void runPeriodics (); // Run the periodic functions from searcha
void learntSizeAdjust (); // Adjust learnts size and print something
void reduceDB (); // Reduce the set of learnt clauses.
void removeSatisfied (vec<CRef>& cs); // Shrink 'cs' to contain only non-satisfied clauses.
void rebuildOrderHeap ();
lbool zeroLevelConflictHandler(); // Common handling of zero-level conflict as it can happen at multiple places
// Maintaining Variable/Clause activity:
//
void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value.
void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
// Added Line
// void boolVarDecActivity( ); // Decrease boolean atoms activity
void claDecayActivity ( ); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
void claBumpActivity ( Clause & c ); // Increase a clause with the current 'bump' value.
// Increase a clause with the current 'bump' value.
// Operations on clauses:
//
virtual void attachClause (CRef cr); // Attach a clause to watcher lists.
virtual void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists.
void removeClause (CRef c); // Detach and free a clause.
bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
void relocAll (ClauseAllocator& to);
// Misc:
//
int decisionLevel () const; // Gives the current decisionlevel.
uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
CRef reason (Var x) const;
int level (Var x) const;
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
bool withinBudget () const;
void printSMTLit ( ostream &, const Lit );
virtual void verifyModel ();
void checkLiteralCount();
//ADDED FOR MINIMIZATION
void printClause ( vec< Lit > & );
// Static helpers:
//
// Returns a random float 0 <= x < 1. Seed must never be 0.
static inline double drand(double& seed)
{
seed *= 1389796;
int q = (int)(seed / 2147483647);
seed -= (double)q * 2147483647;
return seed / 2147483647;
}
// Returns a random integer 0 <= x < size. Seed must never be 0.
static inline int irand(double& seed, int size)
{
return (int)(drand(seed) * size);
}
//=================================================================================================
// Added Code
public:
void printLit (Lit l) const;
template<class C>
void printClause (const C& c);
void printClause ( CRef );
void printClause ( Clause& );
//void printClause ( vec< Lit > & );
void populateClauses (vec<PTRef> & clauses, const vec<CRef> & crefs, unsigned int limit = std::numeric_limits<unsigned int>::max());
void populateClauses (vec<PTRef> & clauses, const vec<Lit> & lits);
char * printCnfClauses ();
char * printCnfLearnts ();
void printProofSMT2 ( ostream & ); // Print proof
protected:
#ifdef STATISTICS
void printStatistics ( ostream & ); // Prints statistics
#endif
void printTrail ( ); // Prints the trail (debugging)
TPropRes checkTheory (bool, int&); // Checks consistency in theory. The second arg is conflictC
TPropRes checkTheory (bool complete) { int tmp; return checkTheory(complete, tmp); }
TPropRes handleSat (); // Theory check resulted in sat
TPropRes handleUnsat (); // Theory check resulted in unsat
void deduceTheory (vec<LitLev>&); // Perform theory-deductions
void cancelUntilVar ( Var ); // Backtrack until a certain variable
void cancelUntilVarTempInit ( Var ); // Backtrack until a certain variable
void cancelUntilVarTempDone ( ); // Backtrack until a certain variable
int restartNextLimit ( int ); // Next conflict limit for restart
void dumpCNF ( ); // Dumps CNF to cnf.smt2
vec<CRef> cleanup; // For cleaning up
// bool first_model_found; // True if we found a first boolean model
double skip_step; // Steps to skip in calling tsolvers
long skipped_calls; // Calls skipped so far
long learnt_t_lemmata; // T-Lemmata stored during search
long perm_learnt_t_lemmata; // T-Lemmata stored during search
unsigned luby_i; // Keep track of luby index
unsigned luby_k; // Keep track of luby k
vector< unsigned > luby_previous; // Previously computed luby numbers
bool cuvti; // For cancelUntilVarTemp
vec<Lit> lit_to_restore; // For cancelUntilVarTemp
vec<lbool> val_to_restore; // For cancelUntilVarTemp
//
// Proof production
//
bool logsProofForInterpolation() const { return static_cast<bool>(proof); }
void finalizeProof(CRef finalConflict);
std::unique_ptr<Proof> proof; // (Pointer to) Proof store
vec< CRef > pleaves; // Store clauses that are still involved in the proof
// End of proof production
//
// Data structures for DTC
//
set< PTRef > interface_equalities; // To check that we do not duplicate eij
set< PTRef > atoms_seen; // Some interface equalities may already exists in the formula
//
// Data structures required for incrementality, backtrackability
//
class undo_stack_el
{
public:
enum oper_t
{
NEWVAR
, NEWUNIT
, NEWCLAUSE
, NEWLEARNT
, NEWAXIOM
};
private:
oper_t op;
union
{
CRef c;
Var v;
};
public:
undo_stack_el(oper_t t, CRef c_) : op(t), c(c_) {}
undo_stack_el(oper_t t, Var v_) : op(t), v(v_) {}
Var getVar() const
{
assert(op == NEWVAR);
return v;
}
CRef getClause() const
{
assert(op == NEWCLAUSE || op == NEWLEARNT || op == NEWAXIOM);
return c;
}
oper_t getType() const
{
return op;
}
};
//
// Automatic push and pop, for enable undo
//
vec<size_t> undo_stack_size; // Keep track of stack_oper size
vec<undo_stack_el> undo_stack; // Keep track of operations
vec<int> undo_trail_size; // Keep track of trail size
//
// TODO: move more data in STATISTICS
//
#ifdef STATISTICS
double preproc_time;
double tsolvers_time;
unsigned elim_tvars;
unsigned total_tvars;
unsigned ie_generated;
#endif
// very debug XXX
#ifdef PEDANTIC_DEBUG
int max_dl_debug;
int analyze_cnt;
#endif
#ifdef DEBUG_REASONS
void addTheoryReasonClause_debug(Lit ded, vec<Lit>& reason);
void checkTheoryReasonClause_debug(Var v);
void removeTheoryReasonClause_debug(Var v);
#endif
// Added Code
//=================================================================================================
public:
void printTrace() const;
void setPartition(std::size_t partitionIndex);
protected:
virtual inline void clausesPublish() {};
virtual inline void clausesUpdate() {};
};
//=================================================================================================
// Implementation of inline methods:
//=================================================================================================
inline CRef CoreSMTSolver::reason(Var x) const
{
return vardata[x].reason;
}
inline int CoreSMTSolver::level (Var x) const
{
return vardata[x].level;
}
inline void CoreSMTSolver::printTrace() const
{
int dl = 0;
for (int i = 0; i < trail.size(); i++)
{
if (i == 0 || (trail_lim.size() > dl-1 && trail_lim[dl-1] == i))
printf("\ndl %d:\n ", dl++);
printf("%s%d ", sign(trail[i]) ? "-" : "", var(trail[i]));
}
printf("\n");
}
inline void CoreSMTSolver::insertVarOrder(Var x)
{
if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x);
}
inline void CoreSMTSolver::varDecayActivity()
{
var_inc *= var_decay;
}
inline void CoreSMTSolver::varBumpActivity(Var v)
{
varBumpActivity(v, var_inc);
}
inline void CoreSMTSolver::varBumpActivity(Var v, double inc)
{
if ( (activity[v] += inc) > 1e100 )
{
// Rescale:
for (int i = 0; i < nVars(); i++)
activity[i] *= 1e-100;
var_inc *= 1e-100;
}
// Update order_heap with respect to new activity:
if (order_heap.inHeap(v))
order_heap.decrease(v);
}
//=================================================================================================
// Added Code
inline void CoreSMTSolver::claDecayActivity() { cla_inc *= clause_decay; }
inline void CoreSMTSolver::claBumpActivity (Clause& c)
{
if ( (c.activity() += cla_inc) > 1e20 )
{
// Rescale:
for (int i = 0; i < learnts.size(); i++)
ca[learnts[i]].activity() *= 1e-20;
cla_inc *= 1e-20;
}
}
inline void CoreSMTSolver::checkGarbage(void) { return checkGarbage(garbage_frac); }
inline void CoreSMTSolver::checkGarbage(double gf)
{
// FIXME Relocation not compatible at the moment with proof tracking
if (this->logsProofForInterpolation()) { return; }
if (ca.wasted() > ca.size() * gf) {
garbageCollect();
}
}
inline bool CoreSMTSolver::enqueue (Lit p, CRef from)
{
return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true);
}
inline bool CoreSMTSolver::addOriginalClause(const vec<Lit> & ps)
{
return addOriginalClause_(ps);
}
inline bool CoreSMTSolver::addEmptyClause ()
{
add_tmp.clear();
return addOriginalClause_(add_tmp);
}
inline bool CoreSMTSolver::addOriginalClause(Lit p)
{
add_tmp.clear();
add_tmp.push(p);
return addOriginalClause_(add_tmp);
}
inline bool CoreSMTSolver::addOriginalClause(Lit p, Lit q)
{
add_tmp.clear();
add_tmp.push(p);
add_tmp.push(q);
return addOriginalClause_(add_tmp);
}
inline bool CoreSMTSolver::addOriginalClause(Lit p, Lit q, Lit r)
{
add_tmp.clear();
add_tmp.push(p);
add_tmp.push(q);
add_tmp.push(r);
return addOriginalClause_(add_tmp);
}
inline bool CoreSMTSolver::locked (const Clause& c) const
{
return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && reason(var(c[0])) != CRef_Fake && ca.lea(reason(var(c[0]))) == &c;
}
#ifndef PEDANTIC_DEBUG
inline void CoreSMTSolver::newDecisionLevel()
{
trail_lim.push(trail.size());
}
#else
inline void CoreSMTSolver::newDecisionLevel()
{
trail_lim.push(trail.size());
max_dl_debug = decisionLevel() > max_dl_debug ? decisionLevel() : max_dl_debug;
}
#endif
inline int CoreSMTSolver::decisionLevel () const { return trail_lim.size(); }
inline uint32_t CoreSMTSolver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
inline lbool CoreSMTSolver::value (Var x) const { return assigns[x]; }
inline lbool CoreSMTSolver::value (Lit p) const { return assigns[var(p)] ^ sign(p); }
inline lbool CoreSMTSolver::safeValue (Var x) const { if (x < assigns.size()) return value(x); else return l_Undef; }
inline lbool CoreSMTSolver::safeValue (Lit p) const { auto varValue = safeValue(var(p)); return varValue != l_Undef ? (varValue ^ sign(p)) : l_Undef; }
inline lbool CoreSMTSolver::modelValue (Lit p) const { return model[var(p)] != l_Undef ? (model[var(p)] ^ sign(p)) : l_Undef; }
inline int CoreSMTSolver::nAssigns () const { return trail.size(); }
inline int CoreSMTSolver::nClauses () const { return clauses.size(); }
inline int CoreSMTSolver::nLearnts () const { return learnts.size(); }
inline int CoreSMTSolver::nVars () const { return vardata.size(); }
inline int CoreSMTSolver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
inline void CoreSMTSolver::setPolarity (Var v, bool b) { polarity[v] = b; }
inline void CoreSMTSolver::setDecisionVar(Var v, bool b)
{
if ( b && !decision[v]) dec_vars++;
else if (!b && decision[v]) dec_vars--;
decision[v] = b;
insertVarOrder(v);
}
inline void CoreSMTSolver::setConfBudget(int64_t x) { conflict_budget = conflicts + x; }
inline void CoreSMTSolver::setPropBudget(int64_t x) { propagation_budget = propagations + x; }
inline void CoreSMTSolver::interrupt() { asynch_interrupt = true; }
inline void CoreSMTSolver::clearInterrupt() { asynch_interrupt = false; }
inline void CoreSMTSolver::budgetOff() { conflict_budget = propagation_budget = -1; }
inline bool CoreSMTSolver::withinBudget() const
{
return !asynch_interrupt &&
(conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) &&
(propagation_budget < 0 || propagations < (uint64_t)propagation_budget);
}
// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
inline bool CoreSMTSolver::solve (const vec<Lit>& assumps)
{
budgetOff();
setAssumptions(assumps);
return solve_() == l_True;
}
inline void CoreSMTSolver::toDimacs(const char* file)
{
vec<Lit> as;
toDimacs(file, as);
}
inline void CoreSMTSolver::toDimacs(const char* file, Lit p)
{
vec<Lit> as;
as.push(p);
toDimacs(file, as);
}
inline void CoreSMTSolver::toDimacs(const char* file, Lit p, Lit q)
{
vec<Lit> as;
as.push(p);
as.push(q);
toDimacs(file, as);
}
inline void CoreSMTSolver::toDimacs(const char* file, Lit p, Lit q, Lit r)
{
vec<Lit> as;
as.push(p);
as.push(q);
as.push(r);
toDimacs(file, as);
}
//=================================================================================================
// Debug + etc:
static inline void logLit(FILE* f, Lit l)
{
fprintf(f, "%sx%d", sign(l) ? "~" : "", var(l)+1);
}
static inline void logLits(FILE* f, const vec<Lit>& ls)
{
fprintf(f, "[ ");
if (ls.size() > 0)
{
logLit(f, ls[0]);
for (int i = 1; i < ls.size(); i++)
{
fprintf(f, ", ");
logLit(f, ls[i]);
}
}
fprintf(f, "] ");
}
static inline const char* showBool(bool b) { return b ? "true" : "false"; }
// Just like 'assert()' but expression will be evaluated in the release version as well.
static inline void check(bool expr) { (void)expr; assert(expr); }
inline void CoreSMTSolver::printLit(Lit l) const
{
std::flush(std::cout);
std::cerr << l;
std::flush(std::cerr);