GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/theory_quantifiers.cpp Lines: 76 80 95.0 %
Date: 2021-05-22 Branches: 97 190 51.1 %

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