python-sat 1.9.dev18__tar.gz → 1.9.dev20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_sat-1.9.dev18/python_sat.egg-info → python_sat-1.9.dev20}/PKG-INFO +1 -1
- python_sat-1.9.dev20/cardenc/iseq.hh +151 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/mto.hh +22 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/pycard.cc +216 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/__init__.py +1 -1
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/card.py +243 -3
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/solvers.py +1 -3
- {python_sat-1.9.dev18 → python_sat-1.9.dev20/python_sat.egg-info}/PKG-INFO +1 -1
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/python_sat.egg-info/SOURCES.txt +2 -0
- python_sat-1.9.dev20/tests/test_iseqcounter.py +103 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/LICENSE.txt +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/MANIFEST.in +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/README.rst +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/allies/__init__.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/allies/approxmc.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/allies/unigen.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/bitwise.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/card.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/clset.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/common.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/itot.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/ladder.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/pairwise.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/ptypes.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/seqcounter.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/sortcard.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/cardenc/utils.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/__init__.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/bbscan.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/bica.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/fm.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/genhard.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/hitman.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/lbx.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/lsu.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/mcsls.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/models.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/musx.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/optux.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/primer.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/rc2.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/examples/usage.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_parse.cc +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_plus.cc +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_plus.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_py.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_scan.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_weight.cc +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pf_weight.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pyformula.cc +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/formula/pyformula.hh +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/_fileio.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/_utils.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/engines.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/formula.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/integer.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/pb.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/pysat/process.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/python_sat.egg-info/dependency_links.txt +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/python_sat.egg-info/requires.txt +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/python_sat.egg-info/top_level.txt +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/requirements.txt +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/setup.cfg +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/setup.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/cadical103.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/cadical153.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/cadical195.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/cadical300.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/ergo.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/glucose30.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/glucose41.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/glucose421.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/lingeling.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/maplechrono.zip +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/maplecm.zip +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/maplesat.zip +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/mergesat3.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/minicard.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/minisat22.tar.gz +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/minisatgh.zip +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/cadical103.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/cadical153.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/cadical195.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/cadical300.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/ergo.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/glucose30.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/glucose41.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/glucose421.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/gluecard30.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/gluecard41.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/kissat404.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/lingeling.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/maplechrono.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/maplecm.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/maplesat.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/mergesat3.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/minicard.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/minisat22.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/minisatep.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/patches/minisatgh.patch +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/prepare.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/solvers/pysolvers.cc +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_accum_stats.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_atmost.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_atmost1.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_atmostk.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_boolengine.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_clausification.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_cnf.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_empty_clause.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_empty_extclause.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_encode_pb_conditional.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_equals1.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_formula_parsing.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_formula_unique.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_hitman.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_idpool.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_integer.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_lsu.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_oom.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_pb.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_process.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_proof.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_propagate.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_unique_model.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_unique_mus.py +0 -0
- {python_sat-1.9.dev18 → python_sat-1.9.dev20}/tests/test_warmstart.py +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* iseq.hh
|
|
3
|
+
*
|
|
4
|
+
* Created on: Dec 15, 2025
|
|
5
|
+
* Author: Jesse Looney
|
|
6
|
+
* E-mail: jesselooney+dev@pm.me
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef ISEQ_HH_
|
|
10
|
+
#define ISEQ_HH_
|
|
11
|
+
|
|
12
|
+
#include <algorithm>
|
|
13
|
+
#include <cmath>
|
|
14
|
+
#include <vector>
|
|
15
|
+
#include <deque>
|
|
16
|
+
#include "clset.hh"
|
|
17
|
+
#include "ptypes.hh"
|
|
18
|
+
#include "utils.hh"
|
|
19
|
+
|
|
20
|
+
using namespace std;
|
|
21
|
+
|
|
22
|
+
struct SeqState {
|
|
23
|
+
vector<int> lhs;
|
|
24
|
+
// We maintain the invariant that `rhs.size() < lhs.size()`.
|
|
25
|
+
vector<int> rhs;
|
|
26
|
+
// A map from pairs of integers to SAT literals (encoded as integers).
|
|
27
|
+
// We maintain the invariant that, for `1 <= i <= rhs.size()` and
|
|
28
|
+
// `i <= j <= lhs.size()`, `s_vars` contains the key `(i, j)`, and the
|
|
29
|
+
// corresponding element is a literal whose negation requires that the sum
|
|
30
|
+
// of the first `j` literals of `lhs` is at most `i - 1`.
|
|
31
|
+
Pair2IntMap s_vars;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Create an at-most-0 constraint in an instantiated sequential counters state.
|
|
35
|
+
// This must always be the first constraint added.
|
|
36
|
+
//=============================================================================
|
|
37
|
+
void _iseq_add_atmost0(SeqState *state, ClauseSet& dest, int& top)
|
|
38
|
+
{
|
|
39
|
+
assert(state->rhs.size() == 0);
|
|
40
|
+
assert(state->lhs.size() > 0);
|
|
41
|
+
|
|
42
|
+
int n = state->lhs.size();
|
|
43
|
+
|
|
44
|
+
// s_1^1 <-- x_0. We could just reuse the literal for x_0, but it is better
|
|
45
|
+
// to have our own copy: iseq_get() hands out s-variables as standalone
|
|
46
|
+
// constraint literals, and callers should be able to treat s_1^1 as
|
|
47
|
+
// distinct from the input literal x_0.
|
|
48
|
+
int s11 = mk_yvar(top, state->s_vars, make_pair(1, 1));
|
|
49
|
+
int x0 = state->lhs[0];
|
|
50
|
+
dest.create_binary_clause(-x0, s11);
|
|
51
|
+
|
|
52
|
+
for (int j = 1; j < n; j++) {
|
|
53
|
+
int s1j1 = mk_yvar(top, state->s_vars, make_pair(1, j + 1));
|
|
54
|
+
int s1j = mk_yvar(top, state->s_vars, make_pair(1, j));
|
|
55
|
+
int xj = state->lhs[j];
|
|
56
|
+
// s_1^(j+1) <-- s_1^j v x_j
|
|
57
|
+
dest.create_binary_clause(-s1j, s1j1);
|
|
58
|
+
dest.create_binary_clause(-xj, s1j1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
int s1n = mk_yvar(top, state->s_vars, make_pair(1, n));
|
|
62
|
+
state->rhs.push_back(s1n);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create an at-most-k constraint in an instantiated sequential counters state.
|
|
66
|
+
// This must always be the (k+1)-th constraint added.
|
|
67
|
+
//=============================================================================
|
|
68
|
+
void _iseq_add_atmostk(SeqState *state, ClauseSet& dest, int& top, unsigned k)
|
|
69
|
+
{
|
|
70
|
+
assert(state->rhs.size() == k);
|
|
71
|
+
assert(state->lhs.size() > k);
|
|
72
|
+
|
|
73
|
+
int n = state->lhs.size();
|
|
74
|
+
|
|
75
|
+
int sk1k1 = mk_yvar(top, state->s_vars, make_pair(k + 1, k + 1));
|
|
76
|
+
int skk = mk_yvar(top, state->s_vars, make_pair(k, k));
|
|
77
|
+
int xk = state->lhs[k];
|
|
78
|
+
// s_(k+1)^(k+1) <-- s_k^k ^ x_k
|
|
79
|
+
dest.create_ternary_clause(-skk, -xk, sk1k1);
|
|
80
|
+
|
|
81
|
+
for (int j = k + 1; j < n; j++) {
|
|
82
|
+
int sk1j1 = mk_yvar(top, state->s_vars, make_pair(k + 1, j + 1));
|
|
83
|
+
int sk1j = mk_yvar(top, state->s_vars, make_pair(k + 1, j));
|
|
84
|
+
int skj = mk_yvar(top, state->s_vars, make_pair(k, j));
|
|
85
|
+
int xj = state->lhs[j];
|
|
86
|
+
// s_(k+1)^(j+1) <-- s_(k+1)^j v (s_k^j ^ x_j)
|
|
87
|
+
dest.create_binary_clause(-sk1j, sk1j1);
|
|
88
|
+
dest.create_ternary_clause(-skj, -xj, sk1j1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int sk1n = mk_yvar(top, state->s_vars, make_pair(k + 1, n));
|
|
92
|
+
state->rhs.push_back(sk1n);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//
|
|
96
|
+
//=============================================================================
|
|
97
|
+
SeqState *iseq_new(ClauseSet& dest, vector<int>& lhs, unsigned rhs, int& top)
|
|
98
|
+
{
|
|
99
|
+
SeqState *state = new SeqState();
|
|
100
|
+
state->lhs = lhs;
|
|
101
|
+
|
|
102
|
+
unsigned kmin = std::min(rhs + 1, (unsigned)state->lhs.size());
|
|
103
|
+
state->rhs.reserve(kmin);
|
|
104
|
+
|
|
105
|
+
for (unsigned i = 0; i < kmin; i++) {
|
|
106
|
+
if (i == 0) {
|
|
107
|
+
_iseq_add_atmost0(state, dest, top);
|
|
108
|
+
} else {
|
|
109
|
+
_iseq_add_atmostk(state, dest, top, i);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return state;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//
|
|
117
|
+
//=============================================================================
|
|
118
|
+
void iseq_increase(SeqState *state, ClauseSet& dest, unsigned rhs, int& top)
|
|
119
|
+
{
|
|
120
|
+
unsigned kmin = std::min(rhs + 1, (unsigned)state->lhs.size());
|
|
121
|
+
state->rhs.reserve(kmin);
|
|
122
|
+
|
|
123
|
+
for (unsigned i = (unsigned)state->rhs.size(); i < kmin; i++) {
|
|
124
|
+
if (i == 0) {
|
|
125
|
+
_iseq_add_atmost0(state, dest, top);
|
|
126
|
+
} else {
|
|
127
|
+
_iseq_add_atmostk(state, dest, top, i);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//
|
|
133
|
+
//=============================================================================
|
|
134
|
+
int iseq_get(SeqState *state, int prefix_len, unsigned bound) {
|
|
135
|
+
assert(bound < state->rhs.size());
|
|
136
|
+
|
|
137
|
+
assert((int)bound < prefix_len);
|
|
138
|
+
assert(prefix_len <= (int)state->lhs.size());
|
|
139
|
+
|
|
140
|
+
// The above assertions ensure that this key exists in the map.
|
|
141
|
+
return state->s_vars.at(make_pair(bound + 1, prefix_len));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//
|
|
145
|
+
//=============================================================================
|
|
146
|
+
static void iseq_destroy(SeqState *state)
|
|
147
|
+
{
|
|
148
|
+
delete state;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
#endif // ISEQ_HH_
|
|
@@ -116,6 +116,16 @@ inline void to_TO(
|
|
|
116
116
|
|
|
117
117
|
to_UA(top_id, clset, *olst, *outfsthalf, *outsndhalf);
|
|
118
118
|
|
|
119
|
+
// leaf vectors are not queued
|
|
120
|
+
if (half < 2) {
|
|
121
|
+
delete fsthalf;
|
|
122
|
+
delete outfsthalf;
|
|
123
|
+
}
|
|
124
|
+
if (n - half < 2) {
|
|
125
|
+
delete sndhalf;
|
|
126
|
+
delete outsndhalf;
|
|
127
|
+
}
|
|
128
|
+
|
|
119
129
|
delete ilst;
|
|
120
130
|
delete olst;
|
|
121
131
|
}
|
|
@@ -387,6 +397,18 @@ inline void mto_MTO_A(
|
|
|
387
397
|
mto_MUA_A(top_id, clset, *ulst, *llst, *ufsthalf, *lfsthalf,
|
|
388
398
|
*usndhalf, *lsndhalf, p);
|
|
389
399
|
|
|
400
|
+
// leaf vectors are not queued
|
|
401
|
+
if (half < p) {
|
|
402
|
+
delete fsthalf;
|
|
403
|
+
delete ufsthalf;
|
|
404
|
+
delete lfsthalf;
|
|
405
|
+
}
|
|
406
|
+
if (ni - half < p) {
|
|
407
|
+
delete sndhalf;
|
|
408
|
+
delete usndhalf;
|
|
409
|
+
delete lsndhalf;
|
|
410
|
+
}
|
|
411
|
+
|
|
390
412
|
delete ilst;
|
|
391
413
|
delete ulst;
|
|
392
414
|
delete llst;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
#include "card.hh"
|
|
18
18
|
#include "itot.hh"
|
|
19
|
+
#include "iseq.hh"
|
|
19
20
|
|
|
20
21
|
using namespace std;
|
|
21
22
|
|
|
@@ -39,6 +40,13 @@ static char itot_ext_docstring[] = "Extends the set of inputs in an iterative"
|
|
|
39
40
|
static char itot_mrg_docstring[] = "Merge two totalizer objects into one.";
|
|
40
41
|
static char itot_del_docstring[] = "Delete an iterative totalizer object";
|
|
41
42
|
|
|
43
|
+
static char iseq_new_docstring[] = "Create an iterative sequential counter"
|
|
44
|
+
"object for an AtMost(k) constraint.";
|
|
45
|
+
static char iseq_inc_docstring[] = "Increase bound in an iterative sequential"
|
|
46
|
+
"counter object";
|
|
47
|
+
static char iseq_del_docstring[] = "Delete an iterative sequential counter";
|
|
48
|
+
static char iseq_get_docstring[] = "Get a constraint for an iterative sequential counter";
|
|
49
|
+
|
|
42
50
|
static PyObject *CardError;
|
|
43
51
|
static jmp_buf env;
|
|
44
52
|
|
|
@@ -124,6 +132,10 @@ extern "C" {
|
|
|
124
132
|
static PyObject *py_itot_ext (PyObject *, PyObject *);
|
|
125
133
|
static PyObject *py_itot_mrg (PyObject *, PyObject *);
|
|
126
134
|
static PyObject *py_itot_del (PyObject *, PyObject *);
|
|
135
|
+
static PyObject *py_iseq_new (PyObject *, PyObject *);
|
|
136
|
+
static PyObject *py_iseq_inc (PyObject *, PyObject *);
|
|
137
|
+
static PyObject *py_iseq_del (PyObject *, PyObject *);
|
|
138
|
+
static PyObject *py_iseq_get (PyObject *, PyObject *);
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
// module specification
|
|
@@ -137,6 +149,11 @@ static PyMethodDef module_methods[] = {
|
|
|
137
149
|
{ "itot_mrg", py_itot_mrg, METH_VARARGS, itot_mrg_docstring },
|
|
138
150
|
{ "itot_del", py_itot_del, METH_VARARGS, itot_del_docstring },
|
|
139
151
|
|
|
152
|
+
{ "iseq_new", py_iseq_new, METH_VARARGS, iseq_new_docstring },
|
|
153
|
+
{ "iseq_inc", py_iseq_inc, METH_VARARGS, iseq_inc_docstring },
|
|
154
|
+
{ "iseq_del", py_iseq_del, METH_VARARGS, iseq_del_docstring },
|
|
155
|
+
{ "iseq_get", py_iseq_get, METH_VARARGS, iseq_get_docstring },
|
|
156
|
+
|
|
140
157
|
{ NULL, NULL, 0, NULL }
|
|
141
158
|
};
|
|
142
159
|
|
|
@@ -860,4 +877,203 @@ static PyObject *py_itot_del(PyObject *self, PyObject *args)
|
|
|
860
877
|
return ret;
|
|
861
878
|
}
|
|
862
879
|
|
|
880
|
+
// Incremental sequential counter contributed by Jesse Looney.
|
|
881
|
+
// From jesselooney/pysat, commit 8d3449e8d1845cc9e0f682a45beb888bbac8be0c.
|
|
882
|
+
//
|
|
883
|
+
//=============================================================================
|
|
884
|
+
static PyObject *py_iseq_new(PyObject *self, PyObject *args)
|
|
885
|
+
{
|
|
886
|
+
PyObject *lhs_obj;
|
|
887
|
+
int rhs;
|
|
888
|
+
int top;
|
|
889
|
+
int main_thread;
|
|
890
|
+
|
|
891
|
+
if (!PyArg_ParseTuple(args, "Oiii", &lhs_obj, &rhs, &top, &main_thread))
|
|
892
|
+
return NULL;
|
|
893
|
+
|
|
894
|
+
vector<int> lhs;
|
|
895
|
+
if (pyiter_to_vector(lhs_obj, lhs) == false)
|
|
896
|
+
return NULL;
|
|
897
|
+
|
|
898
|
+
PyOS_sighandler_t sig_save;
|
|
899
|
+
if (main_thread) {
|
|
900
|
+
sig_save = PyOS_setsig(SIGINT, sigint_handler);
|
|
901
|
+
|
|
902
|
+
if (setjmp(env) != 0) {
|
|
903
|
+
PyErr_SetString(CardError, "Caught keyboard interrupt");
|
|
904
|
+
return NULL;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// calling encoder
|
|
909
|
+
ClauseSet dest;
|
|
910
|
+
SeqState *state = iseq_new(dest, lhs, rhs, top);
|
|
911
|
+
|
|
912
|
+
if (main_thread)
|
|
913
|
+
PyOS_setsig(SIGINT, sig_save);
|
|
914
|
+
|
|
915
|
+
PyIntCache cache = {};
|
|
916
|
+
PyObject *dest_obj = clauseset_to_pylist(dest, &cache);
|
|
917
|
+
pyint_cache_clear(&cache);
|
|
918
|
+
if (dest_obj == NULL) {
|
|
919
|
+
iseq_destroy(state);
|
|
920
|
+
return NULL;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
PyObject *ubs_obj = vector_to_pylist(state->rhs);
|
|
924
|
+
if (ubs_obj == NULL) {
|
|
925
|
+
Py_DECREF(dest_obj);
|
|
926
|
+
iseq_destroy(state);
|
|
927
|
+
return NULL;
|
|
928
|
+
}
|
|
929
|
+
PyObject *state_obj = void_to_pyobj((void *)state);
|
|
930
|
+
if (state_obj == NULL) {
|
|
931
|
+
Py_DECREF(dest_obj);
|
|
932
|
+
Py_DECREF(ubs_obj);
|
|
933
|
+
iseq_destroy(state);
|
|
934
|
+
return NULL;
|
|
935
|
+
}
|
|
936
|
+
PyObject *top_obj = pyint_from_cint(top);
|
|
937
|
+
if (top_obj == NULL) {
|
|
938
|
+
Py_DECREF(dest_obj);
|
|
939
|
+
Py_DECREF(ubs_obj);
|
|
940
|
+
Py_DECREF(state_obj);
|
|
941
|
+
iseq_destroy(state);
|
|
942
|
+
return NULL;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
PyObject *ret = PyTuple_New(4);
|
|
946
|
+
if (ret == NULL) {
|
|
947
|
+
Py_DECREF(dest_obj);
|
|
948
|
+
Py_DECREF(ubs_obj);
|
|
949
|
+
Py_DECREF(state_obj);
|
|
950
|
+
Py_DECREF(top_obj);
|
|
951
|
+
iseq_destroy(state);
|
|
952
|
+
return NULL;
|
|
953
|
+
}
|
|
954
|
+
PyTuple_SET_ITEM(ret, 0, state_obj);
|
|
955
|
+
PyTuple_SET_ITEM(ret, 1, dest_obj);
|
|
956
|
+
PyTuple_SET_ITEM(ret, 2, ubs_obj);
|
|
957
|
+
PyTuple_SET_ITEM(ret, 3, top_obj);
|
|
958
|
+
return ret;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
//
|
|
962
|
+
//=============================================================================
|
|
963
|
+
static PyObject *py_iseq_inc(PyObject *self, PyObject *args)
|
|
964
|
+
{
|
|
965
|
+
PyObject *t_obj;
|
|
966
|
+
int rhs;
|
|
967
|
+
int top;
|
|
968
|
+
int main_thread;
|
|
969
|
+
|
|
970
|
+
if (!PyArg_ParseTuple(args, "Oiii", &t_obj, &rhs, &top, &main_thread))
|
|
971
|
+
return NULL;
|
|
972
|
+
|
|
973
|
+
// get pointer to state
|
|
974
|
+
SeqState *state = (SeqState *)pyobj_to_void(t_obj);
|
|
975
|
+
|
|
976
|
+
PyOS_sighandler_t sig_save;
|
|
977
|
+
if (main_thread) {
|
|
978
|
+
sig_save = PyOS_setsig(SIGINT, sigint_handler);
|
|
979
|
+
|
|
980
|
+
if (setjmp(env) != 0) {
|
|
981
|
+
PyErr_SetString(CardError, "Caught keyboard interrupt");
|
|
982
|
+
return NULL;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// calling encoder
|
|
987
|
+
ClauseSet dest;
|
|
988
|
+
iseq_increase(state, dest, rhs, top);
|
|
989
|
+
|
|
990
|
+
if (main_thread)
|
|
991
|
+
PyOS_setsig(SIGINT, sig_save);
|
|
992
|
+
|
|
993
|
+
PyIntCache cache = {};
|
|
994
|
+
PyObject *dest_obj = clauseset_to_pylist(dest, &cache);
|
|
995
|
+
pyint_cache_clear(&cache);
|
|
996
|
+
if (dest_obj == NULL)
|
|
997
|
+
return NULL;
|
|
998
|
+
|
|
999
|
+
PyObject *ubs_obj = vector_to_pylist(state->rhs);
|
|
1000
|
+
if (ubs_obj == NULL) {
|
|
1001
|
+
Py_DECREF(dest_obj);
|
|
1002
|
+
return NULL;
|
|
1003
|
+
}
|
|
1004
|
+
PyObject *top_obj = pyint_from_cint(top);
|
|
1005
|
+
if (top_obj == NULL) {
|
|
1006
|
+
Py_DECREF(dest_obj);
|
|
1007
|
+
Py_DECREF(ubs_obj);
|
|
1008
|
+
return NULL;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
PyObject *ret = PyTuple_New(3);
|
|
1012
|
+
if (ret == NULL) {
|
|
1013
|
+
Py_DECREF(dest_obj);
|
|
1014
|
+
Py_DECREF(ubs_obj);
|
|
1015
|
+
Py_DECREF(top_obj);
|
|
1016
|
+
return NULL;
|
|
1017
|
+
}
|
|
1018
|
+
PyTuple_SET_ITEM(ret, 0, dest_obj);
|
|
1019
|
+
PyTuple_SET_ITEM(ret, 1, ubs_obj);
|
|
1020
|
+
PyTuple_SET_ITEM(ret, 2, top_obj);
|
|
1021
|
+
return ret;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
//
|
|
1025
|
+
//=============================================================================
|
|
1026
|
+
static PyObject *py_iseq_get(PyObject *self, PyObject *args)
|
|
1027
|
+
{
|
|
1028
|
+
PyObject *t_obj;
|
|
1029
|
+
int prefix_len;
|
|
1030
|
+
int bound;
|
|
1031
|
+
int main_thread;
|
|
1032
|
+
|
|
1033
|
+
if (!PyArg_ParseTuple(args, "Oiii", &t_obj, &prefix_len, &bound, &main_thread))
|
|
1034
|
+
return NULL;
|
|
1035
|
+
|
|
1036
|
+
// get pointer to state
|
|
1037
|
+
SeqState *state = (SeqState *)pyobj_to_void(t_obj);
|
|
1038
|
+
|
|
1039
|
+
PyOS_sighandler_t sig_save;
|
|
1040
|
+
if (main_thread) {
|
|
1041
|
+
sig_save = PyOS_setsig(SIGINT, sigint_handler);
|
|
1042
|
+
|
|
1043
|
+
if (setjmp(env) != 0) {
|
|
1044
|
+
PyErr_SetString(CardError, "Caught keyboard interrupt");
|
|
1045
|
+
return NULL;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// calling encoder
|
|
1050
|
+
int lit = iseq_get(state, prefix_len, bound);
|
|
1051
|
+
|
|
1052
|
+
if (main_thread)
|
|
1053
|
+
PyOS_setsig(SIGINT, sig_save);
|
|
1054
|
+
|
|
1055
|
+
PyObject *ret = Py_BuildValue("i", lit);
|
|
1056
|
+
|
|
1057
|
+
return ret;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
//
|
|
1061
|
+
//=============================================================================
|
|
1062
|
+
static PyObject *py_iseq_del(PyObject *self, PyObject *args)
|
|
1063
|
+
{
|
|
1064
|
+
PyObject *t_obj;
|
|
1065
|
+
|
|
1066
|
+
if (!PyArg_ParseTuple(args, "O", &t_obj))
|
|
1067
|
+
return NULL;
|
|
1068
|
+
|
|
1069
|
+
// get pointer to state
|
|
1070
|
+
SeqState *state = (SeqState *)pyobj_to_void(t_obj);
|
|
1071
|
+
|
|
1072
|
+
// delete
|
|
1073
|
+
iseq_destroy(state);
|
|
1074
|
+
|
|
1075
|
+
PyObject *ret = Py_BuildValue("");
|
|
1076
|
+
return ret;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
863
1079
|
} // extern "C"
|