GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/inference_manager.cpp Lines: 49 89 55.1 %
Date: 2021-11-07 Branches: 112 396 28.3 %

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
15273
InferenceManager::InferenceManager(Env& env, Theory& t, SolverState& s)
29
15273
    : InferenceManagerBuffered(env, t, s, "theory::sets::"), d_state(s)
30
{
31
15273
  d_true = NodeManager::currentNM()->mkConst(true);
32
15273
  d_false = NodeManager::currentNM()->mkConst(false);
33
15273
}
34
35
179551
bool InferenceManager::assertFactRec(Node fact, InferenceId id, Node exp, int inferType)
36
{
37
  // should we send this fact out as a lemma?
38
179551
  if ((options().sets.setsInferAsLemmas && inferType != -1) || inferType == 1)
39
  {
40
179551
    if (d_state.isEntailed(fact, true))
41
    {
42
154847
      return false;
43
    }
44
49408
    Node lem = fact;
45
24704
    if (exp != d_true)
46
    {
47
19309
      lem = NodeManager::currentNM()->mkNode(IMPLIES, exp, fact);
48
    }
49
24704
    addPendingLemma(lem, id);
50
24704
    return true;
51
  }
52
  Trace("sets-fact") << "Assert fact rec : " << fact << ", exp = " << exp
53
                     << std::endl;
54
  if (fact.isConst())
55
  {
56
    // either trivial or a conflict
57
    if (fact == d_false)
58
    {
59
      Trace("sets-lemma") << "Conflict : " << exp << std::endl;
60
      conflict(exp, id);
61
      return true;
62
    }
63
    return false;
64
  }
65
  else if (fact.getKind() == AND
66
           || (fact.getKind() == NOT && fact[0].getKind() == OR))
67
  {
68
    bool ret = false;
69
    Node f = fact.getKind() == NOT ? fact[0] : fact;
70
    for (unsigned i = 0; i < f.getNumChildren(); i++)
71
    {
72
      Node factc = fact.getKind() == NOT ? f[i].negate() : f[i];
73
      bool tret = assertFactRec(factc, id, exp, inferType);
74
      ret = ret || tret;
75
      if (d_state.isInConflict())
76
      {
77
        return true;
78
      }
79
    }
80
    return ret;
81
  }
82
  bool polarity = fact.getKind() != NOT;
83
  TNode atom = polarity ? fact : fact[0];
84
  if (d_state.isEntailed(atom, polarity))
85
  {
86
    return false;
87
  }
88
  // things we can assert to equality engine
89
  if (atom.getKind() == MEMBER
90
      || (atom.getKind() == EQUAL && atom[0].getType().isSet()))
91
  {
92
    // send to equality engine
93
    if (assertSetsFact(atom, polarity, id, exp))
94
    {
95
      // return true if this wasn't redundant
96
      return true;
97
    }
98
  }
99
  else
100
  {
101
    // must send as lemma
102
    Node lem = fact;
103
    if (exp != d_true)
104
    {
105
      lem = NodeManager::currentNM()->mkNode(IMPLIES, exp, fact);
106
    }
107
    addPendingLemma(lem, id);
108
    return true;
109
  }
110
  return false;
111
}
112
113
16926
bool InferenceManager::assertSetsFact(Node atom,
114
                                      bool polarity,
115
                                      InferenceId id,
116
                                      Node exp)
117
{
118
33852
  Node conc = polarity ? atom : atom.notNode();
119
67704
  return assertInternalFact(
120
67704
      atom, polarity, id, PfRule::THEORY_INFERENCE, {exp}, {conc});
121
}
122
123
179551
void InferenceManager::assertInference(Node fact,
124
                                       InferenceId id,
125
                                       Node exp,
126
                                       int inferType)
127
{
128
179551
  if (assertFactRec(fact, id, exp, inferType))
129
  {
130
49408
    Trace("sets-lemma") << "Sets::Lemma : " << fact << " from " << exp << " by "
131
24704
                        << id << std::endl;
132
49408
    Trace("sets-assertion") << "(assert (=> " << exp << " " << fact
133
24704
                            << ")) ; by " << id << std::endl;
134
  }
135
179551
}
136
137
158084
void InferenceManager::assertInference(Node fact,
138
                                       InferenceId id,
139
                                       std::vector<Node>& exp,
140
                                       int inferType)
141
{
142
158084
  Node exp_n = exp.empty() ? d_true
143
154246
                           : (exp.size() == 1
144
5102
                                  ? exp[0]
145
475516
                                  : NodeManager::currentNM()->mkNode(AND, exp));
146
158084
  assertInference(fact, id, exp_n, inferType);
147
158084
}
148
149
10677
void InferenceManager::assertInference(std::vector<Node>& conc,
150
                                       InferenceId id,
151
                                       Node exp,
152
                                       int inferType)
153
{
154
10677
  if (!conc.empty())
155
  {
156
991
    Node fact = conc.size() == 1 ? conc[0]
157
1516
                                 : NodeManager::currentNM()->mkNode(AND, conc);
158
525
    assertInference(fact, id, exp, inferType);
159
  }
160
10677
}
161
void InferenceManager::assertInference(std::vector<Node>& conc,
162
                                       InferenceId id,
163
                                       std::vector<Node>& exp,
164
                                       int inferType)
165
{
166
  Node exp_n = exp.empty() ? d_true
167
                           : (exp.size() == 1
168
                                  ? exp[0]
169
                                  : NodeManager::currentNM()->mkNode(AND, exp));
170
  assertInference(conc, id, exp_n, inferType);
171
}
172
173
468
void InferenceManager::split(Node n, InferenceId id, int reqPol)
174
{
175
468
  n = rewrite(n);
176
936
  Node lem = NodeManager::currentNM()->mkNode(OR, n, n.negate());
177
  // send the lemma
178
468
  lemma(lem, id);
179
468
  Trace("sets-lemma") << "Sets::Lemma split : " << lem << std::endl;
180
468
  if (reqPol != 0)
181
  {
182
4
    Trace("sets-lemma") << "Sets::Require phase " << n << " " << (reqPol > 0)
183
2
                        << std::endl;
184
2
    requirePhase(n, reqPol > 0);
185
  }
186
468
}
187
188
}  // namespace sets
189
}  // namespace theory
190
31137
}  // namespace cvc5