GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bitblast/node_bitblaster.cpp Lines: 73 81 90.1 %
Date: 2021-09-29 Branches: 119 326 36.5 %

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
6268
NodeBitblaster::NodeBitblaster(Env& env, TheoryState* s)
26
6268
    : TBitblaster<Node>(), EnvObj(env), d_state(s)
27
{
28
6268
}
29
30
2466582
void NodeBitblaster::bbAtom(TNode node)
31
{
32
2466582
  node = node.getKind() == kind::NOT ? node[0] : node;
33
34
2466582
  if (hasBBAtom(node))
35
  {
36
2433324
    return;
37
  }
38
39
  /* Note: We rewrite here since it's not guaranteed (yet) that facts sent
40
   * to theories are rewritten.
41
   */
42
66516
  Node normalized = rewrite(node);
43
  Node atom_bb =
44
33258
      normalized.getKind() != kind::CONST_BOOLEAN
45
33209
              && normalized.getKind() != kind::BITVECTOR_BITOF
46
66467
          ? d_atomBBStrategies[normalized.getKind()](normalized, this)
47
99725
          : normalized;
48
49
33258
  storeBBAtom(node, rewrite(atom_bb));
50
}
51
52
33258
void NodeBitblaster::storeBBAtom(TNode atom, Node atom_bb)
53
{
54
33258
  d_bbAtoms.emplace(atom, atom_bb);
55
33258
}
56
57
55386
void NodeBitblaster::storeBBTerm(TNode node, const Bits& bits)
58
{
59
55386
  d_termCache.emplace(node, bits);
60
55386
}
61
62
4933288
bool NodeBitblaster::hasBBAtom(TNode lit) const
63
{
64
4933288
  if (lit.getKind() == kind::NOT)
65
  {
66
    lit = lit[0];
67
  }
68
4933288
  return d_bbAtoms.find(lit) != d_bbAtoms.end();
69
}
70
71
11032
void NodeBitblaster::makeVariable(TNode var, Bits& bits)
72
{
73
11032
  Assert(bits.size() == 0);
74
152634
  for (unsigned i = 0; i < utils::getSize(var); ++i)
75
  {
76
141602
    bits.push_back(utils::mkBitOf(var, i));
77
  }
78
11032
  d_variables.insert(var);
79
11032
}
80
81
Node NodeBitblaster::getBBAtom(TNode node) const { return node; }
82
83
158885
void NodeBitblaster::bbTerm(TNode node, Bits& bits)
84
{
85
158885
  Assert(node.getType().isBitVector());
86
158885
  if (hasBBTerm(node))
87
  {
88
103499
    getBBTerm(node, bits);
89
103499
    return;
90
  }
91
55386
  d_termBBStrategies[node.getKind()](node, bits, this);
92
55386
  Assert(bits.size() == utils::getSize(node));
93
55386
  storeBBTerm(node, bits);
94
}
95
96
2466606
Node NodeBitblaster::getStoredBBAtom(TNode node)
97
{
98
2466606
  bool negated = false;
99
2466606
  if (node.getKind() == kind::NOT)
100
  {
101
1142940
    node = node[0];
102
1142940
    negated = true;
103
  }
104
105
2466606
  Assert(hasBBAtom(node));
106
4933212
  Node atom_bb = d_bbAtoms.at(node);
107
4933212
  return negated ? atom_bb.negate() : atom_bb;
108
}
109
110
33
Node NodeBitblaster::getModelFromSatSolver(TNode a, bool fullModel)
111
{
112
33
  if (!hasBBTerm(a))
113
  {
114
    return utils::mkConst(utils::getSize(a), 0u);
115
  }
116
117
  bool assignment;
118
66
  Bits bits;
119
33
  getBBTerm(a, bits);
120
66
  Integer value(0);
121
66
  Integer one(1), zero(0);
122
457
  for (int i = bits.size() - 1; i >= 0; --i)
123
  {
124
848
    Integer bit;
125
424
    if (d_state->hasSatValue(bits[i], assignment))
126
    {
127
370
      bit = assignment ? one : zero;
128
    }
129
    else
130
    {
131
54
      bit = zero;
132
    }
133
424
    value = value * 2 + bit;
134
  }
135
33
  return utils::mkConst(bits.size(), value);
136
}
137
138
11
void NodeBitblaster::computeRelevantTerms(std::set<Node>& termSet)
139
{
140
11
  Assert(options().bv.bitblastMode == options::BitblastMode::EAGER);
141
36
  for (const auto& var : d_variables)
142
  {
143
25
    termSet.insert(var);
144
  }
145
11
}
146
147
49
bool NodeBitblaster::collectModelValues(TheoryModel* m,
148
                                        const std::set<Node>& relevantTerms)
149
{
150
507
  for (const auto& var : relevantTerms)
151
  {
152
458
    if (d_variables.find(var) == d_variables.end()) continue;
153
154
66
    Node const_value = getModelFromSatSolver(var, true);
155
33
    Assert(const_value.isNull() || const_value.isConst());
156
33
    if (!const_value.isNull())
157
    {
158
33
      if (!m->assertEquality(var, const_value, true))
159
      {
160
        return false;
161
      }
162
    }
163
  }
164
49
  return true;
165
}
166
167
211350
bool NodeBitblaster::isVariable(TNode node)
168
{
169
211350
  return d_variables.find(node) != d_variables.end();
170
}
171
172
Node NodeBitblaster::applyAtomBBStrategy(TNode node)
173
{
174
  Assert(node.getKind() != kind::CONST_BOOLEAN);
175
  Assert(node.getKind() != kind::BITVECTOR_BITOF);
176
  return d_atomBBStrategies[node.getKind()](node, this);
177
}
178
179
}  // namespace bv
180
}  // namespace theory
181
22746
}  // namespace cvc5