ruby-minisat 1.14.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +24 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +56 -0
  4. data/Rakefile +48 -0
  5. data/VERSION +1 -0
  6. data/examples/compat18.rb +65 -0
  7. data/examples/example.rb +26 -0
  8. data/examples/example2.rb +60 -0
  9. data/examples/kakuro.rb +178 -0
  10. data/examples/kakuro.sample +13 -0
  11. data/examples/lonely7.rb +302 -0
  12. data/examples/nonogram.rb +254 -0
  13. data/examples/nonogram.sample +26 -0
  14. data/examples/numberlink.rb +489 -0
  15. data/examples/numberlink.sample +11 -0
  16. data/examples/shikaku.rb +190 -0
  17. data/examples/shikaku.sample +11 -0
  18. data/examples/slitherlink.rb +279 -0
  19. data/examples/slitherlink.sample +11 -0
  20. data/examples/sudoku.rb +216 -0
  21. data/examples/sudoku.sample +11 -0
  22. data/ext/minisat/extconf.rb +9 -0
  23. data/ext/minisat/minisat-wrap.cpp +88 -0
  24. data/ext/minisat/minisat.c +497 -0
  25. data/ext/minisat/minisat.h +53 -0
  26. data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
  27. data/minisat/MiniSat_v1.14/Global.h +274 -0
  28. data/minisat/MiniSat_v1.14/Heap.h +100 -0
  29. data/minisat/MiniSat_v1.14/LICENSE +20 -0
  30. data/minisat/MiniSat_v1.14/Main.C +244 -0
  31. data/minisat/MiniSat_v1.14/Makefile +88 -0
  32. data/minisat/MiniSat_v1.14/README +30 -0
  33. data/minisat/MiniSat_v1.14/Solver.C +781 -0
  34. data/minisat/MiniSat_v1.14/Solver.h +206 -0
  35. data/minisat/MiniSat_v1.14/Solver.o +0 -0
  36. data/minisat/MiniSat_v1.14/SolverTypes.h +130 -0
  37. data/minisat/MiniSat_v1.14/Sort.h +131 -0
  38. data/minisat/MiniSat_v1.14/TODO +73 -0
  39. data/minisat/MiniSat_v1.14/VarOrder.h +96 -0
  40. data/test/test_minisat.rb +143 -0
  41. metadata +114 -0
