Skip to content

Commit 0e31a79

Browse files
author
Martin Blicha
committed
Logic: Rewrite mkAnd/mkOr to avoid term and memory allocations
1 parent bf06ecc commit 0e31a79

File tree

2 files changed

+40
-62
lines changed

2 files changed

+40
-62
lines changed

src/logics/Logic.cc

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@
2323

2424
using namespace std;
2525

26+
namespace {
27+
struct LessThanPTRefIgnoreNot {
28+
Logic & logic;
29+
LessThanPTRefIgnoreNot(Logic & logic) : logic{logic} {}
30+
bool operator() (PTRef first, PTRef second) {
31+
auto firstVal = logic.isNot(first) ? logic.getPterm(first)[0].x : first.x;
32+
auto secondVal = logic.isNot(second) ? logic.getPterm(second)[0].x : second.x;
33+
return firstVal < secondVal;
34+
}
35+
};
36+
}
37+
2638
/***********************************************************
2739
* Class defining logic
2840
***********************************************************/
@@ -430,89 +442,53 @@ Logic::mkIte(vec<PTRef>&& args)
430442
PTRef Logic::mkAnd(vec<PTRef>&& args) {
431443
if (args.size() == 0) { return getTerm_true(); }
432444
// Remove duplicates
433-
vec<PtAsgn> tmp_args;
434-
tmp_args.capacity(args.size());
435-
for (int i = 0; i < args.size(); i++) {
436-
if (!hasSortBool(args[i])) {
437-
return PTRef_Undef;
438-
}
439-
if (isNot(args[i])) {
440-
tmp_args.push(PtAsgn(getPterm(args[i])[0], l_False));
441-
} else {
442-
tmp_args.push(PtAsgn(args[i], l_True));
443-
}
444-
}
445-
std::sort(tmp_args.begin(), tmp_args.end(), LessThan_PtAsgn());
445+
sort(args, LessThanPTRefIgnoreNot(*this));
446446
int i, j;
447447
PtAsgn p = PtAsgn_Undef;
448-
for (i = 0, j = 0; i < tmp_args.size(); i++) {
449-
if (isFalse(tmp_args[i].tr)) {
450-
assert(tmp_args[i].sgn == l_True);
451-
return getTerm_false();
452-
} else if (isTrue(tmp_args[i].tr)) { // skip
453-
assert(tmp_args[i].sgn == l_True);
454-
} else if (p == tmp_args[i]) { // skip
455-
} else if (p.tr == tmp_args[i].tr && p.sgn != tmp_args[i].sgn) {
448+
for (i = 0, j = 0; i < args.size(); i++) {
449+
if (isFalse(args[i])) {
456450
return getTerm_false();
451+
} else if (isTrue(args[i])) { // skip
457452
} else {
458-
tmp_args[j++] = p = tmp_args[i];
453+
PtAsgn arg = toPtAsgn(args[i]);
454+
if (arg == p) { continue; }
455+
if (arg.tr == p.tr) { assert(arg.sgn != p.sgn); return getTerm_false(); }
456+
args[j++] = args[i];
457+
p = arg;
459458
}
460459
}
461-
tmp_args.shrink(i - j);
462-
if (tmp_args.size() == 0) {
460+
args.shrink(i - j);
461+
if (args.size() == 0) {
463462
return getTerm_true();
464-
} else if (tmp_args.size() == 1) {
465-
return tmp_args[0].sgn == l_True ? tmp_args[0].tr : mkNot(tmp_args[0].tr);
466-
}
467-
args.clear();
468-
args.capacity(tmp_args.size());
469-
for (PtAsgn tmp_arg : tmp_args) {
470-
args.push(tmp_arg.sgn == l_True ? tmp_arg.tr : mkNot(tmp_arg.tr));
463+
} else if (args.size() == 1) {
464+
return args[0];
471465
}
472466
return mkFun(getSym_and(), std::move(args));
473467
}
474468

475469
PTRef Logic::mkOr(vec<PTRef> && args) {
476470
if (args.size() == 0) { return getTerm_false(); }
477471
// Remove duplicates
478-
vec<PtAsgn> tmp_args;
479-
tmp_args.capacity(args.size());
480-
for (int i = 0; i < args.size(); i++) {
481-
if (!hasSortBool(args[i])) {
482-
return PTRef_Undef;
483-
}
484-
if (isNot(args[i])) {
485-
tmp_args.push(PtAsgn(getPterm(args[i])[0], l_False));
486-
} else {
487-
tmp_args.push(PtAsgn(args[i], l_True));
488-
}
489-
}
490-
std::sort(tmp_args.begin(), tmp_args.end(), LessThan_PtAsgn());
472+
sort(args, LessThanPTRefIgnoreNot(*this));
491473
int i, j;
492474
PtAsgn p = PtAsgn_Undef;
493-
for (i = 0, j = 0; i < tmp_args.size(); i++) {
494-
if (isTrue(tmp_args[i].tr)) {
495-
assert(tmp_args[i].sgn == l_True);
496-
return getTerm_true();
497-
} else if (isFalse(tmp_args[i].tr)) { // skip
498-
assert(tmp_args[i].sgn == l_True);
499-
} else if (p == tmp_args[i]) { // skip
500-
} else if (p.tr == tmp_args[i].tr && p.sgn != tmp_args[i].sgn) {
475+
for (i = 0, j = 0; i < args.size(); i++) {
476+
if (isTrue(args[i])) {
501477
return getTerm_true();
478+
} else if (isFalse(args[i])) { // skip
502479
} else {
503-
tmp_args[j++] = p = tmp_args[i];
480+
PtAsgn arg = toPtAsgn(args[i]);
481+
if (arg == p) { continue; }
482+
if (arg.tr == p.tr) { assert(arg.sgn != p.sgn); return getTerm_true(); }
483+
args[j++] = args[i];
484+
p = arg;
504485
}
505486
}
506-
tmp_args.shrink(i - j);
507-
if (tmp_args.size() == 0) {
487+
args.shrink(i - j);
488+
if (args.size() == 0) {
508489
return getTerm_false();
509-
} else if (tmp_args.size() == 1) {
510-
return tmp_args[0].sgn == l_True ? tmp_args[0].tr : mkNot(tmp_args[0].tr);
511-
}
512-
args.clear();
513-
args.capacity(tmp_args.size());
514-
for (PtAsgn tmp_arg : tmp_args) {
515-
args.push(tmp_arg.sgn == l_True ? tmp_arg.tr : mkNot(tmp_arg.tr));
490+
} else if (args.size() == 1) {
491+
return args[0];
516492
}
517493
return mkFun(getSym_or(), std::move(args));
518494
}

src/logics/Logic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ class Logic {
238238
bool isInternalSort(SRef) const;
239239
void newUninterpretedSortHandler(SRef);
240240

241+
PtAsgn toPtAsgn(PTRef ref) const { return isNot(ref) ? PtAsgn(getPterm(ref)[0], l_False) : PtAsgn(ref, l_True); }
242+
241243
public:
242244

243245
// General disequalities

0 commit comments

Comments
 (0)