GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/fmf/model_builder.cpp Lines: 39 72 54.2 %
Date: 2021-08-01 Branches: 45 240 18.8 %

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
9838
QModelBuilder::QModelBuilder(QuantifiersState& qs,
34
                             QuantifiersInferenceManager& qim,
35
                             QuantifiersRegistry& qr,
36
9838
                             TermRegistry& tr)
37
    : TheoryEngineModelBuilder(),
38
      d_addedLemmas(0),
39
      d_triedLemmas(0),
40
      d_qstate(qs),
41
      d_qim(qim),
42
      d_qreg(qr),
43
      d_treg(tr),
44
9838
      d_model(nullptr)
45
{
46
9838
}
47
48
8406
void QModelBuilder::finishInit()
49
{
50
  // allocate the default model
51
8406
  d_modelAloc.reset(new FirstOrderModel(d_qstate, d_qreg, d_treg));
52
8406
  d_model = d_modelAloc.get();
53
8406
}
54
55
11008
bool QModelBuilder::optUseModel() {
56
13174
  return options::mbqiMode() != options::MbqiMode::NONE || options::fmfBound()
57
11008
         || options::stringExp();
58
}
59
60
11211
bool QModelBuilder::preProcessBuildModel(TheoryModel* m) {
61
11211
  return preProcessBuildModelStd( m );
62
}
63
64
13190
bool QModelBuilder::preProcessBuildModelStd(TheoryModel* m) {
65
13190
  d_addedLemmas = 0;
66
13190
  d_triedLemmas = 0;
67
13190
  if (options::fmfFunWellDefinedRelevant())
68
  {
69
    //traverse equality engine
70
124
    std::map< TypeNode, bool > eqc_usort;
71
    eq::EqClassesIterator eqcs_i =
72
62
        eq::EqClassesIterator(m->getEqualityEngine());
73
2832
    while( !eqcs_i.isFinished() ){
74
2770
      TypeNode tr = (*eqcs_i).getType();
75
1385
      eqc_usort[tr] = true;
76
1385
      ++eqcs_i;
77
    }
78
    //look at quantified formulas
79
394
    for (size_t i = 0, nquant = d_model->getNumAssertedQuantifiers();
80
394
         i < nquant;
81
         i++)
82
    {
83
664
      Node q = d_model->getAssertedQuantifier(i, true);
84
332
      if (d_model->isQuantifierActive(q))
85
      {
86
        //check if any of these quantified formulas can be set inactive
87
332
        if (q[0].getNumChildren() == 1)
88
        {
89
664
          TypeNode tn = q[0][0].getType();
90
332
          if (tn.getAttribute(AbsTypeFunDefAttribute()))
91
          {
92
            // we are allowed to assume the introduced type is empty
93
314
            if (eqc_usort.find(tn) == eqc_usort.end())
94
            {
95
208
              Trace("model-engine-debug")
96
104
                  << "Irrelevant function definition : " << q << std::endl;
97
104
              d_model->setQuantifierActive(q, false);
98
            }
99
          }
100
        }
101
      }
102
    }
103
  }
104
13190
  return true;
105
}
106
107
217
void QModelBuilder::debugModel( TheoryModel* m ){
108
  //debug the model: cycle through all instantiations for all quantifiers, report ones that are not true
109
217
  if( Trace.isOn("quant-check-model") ){
110
    FirstOrderModel* fm = d_model;
111
    Trace("quant-check-model") << "Testing quantifier instantiations..." << std::endl;
112
    int tests = 0;
113
    int bad = 0;
114
    QuantifiersBoundInference& qbi = d_qreg.getQuantifiersBoundInference();
115
    Instantiate* inst = d_qim.getInstantiate();
116
    for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
117
      Node f = fm->getAssertedQuantifier( i );
118
      std::vector< Node > vars;
119
      for( unsigned j=0; j<f[0].getNumChildren(); j++ ){
120
        vars.push_back( f[0][j] );
121
      }
122
      QRepBoundExt qrbe(qbi, fm);
123
      RepSetIterator riter(m->getRepSet(), &qrbe);
124
      if( riter.setQuantifier( f ) ){
125
        while( !riter.isFinished() ){
126
          tests++;
127
          std::vector< Node > terms;
128
          for (unsigned k = 0; k < riter.getNumTerms(); k++)
129
          {
130
            terms.push_back( riter.getCurrentTerm( k ) );
131
          }
132
          Node n = inst->getInstantiation(f, vars, terms);
133
          Node val = m->getValue(n);
134
          if (!val.isConst() || !val.getConst<bool>())
135
          {
136
            Trace("quant-check-model") << "*******  Instantiation " << n << " for " << std::endl;
137
            Trace("quant-check-model") << "         " << f << std::endl;
138
            Trace("quant-check-model") << "         Evaluates to " << val << std::endl;
139
            bad++;
140
          }
141
          riter.increment();
142
        }
143
        Trace("quant-check-model") << "Tested " << tests << " instantiations";
144
        if( bad>0 ){
145
          Trace("quant-check-model") << ", " << bad << " failed" << std::endl;
146
        }
147
        Trace("quant-check-model") << "." << std::endl;
148
      }else{
149
        if( riter.isIncomplete() ){
150
          Trace("quant-check-model") << "Warning: Could not test quantifier " << f << std::endl;
151
        }
152
      }
153
    }
154
  }
155
217
}
156
39118
FirstOrderModel* QModelBuilder::getModel() { return d_model; }