Improve SMT2 encoding of $reduce_{and,or,bool}
authorClifford Wolf <clifford@clifford.at>
Sun, 4 Mar 2018 20:22:20 +0000 (21:22 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 4 Mar 2018 20:22:20 +0000 (21:22 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
backends/smt2/smt2.cc

index 124364120007a329b6b558a52937795d280f5ab9..47c993d059736f0df90a5403c9ea83be0b932495 100644 (file)
@@ -379,7 +379,8 @@ struct Smt2Worker
 
                if (type == 's' || type == 'd' || type == 'b') {
                        width = max(width, GetSize(cell->getPort("\\A")));
-                       width = max(width, GetSize(cell->getPort("\\B")));
+                       if (cell->hasPort("\\B"))
+                               width = max(width, GetSize(cell->getPort("\\B")));
                }
 
                if (cell->hasPort("\\A")) {
@@ -561,6 +562,13 @@ struct Smt2Worker
                        if (cell->type == "$div") return export_bvop(cell, "(bvUdiv A B)", 'd');
                        if (cell->type == "$mod") return export_bvop(cell, "(bvUrem A B)", 'd');
 
+                       if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool") &&
+                                       2*GetSize(cell->getPort("\\A").chunks()) < GetSize(cell->getPort("\\A"))) {
+                               bool is_and = cell->type == "$reduce_and";
+                               string bits(GetSize(cell->getPort("\\A")), is_and ? '1' : '0');
+                               return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits.c_str()), 'b');
+                       }
+
                        if (cell->type == "$reduce_and") return export_reduce(cell, "(and A)", true);
                        if (cell->type == "$reduce_or") return export_reduce(cell, "(or A)", false);
                        if (cell->type == "$reduce_xor") return export_reduce(cell, "(xor A)", false);