GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bitblast/node_bitblaster.cpp Lines: 72 76 94.7 %
Date: 2021-08-06 Branches: 118 296 39.9 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Mathias Preiner
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Bitblaster used to bitblast to Boolean Nodes.
14
 */
15
#include "theory/bv/bitblast/node_bitblaster.h"
16
17
#include "options/bv_options.h"
18
#include "theory/theory_model.h"
19
#include "theory/theory_state.h"
20
21
namespace cvc5 {
22
namespace theory {
23
namespace bv {
24
25
11417
NodeBitblaster::NodeBitblaster(TheoryState* s) : TBitblaster<Node>(), d_state(s)
26
{
27
11417
}
28
29
2535625
void NodeBitblaster::bbAtom(TNode node)
30
{
31
2535625
  node = node.getKind() == kind::NOT ? node[0] : node;
32
33
2535625
  if (hasBBAtom(node))
34
  {
35
2484492
    return;
36
  }
37
38
102266
  Node normalized = Rewriter::rewrite(node);
39
  Node atom_bb =
40
51133
      normalized.getKind() != kind::CONST_BOOLEAN
41
51079
              && normalized.getKind() != kind::BITVECTOR_BITOF
42
102212
          ? d_atomBBStrategies[normalized.getKind()](normalized, this)
43
153345
          : normalized;
44
45
51133
  storeBBAtom(node, Rewriter::rewrite(atom_bb));
46
}
47
48
51133
void NodeBitblaster::storeBBAtom(TNode atom, Node atom_bb)
49
{
50
51133
  d_bbAtoms.emplace(atom, atom_bb);
51
51133
}
52
53
91141
void NodeBitblaster::storeBBTerm(TNode node, const Bits& bits)
54
{
55
91141
  d_termCache.emplace(node, bits);
56
91141
}
57
58
6921583
bool NodeBitblaster::hasBBAtom(TNode lit) const
59
{
60
6921583
  if (lit.getKind() == kind::NOT)
61
  {
62
    lit = lit[0];
63
  }
64
6921583
  return d_bbAtoms.find(lit) != d_bbAtoms.end();
65
}
66
67
27809
void NodeBitblaster::makeVariable(TNode var, Bits& bits)
68
{
69
27809
  Assert(bits.size() == 0);
70
333920
  for (unsigned i = 0; i < utils::getSize(var); ++i)
71
  {
72
306111
    bits.push_back(utils::mkBitOf(var, i));
73
  }
74
27809
  d_variables.insert(var);
75
27809
}
76
77
Node NodeBitblaster::getBBAtom(TNode node) const { return node; }
78
79
281308
void NodeBitblaster::bbTerm(TNode node, Bits& bits)
80
{
81
281308
  Assert(node.getType().isBitVector());
82
281308
  if (hasBBTerm(node))
83
  {
84
190850
    getBBTerm(node, bits);
85
190850
    return;
86
  }
87
90458
  d_termBBStrategies[node.getKind()](node, bits, this);
88
90458
  Assert(bits.size() == utils::getSize(node));
89
90458
  storeBBTerm(node, bits);
90
}
91
92
3375301
Node NodeBitblaster::getStoredBBAtom(TNode node)
93
{
94
3375301
  bool negated = false;
95
3375301
  if (node.getKind() == kind::NOT)
96
  {
97
1154761
    node = node[0];
98
1154761
    negated = true;
99
  }
100
101
3375301
  Assert(hasBBAtom(node));
102
6750602
  Node atom_bb = d_bbAtoms.at(node);
103
6750602
  return negated ? atom_bb.negate() : atom_bb;
104
}
105
106
4348
Node NodeBitblaster::getModelFromSatSolver(TNode a, bool fullModel)
107
{
108
4348
  if (!hasBBTerm(a))
109
  {
110
    return utils::mkConst(utils::getSize(a), 0u);
111
  }
112
113
  bool assignment;
114
8696
  Bits bits;
115
4348
  getBBTerm(a, bits);
116
8696
  Integer value(0);
117
8696
  Integer one(1), zero(0);
118
46867
  for (int i = bits.size() - 1; i >= 0; --i)
119
  {
120
85038
    Integer bit;
121
42519
    if (d_state->hasSatValue(bits[i], assignment))
122
    {
123
37571
      bit = assignment ? one : zero;
124
    }
125
    else
126
    {
127
4948
      bit = zero;
128
    }
129
42519
    value = value * 2 + bit;
130
  }
131
4348
  return utils::mkConst(bits.size(), value);
132
}
133
134
11
void NodeBitblaster::computeRelevantTerms(std::set<Node>& termSet)
135
{
136
11
  Assert(options::bitblastMode() == options::BitblastMode::EAGER);
137
36
  for (const auto& var : d_variables)
138
  {
139
25
    termSet.insert(var);
140
  }
141
11
}
142
143
1633
bool NodeBitblaster::collectModelValues(TheoryModel* m,
144
                                        const std::set<Node>& relevantTerms)
145
{
146
275582
  for (const auto& var : relevantTerms)
147
  {
148
273949
    if (d_variables.find(var) == d_variables.end()) continue;
149
150
8696
    Node const_value = getModelFromSatSolver(var, true);
151
4348
    Assert(const_value.isNull() || const_value.isConst());
152
4348
    if (!const_value.isNull())
153
    {
154
4348
      if (!m->assertEquality(var, const_value, true))
155
      {
156
        return false;
157
      }
158
    }
159
  }
160
1633
  return true;
161
}
162
163
176976
bool NodeBitblaster::isVariable(TNode node)
164
{
165
176976
  return d_variables.find(node) != d_variables.end();
166
}
167
168
}  // namespace bv
169
}  // namespace theory
170
29322
}  // namespace cvc5