GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/model_core_builder.cpp Lines: 43 54 79.6 %
Date: 2021-09-29 Branches: 66 186 35.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner, Aina Niemetz
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 utility for building model cores.
14
 */
15
16
#include "smt/model_core_builder.h"
17
18
#include "theory/subs_minimize.h"
19
20
using namespace cvc5::kind;
21
22
namespace cvc5 {
23
24
2
ModelCoreBuilder::ModelCoreBuilder(Env& env) : EnvObj(env) {}
25
26
2
bool ModelCoreBuilder::setModelCore(const std::vector<Node>& assertions,
27
                                    theory::TheoryModel* m,
28
                                    options::ModelCoresMode mode)
29
{
30
2
  if (m->isUsingModelCore())
31
  {
32
    // already computed
33
    return true;
34
  }
35
2
  if (Trace.isOn("model-core"))
36
  {
37
    Trace("model-core") << "Compute model core, assertions:" << std::endl;
38
    for (const Node& a : assertions)
39
    {
40
      Trace("model-core") << "  " << a << std::endl;
41
    }
42
  }
43
44
  // convert to nodes
45
2
  NodeManager* nm = NodeManager::currentNM();
46
47
4
  Node formula = nm->mkAnd(assertions);
48
4
  std::vector<Node> vars;
49
4
  std::vector<Node> subs;
50
2
  Trace("model-core") << "Assignments: " << std::endl;
51
4
  std::unordered_set<TNode> visited;
52
4
  std::vector<TNode> visit;
53
4
  TNode cur;
54
2
  visit.push_back(formula);
55
6
  do
56
  {
57
8
    cur = visit.back();
58
8
    visit.pop_back();
59
8
    if (visited.find(cur) == visited.end())
60
    {
61
8
      visited.insert(cur);
62
8
      if (cur.isVar())
63
      {
64
8
        Node vcur = m->getValue(cur);
65
4
        Trace("model-core") << "  " << cur << " -> " << vcur << std::endl;
66
4
        vars.push_back(cur);
67
4
        subs.push_back(vcur);
68
      }
69
8
      if (cur.getMetaKind() == metakind::PARAMETERIZED)
70
      {
71
        visit.push_back(cur.getOperator());
72
      }
73
8
      visit.insert(visit.end(), cur.begin(), cur.end());
74
    }
75
8
  } while (!visit.empty());
76
77
4
  Node truen = nm->mkConst(true);
78
79
2
  Trace("model-core") << "Minimizing substitution..." << std::endl;
80
4
  std::vector<Node> coreVars;
81
4
  std::vector<Node> impliedVars;
82
2
  bool minimized = false;
83
4
  theory::SubstitutionMinimize sm(d_env);
84
2
  if (mode == options::ModelCoresMode::NON_IMPLIED)
85
  {
86
    minimized = sm.findWithImplied(formula, vars, subs, coreVars, impliedVars);
87
  }
88
2
  else if (mode == options::ModelCoresMode::SIMPLE)
89
  {
90
2
    minimized = sm.find(formula, truen, vars, subs, coreVars);
91
  }
92
  else
93
  {
94
    Unreachable() << "Unknown model cores mode";
95
  }
96
2
  Assert(minimized)
97
      << "cannot compute model core, since model does not satisfy input!";
98
2
  if (minimized)
99
  {
100
2
    m->setUsingModelCore();
101
2
    Trace("model-core") << "...got core vars : " << coreVars << std::endl;
102
103
6
    for (const Node& cv : coreVars)
104
    {
105
4
      m->recordModelCoreSymbol(cv);
106
    }
107
2
    return true;
108
  }
109
  Trace("model-core") << "...failed, model does not satisfy input!"
110
                      << std::endl;
111
  return false;
112
}
113
114
22746
}  // namespace cvc5