GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/model_core_builder.cpp Lines: 41 52 78.8 %
Date: 2021-09-16 Branches: 65 184 35.3 %

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