GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/theory_quantifiers.cpp Lines: 69 73 94.5 %
Date: 2021-09-07 Branches: 89 170 52.4 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Tim King
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 theory of quantifiers.
14
 */
15
16
#include "theory/quantifiers/theory_quantifiers.h"
17
18
#include "options/quantifiers_options.h"
19
#include "proof/proof_node_manager.h"
20
#include "theory/quantifiers/quantifiers_macros.h"
21
#include "theory/quantifiers/quantifiers_modules.h"
22
#include "theory/quantifiers/quantifiers_rewriter.h"
23
#include "theory/trust_substitutions.h"
24
#include "theory/valuation.h"
25
26
using namespace cvc5::kind;
27
using namespace cvc5::context;
28
29
namespace cvc5 {
30
namespace theory {
31
namespace quantifiers {
32
33
9926
TheoryQuantifiers::TheoryQuantifiers(Env& env,
34
                                     OutputChannel& out,
35
9926
                                     Valuation valuation)
36
    : Theory(THEORY_QUANTIFIERS, env, out, valuation),
37
      d_qstate(env, valuation, logicInfo()),
38
      d_qreg(),
39
      d_treg(d_qstate, d_qreg),
40
      d_qim(*this, d_qstate, d_qreg, d_treg, d_pnm),
41
9926
      d_qengine(nullptr)
42
{
43
  // construct the quantifiers engine
44
19852
  d_qengine.reset(
45
9926
      new QuantifiersEngine(d_qstate, d_qreg, d_treg, d_qim, d_pnm));
46
47
  // indicate we are using the quantifiers theory state object
48
9926
  d_theoryState = &d_qstate;
49
  // use the inference manager as the official inference manager
50
9926
  d_inferManager = &d_qim;
51
  // Set the pointer to the quantifiers engine, which this theory owns. This
52
  // pointer will be retreived by TheoryEngine and set to all theories
53
  // post-construction.
54
9926
  d_quantEngine = d_qengine.get();
55
56
9926
  if (options::macrosQuant())
57
  {
58
22
    d_qmacros.reset(new QuantifiersMacros(d_qreg));
59
  }
60
9926
}
61
62
19846
TheoryQuantifiers::~TheoryQuantifiers() {
63
19846
}
64
65
9926
TheoryRewriter* TheoryQuantifiers::getTheoryRewriter() { return &d_rewriter; }
66
67
3786
ProofRuleChecker* TheoryQuantifiers::getProofChecker() { return &d_checker; }
68
69
9926
void TheoryQuantifiers::finishInit()
70
{
71
  // quantifiers are not evaluated in getModelValue
72
9926
  d_valuation.setUnevaluatedKind(EXISTS);
73
9926
  d_valuation.setUnevaluatedKind(FORALL);
74
  // witness is used in several instantiation strategies
75
9926
  d_valuation.setUnevaluatedKind(WITNESS);
76
9926
}
77
78
9926
bool TheoryQuantifiers::needsEqualityEngine(EeSetupInfo& esi)
79
{
80
  // use the master equality engine
81
9926
  esi.d_useMaster = true;
82
9926
  return true;
83
}
84
85
31946
void TheoryQuantifiers::preRegisterTerm(TNode n)
86
{
87
31946
  if (n.getKind() != FORALL)
88
  {
89
    return;
90
  }
91
63892
  Debug("quantifiers-prereg")
92
31946
      << "TheoryQuantifiers::preRegisterTerm() " << n << std::endl;
93
  // Preregister the quantified formula.
94
  // This initializes the modules used for handling n in this user context.
95
31947
  getQuantifiersEngine()->preRegisterQuantifier(n);
96
63890
  Debug("quantifiers-prereg")
97
31945
      << "TheoryQuantifiers::preRegisterTerm() done " << n << std::endl;
98
}
99
100
101
15250
void TheoryQuantifiers::presolve() {
102
15250
  Debug("quantifiers-presolve") << "TheoryQuantifiers::presolve()" << std::endl;
103
15250
  if( getQuantifiersEngine() ){
104
8209
    getQuantifiersEngine()->presolve();
105
  }
106
15250
}
107
108
13358
Theory::PPAssertStatus TheoryQuantifiers::ppAssert(
109
    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
110
{
111
13358
  if (d_qmacros != nullptr)
112
  {
113
    bool reqGround =
114
34
        options::macrosQuantMode() != options::MacrosQuantMode::ALL;
115
52
    Node eq = d_qmacros->solve(tin.getProven(), reqGround);
116
34
    if (!eq.isNull())
117
    {
118
      // must be legal
119
16
      if (isLegalElimination(eq[0], eq[1]))
120
      {
121
16
        outSubstitutions.addSubstitution(eq[0], eq[1]);
122
16
        return Theory::PP_ASSERT_STATUS_SOLVED;
123
      }
124
    }
125
  }
126
13342
  return Theory::PP_ASSERT_STATUS_UNSOLVED;
127
}
128
13784
void TheoryQuantifiers::ppNotifyAssertions(
129
    const std::vector<Node>& assertions) {
130
27568
  Trace("quantifiers-presolve")
131
13784
      << "TheoryQuantifiers::ppNotifyAssertions" << std::endl;
132
13784
  if (getQuantifiersEngine()) {
133
8171
    getQuantifiersEngine()->ppNotifyAssertions(assertions);
134
  }
135
13784
}
136
137
13289
bool TheoryQuantifiers::collectModelValues(TheoryModel* m,
138
                                           const std::set<Node>& termSet)
139
{
140
43019
  for(assertions_iterator i = facts_begin(); i != facts_end(); ++i) {
141
29730
    if ((*i).d_assertion.getKind() == NOT)
142
    {
143
8366
      Debug("quantifiers::collectModelInfo")
144
4183
          << "got quant FALSE: " << (*i).d_assertion[0] << std::endl;
145
4183
      if (!m->assertPredicate((*i).d_assertion[0], false))
146
      {
147
        return false;
148
      }
149
    }
150
    else
151
    {
152
51094
      Debug("quantifiers::collectModelInfo")
153
25547
          << "got quant TRUE : " << *i << std::endl;
154
25547
      if (!m->assertPredicate(*i, true))
155
      {
156
        return false;
157
      }
158
    }
159
  }
160
13289
  return true;
161
}
162
163
87690
void TheoryQuantifiers::postCheck(Effort level)
164
{
165
  // call the quantifiers engine to check
166
87690
  getQuantifiersEngine()->check(level);
167
87690
}
168
169
89800
bool TheoryQuantifiers::preNotifyFact(
170
    TNode atom, bool polarity, TNode fact, bool isPrereg, bool isInternal)
171
{
172
89800
  Kind k = atom.getKind();
173
89800
  if (k == FORALL)
174
  {
175
89800
    getQuantifiersEngine()->assertQuantifier(atom, polarity);
176
  }
177
  else
178
  {
179
    Unhandled() << "Unexpected fact " << fact;
180
  }
181
  // don't use equality engine, always return true
182
89800
  return true;
183
}
184
185
}  // namespace quantifiers
186
}  // namespace theory
187
29502
}  // namespace cvc5