GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/theory_quantifiers.cpp Lines: 77 81 95.1 %
Date: 2021-08-17 Branches: 96 184 52.2 %

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
9850
TheoryQuantifiers::TheoryQuantifiers(Env& env,
34
                                     OutputChannel& out,
35
9850
                                     Valuation valuation)
36
    : Theory(THEORY_QUANTIFIERS, env, out, valuation),
37
      d_qstate(env, valuation, getLogicInfo()),
38
      d_qreg(),
39
      d_treg(d_qstate, d_qreg),
40
      d_qim(*this, d_qstate, d_qreg, d_treg, d_pnm),
41
9850
      d_qengine(nullptr)
42
{
43
9850
  out.handleUserAttribute( "fun-def", this );
44
9850
  out.handleUserAttribute("qid", this);
45
9850
  out.handleUserAttribute( "quant-inst-max-level", this );
46
9850
  out.handleUserAttribute( "quant-elim", this );
47
9850
  out.handleUserAttribute( "quant-elim-partial", this );
48
49
  // construct the quantifiers engine
50
19700
  d_qengine.reset(
51
9850
      new QuantifiersEngine(d_qstate, d_qreg, d_treg, d_qim, d_pnm));
52
53
  // indicate we are using the quantifiers theory state object
54
9850
  d_theoryState = &d_qstate;
55
  // use the inference manager as the official inference manager
56
9850
  d_inferManager = &d_qim;
57
  // Set the pointer to the quantifiers engine, which this theory owns. This
58
  // pointer will be retreived by TheoryEngine and set to all theories
59
  // post-construction.
60
9850
  d_quantEngine = d_qengine.get();
61
62
9850
  if (options::macrosQuant())
63
  {
64
22
    d_qmacros.reset(new QuantifiersMacros(d_qreg));
65
  }
66
9850
}
67
68
19700
TheoryQuantifiers::~TheoryQuantifiers() {
69
19700
}
70
71
9850
TheoryRewriter* TheoryQuantifiers::getTheoryRewriter() { return &d_rewriter; }
72
73
3766
ProofRuleChecker* TheoryQuantifiers::getProofChecker() { return &d_checker; }
74
75
9850
void TheoryQuantifiers::finishInit()
76
{
77
  // quantifiers are not evaluated in getModelValue
78
9850
  d_valuation.setUnevaluatedKind(EXISTS);
79
9850
  d_valuation.setUnevaluatedKind(FORALL);
80
  // witness is used in several instantiation strategies
81
9850
  d_valuation.setUnevaluatedKind(WITNESS);
82
9850
}
83
84
9850
bool TheoryQuantifiers::needsEqualityEngine(EeSetupInfo& esi)
85
{
86
  // use the master equality engine
87
9850
  esi.d_useMaster = true;
88
9850
  return true;
89
}
90
91
31955
void TheoryQuantifiers::preRegisterTerm(TNode n)
92
{
93
31955
  if (n.getKind() != FORALL)
94
  {
95
    return;
96
  }
97
63910
  Debug("quantifiers-prereg")
98
31955
      << "TheoryQuantifiers::preRegisterTerm() " << n << std::endl;
99
  // Preregister the quantified formula.
100
  // This initializes the modules used for handling n in this user context.
101
31956
  getQuantifiersEngine()->preRegisterQuantifier(n);
102
63908
  Debug("quantifiers-prereg")
103
31954
      << "TheoryQuantifiers::preRegisterTerm() done " << n << std::endl;
104
}
105
106
107
15201
void TheoryQuantifiers::presolve() {
108
15201
  Debug("quantifiers-presolve") << "TheoryQuantifiers::presolve()" << std::endl;
109
15201
  if( getQuantifiersEngine() ){
110
8163
    getQuantifiersEngine()->presolve();
111
  }
112
15201
}
113
114
13305
Theory::PPAssertStatus TheoryQuantifiers::ppAssert(
115
    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
116
{
117
13305
  if (d_qmacros != nullptr)
118
  {
119
    bool reqGround =
120
34
        options::macrosQuantMode() != options::MacrosQuantMode::ALL;
121
52
    Node eq = d_qmacros->solve(tin.getProven(), reqGround);
122
34
    if (!eq.isNull())
123
    {
124
      // must be legal
125
16
      if (isLegalElimination(eq[0], eq[1]))
126
      {
127
16
        outSubstitutions.addSubstitution(eq[0], eq[1]);
128
16
        return Theory::PP_ASSERT_STATUS_SOLVED;
129
      }
130
    }
131
  }
132
13289
  return Theory::PP_ASSERT_STATUS_UNSOLVED;
133
}
134
13737
void TheoryQuantifiers::ppNotifyAssertions(
135
    const std::vector<Node>& assertions) {
136
27474
  Trace("quantifiers-presolve")
137
13737
      << "TheoryQuantifiers::ppNotifyAssertions" << std::endl;
138
13737
  if (getQuantifiersEngine()) {
139
8127
    getQuantifiersEngine()->ppNotifyAssertions(assertions);
140
  }
141
13737
}
142
143
13189
bool TheoryQuantifiers::collectModelValues(TheoryModel* m,
144
                                           const std::set<Node>& termSet)
145
{
146
42652
  for(assertions_iterator i = facts_begin(); i != facts_end(); ++i) {
147
29463
    if ((*i).d_assertion.getKind() == NOT)
148
    {
149
8352
      Debug("quantifiers::collectModelInfo")
150
4176
          << "got quant FALSE: " << (*i).d_assertion[0] << std::endl;
151
4176
      if (!m->assertPredicate((*i).d_assertion[0], false))
152
      {
153
        return false;
154
      }
155
    }
156
    else
157
    {
158
50574
      Debug("quantifiers::collectModelInfo")
159
25287
          << "got quant TRUE : " << *i << std::endl;
160
25287
      if (!m->assertPredicate(*i, true))
161
      {
162
        return false;
163
      }
164
    }
165
  }
166
13189
  return true;
167
}
168
169
85646
void TheoryQuantifiers::postCheck(Effort level)
170
{
171
  // call the quantifiers engine to check
172
85646
  getQuantifiersEngine()->check(level);
173
85646
}
174
175
89078
bool TheoryQuantifiers::preNotifyFact(
176
    TNode atom, bool polarity, TNode fact, bool isPrereg, bool isInternal)
177
{
178
89078
  Kind k = atom.getKind();
179
89078
  if (k == FORALL)
180
  {
181
89078
    getQuantifiersEngine()->assertQuantifier(atom, polarity);
182
  }
183
  else
184
  {
185
    Unhandled() << "Unexpected fact " << fact;
186
  }
187
  // don't use equality engine, always return true
188
89078
  return true;
189
}
190
191
238
void TheoryQuantifiers::setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value){
192
238
  QuantAttributes::setUserAttribute( attr, n, node_values, str_value );
193
238
}
194
195
}  // namespace quantifiers
196
}  // namespace theory
197
29337
}  // namespace cvc5