GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/inference_manager.cpp Lines: 47 90 52.2 %
Date: 2021-08-01 Branches: 104 404 25.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Gereon Kremer, Aina Niemetz
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 sets.
14
 */
15
16
#include "theory/sets/inference_manager.h"
17
18
#include "options/sets_options.h"
19
#include "theory/rewriter.h"
20
21
using namespace std;
22
using namespace cvc5::kind;
23
24
namespace cvc5 {
25
namespace theory {
26
namespace sets {
27
28
9838
InferenceManager::InferenceManager(Theory& t,
29
                                   SolverState& s,
30
9838
                                   ProofNodeManager* pnm)
31
9838
    : InferenceManagerBuffered(t, s, pnm, "theory::sets::"), d_state(s)
32
{
33
9838
  d_true = NodeManager::currentNM()->mkConst(true);
34
9838
  d_false = NodeManager::currentNM()->mkConst(false);
35
9838
}
36
37
75683
bool InferenceManager::assertFactRec(Node fact, InferenceId id, Node exp, int inferType)
38
{
39
  // should we send this fact out as a lemma?
40
151366
  if ((options::setsInferAsLemmas() && inferType != -1) || inferType == 1)
41
  {
42
75683
    if (d_state.isEntailed(fact, true))
43
    {
44
58109
      return false;
45
    }
46
35148
    Node lem = fact;
47
17574
    if (exp != d_true)
48
    {
49
12682
      lem = NodeManager::currentNM()->mkNode(IMPLIES, exp, fact);
50
    }
51
17574
    addPendingLemma(lem, id);
52
17574
    return true;
53
  }
54
  Trace("sets-fact") << "Assert fact rec : " << fact << ", exp = " << exp
55
                     << std::endl;
56
  if (fact.isConst())
57
  {
58
    // either trivial or a conflict
59
    if (fact == d_false)
60
    {
61
      Trace("sets-lemma") << "Conflict : " << exp << std::endl;
62
      conflict(exp, id);
63
      return true;
64
    }
65
    return false;
66
  }
67
  else if (fact.getKind() == AND
68
           || (fact.getKind() == NOT && fact[0].getKind() == OR))
69
  {
70
    bool ret = false;
71
    Node f = fact.getKind() == NOT ? fact[0] : fact;
72
    for (unsigned i = 0; i < f.getNumChildren(); i++)
73
    {
74
      Node factc = fact.getKind() == NOT ? f[i].negate() : f[i];
75
      bool tret = assertFactRec(factc, id, exp, inferType);
76
      ret = ret || tret;
77
      if (d_state.isInConflict())
78
      {
79
        return true;
80
      }
81
    }
82
    return ret;
83
  }
84
  bool polarity = fact.getKind() != NOT;
85
  TNode atom = polarity ? fact : fact[0];
86
  if (d_state.isEntailed(atom, polarity))
87
  {
88
    return false;
89
  }
90
  // things we can assert to equality engine
91
  if (atom.getKind() == MEMBER
92
      || (atom.getKind() == EQUAL && atom[0].getType().isSet()))
93
  {
94
    // send to equality engine
95
    if (assertSetsFact(atom, polarity, id, exp))
96
    {
97
      // return true if this wasn't redundant
98
      return true;
99
    }
100
  }
101
  else
102
  {
103
    // must send as lemma
104
    Node lem = fact;
105
    if (exp != d_true)
106
    {
107
      lem = NodeManager::currentNM()->mkNode(IMPLIES, exp, fact);
108
    }
109
    addPendingLemma(lem, id);
110
    return true;
111
  }
112
  return false;
113
}
114
115
14267
bool InferenceManager::assertSetsFact(Node atom,
116
                                      bool polarity,
117
                                      InferenceId id,
118
                                      Node exp)
119
{
120
28534
  Node conc = polarity ? atom : atom.notNode();
121
57068
  return assertInternalFact(
122
57068
      atom, polarity, id, PfRule::THEORY_INFERENCE, {exp}, {conc});
123
}
124
125
75683
void InferenceManager::assertInference(Node fact,
126
                                       InferenceId id,
127
                                       Node exp,
128
                                       int inferType)
129
{
130
75683
  if (assertFactRec(fact, id, exp, inferType))
131
  {
132
35148
    Trace("sets-lemma") << "Sets::Lemma : " << fact << " from " << exp << " by "
133
17574
                        << id << std::endl;
134
35148
    Trace("sets-assertion") << "(assert (=> " << exp << " " << fact
135
17574
                            << ")) ; by " << id << std::endl;
136
  }
137
75683
}
138
139
63080
void InferenceManager::assertInference(Node fact,
140
                                       InferenceId id,
141
                                       std::vector<Node>& exp,
142
                                       int inferType)
143
{
144
63080
  Node exp_n = exp.empty() ? d_true
145
59661
                           : (exp.size() == 1
146
2668
                                  ? exp[0]
147
188489
                                  : NodeManager::currentNM()->mkNode(AND, exp));
148
63080
  assertInference(fact, id, exp_n, inferType);
149
63080
}
150
151
5422
void InferenceManager::assertInference(std::vector<Node>& conc,
152
                                       InferenceId id,
153
                                       Node exp,
154
                                       int inferType)
155
{
156
5422
  if (!conc.empty())
157
  {
158
829
    Node fact = conc.size() == 1 ? conc[0]
159
1268
                                 : NodeManager::currentNM()->mkNode(AND, conc);
160
439
    assertInference(fact, id, exp, inferType);
161
  }
162
5422
}
163
void InferenceManager::assertInference(std::vector<Node>& conc,
164
                                       InferenceId id,
165
                                       std::vector<Node>& exp,
166
                                       int inferType)
167
{
168
  Node exp_n = exp.empty() ? d_true
169
                           : (exp.size() == 1
170
                                  ? exp[0]
171
                                  : NodeManager::currentNM()->mkNode(AND, exp));
172
  assertInference(conc, id, exp_n, inferType);
173
}
174
175
393
void InferenceManager::split(Node n, InferenceId id, int reqPol)
176
{
177
393
  n = Rewriter::rewrite(n);
178
786
  Node lem = NodeManager::currentNM()->mkNode(OR, n, n.negate());
179
  // send the lemma
180
393
  lemma(lem, id);
181
393
  Trace("sets-lemma") << "Sets::Lemma split : " << lem << std::endl;
182
393
  if (reqPol != 0)
183
  {
184
    Trace("sets-lemma") << "Sets::Require phase " << n << " " << (reqPol > 0)
185
                        << std::endl;
186
    requirePhase(n, reqPol > 0);
187
  }
188
393
}
189
190
}  // namespace sets
191
}  // namespace theory
192
104963
}  // namespace cvc5