GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/interpolation_solver.cpp Lines: 44 56 78.6 %
Date: 2021-09-15 Branches: 80 200 40.0 %

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
120
InterpolationSolver::InterpolationSolver(Env& env) : EnvObj(env) {}
36
37
240
InterpolationSolver::~InterpolationSolver() {}
38
39
10
bool InterpolationSolver::getInterpol(const std::vector<Node>& axioms,
40
                                      const Node& conj,
41
                                      const TypeNode& grammarType,
42
                                      Node& interpol)
43
{
44
10
  if (options::produceInterpols() == options::ProduceInterpols::NONE)
45
  {
46
    const char* msg =
47
        "Cannot get interpolation when produce-interpol options is off.";
48
    throw ModalException(msg);
49
  }
50
20
  Trace("sygus-interpol") << "SmtEngine::getInterpol: conjecture " << conj
51
10
                          << std::endl;
52
  // must expand definitions
53
20
  Node conjn = d_env.getTopLevelSubstitutions().apply(conj);
54
20
  std::string name("A");
55
56
20
  quantifiers::SygusInterpol interpolSolver(d_env);
57
10
  if (interpolSolver.solveInterpolation(
58
          name, axioms, conjn, grammarType, interpol))
59
  {
60
10
    if (options::checkInterpols())
61
    {
62
8
      checkInterpol(interpol, axioms, conj);
63
    }
64
10
    return true;
65
  }
66
  return false;
67
}
68
69
bool InterpolationSolver::getInterpol(const std::vector<Node>& axioms,
70
                                      const Node& conj,
71
                                      Node& interpol)
72
{
73
  TypeNode grammarType;
74
  return getInterpol(axioms, 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, d_env);
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
29577
}  // namespace cvc5