GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bv_solver_simple.cpp Lines: 52 60 86.7 %
Date: 2021-05-22 Branches: 88 184 47.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Mathias Preiner, Gereon Kremer, Haniel Barbosa
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
 * Simple bit-blast solver that sends bitblast lemmas directly to MiniSat.
14
 */
15
16
#include "theory/bv/bv_solver_simple.h"
17
18
#include "expr/term_conversion_proof_generator.h"
19
#include "theory/bv/theory_bv.h"
20
#include "theory/bv/theory_bv_utils.h"
21
#include "theory/theory_model.h"
22
23
namespace cvc5 {
24
namespace theory {
25
namespace bv {
26
27
/* -------------------------------------------------------------------------- */
28
29
namespace {
30
31
868
bool isBVAtom(TNode n)
32
{
33
1844
  return (n.getKind() == kind::EQUAL && n[0].getType().isBitVector())
34
760
         || n.getKind() == kind::BITVECTOR_ULT
35
752
         || n.getKind() == kind::BITVECTOR_ULE
36
752
         || n.getKind() == kind::BITVECTOR_SLT
37
3356
         || n.getKind() == kind::BITVECTOR_SLE;
38
}
39
40
/* Traverse Boolean nodes and collect BV atoms. */
41
2
void collectBVAtoms(TNode n, std::unordered_set<Node>& atoms)
42
{
43
4
  std::vector<TNode> visit;
44
4
  std::unordered_set<TNode> visited;
45
46
2
  visit.push_back(n);
47
48
4
  do
49
  {
50
12
    TNode cur = visit.back();
51
6
    visit.pop_back();
52
53
6
    if (visited.find(cur) != visited.end() || !cur.getType().isBoolean())
54
      continue;
55
56
6
    visited.insert(cur);
57
6
    if (isBVAtom(cur))
58
    {
59
      atoms.insert(cur);
60
      continue;
61
    }
62
63
6
    visit.insert(visit.end(), cur.begin(), cur.end());
64
6
  } while (!visit.empty());
65
2
}
66
67
}  // namespace
68
69
15
BVSolverSimple::BVSolverSimple(TheoryState* s,
70
                               TheoryInferenceManager& inferMgr,
71
15
                               ProofNodeManager* pnm)
72
    : BVSolver(*s, inferMgr),
73
      d_tcpg(pnm ? new TConvProofGenerator(
74
                 pnm,
75
                 nullptr,
76
                 /* ONCE to visit each term only once, post-order.  FIXPOINT
77
                  * could lead to infinite loops due to terms being rewritten
78
                  * to terms that contain themselves */
79
                 TConvPolicy::ONCE,
80
                 /* STATIC to get the same ProofNode for a shared subterm. */
81
                 TConvCachePolicy::STATIC,
82
                 "BVSolverSimple::TConvProofGenerator",
83
                 nullptr,
84
1
                 false)
85
                 : nullptr),
86
16
      d_bitblaster(new BBProof(s, pnm, d_tcpg.get()))
87
{
88
15
}
89
90
116
void BVSolverSimple::addBBLemma(TNode fact)
91
{
92
116
  if (!d_bitblaster->hasBBAtom(fact))
93
  {
94
68
    d_bitblaster->bbAtom(fact);
95
  }
96
116
  NodeManager* nm = NodeManager::currentNM();
97
98
232
  Node atom_bb = d_bitblaster->getStoredBBAtom(fact);
99
232
  Node lemma = nm->mkNode(kind::EQUAL, fact, atom_bb);
100
101
116
  if (d_tcpg == nullptr)
102
  {
103
116
    d_im.lemma(lemma, InferenceId::BV_SIMPLE_BITBLAST_LEMMA);
104
  }
105
  else
106
  {
107
    TrustNode tlem = TrustNode::mkTrustLemma(lemma, d_tcpg.get());
108
    d_im.trustedLemma(tlem, InferenceId::BV_SIMPLE_BITBLAST_LEMMA);
109
  }
110
116
}
111
112
862
bool BVSolverSimple::preNotifyFact(
113
    TNode atom, bool pol, TNode fact, bool isPrereg, bool isInternal)
114
{
115
862
  if (fact.getKind() == kind::NOT)
116
  {
117
774
    fact = fact[0];
118
  }
119
120
862
  if (isBVAtom(fact))
121
  {
122
116
    addBBLemma(fact);
123
  }
124
746
  else if (fact.getKind() == kind::BITVECTOR_EAGER_ATOM)
125
  {
126
4
    TNode n = fact[0];
127
128
2
    NodeManager* nm = NodeManager::currentNM();
129
4
    Node lemma = nm->mkNode(kind::EQUAL, fact, n);
130
131
2
    if (d_tcpg == nullptr)
132
    {
133
2
      d_im.lemma(lemma, InferenceId::BV_SIMPLE_LEMMA);
134
    }
135
    else
136
    {
137
      TrustNode tlem = TrustNode::mkTrustLemma(lemma, d_tcpg.get());
138
      d_im.trustedLemma(tlem, InferenceId::BV_SIMPLE_LEMMA);
139
    }
140
141
4
    std::unordered_set<Node> bv_atoms;
142
2
    collectBVAtoms(n, bv_atoms);
143
2
    for (const Node& nn : bv_atoms)
144
    {
145
      addBBLemma(nn);
146
    }
147
  }
148
149
862
  return true;
150
}
151
152
7
bool BVSolverSimple::collectModelValues(TheoryModel* m,
153
                                        const std::set<Node>& termSet)
154
{
155
7
  return d_bitblaster->collectModelValues(m, termSet);
156
}
157
158
3
BVProofRuleChecker* BVSolverSimple::getProofChecker() { return &d_checker; }
159
160
}  // namespace bv
161
}  // namespace theory
162
28191
}  // namespace cvc5