GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bitblast/node_bitblaster.cpp Lines: 73 77 94.8 %
Date: 2021-09-13 Branches: 119 292 40.8 %

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
11475
NodeBitblaster::NodeBitblaster(Env& env, TheoryState* s)
26
11475
    : TBitblaster<Node>(), EnvObj(env), d_state(s)
27
{
28
11475
}
29
30
2537132
void NodeBitblaster::bbAtom(TNode node)
31
{
32
2537132
  node = node.getKind() == kind::NOT ? node[0] : node;
33
34
2537132
  if (hasBBAtom(node))
35
  {
36
2486021
    return;
37
  }
38
39
102222
  Node normalized = rewrite(node);
40
  Node atom_bb =
41
51111
      normalized.getKind() != kind::CONST_BOOLEAN
42
51057
              && normalized.getKind() != kind::BITVECTOR_BITOF
43
102168
          ? d_atomBBStrategies[normalized.getKind()](normalized, this)
44
153279
          : normalized;
45
46
51111
  storeBBAtom(node, rewrite(atom_bb));
47
}
48
49
51111
void NodeBitblaster::storeBBAtom(TNode atom, Node atom_bb)
50
{
51
51111
  d_bbAtoms.emplace(atom, atom_bb);
52
51111
}
53
54
91041
void NodeBitblaster::storeBBTerm(TNode node, const Bits& bits)
55
{
56
91041
  d_termCache.emplace(node, bits);
57
91041
}
58
59
7011150
bool NodeBitblaster::hasBBAtom(TNode lit) const
60
{
61
7011150
  if (lit.getKind() == kind::NOT)
62
  {
63
    lit = lit[0];
64
  }
65
7011150
  return d_bbAtoms.find(lit) != d_bbAtoms.end();
66
}
67
68
27756
void NodeBitblaster::makeVariable(TNode var, Bits& bits)
69
{
70
27756
  Assert(bits.size() == 0);
71
332766
  for (unsigned i = 0; i < utils::getSize(var); ++i)
72
  {
73
305010
    bits.push_back(utils::mkBitOf(var, i));
74
  }
75
27756
  d_variables.insert(var);
76
27756
}
77
78
Node NodeBitblaster::getBBAtom(TNode node) const { return node; }
79
80
280941
void NodeBitblaster::bbTerm(TNode node, Bits& bits)
81
{
82
280941
  Assert(node.getType().isBitVector());
83
280941
  if (hasBBTerm(node))
84
  {
85
190583
    getBBTerm(node, bits);
86
190583
    return;
87
  }
88
90358
  d_termBBStrategies[node.getKind()](node, bits, this);
89
90358
  Assert(bits.size() == utils::getSize(node));
90
90358
  storeBBTerm(node, bits);
91
}
92
93
3420114
Node NodeBitblaster::getStoredBBAtom(TNode node)
94
{
95
3420114
  bool negated = false;
96
3420114
  if (node.getKind() == kind::NOT)
97
  {
98
1155372
    node = node[0];
99
1155372
    negated = true;
100
  }
101
102
3420114
  Assert(hasBBAtom(node));
103
6840228
  Node atom_bb = d_bbAtoms.at(node);
104
6840228
  return negated ? atom_bb.negate() : atom_bb;
105
}
106
107
4348
Node NodeBitblaster::getModelFromSatSolver(TNode a, bool fullModel)
108
{
109
4348
  if (!hasBBTerm(a))
110
  {
111
    return utils::mkConst(utils::getSize(a), 0u);
112
  }
113
114
  bool assignment;
115
8696
  Bits bits;
116
4348
  getBBTerm(a, bits);
117
8696
  Integer value(0);
118
8696
  Integer one(1), zero(0);
119
46867
  for (int i = bits.size() - 1; i >= 0; --i)
120
  {
121
85038
    Integer bit;
122
42519
    if (d_state->hasSatValue(bits[i], assignment))
123
    {
124
37571
      bit = assignment ? one : zero;
125
    }
126
    else
127
    {
128
4948
      bit = zero;
129
    }
130
42519
    value = value * 2 + bit;
131
  }
132
4348
  return utils::mkConst(bits.size(), value);
133
}
134
135
11
void NodeBitblaster::computeRelevantTerms(std::set<Node>& termSet)
136
{
137
11
  Assert(options().bv.bitblastMode == options::BitblastMode::EAGER);
138
36
  for (const auto& var : d_variables)
139
  {
140
25
    termSet.insert(var);
141
  }
142
11
}
143
144
1620
bool NodeBitblaster::collectModelValues(TheoryModel* m,
145
                                        const std::set<Node>& relevantTerms)
146
{
147
275569
  for (const auto& var : relevantTerms)
148
  {
149
273949
    if (d_variables.find(var) == d_variables.end()) continue;
150
151
8696
    Node const_value = getModelFromSatSolver(var, true);
152
4348
    Assert(const_value.isNull() || const_value.isConst());
153
4348
    if (!const_value.isNull())
154
    {
155
4348
      if (!m->assertEquality(var, const_value, true))
156
      {
157
        return false;
158
      }
159
    }
160
  }
161
1620
  return true;
162
}
163
164
186570
bool NodeBitblaster::isVariable(TNode node)
165
{
166
186570
  return d_variables.find(node) != d_variables.end();
167
}
168
169
}  // namespace bv
170
}  // namespace theory
171
29514
}  // namespace cvc5