32# include <gtest/gtest.h>
49 auto lit_val = [&](
long v) ->
bool {
50 return v > 0 ?
assignment(
static_cast<size_t>(v - 1))
54 for (
size_t i = 0; i <
clauses.size(); ++i)
80 sat.add_clause(
sat.pos_lit(0),
sat.pos_lit(1));
93 sat.set_true(
sat.pos_lit(0));
104 sat.set_false(
sat.pos_lit(0));
115 sat.set_true(
sat.pos_lit(0));
116 sat.set_true(
sat.neg_lit(0));
126 sat.set_true(
sat.pos_lit(0));
127 sat.add_implication(
sat.pos_lit(0),
sat.pos_lit(1));
139 sat.set_true(
sat.pos_lit(0));
140 sat.add_implication(
sat.pos_lit(0),
sat.pos_lit(1));
141 sat.add_implication(
sat.pos_lit(1),
sat.pos_lit(2));
142 sat.add_implication(
sat.pos_lit(2),
sat.pos_lit(3));
146 for (
size_t i = 0; i < 4; ++i)
154 sat.set_true(
sat.pos_lit(0));
155 sat.add_implication(
sat.pos_lit(0),
sat.pos_lit(1));
156 sat.add_implication(
sat.pos_lit(1),
sat.pos_lit(2));
157 sat.set_false(
sat.pos_lit(2));
166 sat.set_true(
sat.pos_lit(0));
167 sat.add_equiv(
sat.pos_lit(0),
sat.pos_lit(1));
179 sat.add_xor(
sat.pos_lit(0),
sat.pos_lit(1));
190 sat.add_xor(
sat.pos_lit(0),
sat.pos_lit(1));
191 sat.set_true(
sat.pos_lit(0));
192 sat.set_true(
sat.pos_lit(1));
205 sat.add_clause_signed(1, 2);
206 sat.add_clause_signed(-1, 3);
207 sat.add_clause_signed(-2, -3);
220 sat.add_clause_signed(1, 1);
221 sat.add_clause_signed(-1, -1);
241 for (
size_t i = 0; i < 3; ++i)
254 sat.set_true(
sat.pos_lit(0));
269 sat.set_true(
sat.pos_lit(0));
270 sat.set_true(
sat.pos_lit(1));
293 EXPECT_THROW(
sat.add_at_most_one({sat.pos_lit(5)}), std::domain_error);
306 sat.add_xor(
sat.pos_lit(0),
sat.pos_lit(1));
307 sat.add_xor(
sat.pos_lit(1),
sat.pos_lit(2));
308 sat.add_xor(
sat.pos_lit(0),
sat.pos_lit(2));
317 sat.add_xor(
sat.pos_lit(0),
sat.pos_lit(1));
318 sat.add_xor(
sat.pos_lit(1),
sat.pos_lit(2));
319 sat.add_xor(
sat.pos_lit(2),
sat.pos_lit(3));
334 sat.add_clause(
sat.pos_lit(0),
sat.pos_lit(0));
355 EXPECT_THROW(
sat.add_clause_signed(std::numeric_limits<long>::min(), 1),
357 EXPECT_THROW(
sat.add_clause_signed(1, std::numeric_limits<long>::min()),
368 constexpr size_t N = 8;
372 std::mt19937
rng(2024);
373 std::uniform_int_distribution<size_t>
var_dist(0,
N - 1);
374 std::uniform_int_distribution<int>
sign_dist(0, 1);
387 sat.add_clause_signed(a, b);
395 for (
unsigned mask = 0; mask < (1U <<
N); ++mask)
398 for (
size_t i = 0; i <
N; ++i)
399 bf(i) = ((mask >> i) & 1) != 0;
409 <<
"Trial " <<
trial <<
": solver says "
410 << (
ok ?
"SAT" :
"UNSAT") <<
" but brute-force says "
415 <<
"Trial " <<
trial <<
": assignment does not satisfy formula";
429 sat.add_clause(
sat.pos_lit(0),
sat.pos_lit(1));
430 sat.add_clause(
sat.neg_lit(0),
sat.pos_lit(2));
431 sat.add_clause(
sat.neg_lit(1),
sat.neg_lit(2));
445 sat.add_clause(
sat.pos_lit(0),
sat.pos_lit(1));
446 sat.add_clause(
sat.neg_lit(0),
sat.pos_lit(2));
447 sat.add_clause(
sat.neg_lit(1),
sat.neg_lit(2));
464 constexpr size_t N = 500;
465 constexpr size_t M = 2000;
467 std::mt19937
rng(42);
468 std::uniform_int_distribution<size_t>
var_dist(0,
N - 1);
469 std::uniform_int_distribution<int>
sign_dist(0, 1);
473 for (
size_t i = 0; i <
N; ++i)
479 for (
size_t c = 0; c < M; ++c)
485 size_t l1 = target(v1) ?
sat.pos_lit(v1) :
sat.neg_lit(v1);
486 size_t l2 = target(v2) ?
sat.pos_lit(v2) :
sat.neg_lit(v2);
494 for (
size_t c = 0; c <
clauses.size(); ++c)
510 constexpr size_t N = 200;
512 sat.set_true(
sat.pos_lit(0));
514 for (
size_t i = 0; i + 1 <
N; ++i)
515 sat.add_implication(
sat.pos_lit(i),
sat.pos_lit(i + 1));
518 sat.add_implication(
sat.pos_lit(
N - 1),
sat.neg_lit(0));
2-SAT solver based on Tarjan's SCC algorithm.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
T & append(const T &data)
Append a copy of data
Generic directed graph (digraph) wrapper template.
Arc for graphs implemented with simple adjacency lists.
2-SAT solver using Tarjan's SCC algorithm.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Array-based graph implementation.
Simple graph implementation with adjacency lists.
static bool verify_assignment(const Array< bool > &assignment, const Array< std::pair< long, long > > &clauses)