GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/expr_miner_manager.cpp Lines: 69 101 68.3 %
Date: 2021-11-07 Branches: 62 154 40.3 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds
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 expression miner manager.
14
 */
15
16
#include "theory/quantifiers/expr_miner_manager.h"
17
18
#include "options/quantifiers_options.h"
19
#include "smt/env.h"
20
21
namespace cvc5 {
22
namespace theory {
23
namespace quantifiers {
24
25
14
ExpressionMinerManager::ExpressionMinerManager(Env& env)
26
    : EnvObj(env),
27
      d_doRewSynth(false),
28
      d_doQueryGen(false),
29
      d_doFilterLogicalStrength(false),
30
      d_use_sygus_type(false),
31
      d_tds(nullptr),
32
      d_crd(env,
33
14
            options().quantifiers.sygusRewSynthCheck,
34
14
            options().quantifiers.sygusRewSynthAccel,
35
            false),
36
      d_sols(env),
37
42
      d_sampler(env)
38
{
39
14
}
40
41
void ExpressionMinerManager::initialize(const std::vector<Node>& vars,
42
                                        TypeNode tn,
43
                                        unsigned nsamples,
44
                                        bool unique_type_ids)
45
{
46
  d_doRewSynth = false;
47
  d_doQueryGen = false;
48
  d_doFilterLogicalStrength = false;
49
  d_sygus_fun = Node::null();
50
  d_use_sygus_type = false;
51
  d_tds = nullptr;
52
  // initialize the sampler
53
  d_sampler.initialize(tn, vars, nsamples, unique_type_ids);
54
}
55
56
14
void ExpressionMinerManager::initializeSygus(TermDbSygus* tds,
57
                                             Node f,
58
                                             unsigned nsamples,
59
                                             bool useSygusType)
60
{
61
14
  d_doRewSynth = false;
62
14
  d_doQueryGen = false;
63
14
  d_doFilterLogicalStrength = false;
64
14
  d_sygus_fun = f;
65
14
  d_use_sygus_type = useSygusType;
66
14
  d_tds = tds;
67
  // initialize the sampler
68
14
  d_sampler.initializeSygus(d_tds, f, nsamples, useSygusType);
69
14
}
70
71
14
void ExpressionMinerManager::initializeMinersForOptions()
72
{
73
14
  if (options().quantifiers.sygusRewSynth)
74
  {
75
8
    enableRewriteRuleSynth();
76
  }
77
14
  if (options().quantifiers.sygusQueryGen != options::SygusQueryGenMode::NONE)
78
  {
79
2
    enableQueryGeneration(options().quantifiers.sygusQueryGenThresh);
80
  }
81
28
  if (options().quantifiers.sygusFilterSolMode
82
14
      != options::SygusFilterSolMode::NONE)
83
  {
84
8
    if (options().quantifiers.sygusFilterSolMode
85
4
        == options::SygusFilterSolMode::STRONG)
86
    {
87
4
      enableFilterStrongSolutions();
88
    }
89
    else if (options().quantifiers.sygusFilterSolMode
90
             == options::SygusFilterSolMode::WEAK)
91
    {
92
      enableFilterWeakSolutions();
93
    }
94
  }
95
14
}
96
97
8
void ExpressionMinerManager::enableRewriteRuleSynth()
98
{
99
8
  if (d_doRewSynth)
100
  {
101
    // already enabled
102
    return;
103
  }
104
8
  d_doRewSynth = true;
105
16
  std::vector<Node> vars;
106
8
  d_sampler.getVariables(vars);
107
  // initialize the candidate rewrite database
108
8
  if (!d_sygus_fun.isNull())
109
  {
110
8
    Assert(d_tds != nullptr);
111
8
    d_crd.initializeSygus(vars, d_tds, d_sygus_fun, &d_sampler);
112
  }
113
  else
114
  {
115
    d_crd.initialize(vars, &d_sampler);
116
  }
117
8
  d_crd.enableExtendedRewriter();
118
8
  d_crd.setSilent(false);
119
}
120
121
2
void ExpressionMinerManager::enableQueryGeneration(unsigned deqThresh)
122
{
123
2
  if (d_doQueryGen)
124
  {
125
    // already enabled
126
    return;
127
  }
128
2
  d_doQueryGen = true;
129
2
  options::SygusQueryGenMode mode = options().quantifiers.sygusQueryGen;
130
4
  std::vector<Node> vars;
131
2
  d_sampler.getVariables(vars);
132
2
  if (mode == options::SygusQueryGenMode::SAT)
133
  {
134
    // must also enable rewrite rule synthesis
135
    if (!d_doRewSynth)
136
    {
137
      // initialize the candidate rewrite database, in silent mode
138
      enableRewriteRuleSynth();
139
      d_crd.setSilent(true);
140
    }
141
    d_qg = std::make_unique<QueryGenerator>(d_env);
142
    // initialize the query generator
143
    d_qg->initialize(vars, &d_sampler);
144
    d_qg->setThreshold(deqThresh);
145
  }
146
2
  else if (mode == options::SygusQueryGenMode::UNSAT)
147
  {
148
2
    d_qgu = std::make_unique<QueryGeneratorUnsat>(d_env);
149
    // initialize the query generator
150
2
    d_qgu->initialize(vars, &d_sampler);
151
  }
152
}
153
154
void ExpressionMinerManager::enableFilterWeakSolutions()
155
{
156
  d_doFilterLogicalStrength = true;
157
  std::vector<Node> vars;
158
  d_sampler.getVariables(vars);
159
  d_sols.initialize(vars, &d_sampler);
160
  d_sols.setLogicallyStrong(true);
161
}
162
163
4
void ExpressionMinerManager::enableFilterStrongSolutions()
164
{
165
4
  d_doFilterLogicalStrength = true;
166
8
  std::vector<Node> vars;
167
4
  d_sampler.getVariables(vars);
168
4
  d_sols.initialize(vars, &d_sampler);
169
4
  d_sols.setLogicallyStrong(false);
170
4
}
171
172
1923
bool ExpressionMinerManager::addTerm(Node sol,
173
                                     std::ostream& out,
174
                                     bool& rew_print)
175
{
176
  // set the builtin version
177
3846
  Node solb = sol;
178
1923
  if (d_use_sygus_type)
179
  {
180
1923
    solb = d_tds->sygusToBuiltin(sol);
181
  }
182
183
  // add to the candidate rewrite rule database
184
1923
  bool ret = true;
185
1923
  if (d_doRewSynth)
186
  {
187
    Node rsol = d_crd.addTerm(
188
2754
        sol, options().quantifiers.sygusRewSynthRec, out, rew_print);
189
1377
    ret = (sol == rsol);
190
  }
191
192
  // a unique term, let's try the query generator
193
1923
  if (ret && d_doQueryGen)
194
  {
195
418
    options::SygusQueryGenMode mode = options().quantifiers.sygusQueryGen;
196
418
    if (mode == options::SygusQueryGenMode::SAT)
197
    {
198
      d_qg->addTerm(solb, out);
199
    }
200
418
    else if (mode == options::SygusQueryGenMode::UNSAT)
201
    {
202
418
      d_qgu->addTerm(solb, out);
203
    }
204
  }
205
206
  // filter based on logical strength
207
1923
  if (ret && d_doFilterLogicalStrength)
208
  {
209
128
    ret = d_sols.addTerm(solb, out);
210
  }
211
3846
  return ret;
212
}
213
214
bool ExpressionMinerManager::addTerm(Node sol, std::ostream& out)
215
{
216
  bool rew_print = false;
217
  return addTerm(sol, out, rew_print);
218
}
219
220
}  // namespace quantifiers
221
}  // namespace theory
222
31137
}  // namespace cvc5