GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/solution_filter.cpp Lines: 30 47 63.8 %
Date: 2021-09-29 Branches: 46 162 28.4 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, 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
 * Utilities for filtering solutions.
14
 */
15
16
#include "theory/quantifiers/solution_filter.h"
17
18
#include <fstream>
19
20
#include "options/base_options.h"
21
#include "options/quantifiers_options.h"
22
#include "smt/env.h"
23
#include "util/random.h"
24
25
using namespace cvc5::kind;
26
27
namespace cvc5 {
28
namespace theory {
29
namespace quantifiers {
30
31
9
SolutionFilterStrength::SolutionFilterStrength(Env& env)
32
9
    : ExprMiner(env), d_isStrong(true)
33
{
34
9
}
35
2
void SolutionFilterStrength::initialize(const std::vector<Node>& vars,
36
                                        SygusSampler* ss)
37
{
38
2
  ExprMiner::initialize(vars, ss);
39
2
}
40
41
2
void SolutionFilterStrength::setLogicallyStrong(bool isStrong)
42
{
43
2
  d_isStrong = isStrong;
44
2
}
45
46
56
bool SolutionFilterStrength::addTerm(Node n, std::ostream& out)
47
{
48
56
  if (!n.getType().isBoolean())
49
  {
50
    // currently, should not register non-Boolean terms here
51
    Assert(false);
52
    return true;
53
  }
54
112
  Node basen = d_isStrong ? n : n.negate();
55
56
  NodeManager* nm = NodeManager::currentNM();
56
  // Do i subsume the disjunction of all previous solutions? If so, we discard
57
  // this immediately
58
112
  Node curr;
59
56
  if (!d_curr_sols.empty())
60
  {
61
108
    curr = d_curr_sols.size() == 1
62
160
               ? d_curr_sols[0]
63
52
               : nm->mkNode(d_isStrong ? OR : AND, d_curr_sols);
64
73
    Node imp = nm->mkNode(AND, basen.negate(), curr);
65
108
    Trace("sygus-sol-implied")
66
54
        << "  implies: check subsumed (strong=" << d_isStrong << ") " << imp
67
54
        << "..." << std::endl;
68
    // check the satisfiability query
69
73
    Result r = doCheck(imp);
70
54
    Trace("sygus-sol-implied") << "  implies: ...got : " << r << std::endl;
71
54
    if (r.asSatisfiabilityResult().isSat() == Result::UNSAT)
72
    {
73
      // it is subsumed by the current, discard this
74
35
      return false;
75
    }
76
  }
77
  // check which solutions would have been filtered if the current had come
78
  // first
79
21
  if (options::sygusFilterSolRevSubsume())
80
  {
81
    std::vector<Node> nsubsume;
82
    for (const Node& s : d_curr_sols)
83
    {
84
      Node imp = nm->mkNode(AND, s.negate(), basen);
85
      Trace("sygus-sol-implied")
86
          << "  implies: check subsuming " << imp << "..." << std::endl;
87
      // check the satisfiability query
88
      Result r = doCheck(imp);
89
      Trace("sygus-sol-implied") << "  implies: ...got : " << r << std::endl;
90
      if (r.asSatisfiabilityResult().isSat() != Result::UNSAT)
91
      {
92
        nsubsume.push_back(s);
93
      }
94
      else
95
      {
96
        const Options& opts = d_env.getOptions();
97
        std::ostream* smtOut = opts.base.out;
98
        (*smtOut) << "; (filtered " << (d_isStrong ? s : s.negate()) << ")"
99
                  << std::endl;
100
      }
101
    }
102
    d_curr_sols.clear();
103
    d_curr_sols.insert(d_curr_sols.end(), nsubsume.begin(), nsubsume.end());
104
  }
105
21
  d_curr_sols.push_back(basen);
106
21
  return true;
107
}
108
109
}  // namespace quantifiers
110
}  // namespace theory
111
22746
}  // namespace cvc5