summaryrefslogtreecommitdiff
path: root/src/theory/difficulty_manager.cpp
blob: 0a9eba60d7e69a6f0f4cfd043933e780db2d43da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/******************************************************************************
 * Top contributors (to current version):
 *   Andrew Reynolds
 *
 * This file is part of the cvc5 project.
 *
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
 * in the top-level source directory and their institutional affiliations.
 * All rights reserved.  See the file COPYING in the top-level source
 * directory for licensing information.
 * ****************************************************************************
 *
 * Difficulty manager.
 */

#include "theory/difficulty_manager.h"

#include "options/smt_options.h"
#include "smt/env.h"
#include "theory/theory_model.h"
#include "util/rational.h"

using namespace cvc5::kind;

namespace cvc5 {
namespace theory {

DifficultyManager::DifficultyManager(context::Context* c, Valuation val)
    : d_val(val), d_dfmap(c)
{
}

void DifficultyManager::getDifficultyMap(std::map<Node, Node>& dmap)
{
  NodeManager* nm = NodeManager::currentNM();
  for (const std::pair<const Node, uint64_t> p : d_dfmap)
  {
    dmap[p.first] = nm->mkConst(CONST_RATIONAL, Rational(p.second));
  }
}

void DifficultyManager::notifyLemma(const std::map<TNode, TNode>& rse, Node n)
{
  if (options::difficultyMode() != options::DifficultyMode::LEMMA_LITERAL)
  {
    return;
  }
  Trace("diff-man") << "notifyLemma: " << n << std::endl;
  Kind nk = n.getKind();
  // for lemma (or a_1 ... a_n), if a_i is a literal that is not true in the
  // valuation, then we increment the difficulty of that assertion
  std::vector<TNode> litsToCheck;
  if (nk == kind::OR)
  {
    litsToCheck.insert(litsToCheck.end(), n.begin(), n.end());
  }
  else if (nk == kind::IMPLIES)
  {
    litsToCheck.push_back(n[0].negate());
    litsToCheck.push_back(n[1]);
  }
  else
  {
    litsToCheck.push_back(n);
  }
  std::map<TNode, TNode>::const_iterator it;
  for (TNode nc : litsToCheck)
  {
    bool pol = nc.getKind() != kind::NOT;
    TNode atom = pol ? nc : nc[0];
    it = rse.find(atom);
    Trace("diff-man-debug")
        << "Check literal: " << atom << ", has reason = " << (it != rse.end())
        << std::endl;
    if (it != rse.end())
    {
      incrementDifficulty(it->second);
    }
  }
}

void DifficultyManager::notifyCandidateModel(const NodeList& input,
                                             TheoryModel* m)
{
  if (options::difficultyMode() != options::DifficultyMode::MODEL_CHECK)
  {
    return;
  }
  Trace("diff-man") << "DifficultyManager::notifyCandidateModel, #input="
                    << input.size() << std::endl;
  for (const Node& a : input)
  {
    // should have miniscoped the assertions upstream
    Assert(a.getKind() != kind::AND);
    // check if each input is satisfied
    Node av = m->getValue(a);
    if (av.isConst() && av.getConst<bool>())
    {
      continue;
    }
    Trace("diff-man") << "  not true: " << a << std::endl;
    // not satisfied, increment counter
    incrementDifficulty(a);
  }
  Trace("diff-man") << std::endl;
}
void DifficultyManager::incrementDifficulty(TNode a, uint64_t amount)
{
  Assert(a.getType().isBoolean());
  d_dfmap[a] = d_dfmap[a] + amount;
}

}  // namespace theory
}  // namespace cvc5
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback