1 /********************* */
2 /*! \file theory_quantifiers.cpp
4 ** Top contributors (to current version):
5 ** Morgan Deters, Andrew Reynolds, Tim King
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2018 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.\endverbatim
12 ** \brief Implementation of the theory of quantifiers
14 ** Implementation of the theory of quantifiers.
17 #include "theory/quantifiers/theory_quantifiers.h"
20 #include "base/cvc4_assert.h"
21 #include "expr/kind.h"
22 #include "options/quantifiers_options.h"
23 #include "theory/quantifiers/ematching/instantiation_engine.h"
24 #include "theory/quantifiers/fmf/model_engine.h"
25 #include "theory/quantifiers/quantifiers_attributes.h"
26 #include "theory/quantifiers/term_database.h"
27 #include "theory/quantifiers/term_util.h"
28 #include "theory/quantifiers_engine.h"
29 #include "theory/valuation.h"
33 using namespace CVC4::kind
;
34 using namespace CVC4::context
;
35 using namespace CVC4::theory
;
36 using namespace CVC4::theory::quantifiers
;
38 TheoryQuantifiers::TheoryQuantifiers(Context
* c
, context::UserContext
* u
, OutputChannel
& out
, Valuation valuation
, const LogicInfo
& logicInfo
) :
39 Theory(THEORY_QUANTIFIERS
, c
, u
, out
, valuation
, logicInfo
)
41 d_numInstantiations
= 0;
43 out
.handleUserAttribute( "axiom", this );
44 out
.handleUserAttribute( "conjecture", this );
45 out
.handleUserAttribute( "fun-def", this );
46 out
.handleUserAttribute( "sygus", this );
47 out
.handleUserAttribute("quant-name", this);
48 out
.handleUserAttribute("sygus-synth-grammar", this);
49 out
.handleUserAttribute( "sygus-synth-fun-var-list", this );
50 out
.handleUserAttribute( "synthesis", this );
51 out
.handleUserAttribute( "quant-inst-max-level", this );
52 out
.handleUserAttribute( "rr-priority", this );
53 out
.handleUserAttribute( "quant-elim", this );
54 out
.handleUserAttribute( "quant-elim-partial", this );
57 TheoryQuantifiers::~TheoryQuantifiers() {
60 void TheoryQuantifiers::finishInit()
62 // quantifiers are not evaluated in getModelValue
63 TheoryModel
* tm
= d_valuation
.getModel();
64 Assert(tm
!= nullptr);
65 tm
->setUnevaluatedKind(EXISTS
);
66 tm
->setUnevaluatedKind(FORALL
);
69 void TheoryQuantifiers::preRegisterTerm(TNode n
) {
70 if (n
.getKind() != FORALL
)
74 Debug("quantifiers-prereg") << "TheoryQuantifiers::preRegisterTerm() " << n
<< endl
;
75 if (options::cbqi() && !options::recurseCbqi()
76 && TermUtil::hasInstConstAttr(n
))
78 Debug("quantifiers-prereg")
79 << "TheoryQuantifiers::preRegisterTerm() done, unused " << n
<< endl
;
82 // Preregister the quantified formula.
83 // This initializes the modules used for handling n in this user context.
84 getQuantifiersEngine()->preRegisterQuantifier(n
);
85 Debug("quantifiers-prereg")
86 << "TheoryQuantifiers::preRegisterTerm() done " << n
<< endl
;
90 void TheoryQuantifiers::presolve() {
91 Debug("quantifiers-presolve") << "TheoryQuantifiers::presolve()" << endl
;
92 if( getQuantifiersEngine() ){
93 getQuantifiersEngine()->presolve();
97 void TheoryQuantifiers::ppNotifyAssertions(
98 const std::vector
<Node
>& assertions
) {
99 Trace("quantifiers-presolve")
100 << "TheoryQuantifiers::ppNotifyAssertions" << std::endl
;
101 if (getQuantifiersEngine()) {
102 getQuantifiersEngine()->ppNotifyAssertions(assertions
);
106 bool TheoryQuantifiers::collectModelInfo(TheoryModel
* m
)
108 for(assertions_iterator i
= facts_begin(); i
!= facts_end(); ++i
) {
109 if((*i
).assertion
.getKind() == kind::NOT
) {
110 Debug("quantifiers::collectModelInfo") << "got quant FALSE: " << (*i
).assertion
[0] << endl
;
111 if (!m
->assertPredicate((*i
).assertion
[0], false))
116 Debug("quantifiers::collectModelInfo") << "got quant TRUE : " << *i
<< endl
;
117 if (!m
->assertPredicate(*i
, true))
126 void TheoryQuantifiers::check(Effort e
) {
127 if (done() && !fullEffort(e
)) {
131 TimerStat::CodeTimer
checkTimer(d_checkTime
);
133 Trace("quantifiers-check") << "quantifiers::check(" << e
<< ")" << std::endl
;
135 Node assertion
= get();
136 Trace("quantifiers-assert") << "quantifiers::assert(): " << assertion
<< std::endl
;
137 switch(assertion
.getKind()) {
139 assertUniversal( assertion
);
141 case kind::INST_CLOSURE
:
142 getQuantifiersEngine()->addTermToDatabase( assertion
[0], false, true );
143 if( !options::lteRestrictInstClosure() ){
144 getQuantifiersEngine()->getMasterEqualityEngine()->addTerm( assertion
[0] );
152 switch( assertion
[0].getKind()) {
154 assertExistential( assertion
);
159 case kind::INST_CLOSURE
:
161 Unhandled(assertion
[0].getKind());
167 Unhandled(assertion
.getKind());
171 // call the quantifiers engine to check
172 getQuantifiersEngine()->check( e
);
175 Node
TheoryQuantifiers::getNextDecisionRequest( unsigned& priority
){
176 return getQuantifiersEngine()->getNextDecisionRequest( priority
);
179 void TheoryQuantifiers::assertUniversal( Node n
){
180 Assert( n
.getKind()==FORALL
);
181 if( !options::cbqi() || options::recurseCbqi() || !TermUtil::hasInstConstAttr(n
) ){
182 getQuantifiersEngine()->assertQuantifier( n
, true );
186 void TheoryQuantifiers::assertExistential( Node n
){
187 Assert( n
.getKind()== NOT
&& n
[0].getKind()==FORALL
);
188 if( !options::cbqi() || options::recurseCbqi() || !TermUtil::hasInstConstAttr(n
[0]) ){
189 getQuantifiersEngine()->assertQuantifier( n
[0], false );
193 void TheoryQuantifiers::setUserAttribute(const std::string
& attr
, Node n
, std::vector
<Node
> node_values
, std::string str_value
){
194 QuantAttributes::setUserAttribute( attr
, n
, node_values
, str_value
);