GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/inference_manager.cpp Lines: 56 73 76.7 %
Date: 2021-09-15 Branches: 59 172 34.3 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Gereon Kremer, Makai Mann, 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
 * Implementation of the inference manager for the theory of strings.
14
 */
15
16
#include "theory/arith/inference_manager.h"
17
18
#include "options/arith_options.h"
19
#include "theory/arith/arith_state.h"
20
#include "theory/arith/theory_arith.h"
21
#include "theory/rewriter.h"
22
23
namespace cvc5 {
24
namespace theory {
25
namespace arith {
26
27
9942
InferenceManager::InferenceManager(Env& env,
28
                                   TheoryArith& ta,
29
                                   ArithState& astate,
30
9942
                                   ProofNodeManager* pnm)
31
    : InferenceManagerBuffered(env, ta, astate, pnm, "theory::arith::"),
32
      // currently must track propagated literals if using the equality solver
33
9942
      d_trackPropLits(options().arith.arithEqSolver),
34
19884
      d_propLits(context())
35
{
36
9942
}
37
38
12578
void InferenceManager::addPendingLemma(std::unique_ptr<SimpleTheoryLemma> lemma,
39
                                       bool isWaiting)
40
{
41
25156
  Trace("arith::infman") << "Add " << lemma->getId() << " " << lemma->d_node
42
12578
                         << (isWaiting ? " as waiting" : "") << std::endl;
43
12578
  if (hasCachedLemma(lemma->d_node, lemma->d_property))
44
  {
45
182
    return;
46
  }
47
12396
  if (isEntailedFalse(*lemma))
48
  {
49
    if (isWaiting)
50
    {
51
      d_waitingLem.clear();
52
    }
53
    else
54
    {
55
      d_pendingLem.clear();
56
      d_theoryState.notifyInConflict();
57
    }
58
  }
59
12396
  if (isWaiting)
60
  {
61
4071
    d_waitingLem.emplace_back(std::move(lemma));
62
  }
63
  else
64
  {
65
8325
    d_pendingLem.emplace_back(std::move(lemma));
66
  }
67
}
68
3350
void InferenceManager::addPendingLemma(const SimpleTheoryLemma& lemma,
69
                                       bool isWaiting)
70
{
71
6700
  addPendingLemma(
72
6700
      std::unique_ptr<SimpleTheoryLemma>(new SimpleTheoryLemma(lemma)),
73
      isWaiting);
74
3350
}
75
9228
void InferenceManager::addPendingLemma(const Node& lemma,
76
                                       InferenceId inftype,
77
                                       ProofGenerator* pg,
78
                                       bool isWaiting,
79
                                       LemmaProperty p)
80
{
81
18456
  addPendingLemma(std::unique_ptr<SimpleTheoryLemma>(
82
9228
                      new SimpleTheoryLemma(inftype, lemma, p, pg)),
83
                  isWaiting);
84
9228
}
85
86
827
void InferenceManager::flushWaitingLemmas()
87
{
88
1917
  for (auto& lem : d_waitingLem)
89
  {
90
2180
    Trace("arith::infman") << "Flush waiting lemma to pending: "
91
2180
                           << lem->getId() << " " << lem->d_node
92
1090
                           << std::endl;
93
1090
    d_pendingLem.emplace_back(std::move(lem));
94
  }
95
827
  d_waitingLem.clear();
96
827
}
97
4144
void InferenceManager::clearWaitingLemmas()
98
{
99
4144
  d_waitingLem.clear();
100
4144
}
101
102
3723
bool InferenceManager::hasUsed() const
103
{
104
3723
  return hasSent() || hasPending();
105
}
106
107
337
bool InferenceManager::hasWaitingLemma() const
108
{
109
337
  return !d_waitingLem.empty();
110
}
111
112
5686
std::size_t InferenceManager::numWaitingLemmas() const
113
{
114
5686
  return d_waitingLem.size();
115
}
116
117
12578
bool InferenceManager::hasCachedLemma(TNode lem, LemmaProperty p)
118
{
119
25156
  Node rewritten = Rewriter::rewrite(lem);
120
25156
  return TheoryInferenceManager::hasCachedLemma(rewritten, p);
121
}
122
123
181264
bool InferenceManager::cacheLemma(TNode lem, LemmaProperty p)
124
{
125
362528
  Node rewritten = Rewriter::rewrite(lem);
126
362528
  return TheoryInferenceManager::cacheLemma(rewritten, p);
127
}
128
129
12396
bool InferenceManager::isEntailedFalse(const SimpleTheoryLemma& lem)
130
{
131
12396
  if (options().arith.nlExtEntailConflicts)
132
  {
133
    Node ch_lemma = lem.d_node.negate();
134
    ch_lemma = Rewriter::rewrite(ch_lemma);
135
    Trace("arith-inf-manager") << "InferenceManager::Check entailment of "
136
                               << ch_lemma << "..." << std::endl;
137
138
    std::pair<bool, Node> et = d_theory.getValuation().entailmentCheck(
139
        options::TheoryOfMode::THEORY_OF_TYPE_BASED, ch_lemma);
140
    Trace("arith-inf-manager") << "entailment test result : " << et.first << " "
141
                               << et.second << std::endl;
142
    if (et.first)
143
    {
144
      Trace("arith-inf-manager")
145
          << "*** Lemma entailed to be in conflict : " << lem.d_node
146
          << std::endl;
147
      return true;
148
    }
149
  }
150
12396
  return false;
151
}
152
153
1580807
bool InferenceManager::propagateLit(TNode lit)
154
{
155
1580807
  if (d_trackPropLits)
156
  {
157
640
    d_propLits.insert(lit);
158
  }
159
1580807
  return TheoryInferenceManager::propagateLit(lit);
160
}
161
162
186
bool InferenceManager::hasPropagated(TNode lit) const
163
{
164
186
  Assert(d_trackPropLits);
165
186
  return d_propLits.find(lit) != d_propLits.end();
166
}
167
168
}  // namespace arith
169
}  // namespace theory
170
29577
}  // namespace cvc5