python-sat 1.9.dev18__tar.gz → 1.9.dev19__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.

Potentially problematic release.


This version of python-sat might be problematic. Click here for more details.

Files changed (127) hide show
  1. {python_sat-1.9.dev18/python_sat.egg-info → python_sat-1.9.dev19}/PKG-INFO +1 -1
  2. python_sat-1.9.dev19/cardenc/iseq.hh +151 -0
  3. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/mto.hh +22 -0
  4. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/pycard.cc +216 -0
  5. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/__init__.py +1 -1
  6. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/card.py +243 -3
  7. {python_sat-1.9.dev18 → python_sat-1.9.dev19/python_sat.egg-info}/PKG-INFO +1 -1
  8. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/python_sat.egg-info/SOURCES.txt +2 -0
  9. python_sat-1.9.dev19/tests/test_iseqcounter.py +103 -0
  10. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/LICENSE.txt +0 -0
  11. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/MANIFEST.in +0 -0
  12. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/README.rst +0 -0
  13. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/allies/__init__.py +0 -0
  14. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/allies/approxmc.py +0 -0
  15. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/allies/unigen.py +0 -0
  16. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/bitwise.hh +0 -0
  17. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/card.hh +0 -0
  18. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/clset.hh +0 -0
  19. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/common.hh +0 -0
  20. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/itot.hh +0 -0
  21. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/ladder.hh +0 -0
  22. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/pairwise.hh +0 -0
  23. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/ptypes.hh +0 -0
  24. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/seqcounter.hh +0 -0
  25. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/sortcard.hh +0 -0
  26. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/cardenc/utils.hh +0 -0
  27. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/__init__.py +0 -0
  28. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/bbscan.py +0 -0
  29. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/bica.py +0 -0
  30. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/fm.py +0 -0
  31. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/genhard.py +0 -0
  32. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/hitman.py +0 -0
  33. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/lbx.py +0 -0
  34. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/lsu.py +0 -0
  35. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/mcsls.py +0 -0
  36. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/models.py +0 -0
  37. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/musx.py +0 -0
  38. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/optux.py +0 -0
  39. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/primer.py +0 -0
  40. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/rc2.py +0 -0
  41. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/examples/usage.py +0 -0
  42. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_parse.cc +0 -0
  43. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_plus.cc +0 -0
  44. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_plus.hh +0 -0
  45. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_py.hh +0 -0
  46. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_scan.hh +0 -0
  47. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_weight.cc +0 -0
  48. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pf_weight.hh +0 -0
  49. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pyformula.cc +0 -0
  50. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/formula/pyformula.hh +0 -0
  51. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/_fileio.py +0 -0
  52. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/_utils.py +0 -0
  53. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/engines.py +0 -0
  54. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/formula.py +0 -0
  55. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/integer.py +0 -0
  56. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/pb.py +0 -0
  57. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/process.py +0 -0
  58. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/pysat/solvers.py +0 -0
  59. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/python_sat.egg-info/dependency_links.txt +0 -0
  60. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/python_sat.egg-info/requires.txt +0 -0
  61. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/python_sat.egg-info/top_level.txt +0 -0
  62. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/requirements.txt +0 -0
  63. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/setup.cfg +0 -0
  64. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/setup.py +0 -0
  65. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/cadical103.tar.gz +0 -0
  66. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/cadical153.tar.gz +0 -0
  67. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/cadical195.tar.gz +0 -0
  68. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/cadical300.tar.gz +0 -0
  69. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/ergo.tar.gz +0 -0
  70. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/glucose30.tar.gz +0 -0
  71. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/glucose41.tar.gz +0 -0
  72. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/glucose421.tar.gz +0 -0
  73. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/lingeling.tar.gz +0 -0
  74. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/maplechrono.zip +0 -0
  75. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/maplecm.zip +0 -0
  76. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/maplesat.zip +0 -0
  77. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/mergesat3.tar.gz +0 -0
  78. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/minicard.tar.gz +0 -0
  79. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/minisat22.tar.gz +0 -0
  80. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/minisatgh.zip +0 -0
  81. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/cadical103.patch +0 -0
  82. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/cadical153.patch +0 -0
  83. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/cadical195.patch +0 -0
  84. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/cadical300.patch +0 -0
  85. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/ergo.patch +0 -0
  86. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/glucose30.patch +0 -0
  87. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/glucose41.patch +0 -0
  88. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/glucose421.patch +0 -0
  89. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/gluecard30.patch +0 -0
  90. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/gluecard41.patch +0 -0
  91. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/kissat404.patch +0 -0
  92. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/lingeling.patch +0 -0
  93. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/maplechrono.patch +0 -0
  94. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/maplecm.patch +0 -0
  95. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/maplesat.patch +0 -0
  96. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/mergesat3.patch +0 -0
  97. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/minicard.patch +0 -0
  98. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/minisat22.patch +0 -0
  99. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/minisatep.patch +0 -0
  100. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/patches/minisatgh.patch +0 -0
  101. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/prepare.py +0 -0
  102. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/solvers/pysolvers.cc +0 -0
  103. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_accum_stats.py +0 -0
  104. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_atmost.py +0 -0
  105. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_atmost1.py +0 -0
  106. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_atmostk.py +0 -0
  107. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_boolengine.py +0 -0
  108. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_clausification.py +0 -0
  109. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_cnf.py +0 -0
  110. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_empty_clause.py +0 -0
  111. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_empty_extclause.py +0 -0
  112. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_encode_pb_conditional.py +0 -0
  113. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_equals1.py +0 -0
  114. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_formula_parsing.py +0 -0
  115. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_formula_unique.py +0 -0
  116. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_hitman.py +0 -0
  117. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_idpool.py +0 -0
  118. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_integer.py +0 -0
  119. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_lsu.py +0 -0
  120. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_oom.py +0 -0
  121. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_pb.py +0 -0
  122. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_process.py +0 -0
  123. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_proof.py +0 -0
  124. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_propagate.py +0 -0
  125. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_unique_model.py +0 -0
  126. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_unique_mus.py +0 -0
  127. {python_sat-1.9.dev18 → python_sat-1.9.dev19}/tests/test_warmstart.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-sat
3
- Version: 1.9.dev18
3
+ Version: 1.9.dev19
4
4
  Summary: A Python library for prototyping with SAT oracles
5
5
  Home-page: https://github.com/pysathq/pysat
6
6
  Author: Alexey Ignatiev, Joao Marques-Silva, Antonio Morgado
@@ -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"
@@ -10,7 +10,7 @@
10
10
 
11
11
  # current version
12
12
  #==============================================================================
13
- VERSION = (1, 9, 'dev', 18)
13
+ VERSION = (1, 9, 'dev', 19)
14
14
 
15
15
 
16
16
  # PEP440 Format