GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/proof_ensure_closed.cpp Lines: 12 76 15.8 %
Date: 2021-05-24 Branches: 18 410 4.4 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Haniel Barbosa
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 debug checks for ensuring proofs are closed.
14
 */
15
16
#include "expr/proof_ensure_closed.h"
17
18
#include <sstream>
19
20
#include "expr/proof_generator.h"
21
#include "expr/proof_node.h"
22
#include "expr/proof_node_algorithm.h"
23
#include "options/proof_options.h"
24
#include "options/smt_options.h"
25
26
namespace cvc5 {
27
28
/**
29
 * Ensure closed with respect to assumptions, internal version, which
30
 * generalizes the check for a proof generator or a proof node.
31
 */
32
752408
void ensureClosedWrtInternal(Node proven,
33
                             ProofGenerator* pg,
34
                             ProofNode* pnp,
35
                             const std::vector<Node>& assumps,
36
                             const char* c,
37
                             const char* ctx,
38
                             bool reqGen)
39
{
40
752408
  if (!options::produceProofs())
41
  {
42
    // proofs not enabled, do not do check
43
925403
    return;
44
  }
45
579413
  bool isTraceDebug = Trace.isOn(c);
46
579413
  if (!options::proofEagerChecking() && !isTraceDebug)
47
  {
48
    // trace is off and proof new eager checking is off, do not do check
49
579413
    return;
50
  }
51
  std::stringstream sdiag;
52
  bool isTraceOn = Trace.isOn(c);
53
  if (!isTraceOn)
54
  {
55
    sdiag << ", use -t " << c << " for details";
56
  }
57
  bool dumpProofTraceOn = Trace.isOn("dump-proof-error");
58
  if (!dumpProofTraceOn)
59
  {
60
    sdiag << ", use -t dump-proof-error for details on proof";
61
  }
62
  // get the proof node in question, which is either provided or built by the
63
  // proof generator
64
  std::shared_ptr<ProofNode> pn;
65
  std::stringstream ss;
66
  if (pnp != nullptr)
67
  {
68
    Assert(pg == nullptr);
69
    ss << "ProofNode in context " << ctx;
70
  }
71
  else
72
  {
73
    ss << "ProofGenerator: " << (pg == nullptr ? "null" : pg->identify())
74
       << " in context " << ctx;
75
    if (pg == nullptr)
76
    {
77
      // only failure if flag is true
78
      if (reqGen)
79
      {
80
        Unreachable() << "...ensureClosed: no generator in context " << ctx
81
                      << sdiag.str();
82
      }
83
    }
84
    else
85
    {
86
      Assert(!proven.isNull());
87
      pn = pg->getProofFor(proven);
88
      pnp = pn.get();
89
    }
90
  }
91
  Trace(c) << "=== ensureClosed: " << ss.str() << std::endl;
92
  Trace(c) << "Proven: " << proven << std::endl;
93
  if (pnp == nullptr)
94
  {
95
    if (pg == nullptr)
96
    {
97
      // did not require generator
98
      Assert(!reqGen);
99
      Trace(c) << "...ensureClosed: no generator in context " << ctx
100
               << std::endl;
101
      return;
102
    }
103
  }
104
  // if we don't have a proof node, a generator failed
105
  if (pnp == nullptr)
106
  {
107
    Assert(pg != nullptr);
108
    AlwaysAssert(false) << "...ensureClosed: null proof from " << ss.str()
109
                        << sdiag.str();
110
  }
111
  std::vector<Node> fassumps;
112
  expr::getFreeAssumptions(pnp, fassumps);
113
  bool isClosed = true;
114
  std::stringstream ssf;
115
  for (const Node& fa : fassumps)
116
  {
117
    if (std::find(assumps.begin(), assumps.end(), fa) == assumps.end())
118
    {
119
      isClosed = false;
120
      ssf << "- " << fa << std::endl;
121
    }
122
  }
123
  if (!isClosed)
124
  {
125
    Trace(c) << "Free assumptions:" << std::endl;
126
    Trace(c) << ssf.str();
127
    if (!assumps.empty())
128
    {
129
      Trace(c) << "Expected assumptions:" << std::endl;
130
      for (const Node& a : assumps)
131
      {
132
        Trace(c) << "- " << a << std::endl;
133
      }
134
    }
135
    if (dumpProofTraceOn)
136
    {
137
      Trace("dump-proof-error") << " Proof: " << *pnp << std::endl;
138
    }
139
  }
140
  AlwaysAssert(isClosed) << "...ensureClosed: open proof from " << ss.str()
141
                         << sdiag.str();
142
  Trace(c) << "...ensureClosed: success" << std::endl;
143
  Trace(c) << "====" << std::endl;
144
}
145
146
752408
void pfgEnsureClosed(Node proven,
147
                     ProofGenerator* pg,
148
                     const char* c,
149
                     const char* ctx,
150
                     bool reqGen)
151
{
152
752408
  Assert(!proven.isNull());
153
  // proof generator may be null
154
1504816
  std::vector<Node> assumps;
155
752408
  ensureClosedWrtInternal(proven, pg, nullptr, assumps, c, ctx, reqGen);
156
752408
}
157
158
void pfgEnsureClosedWrt(Node proven,
159
                        ProofGenerator* pg,
160
                        const std::vector<Node>& assumps,
161
                        const char* c,
162
                        const char* ctx,
163
                        bool reqGen)
164
{
165
  Assert(!proven.isNull());
166
  // proof generator may be null
167
  ensureClosedWrtInternal(proven, pg, nullptr, assumps, c, ctx, reqGen);
168
}
169
170
void pfnEnsureClosed(ProofNode* pn, const char* c, const char* ctx)
171
{
172
  ensureClosedWrtInternal(Node::null(), nullptr, pn, {}, c, ctx, false);
173
}
174
175
void pfnEnsureClosedWrt(ProofNode* pn,
176
                        const std::vector<Node>& assumps,
177
                        const char* c,
178
                        const char* ctx)
179
{
180
  ensureClosedWrtInternal(Node::null(), nullptr, pn, assumps, c, ctx, false);
181
}
182
183
28191
}  // namespace cvc5