@@ -0,0 +1,206 @@
1
+ /****************************************************************************************[Solver.h]
2
+ MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ **************************************************************************************************/
19
+
20
+ #ifndef Solver_h
21
+ #define Solver_h
22
+
23
+ #include "SolverTypes.h"
24
+ #include "VarOrder.h"
25
+
26
+ // Redfine if you want output to go somewhere else:
27
+ #define reportf(format, args...) ( printf(format , ## args), fflush(stdout) )
28
+
29
+
30
+ //=================================================================================================
31
+ // Solver -- the main class:
32
+
33
+
34
+ struct SolverStats {
35
+ int64 starts, decisions, propagations, conflicts;
36
+ int64 clauses_literals, learnts_literals, max_literals, tot_literals;
37
+ SolverStats() : starts(0), decisions(0), propagations(0), conflicts(0)
38
+ , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) { }
39
+ };
40
+
41
+
42
+ struct SearchParams {
43
+ double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02)
44
+ SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { }
45
+ };
46
+
47
+
48
+
49
+ class Solver {
50
+ protected:
51
+ // Solver state:
52
+ //
53
+ bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
54
+ vec<Clause*> clauses; // List of problem clauses.
55
+ vec<Clause*> learnts; // List of learnt clauses.
56
+ int n_bin_clauses; // Keep track of number of binary clauses "inlined" into the watcher lists (we do this primarily to get identical behavior to the version without the binary clauses trick).
57
+ double cla_inc; // Amount to bump next clause with.
58
+ double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
59
+
60
+ vec<double> activity; // A heuristic measurement of the activity of a variable.
61
+ double var_inc; // Amount to bump next variable with.
62
+ double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
63
+ VarOrder order; // Keeps track of the decision variable order.
64
+
65
+ vec<vec<GClause> > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
66
+ vec<char> assigns; // The current assignments (lbool:s stored as char:s).
67
+ vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
68
+ vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
69
+ vec<GClause> reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
70
+ vec<int> level; // 'level[var]' is the decision level at which assignment was made.
71
+ int root_level; // Level of first proper decision.
72
+ int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
73
+ int simpDB_assigns; // Number of top-level assignments since last execution of 'simplifyDB()'.
74
+ int64 simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplifyDB()'.
75
+
76
+ // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which is used:
77
+ //
78
+ vec<char> analyze_seen;
79
+ vec<Lit> analyze_stack;
80
+ vec<Lit> analyze_toclear;
81
+ Clause* propagate_tmpbin;
82
+ Clause* analyze_tmpbin;
83
+ Clause* solve_tmpunit;
84
+ vec<Lit> addBinary_tmp;
85
+ vec<Lit> addTernary_tmp;
86
+
87
+ // Main internal methods:
88
+ //
89
+ bool assume (Lit p);
90
+ void cancelUntil (int level);
91
+ void record (const vec<Lit>& clause);
92
+
93
+ void analyze (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
94
+ bool analyze_removable(Lit p, uint min_level); // (helper method for 'analyze()')
95
+ void analyzeFinal (Clause* confl, bool skip_first = false);
96
+ bool enqueue (Lit fact, GClause from = GClause_new((Clause*)NULL));
97
+ Clause* propagate ();
98
+ void reduceDB ();
99
+ Lit pickBranchLit (const SearchParams& params);
100
+ lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params);
101
+ double progressEstimate ();
102
+
103
+ // Activity:
104
+ //
105
+ void varBumpActivity(Lit p) {
106
+ if (var_decay < 0) return; // (negative decay means static variable order -- don't bump)
107
+ if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
108
+ order.update(var(p)); }
109
+ void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; }
110
+ void varRescaleActivity();
111
+ void claDecayActivity () { cla_inc *= cla_decay; }
112
+ void claRescaleActivity();
113
+
114
+ // Operations on clauses:
115
+ //
116
+ void newClause(const vec<Lit>& ps, bool learnt = false);
117
+ void claBumpActivity (Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
118
+ void remove (Clause* c, bool just_dealloc = false);
119
+ bool locked (const Clause* c) const { GClause r = reason[var((*c)[0])]; return !r.isLit() && r.clause() == c; }
120
+ bool simplify (Clause* c) const;
121
+
122
+ int decisionLevel() const { return trail_lim.size(); }
123
+
124
+ public:
125
+ Solver() : ok (true)
126
+ , n_bin_clauses (0)
127
+ , cla_inc (1)
128
+ , cla_decay (1)
129
+ , var_inc (1)
130
+ , var_decay (1)
131
+ , order (assigns, activity)
132
+ , qhead (0)
133
+ , simpDB_assigns (0)
134
+ , simpDB_props (0)
135
+ , default_params (SearchParams(0.95, 0.999, 0.02))
136
+ , expensive_ccmin (true)
137
+ , verbosity (0)
138
+ , progress_estimate(0)
139
+ {
140
+ vec<Lit> dummy(2,lit_Undef);
141
+ propagate_tmpbin = Clause_new(false, dummy);
142
+ analyze_tmpbin = Clause_new(false, dummy);
143
+ dummy.pop();
144
+ solve_tmpunit = Clause_new(false, dummy);
145
+ addBinary_tmp .growTo(2);
146
+ addTernary_tmp.growTo(3);
147
+ }
148
+
149
+ ~Solver() {
150
+ for (int i = 0; i < learnts.size(); i++) remove(learnts[i], true);
151
+ for (int i = 0; i < clauses.size(); i++) if (clauses[i] != NULL) remove(clauses[i], true); }
152
+
153
+ // Helpers: (semi-internal)
154
+ //
155
+ lbool value(Var x) const { return toLbool(assigns[x]); }
156
+ lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
157
+
158
+ int nAssigns() { return trail.size(); }
159
+ int nClauses() { return clauses.size() + n_bin_clauses; } // (minor difference from MiniSat without the GClause trick: learnt binary clauses will be counted as original clauses)
160
+ int nLearnts() { return learnts.size(); }
161
+
162
+ // Statistics: (read-only member variable)
163
+ //
164
+ SolverStats stats;
165
+
166
+ // Mode of operation:
167
+ //
168
+ SearchParams default_params; // Restart frequency etc.
169
+ bool expensive_ccmin; // Controls conflict clause minimization. TRUE by default.
170
+ int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
171
+
172
+ // Problem specification:
173
+ //
174
+ Var newVar ();
175
+ int nVars () { return assigns.size(); }
176
+ void addUnit (Lit p) { if (ok) ok = enqueue(p); }
177
+ void addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; addClause(addBinary_tmp); }
178
+ void addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; addClause(addTernary_tmp); }
179
+ void addClause (const vec<Lit>& ps) { newClause(ps); } // (used to be a difference between internal and external method...)
180
+
181
+ // Solving:
182
+ //
183
+ bool okay() { return ok; } // FALSE means solver is in an conflicting state (must never be used again!)
184
+ void simplifyDB();
185
+ bool solve(const vec<Lit>& assumps);
186
+ bool solve() { vec<Lit> tmp; return solve(tmp); }
187
+
188
+ double progress_estimate; // Set by 'search()'.
189
+ vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
190
+ vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions), this vector represent the conflict clause expressed in the assumptions.
191
+ };
192
+
193
+
194
+ //=================================================================================================
195
+ // Debug:
196
+
197
+
198
+ #define L_LIT "%sx%d"
199
+ #define L_lit(p) sign(p)?"~":"", var(p)
200
+
201
+ // Just like 'assert()' but expression will be evaluated in the release version as well.
202
+ inline void check(bool expr) { assert(expr); }
203
+
204
+
205
+ //=================================================================================================
206
+ #endif
Binary file
@@ -0,0 +1,130 @@
1
+ /***********************************************************************************[SolverTypes.h]
2
+ MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ **************************************************************************************************/
19
+
20
+
21
+ #ifndef SolverTypes_h
22
+ #define SolverTypes_h
23
+
24
+ #ifndef Global_h
25
+ #include "Global.h"
26
+ #endif
27
+
28
+
29
+ //=================================================================================================
30
+ // Variables, literals, clause IDs:
31
+
32
+
33
+ // NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
34
+ // so that they can be used as array indices.
35
+
36
+ typedef int Var;
37
+ #define var_Undef (-1)
38
+
39
+
40
+ class Lit {
41
+ int x;
42
+ public:
43
+ Lit() : x(2*var_Undef) {} // (lit_Undef)
44
+ explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {}
45
+ friend Lit operator ~ (Lit p);
46
+
47
+ friend bool sign (Lit p);
48
+ friend int var (Lit p);
49
+ friend int index (Lit p);
50
+ friend Lit toLit (int i);
51
+ friend Lit unsign(Lit p);
52
+ friend Lit id (Lit p, bool sgn);
53
+
54
+ friend bool operator == (Lit p, Lit q);
55
+ friend bool operator < (Lit p, Lit q);
56
+
57
+ uint hash() const { return (uint)x; }
58
+ };
59
+ inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; }
60
+ inline bool sign (Lit p) { return p.x & 1; }
61
+ inline int var (Lit p) { return p.x >> 1; }
62
+ inline int index (Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing.
63
+ inline Lit toLit (int i) { Lit p; p.x = i; return p; } // Inverse of 'index()'.
64
+ inline Lit unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; }
65
+ inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
66
+ inline bool operator == (Lit p, Lit q) { return index(p) == index(q); }
67
+ inline bool operator < (Lit p, Lit q) { return index(p) < index(q); } // '<' guarantees that p, ~p are adjacent in the ordering.
68
+
69
+ const Lit lit_Undef(var_Undef, false); // }- Useful special constants.
70
+ const Lit lit_Error(var_Undef, true ); // }
71
+
72
+ inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; }
73
+
74
+
75
+ //=================================================================================================
76
+ // Clause -- a simple class for representing a clause:
77
+
78
+
79
+ class Clause {
80
+ uint size_learnt;
81
+ Lit data[1];
82
+ public:
83
+ // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
84
+ Clause(bool learnt, const vec<Lit>& ps) {
85
+ size_learnt = (ps.size() << 1) | (int)learnt;
86
+ for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
87
+ if (learnt) activity() = 0; }
88
+
89
+ // -- use this function instead:
90
+ friend Clause* Clause_new(bool learnt, const vec<Lit>& ps);
91
+
92
+ int size () const { return size_learnt >> 1; }
93
+ bool learnt () const { return size_learnt & 1; }
94
+ Lit operator [] (int i) const { return data[i]; }
95
+ Lit& operator [] (int i) { return data[i]; }
96
+ float& activity () const { return *((float*)&data[size()]); }
97
+ };
98
+ inline Clause* Clause_new(bool learnt, const vec<Lit>& ps) {
99
+ assert(sizeof(Lit) == sizeof(uint));
100
+ assert(sizeof(float) == sizeof(uint));
101
+ void* mem = xmalloc<char>(sizeof(Clause) - sizeof(Lit) + sizeof(uint)*(ps.size() + (int)learnt));
102
+ return new (mem) Clause(learnt, ps); }
103
+
104
+
105
+ //=================================================================================================
106
+ // GClause -- Generalize clause:
107
+
108
+
109
+ // Either a pointer to a clause or a literal.
110
+ class GClause {
111
+ void* data;
112
+ GClause(void* d) : data(d) {}
113
+ public:
114
+ friend GClause GClause_new(Lit p);
115
+ friend GClause GClause_new(Clause* c);
116
+
117
+ bool isLit () const { return ((uintp)data & 1) == 1; }
118
+ Lit lit () const { return toLit(((intp)data) >> 1); }
119
+ Clause* clause () const { return (Clause*)data; }
120
+ bool operator == (GClause c) const { return data == c.data; }
121
+ bool operator != (GClause c) const { return data != c.data; }
122
+ };
123
+ inline GClause GClause_new(Lit p) { return GClause((void*)(((intp)index(p) << 1) + 1)); }
124
+ inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); }
125
+
126
+ #define GClause_NULL GClause_new((Clause*)NULL)
127
+
128
+
129
+ //=================================================================================================
130
+ #endif
@@ -0,0 +1,131 @@
1
+ /******************************************************************************************[Sort.h]
2
+ MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ **************************************************************************************************/
19
+
20
+ #ifndef Sort_h
21
+ #define Sort_h
22
+
23
+
24
+ //=================================================================================================
25
+
26
+
27
+ template<class T>
28
+ struct LessThan_default {
29
+ bool operator () (T x, T y) { return x < y; }
30
+ };
31
+
32
+
33
+ //=================================================================================================
34
+
35
+
36
+ template <class T, class LessThan>
37
+ void selectionSort(T* array, int size, LessThan lt)
38
+ {
39
+ int i, j, best_i;
40
+ T tmp;
41
+
42
+ for (i = 0; i < size-1; i++){
43
+ best_i = i;
44
+ for (j = i+1; j < size; j++){
45
+ if (lt(array[j], array[best_i]))
46
+ best_i = j;
47
+ }
48
+ tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
49
+ }
50
+ }
51
+ template <class T> static inline void selectionSort(T* array, int size) {
52
+ selectionSort(array, size, LessThan_default<T>()); }
53
+
54
+
55
+ template <class T, class LessThan>
56
+ void sort(T* array, int size, LessThan lt, double& seed)
57
+ {
58
+ if (size <= 15)
59
+ selectionSort(array, size, lt);
60
+
61
+ else{
62
+ T pivot = array[irand(seed, size)];
63
+ T tmp;
64
+ int i = -1;
65
+ int j = size;
66
+
67
+ for(;;){
68
+ do i++; while(lt(array[i], pivot));
69
+ do j--; while(lt(pivot, array[j]));
70
+
71
+ if (i >= j) break;
72
+
73
+ tmp = array[i]; array[i] = array[j]; array[j] = tmp;
74
+ }
75
+
76
+ sort(array , i , lt, seed);
77
+ sort(&array[i], size-i, lt, seed);
78
+ }
79
+ }
80
+ template <class T, class LessThan> void sort(T* array, int size, LessThan lt) {
81
+ double seed = 91648253; sort(array, size, lt, seed); }
82
+ template <class T> static inline void sort(T* array, int size) {
83
+ sort(array, size, LessThan_default<T>()); }
84
+
85
+
86
+ template <class T, class LessThan>
87
+ void sortUnique(T* array, int& size, LessThan lt)
88
+ {
89
+ int i, j;
90
+ T last;
91
+
92
+ if (size == 0) return;
93
+
94
+ sort(array, size, lt);
95
+
96
+ i = 1;
97
+ last = array[0];
98
+ for (j = 1; j < size; j++){
99
+ if (lt(last, array[j])){
100
+ last = array[i] = array[j];
101
+ i++; }
102
+ }
103
+
104
+ size = i;
105
+ }
106
+ template <class T> static inline void sortUnique(T* array, int& size) {
107
+ sortUnique(array, size, LessThan_default<T>()); }
108
+
109
+
110
+ //=================================================================================================
111
+ // For 'vec's:
112
+
113
+
114
+ template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
115
+ sort((T*)v, v.size(), lt); }
116
+ template <class T> void sort(vec<T>& v) {
117
+ sort(v, LessThan_default<T>()); }
118
+
119
+
120
+ template <class T, class LessThan> void sortUnique(vec<T>& v, LessThan lt) {
121
+ int size = v.size();
122
+ T* data = v.release();
123
+ sortUnique(data, size, lt);
124
+ v.~vec<T>();
125
+ new (&v) vec<T>(data, size); }
126
+ template <class T> void sortUnique(vec<T>& v) {
127
+ sortUnique(v, LessThan_default<T>()); }
128
+
129
+
130
+ //=================================================================================================
131
+ #endif