GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/inference_manager.cpp Lines: 43 86 50.0 %
Date: 2021-05-22 Branches: 92 378 24.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
9460
InferenceManager::InferenceManager(Theory& t,
29
                                   SolverState& s,
30
9460
                                   ProofNodeManager* pnm)
31
9460
    : InferenceManagerBuffered(t, s, pnm, "theory::sets::"), d_state(s)
32
{
33
9460
  d_true = NodeManager::currentNM()->mkConst(true);
34
9460
  d_false = NodeManager::currentNM()->mkConst(false);
35
9460
}
36
37
72974
bool InferenceManager::assertFactRec(Node fact, InferenceId id, Node exp, int inferType)
38
{
39
  // should we send this fact out as a lemma?
40
145950
  if ((options::setsInferAsLemmas() && inferType != -1) || inferType == 1)
41
  {
42
72974
    if (d_state.isEntailed(fact, true))
43
    {
44
55795
      return false;
45
    }
46
34358
    Node lem = fact;
47
17179
    if (exp != d_true)
48
    {
49
12395
      lem = NodeManager::currentNM()->mkNode(IMPLIES, exp, fact);
50
    }
51
17179
    addPendingLemma(lem, id);
52
17179
    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 (assertInternalFact(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
72974
void InferenceManager::assertInference(Node fact,
115
                                       InferenceId id,
116
                                       Node exp,
117
                                       int inferType)
118
{
119
72974
  if (assertFactRec(fact, id, exp, inferType))
120
  {
121
34358
    Trace("sets-lemma") << "Sets::Lemma : " << fact << " from " << exp << " by "
122
17179
                        << id << std::endl;
123
34358
    Trace("sets-assertion") << "(assert (=> " << exp << " " << fact
124
17179
                            << ")) ; by " << id << std::endl;
125
  }
126
72974
}
127
128
60800
void InferenceManager::assertInference(Node fact,
129
                                       InferenceId id,
130
                                       std::vector<Node>& exp,
131
                                       int inferType)
132
{
133
60800
  Node exp_n = exp.empty() ? d_true
134
57468
                           : (exp.size() == 1
135
2378
                                  ? exp[0]
136
181446
                                  : NodeManager::currentNM()->mkNode(AND, exp));
137
60800
  assertInference(fact, id, exp_n, inferType);
138
60800
}
139
140
5050
void InferenceManager::assertInference(std::vector<Node>& conc,
141
                                       InferenceId id,
142
                                       Node exp,
143
                                       int inferType)
144
{
145
5050
  if (!conc.empty())
146
  {
147
761
    Node fact = conc.size() == 1 ? conc[0]
148
1166
                                 : NodeManager::currentNM()->mkNode(AND, conc);
149
405
    assertInference(fact, id, exp, inferType);
150
  }
151
5050
}
152
void InferenceManager::assertInference(std::vector<Node>& conc,
153
                                       InferenceId id,
154
                                       std::vector<Node>& exp,
155
                                       int inferType)
156
{
157
  Node exp_n = exp.empty() ? d_true
158
                           : (exp.size() == 1
159
                                  ? exp[0]
160
                                  : NodeManager::currentNM()->mkNode(AND, exp));
161
  assertInference(conc, id, exp_n, inferType);
162
}
163
164
369
void InferenceManager::split(Node n, InferenceId id, int reqPol)
165
{
166
369
  n = Rewriter::rewrite(n);
167
738
  Node lem = NodeManager::currentNM()->mkNode(OR, n, n.negate());
168
  // send the lemma
169
369
  lemma(lem, id);
170
369
  Trace("sets-lemma") << "Sets::Lemma split : " << lem << std::endl;
171
369
  if (reqPol != 0)
172
  {
173
    Trace("sets-lemma") << "Sets::Require phase " << n << " " << (reqPol > 0)
174
                        << std::endl;
175
    requirePhase(n, reqPol > 0);
176
  }
177
369
}
178
179
}  // namespace sets
180
}  // namespace theory
181
101170
}  // namespace cvc5