GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/interpolation_solver.cpp Lines: 46 58 79.3 %
Date: 2021-05-22 Branches: 86 216 39.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Ying Sheng, 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
 * The solver for interpolation queries.
14
 */
15
16
#include "smt/interpolation_solver.h"
17
18
#include <sstream>
19
20
#include "base/modal_exception.h"
21
#include "options/smt_options.h"
22
#include "smt/env.h"
23
#include "smt/smt_engine.h"
24
#include "theory/quantifiers/quantifiers_attributes.h"
25
#include "theory/quantifiers/sygus/sygus_grammar_cons.h"
26
#include "theory/quantifiers/sygus/sygus_interpol.h"
27
#include "theory/smt_engine_subsolver.h"
28
#include "theory/trust_substitutions.h"
29
30
using namespace cvc5::theory;
31
32
namespace cvc5 {
33
namespace smt {
34
35
115
InterpolationSolver::InterpolationSolver(SmtEngine* parent) : d_parent(parent)
36
{
37
115
}
38
39
115
InterpolationSolver::~InterpolationSolver() {}
40
41
10
bool InterpolationSolver::getInterpol(const Node& conj,
42
                                      const TypeNode& grammarType,
43
                                      Node& interpol)
44
{
45
23647
  if (options::produceInterpols() == options::ProduceInterpols::NONE)
46
  {
47
    const char* msg =
48
        "Cannot get interpolation when produce-interpol options is off.";
49
    throw ModalException(msg);
50
  }
51
20
  Trace("sygus-interpol") << "SmtEngine::getInterpol: conjecture " << conj
52
10
                          << std::endl;
53
20
  std::vector<Node> axioms = d_parent->getExpandedAssertions();
54
  // must expand definitions
55
20
  Node conjn = d_parent->getEnv().getTopLevelSubstitutions().apply(conj);
56
20
  std::string name("A");
57
58
20
  quantifiers::SygusInterpol interpolSolver;
59
10
  if (interpolSolver.solveInterpolation(
60
          name, axioms, conjn, grammarType, interpol))
61
  {
62
28
    if (options::checkInterpols())
63
    {
64
8
      checkInterpol(interpol, axioms, conj);
65
    }
66
10
    return true;
67
  }
68
  return false;
69
}
70
71
bool InterpolationSolver::getInterpol(const Node& conj, Node& interpol)
72
{
73
  TypeNode grammarType;
74
  return getInterpol(conj, grammarType, interpol);
75
}
76
77
8
void InterpolationSolver::checkInterpol(Node interpol,
78
                                        const std::vector<Node>& easserts,
79
                                        const Node& conj)
80
{
81
8
  Assert(interpol.getType().isBoolean());
82
16
  Trace("check-interpol") << "SmtEngine::checkInterpol: get expanded assertions"
83
8
                          << std::endl;
84
85
  // two checks: first, axioms imply interpol, second, interpol implies conj.
86
24
  for (unsigned j = 0; j < 2; j++)
87
  {
88
16
    if (j == 1)
89
    {
90
16
      Trace("check-interpol")
91
8
          << "SmtEngine::checkInterpol: conjecture is " << conj << std::endl;
92
    }
93
32
    Trace("check-interpol") << "SmtEngine::checkInterpol: phase " << j
94
16
                            << ": make new SMT engine" << std::endl;
95
    // Start new SMT engine to check solution
96
32
    std::unique_ptr<SmtEngine> itpChecker;
97
16
    initializeSubsolver(itpChecker);
98
32
    Trace("check-interpol") << "SmtEngine::checkInterpol: phase " << j
99
16
                            << ": asserting formulas" << std::endl;
100
16
    if (j == 0)
101
    {
102
29
      for (const Node& e : easserts)
103
      {
104
21
        itpChecker->assertFormula(e);
105
      }
106
16
      Node negitp = interpol.notNode();
107
8
      itpChecker->assertFormula(negitp);
108
    }
109
    else
110
    {
111
8
      itpChecker->assertFormula(interpol);
112
8
      Assert(!conj.isNull());
113
8
      itpChecker->assertFormula(conj.notNode());
114
    }
115
32
    Trace("check-interpol") << "SmtEngine::checkInterpol: phase " << j
116
16
                            << ": check the assertions" << std::endl;
117
32
    Result r = itpChecker->checkSat();
118
32
    Trace("check-interpol") << "SmtEngine::checkInterpol: phase " << j
119
16
                            << ": result is " << r << std::endl;
120
32
    std::stringstream serr;
121
16
    if (r.asSatisfiabilityResult().isSat() != Result::UNSAT)
122
    {
123
      if (j == 0)
124
      {
125
        serr << "SmtEngine::checkInterpol(): negated produced solution cannot "
126
                "be shown "
127
                "satisfiable with assertions, result was "
128
             << r;
129
      }
130
      else
131
      {
132
        serr
133
            << "SmtEngine::checkInterpol(): negated conjecture cannot be shown "
134
               "satisfiable with produced solution, result was "
135
            << r;
136
      }
137
      InternalError() << serr.str();
138
    }
139
  }
140
8
}
141
142
}  // namespace smt
143
51846
}  // namespace cvc5