GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/model_core_builder.cpp Lines: 1 50 2.0 %
Date: 2021-05-22 Branches: 2 182 1.1 %

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