yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ezsat.cc
Go to the documentation of this file.
1 /*
2  * ezSAT -- A simple and easy to use CNF generator for SAT solvers
3  *
4  * Copyright (C) 2013 Clifford Wolf <clifford@clifford.at>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #include "ezsat.h"
21 
22 #include <cmath>
23 #include <algorithm>
24 #include <cassert>
25 #include <string>
26 
27 #include <stdlib.h>
28 
29 const int ezSAT::CONST_TRUE = 1;
30 const int ezSAT::CONST_FALSE = 2;
31 
32 static std::string my_int_to_string(int i)
33 {
34 #ifdef __MINGW32__
35  char buffer[64];
36  snprintf(buffer, 64, "%d", i);
37  return buffer;
38 #else
39  return std::to_string(i);
40 #endif
41 }
42 
44 {
45  flag_keep_cnf = false;
46  flag_non_incremental = false;
47 
49 
50  cnfConsumed = false;
51  cnfVariableCount = 0;
52  cnfClausesCount = 0;
53 
54  solverTimeout = 0;
55  solverTimoutStatus = false;
56 
57  literal("CONST_TRUE");
58  literal("CONST_FALSE");
59 
60  assert(literal("CONST_TRUE") == CONST_TRUE);
61  assert(literal("CONST_FALSE") == CONST_FALSE);
62 }
63 
65 {
66 }
67 
68 int ezSAT::value(bool val)
69 {
70  return val ? CONST_TRUE : CONST_FALSE;
71 }
72 
74 {
75  literals.push_back(std::string());
76  return literals.size();
77 }
78 
79 int ezSAT::literal(const std::string &name)
80 {
81  if (literalsCache.count(name) == 0) {
82  literals.push_back(name);
83  literalsCache[name] = literals.size();
84  }
85  return literalsCache.at(name);
86 }
87 
89 {
90  int id = literal();
91  freeze(id);
92  return id;
93 }
94 
95 int ezSAT::frozen_literal(const std::string &name)
96 {
97  int id = literal(name);
98  freeze(id);
99  return id;
100 }
101 
102 int ezSAT::expression(OpId op, int a, int b, int c, int d, int e, int f)
103 {
104  std::vector<int> args(6);
105  args[0] = a, args[1] = b, args[2] = c;
106  args[3] = d, args[4] = e, args[5] = f;
107  return expression(op, args);
108 }
109 
110 int ezSAT::expression(OpId op, const std::vector<int> &args)
111 {
112  std::vector<int> myArgs;
113  myArgs.reserve(args.size());
114  bool xorRemovedOddTrues = false;
115 
116  for (auto arg : args)
117  {
118  if (arg == 0)
119  continue;
120  if (op == OpAnd && arg == CONST_TRUE)
121  continue;
122  if ((op == OpOr || op == OpXor) && arg == CONST_FALSE)
123  continue;
124  if (op == OpXor && arg == CONST_TRUE) {
125  xorRemovedOddTrues = !xorRemovedOddTrues;
126  continue;
127  }
128  myArgs.push_back(arg);
129  }
130 
131  if (myArgs.size() > 0 && (op == OpAnd || op == OpOr || op == OpXor || op == OpIFF)) {
132  std::sort(myArgs.begin(), myArgs.end());
133  int j = 0;
134  for (int i = 1; i < int(myArgs.size()); i++)
135  if (j < 0 || myArgs[j] != myArgs[i])
136  myArgs[++j] = myArgs[i];
137  else if (op == OpXor)
138  j--;
139  myArgs.resize(j+1);
140  }
141 
142  switch (op)
143  {
144  case OpNot:
145  assert(myArgs.size() == 1);
146  if (myArgs[0] == CONST_TRUE)
147  return CONST_FALSE;
148  if (myArgs[0] == CONST_FALSE)
149  return CONST_TRUE;
150  break;
151 
152  case OpAnd:
153  if (myArgs.size() == 0)
154  return CONST_TRUE;
155  if (myArgs.size() == 1)
156  return myArgs[0];
157  break;
158 
159  case OpOr:
160  if (myArgs.size() == 0)
161  return CONST_FALSE;
162  if (myArgs.size() == 1)
163  return myArgs[0];
164  break;
165 
166  case OpXor:
167  if (myArgs.size() == 0)
168  return xorRemovedOddTrues ? CONST_TRUE : CONST_FALSE;
169  if (myArgs.size() == 1)
170  return xorRemovedOddTrues ? NOT(myArgs[0]) : myArgs[0];
171  break;
172 
173  case OpIFF:
174  assert(myArgs.size() >= 1);
175  if (myArgs.size() == 1)
176  return CONST_TRUE;
177  // FIXME: Add proper const folding
178  break;
179 
180  case OpITE:
181  assert(myArgs.size() == 3);
182  if (myArgs[0] == CONST_TRUE)
183  return myArgs[1];
184  if (myArgs[0] == CONST_FALSE)
185  return myArgs[2];
186  break;
187 
188  default:
189  abort();
190  }
191 
192  std::pair<OpId, std::vector<int>> myExpr(op, myArgs);
193  int id = 0;
194 
195  if (expressionsCache.count(myExpr) > 0) {
196  id = expressionsCache.at(myExpr);
197  } else {
198  id = -(int(expressions.size()) + 1);
199  expressionsCache[myExpr] = id;
200  expressions.push_back(myExpr);
201  }
202 
203  return xorRemovedOddTrues ? NOT(id) : id;
204 }
205 
206 void ezSAT::lookup_literal(int id, std::string &name) const
207 {
208  assert(0 < id && id <= int(literals.size()));
209  name = literals[id - 1];
210 }
211 
212 const std::string &ezSAT::lookup_literal(int id) const
213 {
214  assert(0 < id && id <= int(literals.size()));
215  return literals[id - 1];
216 }
217 
218 void ezSAT::lookup_expression(int id, OpId &op, std::vector<int> &args) const
219 {
220  assert(0 < -id && -id <= int(expressions.size()));
221  op = expressions[-id - 1].first;
222  args = expressions[-id - 1].second;
223 }
224 
225 const std::vector<int> &ezSAT::lookup_expression(int id, OpId &op) const
226 {
227  assert(0 < -id && -id <= int(expressions.size()));
228  op = expressions[-id - 1].first;
229  return expressions[-id - 1].second;
230 }
231 
232 int ezSAT::parse_string(const std::string &)
233 {
234  abort();
235 }
236 
237 std::string ezSAT::to_string(int id) const
238 {
239  std::string text;
240 
241  if (id > 0)
242  {
243  lookup_literal(id, text);
244  }
245  else
246  {
247  OpId op;
248  std::vector<int> args;
249  lookup_expression(id, op, args);
250 
251  switch (op)
252  {
253  case OpNot:
254  text = "not(";
255  break;
256 
257  case OpAnd:
258  text = "and(";
259  break;
260 
261  case OpOr:
262  text = "or(";
263  break;
264 
265  case OpXor:
266  text = "xor(";
267  break;
268 
269  case OpIFF:
270  text = "iff(";
271  break;
272 
273  case OpITE:
274  text = "ite(";
275  break;
276 
277  default:
278  abort();
279  }
280 
281  for (int i = 0; i < int(args.size()); i++) {
282  if (i > 0)
283  text += ", ";
284  text += to_string(args[i]);
285  }
286 
287  text += ")";
288  }
289 
290  return text;
291 }
292 
293 int ezSAT::eval(int id, const std::vector<int> &values) const
294 {
295  if (id > 0) {
296  if (id <= int(values.size()) && (values[id-1] == CONST_TRUE || values[id-1] == CONST_FALSE || values[id-1] == 0))
297  return values[id-1];
298  return 0;
299  }
300 
301  OpId op;
302  const std::vector<int> &args = lookup_expression(id, op);
303  int a, b;
304 
305  switch (op)
306  {
307  case OpNot:
308  assert(args.size() == 1);
309  a = eval(args[0], values);
310  if (a == CONST_TRUE)
311  return CONST_FALSE;
312  if (a == CONST_FALSE)
313  return CONST_TRUE;
314  return 0;
315  case OpAnd:
316  a = CONST_TRUE;
317  for (auto arg : args) {
318  b = eval(arg, values);
319  if (b != CONST_TRUE && b != CONST_FALSE)
320  a = 0;
321  if (b == CONST_FALSE)
322  return CONST_FALSE;
323  }
324  return a;
325  case OpOr:
326  a = CONST_FALSE;
327  for (auto arg : args) {
328  b = eval(arg, values);
329  if (b != CONST_TRUE && b != CONST_FALSE)
330  a = 0;
331  if (b == CONST_TRUE)
332  return CONST_TRUE;
333  }
334  return a;
335  case OpXor:
336  a = CONST_FALSE;
337  for (auto arg : args) {
338  b = eval(arg, values);
339  if (b != CONST_TRUE && b != CONST_FALSE)
340  return 0;
341  if (b == CONST_TRUE)
342  a = a == CONST_TRUE ? CONST_FALSE : CONST_TRUE;
343  }
344  return a;
345  case OpIFF:
346  assert(args.size() > 0);
347  a = eval(args[0], values);
348  for (auto arg : args) {
349  b = eval(arg, values);
350  if (b != CONST_TRUE && b != CONST_FALSE)
351  return 0;
352  if (b != a)
353  return CONST_FALSE;
354  }
355  return CONST_TRUE;
356  case OpITE:
357  assert(args.size() == 3);
358  a = eval(args[0], values);
359  if (a == CONST_TRUE)
360  return eval(args[1], values);
361  if (a == CONST_FALSE)
362  return eval(args[2], values);
363  return 0;
364  default:
365  abort();
366  }
367 }
368 
370 {
371  cnfConsumed = false;
372  cnfVariableCount = 0;
373  cnfClausesCount = 0;
374  cnfLiteralVariables.clear();
375  cnfExpressionVariables.clear();
376  cnfClauses.clear();
377 }
378 
379 void ezSAT::freeze(int)
380 {
381 }
382 
384 {
385  return false;
386 }
387 
388 void ezSAT::assume(int id)
389 {
390  if (id < 0)
391  {
392  assert(0 < -id && -id <= int(expressions.size()));
393  cnfExpressionVariables.resize(expressions.size());
394 
395  if (cnfExpressionVariables[-id-1] == 0)
396  {
397  OpId op;
398  std::vector<int> args;
399  lookup_expression(id, op, args);
400 
401  if (op == OpNot) {
402  int idx = bind(args[0]);
403  cnfClauses.push_back(std::vector<int>(1, -idx));
404  cnfClausesCount++;
405  return;
406  }
407  if (op == OpOr) {
408  std::vector<int> clause;
409  for (int arg : args)
410  clause.push_back(bind(arg));
411  cnfClauses.push_back(clause);
412  cnfClausesCount++;
413  return;
414  }
415  if (op == OpAnd) {
416  for (int arg : args) {
417  cnfClauses.push_back(std::vector<int>(1, bind(arg)));
418  cnfClausesCount++;
419  }
420  return;
421  }
422  }
423  }
424 
425  int idx = bind(id);
426  cnfClauses.push_back(std::vector<int>(1, idx));
427  cnfClausesCount++;
428 }
429 
430 void ezSAT::add_clause(const std::vector<int> &args)
431 {
432  cnfClauses.push_back(args);
433  cnfClausesCount++;
434 }
435 
436 void ezSAT::add_clause(const std::vector<int> &args, bool argsPolarity, int a, int b, int c)
437 {
438  std::vector<int> clause;
439  for (auto arg : args)
440  clause.push_back(argsPolarity ? +arg : -arg);
441  if (a != 0)
442  clause.push_back(a);
443  if (b != 0)
444  clause.push_back(b);
445  if (c != 0)
446  clause.push_back(c);
447  add_clause(clause);
448 }
449 
450 void ezSAT::add_clause(int a, int b, int c)
451 {
452  std::vector<int> clause;
453  if (a != 0)
454  clause.push_back(a);
455  if (b != 0)
456  clause.push_back(b);
457  if (c != 0)
458  clause.push_back(c);
459  add_clause(clause);
460 }
461 
462 int ezSAT::bind_cnf_not(const std::vector<int> &args)
463 {
464  assert(args.size() == 1);
465  return -args[0];
466 }
467 
468 int ezSAT::bind_cnf_and(const std::vector<int> &args)
469 {
470  assert(args.size() >= 2);
471 
472  int idx = ++cnfVariableCount;
473  add_clause(args, false, idx);
474 
475  for (auto arg : args)
476  add_clause(-idx, arg);
477 
478  return idx;
479 }
480 
481 int ezSAT::bind_cnf_or(const std::vector<int> &args)
482 {
483  assert(args.size() >= 2);
484 
485  int idx = ++cnfVariableCount;
486  add_clause(args, true, -idx);
487 
488  for (auto arg : args)
489  add_clause(idx, -arg);
490 
491  return idx;
492 }
493 
494 int ezSAT::bound(int id) const
495 {
496  if (id > 0 && id <= int(cnfLiteralVariables.size()))
497  return cnfLiteralVariables[id-1];
498  if (-id > 0 && -id <= int(cnfExpressionVariables.size()))
499  return cnfExpressionVariables[-id-1];
500  return 0;
501 }
502 
503 std::string ezSAT::cnfLiteralInfo(int idx) const
504 {
505  for (int i = 0; i < int(cnfLiteralVariables.size()); i++) {
506  if (cnfLiteralVariables[i] == idx)
507  return to_string(i+1);
508  if (cnfLiteralVariables[i] == -idx)
509  return "NOT " + to_string(i+1);
510  }
511  for (int i = 0; i < int(cnfExpressionVariables.size()); i++) {
512  if (cnfExpressionVariables[i] == idx)
513  return to_string(-i-1);
514  if (cnfExpressionVariables[i] == -idx)
515  return "NOT " + to_string(-i-1);
516  }
517  return "<unnamed>";
518 }
519 
520 int ezSAT::bind(int id, bool auto_freeze)
521 {
522  if (id >= 0) {
523  assert(0 < id && id <= int(literals.size()));
524  cnfLiteralVariables.resize(literals.size());
525  if (eliminated(cnfLiteralVariables[id-1])) {
526  fprintf(stderr, "ezSAT: Missing freeze on literal `%s'.\n", to_string(id).c_str());
527  abort();
528  }
529  if (cnfLiteralVariables[id-1] == 0) {
531  if (id == CONST_TRUE)
533  if (id == CONST_FALSE)
535  }
536  return cnfLiteralVariables[id-1];
537  }
538 
539  assert(0 < -id && -id <= int(expressions.size()));
540  cnfExpressionVariables.resize(expressions.size());
541 
543  {
544  cnfExpressionVariables[-id-1] = 0;
545 
546  // this will recursively call bind(id). within the recursion
547  // the cnf is pre-set to 0. an idx is allocated there, then it
548  // is frozen, then it returns here with the new idx already set.
549  if (auto_freeze)
550  freeze(id);
551  }
552 
553  if (cnfExpressionVariables[-id-1] == 0)
554  {
555  OpId op;
556  std::vector<int> args;
557  lookup_expression(id, op, args);
558  int idx = 0;
559 
560  if (op == OpXor) {
561  while (args.size() > 1) {
562  std::vector<int> newArgs;
563  for (int i = 0; i < int(args.size()); i += 2)
564  if (i+1 == int(args.size()))
565  newArgs.push_back(args[i]);
566  else
567  newArgs.push_back(OR(AND(args[i], NOT(args[i+1])), AND(NOT(args[i]), args[i+1])));
568  args.swap(newArgs);
569  }
570  idx = bind(args.at(0), false);
571  goto assign_idx;
572  }
573 
574  if (op == OpIFF) {
575  std::vector<int> invArgs;
576  for (auto arg : args)
577  invArgs.push_back(NOT(arg));
578  idx = bind(OR(expression(OpAnd, args), expression(OpAnd, invArgs)), false);
579  goto assign_idx;
580  }
581 
582  if (op == OpITE) {
583  idx = bind(OR(AND(args[0], args[1]), AND(NOT(args[0]), args[2])), false);
584  goto assign_idx;
585  }
586 
587  for (int i = 0; i < int(args.size()); i++)
588  args[i] = bind(args[i], false);
589 
590  switch (op)
591  {
592  case OpNot: idx = bind_cnf_not(args); break;
593  case OpAnd: idx = bind_cnf_and(args); break;
594  case OpOr: idx = bind_cnf_or(args); break;
595  default: abort();
596  }
597 
598  assign_idx:
599  assert(idx != 0);
600  cnfExpressionVariables[-id-1] = idx;
601  }
602 
603  return cnfExpressionVariables[-id-1];
604 }
605 
607 {
608  if (mode_keep_cnf())
609  cnfClausesBackup.insert(cnfClausesBackup.end(), cnfClauses.begin(), cnfClauses.end());
610  else
611  cnfConsumed = true;
612  cnfClauses.clear();
613 }
614 
615 void ezSAT::consumeCnf(std::vector<std::vector<int>> &cnf)
616 {
617  if (mode_keep_cnf())
618  cnfClausesBackup.insert(cnfClausesBackup.end(), cnfClauses.begin(), cnfClauses.end());
619  else
620  cnfConsumed = true;
621  cnf.swap(cnfClauses);
622  cnfClauses.clear();
623 }
624 
625 void ezSAT::getFullCnf(std::vector<std::vector<int>> &full_cnf) const
626 {
627  assert(full_cnf.empty());
628  full_cnf.insert(full_cnf.end(), cnfClausesBackup.begin(), cnfClausesBackup.end());
629  full_cnf.insert(full_cnf.end(), cnfClauses.begin(), cnfClauses.end());
630 }
631 
633 {
635  if (mode_non_incremental())
637 }
638 
639 bool ezSAT::solver(const std::vector<int>&, std::vector<bool>&, const std::vector<int>&)
640 {
642  fprintf(stderr, "************************************************************************\n");
643  fprintf(stderr, "ERROR: You are trying to use the solve() method of the ezSAT base class!\n");
644  fprintf(stderr, "Use a dervied class like ezMiniSAT instead.\n");
645  fprintf(stderr, "************************************************************************\n");
646  abort();
647 }
648 
649 std::vector<int> ezSAT::vec_const(const std::vector<bool> &bits)
650 {
651  std::vector<int> vec;
652  for (auto bit : bits)
653  vec.push_back(bit ? CONST_TRUE : CONST_FALSE);
654  return vec;
655 }
656 
657 std::vector<int> ezSAT::vec_const_signed(int64_t value, int numBits)
658 {
659  std::vector<int> vec;
660  for (int i = 0; i < numBits; i++)
661  vec.push_back(((value >> i) & 1) != 0 ? CONST_TRUE : CONST_FALSE);
662  return vec;
663 }
664 
665 std::vector<int> ezSAT::vec_const_unsigned(uint64_t value, int numBits)
666 {
667  std::vector<int> vec;
668  for (int i = 0; i < numBits; i++)
669  vec.push_back(((value >> i) & 1) != 0 ? CONST_TRUE : CONST_FALSE);
670  return vec;
671 }
672 
673 std::vector<int> ezSAT::vec_var(int numBits)
674 {
675  std::vector<int> vec;
676  for (int i = 0; i < numBits; i++)
677  vec.push_back(literal());
678  return vec;
679 }
680 
681 std::vector<int> ezSAT::vec_var(std::string name, int numBits)
682 {
683  std::vector<int> vec;
684  for (int i = 0; i < numBits; i++) {
685  vec.push_back(VAR(name + my_int_to_string(i)));
686  }
687  return vec;
688 }
689 
690 std::vector<int> ezSAT::vec_cast(const std::vector<int> &vec1, int toBits, bool signExtend)
691 {
692  std::vector<int> vec;
693  for (int i = 0; i < toBits; i++)
694  if (i >= int(vec1.size()))
695  vec.push_back(signExtend ? vec1.back() : CONST_FALSE);
696  else
697  vec.push_back(vec1[i]);
698  return vec;
699 }
700 
701 std::vector<int> ezSAT::vec_not(const std::vector<int> &vec1)
702 {
703  std::vector<int> vec;
704  for (auto bit : vec1)
705  vec.push_back(NOT(bit));
706  return vec;
707 }
708 
709 std::vector<int> ezSAT::vec_and(const std::vector<int> &vec1, const std::vector<int> &vec2)
710 {
711  assert(vec1.size() == vec2.size());
712  std::vector<int> vec(vec1.size());
713  for (int i = 0; i < int(vec1.size()); i++)
714  vec[i] = AND(vec1[i], vec2[i]);
715  return vec;
716 }
717 
718 std::vector<int> ezSAT::vec_or(const std::vector<int> &vec1, const std::vector<int> &vec2)
719 {
720  assert(vec1.size() == vec2.size());
721  std::vector<int> vec(vec1.size());
722  for (int i = 0; i < int(vec1.size()); i++)
723  vec[i] = OR(vec1[i], vec2[i]);
724  return vec;
725 }
726 
727 std::vector<int> ezSAT::vec_xor(const std::vector<int> &vec1, const std::vector<int> &vec2)
728 {
729  assert(vec1.size() == vec2.size());
730  std::vector<int> vec(vec1.size());
731  for (int i = 0; i < int(vec1.size()); i++)
732  vec[i] = XOR(vec1[i], vec2[i]);
733  return vec;
734 }
735 
736 std::vector<int> ezSAT::vec_iff(const std::vector<int> &vec1, const std::vector<int> &vec2)
737 {
738  assert(vec1.size() == vec2.size());
739  std::vector<int> vec(vec1.size());
740  for (int i = 0; i < int(vec1.size()); i++)
741  vec[i] = IFF(vec1[i], vec2[i]);
742  return vec;
743 }
744 
745 std::vector<int> ezSAT::vec_ite(const std::vector<int> &vec1, const std::vector<int> &vec2, const std::vector<int> &vec3)
746 {
747  assert(vec1.size() == vec2.size() && vec2.size() == vec3.size());
748  std::vector<int> vec(vec1.size());
749  for (int i = 0; i < int(vec1.size()); i++)
750  vec[i] = ITE(vec1[i], vec2[i], vec3[i]);
751  return vec;
752 }
753 
754 
755 std::vector<int> ezSAT::vec_ite(int sel, const std::vector<int> &vec1, const std::vector<int> &vec2)
756 {
757  assert(vec1.size() == vec2.size());
758  std::vector<int> vec(vec1.size());
759  for (int i = 0; i < int(vec1.size()); i++)
760  vec[i] = ITE(sel, vec1[i], vec2[i]);
761  return vec;
762 }
763 
764 // 'y' is the MSB (carry) and x the LSB (sum) output
765 static void fulladder(ezSAT *that, int a, int b, int c, int &y, int &x)
766 {
767  int tmp = that->XOR(a, b);
768  int new_x = that->XOR(tmp, c);
769  int new_y = that->OR(that->AND(a, b), that->AND(c, tmp));
770 #if 0
771  printf("FULLADD> a=%s, b=%s, c=%s, carry=%s, sum=%s\n", that->to_string(a).c_str(), that->to_string(b).c_str(),
772  that->to_string(c).c_str(), that->to_string(new_y).c_str(), that->to_string(new_x).c_str());
773 #endif
774  x = new_x, y = new_y;
775 }
776 
777 // 'y' is the MSB (carry) and x the LSB (sum) output
778 static void halfadder(ezSAT *that, int a, int b, int &y, int &x)
779 {
780  int new_x = that->XOR(a, b);
781  int new_y = that->AND(a, b);
782 #if 0
783  printf("HALFADD> a=%s, b=%s, carry=%s, sum=%s\n", that->to_string(a).c_str(), that->to_string(b).c_str(),
784  that->to_string(new_y).c_str(), that->to_string(new_x).c_str());
785 #endif
786  x = new_x, y = new_y;
787 }
788 
789 std::vector<int> ezSAT::vec_count(const std::vector<int> &vec, int numBits, bool clip)
790 {
791  std::vector<int> sum = vec_const_unsigned(0, numBits);
792  std::vector<int> carry_vector;
793 
794  for (auto bit : vec) {
795  int carry = bit;
796  for (int i = 0; i < numBits; i++)
797  halfadder(this, carry, sum[i], carry, sum[i]);
798  carry_vector.push_back(carry);
799  }
800 
801  if (clip) {
802  int overflow = vec_reduce_or(carry_vector);
803  sum = vec_ite(overflow, vec_const_unsigned(~0, numBits), sum);
804  }
805 
806 #if 0
807  printf("COUNT> vec=[");
808  for (int i = int(vec.size())-1; i >= 0; i--)
809  printf("%s%s", to_string(vec[i]).c_str(), i ? ", " : "");
810  printf("], result=[");
811  for (int i = int(sum.size())-1; i >= 0; i--)
812  printf("%s%s", to_string(sum[i]).c_str(), i ? ", " : "");
813  printf("]\n");
814 #endif
815 
816  return sum;
817 }
818 
819 std::vector<int> ezSAT::vec_add(const std::vector<int> &vec1, const std::vector<int> &vec2)
820 {
821  assert(vec1.size() == vec2.size());
822  std::vector<int> vec(vec1.size());
823  int carry = CONST_FALSE;
824  for (int i = 0; i < int(vec1.size()); i++)
825  fulladder(this, vec1[i], vec2[i], carry, carry, vec[i]);
826 
827 #if 0
828  printf("ADD> vec1=[");
829  for (int i = int(vec1.size())-1; i >= 0; i--)
830  printf("%s%s", to_string(vec1[i]).c_str(), i ? ", " : "");
831  printf("], vec2=[");
832  for (int i = int(vec2.size())-1; i >= 0; i--)
833  printf("%s%s", to_string(vec2[i]).c_str(), i ? ", " : "");
834  printf("], result=[");
835  for (int i = int(vec.size())-1; i >= 0; i--)
836  printf("%s%s", to_string(vec[i]).c_str(), i ? ", " : "");
837  printf("]\n");
838 #endif
839 
840  return vec;
841 }
842 
843 std::vector<int> ezSAT::vec_sub(const std::vector<int> &vec1, const std::vector<int> &vec2)
844 {
845  assert(vec1.size() == vec2.size());
846  std::vector<int> vec(vec1.size());
847  int carry = CONST_TRUE;
848  for (int i = 0; i < int(vec1.size()); i++)
849  fulladder(this, vec1[i], NOT(vec2[i]), carry, carry, vec[i]);
850 
851 #if 0
852  printf("SUB> vec1=[");
853  for (int i = int(vec1.size())-1; i >= 0; i--)
854  printf("%s%s", to_string(vec1[i]).c_str(), i ? ", " : "");
855  printf("], vec2=[");
856  for (int i = int(vec2.size())-1; i >= 0; i--)
857  printf("%s%s", to_string(vec2[i]).c_str(), i ? ", " : "");
858  printf("], result=[");
859  for (int i = int(vec.size())-1; i >= 0; i--)
860  printf("%s%s", to_string(vec[i]).c_str(), i ? ", " : "");
861  printf("]\n");
862 #endif
863 
864  return vec;
865 }
866 
867 std::vector<int> ezSAT::vec_neg(const std::vector<int> &vec)
868 {
869  std::vector<int> zero(vec.size(), CONST_FALSE);
870  return vec_sub(zero, vec);
871 }
872 
873 void ezSAT::vec_cmp(const std::vector<int> &vec1, const std::vector<int> &vec2, int &carry, int &overflow, int &sign, int &zero)
874 {
875  assert(vec1.size() == vec2.size());
876  carry = CONST_TRUE;
877  zero = CONST_FALSE;
878  for (int i = 0; i < int(vec1.size()); i++) {
879  overflow = carry;
880  fulladder(this, vec1[i], NOT(vec2[i]), carry, carry, sign);
881  zero = OR(zero, sign);
882  }
883  overflow = XOR(overflow, carry);
884  carry = NOT(carry);
885  zero = NOT(zero);
886 
887 #if 0
888  printf("CMP> vec1=[");
889  for (int i = int(vec1.size())-1; i >= 0; i--)
890  printf("%s%s", to_string(vec1[i]).c_str(), i ? ", " : "");
891  printf("], vec2=[");
892  for (int i = int(vec2.size())-1; i >= 0; i--)
893  printf("%s%s", to_string(vec2[i]).c_str(), i ? ", " : "");
894  printf("], carry=%s, overflow=%s, sign=%s, zero=%s\n", to_string(carry).c_str(), to_string(overflow).c_str(), to_string(sign).c_str(), to_string(zero).c_str());
895 #endif
896 }
897 
898 int ezSAT::vec_lt_signed(const std::vector<int> &vec1, const std::vector<int> &vec2)
899 {
900  int carry, overflow, sign, zero;
901  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
902  return OR(AND(NOT(overflow), sign), AND(overflow, NOT(sign)));
903 }
904 
905 int ezSAT::vec_le_signed(const std::vector<int> &vec1, const std::vector<int> &vec2)
906 {
907  int carry, overflow, sign, zero;
908  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
909  return OR(AND(NOT(overflow), sign), AND(overflow, NOT(sign)), zero);
910 }
911 
912 int ezSAT::vec_ge_signed(const std::vector<int> &vec1, const std::vector<int> &vec2)
913 {
914  int carry, overflow, sign, zero;
915  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
916  return OR(AND(NOT(overflow), NOT(sign)), AND(overflow, sign));
917 }
918 
919 int ezSAT::vec_gt_signed(const std::vector<int> &vec1, const std::vector<int> &vec2)
920 {
921  int carry, overflow, sign, zero;
922  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
923  return AND(OR(AND(NOT(overflow), NOT(sign)), AND(overflow, sign)), NOT(zero));
924 }
925 
926 int ezSAT::vec_lt_unsigned(const std::vector<int> &vec1, const std::vector<int> &vec2)
927 {
928  int carry, overflow, sign, zero;
929  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
930  return carry;
931 }
932 
933 int ezSAT::vec_le_unsigned(const std::vector<int> &vec1, const std::vector<int> &vec2)
934 {
935  int carry, overflow, sign, zero;
936  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
937  return OR(carry, zero);
938 }
939 
940 int ezSAT::vec_ge_unsigned(const std::vector<int> &vec1, const std::vector<int> &vec2)
941 {
942  int carry, overflow, sign, zero;
943  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
944  return NOT(carry);
945 }
946 
947 int ezSAT::vec_gt_unsigned(const std::vector<int> &vec1, const std::vector<int> &vec2)
948 {
949  int carry, overflow, sign, zero;
950  vec_cmp(vec1, vec2, carry, overflow, sign, zero);
951  return AND(NOT(carry), NOT(zero));
952 }
953 
954 int ezSAT::vec_eq(const std::vector<int> &vec1, const std::vector<int> &vec2)
955 {
956  return vec_reduce_and(vec_iff(vec1, vec2));
957 }
958 
959 int ezSAT::vec_ne(const std::vector<int> &vec1, const std::vector<int> &vec2)
960 {
961  return NOT(vec_reduce_and(vec_iff(vec1, vec2)));
962 }
963 
964 std::vector<int> ezSAT::vec_shl(const std::vector<int> &vec1, int shift, bool signExtend)
965 {
966  std::vector<int> vec;
967  for (int i = 0; i < int(vec1.size()); i++) {
968  int j = i-shift;
969  if (int(vec1.size()) <= j)
970  vec.push_back(signExtend ? vec1.back() : CONST_FALSE);
971  else if (0 <= j)
972  vec.push_back(vec1[j]);
973  else
974  vec.push_back(CONST_FALSE);
975  }
976  return vec;
977 }
978 
979 std::vector<int> ezSAT::vec_srl(const std::vector<int> &vec1, int shift)
980 {
981  std::vector<int> vec;
982  for (int i = 0; i < int(vec1.size()); i++) {
983  int j = i-shift;
984  while (j < 0)
985  j += vec1.size();
986  while (j >= int(vec1.size()))
987  j -= vec1.size();
988  vec.push_back(vec1[j]);
989  }
990  return vec;
991 }
992 
993 std::vector<int> ezSAT::vec_shift(const std::vector<int> &vec1, int shift, int extend_left, int extend_right)
994 {
995  std::vector<int> vec;
996  for (int i = 0; i < int(vec1.size()); i++) {
997  int j = i+shift;
998  if (j < 0)
999  vec.push_back(extend_right);
1000  else if (j >= int(vec1.size()))
1001  vec.push_back(extend_left);
1002  else
1003  vec.push_back(vec1[j]);
1004  }
1005  return vec;
1006 }
1007 
1008 static int my_clog2(int x)
1009 {
1010  int result = 0;
1011  for (x--; x > 0; result++)
1012  x >>= 1;
1013  return result;
1014 }
1015 
1016 std::vector<int> ezSAT::vec_shift_right(const std::vector<int> &vec1, const std::vector<int> &vec2, bool vec2_signed, int extend_left, int extend_right)
1017 {
1018  int vec2_bits = std::min(my_clog2(vec1.size()) + (vec2_signed ? 1 : 0), int(vec2.size()));
1019 
1020  std::vector<int> overflow_bits(vec2.begin() + vec2_bits, vec2.end());
1021  int overflow_left = CONST_FALSE, overflow_right = CONST_FALSE;
1022 
1023  if (vec2_signed) {
1024  int overflow = CONST_FALSE;
1025  for (auto bit : overflow_bits)
1026  overflow = OR(overflow, XOR(bit, vec2[vec2_bits-1]));
1027  overflow_left = AND(overflow, NOT(vec2.back()));
1028  overflow_right = AND(overflow, vec2.back());
1029  } else
1030  overflow_left = vec_reduce_or(overflow_bits);
1031 
1032  std::vector<int> buffer = vec1;
1033 
1034  if (vec2_signed)
1035  while (buffer.size() < vec1.size() + (1 << vec2_bits))
1036  buffer.push_back(extend_left);
1037 
1038  std::vector<int> overflow_pattern_left(buffer.size(), extend_left);
1039  std::vector<int> overflow_pattern_right(buffer.size(), extend_right);
1040 
1041  buffer = vec_ite(overflow_left, overflow_pattern_left, buffer);
1042 
1043  if (vec2_signed)
1044  buffer = vec_ite(overflow_right, overflow_pattern_left, buffer);
1045 
1046  for (int i = vec2_bits-1; i >= 0; i--) {
1047  std::vector<int> shifted_buffer;
1048  if (vec2_signed && i == vec2_bits-1)
1049  shifted_buffer = vec_shift(buffer, -(1 << i), extend_left, extend_right);
1050  else
1051  shifted_buffer = vec_shift(buffer, 1 << i, extend_left, extend_right);
1052  buffer = vec_ite(vec2[i], shifted_buffer, buffer);
1053  }
1054 
1055  buffer.resize(vec1.size());
1056  return buffer;
1057 }
1058 
1059 std::vector<int> ezSAT::vec_shift_left(const std::vector<int> &vec1, const std::vector<int> &vec2, bool vec2_signed, int extend_left, int extend_right)
1060 {
1061  // vec2_signed is not implemented in vec_shift_left() yet
1062  assert(vec2_signed == false);
1063 
1064  int vec2_bits = std::min(my_clog2(vec1.size()), int(vec2.size()));
1065 
1066  std::vector<int> overflow_bits(vec2.begin() + vec2_bits, vec2.end());
1067  int overflow = vec_reduce_or(overflow_bits);
1068 
1069  std::vector<int> buffer = vec1;
1070  std::vector<int> overflow_pattern_right(buffer.size(), extend_right);
1071  buffer = vec_ite(overflow, overflow_pattern_right, buffer);
1072 
1073  for (int i = 0; i < vec2_bits; i++) {
1074  std::vector<int> shifted_buffer;
1075  shifted_buffer = vec_shift(buffer, -(1 << i), extend_left, extend_right);
1076  buffer = vec_ite(vec2[i], shifted_buffer, buffer);
1077  }
1078 
1079  buffer.resize(vec1.size());
1080  return buffer;
1081 }
1082 
1083 void ezSAT::vec_append(std::vector<int> &vec, const std::vector<int> &vec1) const
1084 {
1085  for (auto bit : vec1)
1086  vec.push_back(bit);
1087 }
1088 
1089 void ezSAT::vec_append_signed(std::vector<int> &vec, const std::vector<int> &vec1, int64_t value)
1090 {
1091  assert(int(vec1.size()) <= 64);
1092  for (int i = 0; i < int(vec1.size()); i++) {
1093  if (((value >> i) & 1) != 0)
1094  vec.push_back(vec1[i]);
1095  else
1096  vec.push_back(NOT(vec1[i]));
1097  }
1098 }
1099 
1100 void ezSAT::vec_append_unsigned(std::vector<int> &vec, const std::vector<int> &vec1, uint64_t value)
1101 {
1102  assert(int(vec1.size()) <= 64);
1103  for (int i = 0; i < int(vec1.size()); i++) {
1104  if (((value >> i) & 1) != 0)
1105  vec.push_back(vec1[i]);
1106  else
1107  vec.push_back(NOT(vec1[i]));
1108  }
1109 }
1110 
1111 int64_t ezSAT::vec_model_get_signed(const std::vector<int> &modelExpressions, const std::vector<bool> &modelValues, const std::vector<int> &vec1) const
1112 {
1113  int64_t value = 0;
1114  std::map<int, bool> modelMap;
1115  assert(modelExpressions.size() == modelValues.size());
1116  for (int i = 0; i < int(modelExpressions.size()); i++)
1117  modelMap[modelExpressions[i]] = modelValues[i];
1118  for (int i = 0; i < 64; i++) {
1119  int j = i < int(vec1.size()) ? i : vec1.size()-1;
1120  if (modelMap.at(vec1[j]))
1121  value |= int64_t(1) << i;
1122  }
1123  return value;
1124 }
1125 
1126 uint64_t ezSAT::vec_model_get_unsigned(const std::vector<int> &modelExpressions, const std::vector<bool> &modelValues, const std::vector<int> &vec1) const
1127 {
1128  uint64_t value = 0;
1129  std::map<int, bool> modelMap;
1130  assert(modelExpressions.size() == modelValues.size());
1131  for (int i = 0; i < int(modelExpressions.size()); i++)
1132  modelMap[modelExpressions[i]] = modelValues[i];
1133  for (int i = 0; i < int(vec1.size()); i++)
1134  if (modelMap.at(vec1[i]))
1135  value |= uint64_t(1) << i;
1136  return value;
1137 }
1138 
1139 int ezSAT::vec_reduce_and(const std::vector<int> &vec1)
1140 {
1141  return expression(OpAnd, vec1);
1142 }
1143 
1144 int ezSAT::vec_reduce_or(const std::vector<int> &vec1)
1145 {
1146  return expression(OpOr, vec1);
1147 }
1148 
1149 void ezSAT::vec_set(const std::vector<int> &vec1, const std::vector<int> &vec2)
1150 {
1151  assert(vec1.size() == vec2.size());
1152  for (int i = 0; i < int(vec1.size()); i++)
1153  SET(vec1[i], vec2[i]);
1154 }
1155 
1156 void ezSAT::vec_set_signed(const std::vector<int> &vec1, int64_t value)
1157 {
1158  assert(int(vec1.size()) <= 64);
1159  for (int i = 0; i < int(vec1.size()); i++) {
1160  if (((value >> i) & 1) != 0)
1161  assume(vec1[i]);
1162  else
1163  assume(NOT(vec1[i]));
1164  }
1165 }
1166 
1167 void ezSAT::vec_set_unsigned(const std::vector<int> &vec1, uint64_t value)
1168 {
1169  assert(int(vec1.size()) <= 64);
1170  for (int i = 0; i < int(vec1.size()); i++) {
1171  if (((value >> i) & 1) != 0)
1172  assume(vec1[i]);
1173  else
1174  assume(NOT(vec1[i]));
1175  }
1176 }
1177 
1179 {
1180  return ezSATbit(*this, a);
1181 }
1182 
1183 ezSATvec ezSAT::vec(const std::vector<int> &vec)
1184 {
1185  return ezSATvec(*this, vec);
1186 }
1187 
1188 void ezSAT::printDIMACS(FILE *f, bool verbose) const
1189 {
1190  if (cnfConsumed) {
1191  fprintf(stderr, "Usage error: printDIMACS() must not be called after cnfConsumed()!");
1192  abort();
1193  }
1194 
1195  int digits = ceil(log10f(cnfVariableCount)) + 2;
1196 
1197  fprintf(f, "c generated by ezSAT\n");
1198 
1199  if (verbose)
1200  {
1201  fprintf(f, "c\n");
1202  fprintf(f, "c mapping of variables to literals:\n");
1203  for (int i = 0; i < int(cnfLiteralVariables.size()); i++)
1204  if (cnfLiteralVariables[i] != 0)
1205  fprintf(f, "c %*d: %s\n", digits, cnfLiteralVariables[i], literals[i].c_str());
1206 
1207  fprintf(f, "c\n");
1208  fprintf(f, "c mapping of variables to expressions:\n");
1209  for (int i = 0; i < int(cnfExpressionVariables.size()); i++)
1210  if (cnfExpressionVariables[i] != 0)
1211  fprintf(f, "c %*d: %d\n", digits, cnfExpressionVariables[i], -i-1);
1212 
1213  if (mode_keep_cnf()) {
1214  fprintf(f, "c\n");
1215  fprintf(f, "c %d clauses from backup, %d from current buffer\n",
1216  int(cnfClausesBackup.size()), int(cnfClauses.size()));
1217  }
1218 
1219  fprintf(f, "c\n");
1220  }
1221 
1222  std::vector<std::vector<int>> all_clauses;
1223  getFullCnf(all_clauses);
1224  assert(cnfClausesCount == int(all_clauses.size()));
1225 
1226  fprintf(f, "p cnf %d %d\n", cnfVariableCount, cnfClausesCount);
1227  int maxClauseLen = 0;
1228  for (auto &clause : all_clauses)
1229  maxClauseLen = std::max(int(clause.size()), maxClauseLen);
1230  if (!verbose)
1231  maxClauseLen = std::min(maxClauseLen, 3);
1232  for (auto &clause : all_clauses) {
1233  for (auto idx : clause)
1234  fprintf(f, " %*d", digits, idx);
1235  if (maxClauseLen >= int(clause.size()))
1236  fprintf(f, " %*d\n", (digits + 1)*int(maxClauseLen - clause.size()) + digits, 0);
1237  else
1238  fprintf(f, " %*d\n", digits, 0);
1239  }
1240 }
1241 
1242 static std::string expression2str(const std::pair<ezSAT::OpId, std::vector<int>> &data)
1243 {
1244  std::string text;
1245  switch (data.first) {
1246 #define X(op) case ezSAT::op: text += #op; break;
1247  X(OpNot)
1248  X(OpAnd)
1249  X(OpOr)
1250  X(OpXor)
1251  X(OpIFF)
1252  X(OpITE)
1253  default:
1254  abort();
1255 #undef X
1256  }
1257  text += ":";
1258  for (auto it : data.second)
1259  text += " " + my_int_to_string(it);
1260  return text;
1261 }
1262 
1263 void ezSAT::printInternalState(FILE *f) const
1264 {
1265  fprintf(f, "--8<-- snip --8<--\n");
1266 
1267  fprintf(f, "literalsCache:\n");
1268  for (auto &it : literalsCache)
1269  fprintf(f, " `%s' -> %d\n", it.first.c_str(), it.second);
1270 
1271  fprintf(f, "literals:\n");
1272  for (int i = 0; i < int(literals.size()); i++)
1273  fprintf(f, " %d: `%s'\n", i+1, literals[i].c_str());
1274 
1275  fprintf(f, "expressionsCache:\n");
1276  for (auto &it : expressionsCache)
1277  fprintf(f, " `%s' -> %d\n", expression2str(it.first).c_str(), it.second);
1278 
1279  fprintf(f, "expressions:\n");
1280  for (int i = 0; i < int(expressions.size()); i++)
1281  fprintf(f, " %d: `%s'\n", -i-1, expression2str(expressions[i]).c_str());
1282 
1283  fprintf(f, "cnfVariables (count=%d):\n", cnfVariableCount);
1284  for (int i = 0; i < int(cnfLiteralVariables.size()); i++)
1285  if (cnfLiteralVariables[i] != 0)
1286  fprintf(f, " literal %d -> %d (%s)\n", i+1, cnfLiteralVariables[i], to_string(i+1).c_str());
1287  for (int i = 0; i < int(cnfExpressionVariables.size()); i++)
1288  if (cnfExpressionVariables[i] != 0)
1289  fprintf(f, " expression %d -> %d (%s)\n", -i-1, cnfExpressionVariables[i], to_string(-i-1).c_str());
1290 
1291  fprintf(f, "cnfClauses:\n");
1292  for (auto &i1 : cnfClauses) {
1293  for (auto &i2 : i1)
1294  fprintf(f, " %4d", i2);
1295  fprintf(f, "\n");
1296  }
1297  if (cnfConsumed)
1298  fprintf(f, " *** more clauses consumed via cnfConsume() ***\n");
1299 
1300  fprintf(f, "--8<-- snap --8<--\n");
1301 }
1302 
1303 int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
1304 {
1305  // Mixed one-hot/binary encoding as described by Claessen in Sec. 4.2 of
1306  // "Successful SAT Encoding Techniques. Magnus Bjiirk. 25th July 2009".
1307  // http://jsat.ewi.tudelft.nl/addendum/Bjork_encoding.pdf
1308 
1309  std::vector<int> formula;
1310 
1311  // add at-leat-one constraint
1312  if (max_only == false)
1313  formula.push_back(expression(OpOr, vec));
1314 
1315  // create binary vector
1316  int num_bits = ceil(log2(vec.size()));
1317  std::vector<int> bits;
1318  for (int k = 0; k < num_bits; k++)
1319  bits.push_back(literal());
1320 
1321  // add at-most-one clauses using binary encoding
1322  for (size_t i = 0; i < vec.size(); i++)
1323  for (int k = 0; k < num_bits; k++) {
1324  std::vector<int> clause;
1325  clause.push_back(NOT(vec[i]));
1326  clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
1327  formula.push_back(expression(OpOr, clause));
1328  }
1329 
1330  return expression(OpAnd, formula);
1331 }
1332 
1333 int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
1334 {
1335  // many-hot encoding using a simple sorting network
1336 
1337  if (max_hot < 0)
1338  max_hot = min_hot;
1339 
1340  std::vector<int> formula;
1341  int M = max_hot+1, N = vec.size();
1342  std::map<std::pair<int,int>, int> x;
1343 
1344  for (int i = -1; i < N; i++)
1345  for (int j = -1; j < M; j++)
1346  x[std::pair<int,int>(i,j)] = j < 0 ? CONST_TRUE : i < 0 ? CONST_FALSE : literal();
1347 
1348  for (int i = 0; i < N; i++)
1349  for (int j = 0; j < M; j++) {
1350  formula.push_back(OR(NOT(vec[i]), x[std::pair<int,int>(i-1,j-1)], NOT(x[std::pair<int,int>(i,j)])));
1351  formula.push_back(OR(NOT(vec[i]), NOT(x[std::pair<int,int>(i-1,j-1)]), x[std::pair<int,int>(i,j)]));
1352  formula.push_back(OR(vec[i], x[std::pair<int,int>(i-1,j)], NOT(x[std::pair<int,int>(i,j)])));
1353  formula.push_back(OR(vec[i], NOT(x[std::pair<int,int>(i-1,j)]), x[std::pair<int,int>(i,j)]));
1354 #if 0
1355  // explicit resolution clauses -- in tests it was better to let the sat solver figure those out
1356  formula.push_back(OR(NOT(x[std::pair<int,int>(i-1,j-1)]), NOT(x[std::pair<int,int>(i-1,j)]), x[std::pair<int,int>(i,j)]));
1357  formula.push_back(OR(x[std::pair<int,int>(i-1,j-1)], x[std::pair<int,int>(i-1,j)], NOT(x[std::pair<int,int>(i,j)])));
1358 #endif
1359  }
1360 
1361  for (int j = 0; j < M; j++) {
1362  if (j+1 <= min_hot)
1363  formula.push_back(x[std::pair<int,int>(N-1,j)]);
1364  else if (j+1 > max_hot)
1365  formula.push_back(NOT(x[std::pair<int,int>(N-1,j)]));
1366  }
1367 
1368  return expression(OpAnd, formula);
1369 }
1370 
1371 int ezSAT::ordered(const std::vector<int> &vec1, const std::vector<int> &vec2, bool allow_equal)
1372 {
1373  std::vector<int> formula;
1374  int last_x = CONST_FALSE;
1375 
1376  assert(vec1.size() == vec2.size());
1377  for (size_t i = 0; i < vec1.size(); i++)
1378  {
1379  int a = vec1[i], b = vec2[i];
1380  formula.push_back(OR(NOT(a), b, last_x));
1381 
1382  int next_x = i+1 < vec1.size() ? literal() : allow_equal ? CONST_FALSE : CONST_TRUE;
1383  formula.push_back(OR(a, b, last_x, NOT(next_x)));
1384  formula.push_back(OR(NOT(a), NOT(b), last_x, NOT(next_x)));
1385  last_x = next_x;
1386  }
1387 
1388  return expression(OpAnd, formula);
1389 }
1390 
std::vector< int > vec_sub(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:843
const std::vector< std::vector< int > > & cnf() const
Definition: ezsat.h:168
std::vector< int > vec_const_signed(int64_t value, int numBits)
Definition: ezsat.cc:657
std::string cnfLiteralInfo(int idx) const
Definition: ezsat.cc:503
int vec_ge_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:912
void SET(_V a, _V b)
Definition: ezsat.h:221
int frozen_literal()
Definition: ezsat.cc:88
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:57
void lookup_expression(int id, OpId &op, std::vector< int > &args) const
Definition: ezsat.cc:218
OpId
Definition: ezsat.h:44
int parse_string(const std::string &text)
Definition: ezsat.cc:232
int solverTimeout
Definition: ezsat.h:80
std::vector< int > vec_var(int numBits)
Definition: ezsat.cc:673
virtual bool solver(const std::vector< int > &modelExpressions, std::vector< bool > &modelValues, const std::vector< int > &assumptions)
Definition: ezsat.cc:639
virtual bool eliminated(int idx)
Definition: ezsat.cc:383
static const int CONST_FALSE
Definition: ezsat.h:49
void vec_append_signed(std::vector< int > &vec, const std::vector< int > &vec1, int64_t value)
Definition: ezsat.cc:1089
std::vector< int > vec_iff(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:736
int cnfClausesCount
Definition: ezsat.h:64
int eval(int id, const std::vector< int > &values) const
Definition: ezsat.cc:293
int vec_le_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:905
static std::string idx(std::string str)
Definition: test_autotb.cc:57
void add_clause(const std::vector< int > &args)
Definition: ezsat.cc:430
int NOT(_V a)
Definition: ezsat.h:197
void vec_cmp(const std::vector< int > &vec1, const std::vector< int > &vec2, int &carry, int &overflow, int &sign, int &zero)
Definition: ezsat.cc:873
int vec_lt_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:926
bool mode_keep_cnf() const
Definition: ezsat.h:89
std::vector< int > vec_count(const std::vector< int > &vec, int numBits, bool clip=true)
Definition: ezsat.cc:789
std::vector< std::string > literals
Definition: ezsat.h:58
static std::string my_int_to_string(int i)
Definition: ezsat.cc:32
void vec_set(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:1149
std::vector< int > vec_shift(const std::vector< int > &vec1, int shift, int extend_left, int extend_right)
Definition: ezsat.cc:993
int value(bool val)
Definition: ezsat.cc:68
void assume(int id)
Definition: ezsat.cc:388
int ITE(_V a, _V b, _V c)
Definition: ezsat.h:217
std::vector< int > vec_shl(const std::vector< int > &vec1, int shift, bool signExtend=false)
Definition: ezsat.cc:964
std::vector< std::pair< OpId, std::vector< int > > > expressions
Definition: ezsat.h:61
void consumeCnf()
Definition: ezsat.cc:606
int AND(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
Definition: ezsat.h:201
std::vector< int > vec_or(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:718
void preSolverCallback()
Definition: ezsat.cc:632
int onehot(const std::vector< int > &vec, bool max_only=false)
Definition: ezsat.cc:1303
void vec_set_unsigned(const std::vector< int > &vec1, uint64_t value)
Definition: ezsat.cc:1167
bool sign(Lit p)
Definition: SolverTypes.h:66
std::vector< int > vec_srl(const std::vector< int > &vec1, int shift)
Definition: ezsat.cc:979
void lookup_literal(int id, std::string &name) const
Definition: ezsat.cc:206
std::vector< int > cnfLiteralVariables
Definition: ezsat.h:65
std::string to_string(int id) const
Definition: ezsat.cc:237
std::map< std::pair< OpId, std::vector< int > >, int > expressionsCache
Definition: ezsat.h:60
uint64_t vec_model_get_unsigned(const std::vector< int > &modelExpressions, const std::vector< bool > &modelValues, const std::vector< int > &vec1) const
Definition: ezsat.cc:1126
int vec_gt_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:947
std::vector< int > vec_neg(const std::vector< int > &vec)
Definition: ezsat.cc:867
std::vector< int > vec_const_unsigned(uint64_t value, int numBits)
Definition: ezsat.cc:665
void vec_append_unsigned(std::vector< int > &vec, const std::vector< int > &vec1, uint64_t value)
Definition: ezsat.cc:1100
int vec_ne(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:959
bool cnfConsumed
Definition: ezsat.h:63
std::vector< int > vec_shift_left(const std::vector< int > &vec1, const std::vector< int > &vec2, bool vec2_signed, int extend_left, int extend_right)
Definition: ezsat.cc:1059
int VAR(_V a)
Definition: ezsat.h:193
void printInternalState(FILE *f) const
Definition: ezsat.cc:1263
void printDIMACS(FILE *f, bool verbose=false) const
Definition: ezsat.cc:1188
static void halfadder(ezSAT *that, int a, int b, int &y, int &x)
Definition: ezsat.cc:778
static int my_clog2(int x)
Definition: ezsat.cc:1008
int bind_cnf_and(const std::vector< int > &args)
Definition: ezsat.cc:468
int64_t vec_model_get_signed(const std::vector< int > &modelExpressions, const std::vector< bool > &modelValues, const std::vector< int > &vec1) const
Definition: ezsat.cc:1111
std::vector< int > vec_shift_right(const std::vector< int > &vec1, const std::vector< int > &vec2, bool vec2_signed, int extend_left, int extend_right)
Definition: ezsat.cc:1016
int ordered(const std::vector< int > &vec1, const std::vector< int > &vec2, bool allow_equal=true)
Definition: ezsat.cc:1371
int vec_reduce_and(const std::vector< int > &vec1)
Definition: ezsat.cc:1139
std::vector< int > vec_cast(const std::vector< int > &vec1, int toBits, bool signExtend=false)
Definition: ezsat.cc:690
std::vector< int > vec_xor(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:727
int bound(int id) const
Definition: ezsat.cc:494
int vec_reduce_or(const std::vector< int > &vec1)
Definition: ezsat.cc:1144
int vec_gt_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:919
static std::string expression2str(const std::pair< ezSAT::OpId, std::vector< int >> &data)
Definition: ezsat.cc:1242
virtual void freeze(int id)
Definition: ezsat.cc:379
bool solverTimoutStatus
Definition: ezsat.h:81
int bind_cnf_not(const std::vector< int > &args)
Definition: ezsat.cc:462
static const int CONST_TRUE
Definition: ezsat.h:48
virtual ~ezSAT()
Definition: ezsat.cc:64
std::vector< int > vec_add(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:819
int cnfVariableCount
Definition: ezsat.h:64
int literal()
Definition: ezsat.cc:73
void getFullCnf(std::vector< std::vector< int >> &full_cnf) const
Definition: ezsat.cc:625
std::vector< int > vec_ite(const std::vector< int > &vec1, const std::vector< int > &vec2, const std::vector< int > &vec3)
Definition: ezsat.cc:745
int manyhot(const std::vector< int > &vec, int min_hot, int max_hot=-1)
Definition: ezsat.cc:1333
ezSAT()
Definition: ezsat.cc:43
virtual void clear()
Definition: ezsat.cc:369
int XOR(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
Definition: ezsat.h:209
int expression(OpId op, int a=0, int b=0, int c=0, int d=0, int e=0, int f=0)
Definition: ezsat.cc:102
int vec_eq(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:954
int vec_lt_signed(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:898
int OR(_V a=0, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
Definition: ezsat.h:205
bool flag_keep_cnf
Definition: ezsat.h:52
bool flag_non_incremental
Definition: ezsat.h:53
std::vector< int > vec_const(const std::vector< bool > &bits)
Definition: ezsat.cc:649
int bind_cnf_or(const std::vector< int > &args)
Definition: ezsat.cc:481
std::vector< std::vector< int > > cnfClauses
Definition: ezsat.h:66
std::string id(RTLIL::IdString internal_id, bool may_rename=true)
#define X(op)
std::map< std::string, int > literalsCache
Definition: ezsat.h:57
void vec_set_signed(const std::vector< int > &vec1, int64_t value)
Definition: ezsat.cc:1156
Definition: ezsat.h:30
int IFF(_V a, _V b=0, _V c=0, _V d=0, _V e=0, _V f=0)
Definition: ezsat.h:213
std::vector< std::vector< int > > cnfClausesBackup
Definition: ezsat.h:66
bool mode_non_incremental() const
Definition: ezsat.h:90
std::vector< int > vec_not(const std::vector< int > &vec1)
Definition: ezsat.cc:701
std::vector< int > cnfExpressionVariables
Definition: ezsat.h:65
int vec_ge_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:940
struct ezSATbit bit(_V a)
Definition: ezsat.cc:1178
bool non_incremental_solve_used_up
Definition: ezsat.h:55
void vec_append(std::vector< int > &vec, const std::vector< int > &vec1) const
Definition: ezsat.cc:1083
struct ezSATvec vec(const std::vector< int > &vec)
Definition: ezsat.cc:1183
int vec_le_unsigned(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:933
static void fulladder(ezSAT *that, int a, int b, int c, int &y, int &x)
Definition: ezsat.cc:765
int bind(int id, bool auto_freeze=true)
Definition: ezsat.cc:520
std::vector< int > vec_and(const std::vector< int > &vec1, const std::vector< int > &vec2)
Definition: ezsat.cc:709