GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/fmf/model_builder.cpp Lines: 39 72 54.2 %
Date: 2021-09-16 Branches: 45 228 19.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Aina Niemetz, Mathias Preiner
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 model builder class.
14
 */
15
16
#include "theory/quantifiers/fmf/model_builder.h"
17
18
#include "options/quantifiers_options.h"
19
#include "options/strings_options.h"
20
#include "theory/quantifiers/first_order_model.h"
21
#include "theory/quantifiers/fmf/model_engine.h"
22
#include "theory/quantifiers/instantiate.h"
23
#include "theory/quantifiers/quant_rep_bound_ext.h"
24
#include "theory/quantifiers/quantifiers_state.h"
25
26
using namespace std;
27
using namespace cvc5;
28
using namespace cvc5::kind;
29
using namespace cvc5::context;
30
using namespace cvc5::theory;
31
using namespace cvc5::theory::quantifiers;
32
33
9942
QModelBuilder::QModelBuilder(Env& env,
34
                             QuantifiersState& qs,
35
                             QuantifiersInferenceManager& qim,
36
                             QuantifiersRegistry& qr,
37
9942
                             TermRegistry& tr)
38
    : TheoryEngineModelBuilder(env),
39
      d_addedLemmas(0),
40
      d_triedLemmas(0),
41
      d_qstate(qs),
42
      d_qim(qim),
43
      d_qreg(qr),
44
      d_treg(tr),
45
9942
      d_model(nullptr)
46
{
47
9942
}
48
49
8480
void QModelBuilder::finishInit()
50
{
51
  // allocate the default model
52
8480
  d_modelAloc.reset(new FirstOrderModel(d_env, d_qstate, d_qreg, d_treg));
53
8480
  d_model = d_modelAloc.get();
54
8480
}
55
56
11567
bool QModelBuilder::optUseModel() {
57
13735
  return options::mbqiMode() != options::MbqiMode::NONE || options::fmfBound()
58
11567
         || options::stringExp();
59
}
60
61
10962
bool QModelBuilder::preProcessBuildModel(TheoryModel* m) {
62
10962
  return preProcessBuildModelStd( m );
63
}
64
65
13000
bool QModelBuilder::preProcessBuildModelStd(TheoryModel* m) {
66
13000
  d_addedLemmas = 0;
67
13000
  d_triedLemmas = 0;
68
13000
  if (options::fmfFunWellDefinedRelevant())
69
  {
70
    //traverse equality engine
71
128
    std::map< TypeNode, bool > eqc_usort;
72
    eq::EqClassesIterator eqcs_i =
73
64
        eq::EqClassesIterator(m->getEqualityEngine());
74
2916
    while( !eqcs_i.isFinished() ){
75
2852
      TypeNode tr = (*eqcs_i).getType();
76
1426
      eqc_usort[tr] = true;
77
1426
      ++eqcs_i;
78
    }
79
    //look at quantified formulas
80
404
    for (size_t i = 0, nquant = d_model->getNumAssertedQuantifiers();
81
404
         i < nquant;
82
         i++)
83
    {
84
680
      Node q = d_model->getAssertedQuantifier(i, true);
85
340
      if (d_model->isQuantifierActive(q))
86
      {
87
        //check if any of these quantified formulas can be set inactive
88
340
        if (q[0].getNumChildren() == 1)
89
        {
90
680
          TypeNode tn = q[0][0].getType();
91
340
          if (tn.getAttribute(AbsTypeFunDefAttribute()))
92
          {
93
            // we are allowed to assume the introduced type is empty
94
322
            if (eqc_usort.find(tn) == eqc_usort.end())
95
            {
96
208
              Trace("model-engine-debug")
97
104
                  << "Irrelevant function definition : " << q << std::endl;
98
104
              d_model->setQuantifierActive(q, false);
99
            }
100
          }
101
        }
102
      }
103
    }
104
  }
105
13000
  return true;
106
}
107
108
221
void QModelBuilder::debugModel( TheoryModel* m ){
109
  //debug the model: cycle through all instantiations for all quantifiers, report ones that are not true
110
221
  if( Trace.isOn("quant-check-model") ){
111
    FirstOrderModel* fm = d_model;
112
    Trace("quant-check-model") << "Testing quantifier instantiations..." << std::endl;
113
    int tests = 0;
114
    int bad = 0;
115
    QuantifiersBoundInference& qbi = d_qreg.getQuantifiersBoundInference();
116
    Instantiate* inst = d_qim.getInstantiate();
117
    for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
118
      Node f = fm->getAssertedQuantifier( i );
119
      std::vector< Node > vars;
120
      for( unsigned j=0; j<f[0].getNumChildren(); j++ ){
121
        vars.push_back( f[0][j] );
122
      }
123
      QRepBoundExt qrbe(qbi, fm);
124
      RepSetIterator riter(m->getRepSet(), &qrbe);
125
      if( riter.setQuantifier( f ) ){
126
        while( !riter.isFinished() ){
127
          tests++;
128
          std::vector< Node > terms;
129
          for (unsigned k = 0; k < riter.getNumTerms(); k++)
130
          {
131
            terms.push_back( riter.getCurrentTerm( k ) );
132
          }
133
          Node n = inst->getInstantiation(f, vars, terms);
134
          Node val = m->getValue(n);
135
          if (!val.isConst() || !val.getConst<bool>())
136
          {
137
            Trace("quant-check-model") << "*******  Instantiation " << n << " for " << std::endl;
138
            Trace("quant-check-model") << "         " << f << std::endl;
139
            Trace("quant-check-model") << "         Evaluates to " << val << std::endl;
140
            bad++;
141
          }
142
          riter.increment();
143
        }
144
        Trace("quant-check-model") << "Tested " << tests << " instantiations";
145
        if( bad>0 ){
146
          Trace("quant-check-model") << ", " << bad << " failed" << std::endl;
147
        }
148
        Trace("quant-check-model") << "." << std::endl;
149
      }else{
150
        if( riter.isIncomplete() ){
151
          Trace("quant-check-model") << "Warning: Could not test quantifier " << f << std::endl;
152
        }
153
      }
154
    }
155
  }
156
221
}
157
39519
FirstOrderModel* QModelBuilder::getModel() { return d_model; }