GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/util/result.cpp Lines: 124 198 62.6 %
Date: 2021-05-22 Branches: 79 228 34.6 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Aina Niemetz, Morgan Deters, Tim King
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
 * Encapsulation of the result of a query.
14
 */
15
#include "util/result.h"
16
17
#include <algorithm>
18
#include <cctype>
19
#include <iostream>
20
#include <sstream>
21
#include <string>
22
23
#include "base/check.h"
24
#include "options/set_language.h"
25
26
using namespace std;
27
28
namespace cvc5 {
29
30
359440
Result::Result()
31
    : d_sat(SAT_UNKNOWN),
32
      d_entailment(ENTAILMENT_UNKNOWN),
33
      d_which(TYPE_NONE),
34
      d_unknownExplanation(UNKNOWN_REASON),
35
359440
      d_inputName("")
36
{
37
359440
}
38
39
14584
Result::Result(enum Sat s, std::string inputName)
40
    : d_sat(s),
41
      d_entailment(ENTAILMENT_UNKNOWN),
42
      d_which(TYPE_SAT),
43
      d_unknownExplanation(UNKNOWN_REASON),
44
14584
      d_inputName(inputName)
45
{
46
14584
  PrettyCheckArgument(s != SAT_UNKNOWN,
47
                      "Must provide a reason for satisfiability being unknown");
48
14584
}
49
50
629
Result::Result(enum Entailment e, std::string inputName)
51
    : d_sat(SAT_UNKNOWN),
52
      d_entailment(e),
53
      d_which(TYPE_ENTAILMENT),
54
      d_unknownExplanation(UNKNOWN_REASON),
55
629
      d_inputName(inputName)
56
{
57
629
  PrettyCheckArgument(e != ENTAILMENT_UNKNOWN,
58
                      "Must provide a reason for entailment being unknown");
59
629
}
60
61
14904
Result::Result(enum Sat s,
62
               enum UnknownExplanation unknownExplanation,
63
14904
               std::string inputName)
64
    : d_sat(s),
65
      d_entailment(ENTAILMENT_UNKNOWN),
66
      d_which(TYPE_SAT),
67
      d_unknownExplanation(unknownExplanation),
68
14904
      d_inputName(inputName)
69
{
70
14904
  PrettyCheckArgument(s == SAT_UNKNOWN,
71
                      "improper use of unknown-result constructor");
72
14904
}
73
74
89075
Result::Result(enum Entailment e,
75
               enum UnknownExplanation unknownExplanation,
76
89075
               std::string inputName)
77
    : d_sat(SAT_UNKNOWN),
78
      d_entailment(e),
79
      d_which(TYPE_ENTAILMENT),
80
      d_unknownExplanation(unknownExplanation),
81
89075
      d_inputName(inputName)
82
{
83
89075
  PrettyCheckArgument(e == ENTAILMENT_UNKNOWN,
84
                      "improper use of unknown-result constructor");
85
89075
}
86
87
3504
Result::Result(const std::string& instr, std::string inputName)
88
    : d_sat(SAT_UNKNOWN),
89
      d_entailment(ENTAILMENT_UNKNOWN),
90
      d_which(TYPE_NONE),
91
      d_unknownExplanation(UNKNOWN_REASON),
92
3504
      d_inputName(inputName)
93
{
94
7008
  string s = instr;
95
3504
  transform(s.begin(), s.end(), s.begin(), ::tolower);
96
3504
  if (s == "sat" || s == "satisfiable") {
97
1431
    d_which = TYPE_SAT;
98
1431
    d_sat = SAT;
99
2073
  } else if (s == "unsat" || s == "unsatisfiable") {
100
2034
    d_which = TYPE_SAT;
101
2034
    d_sat = UNSAT;
102
  }
103
39
  else if (s == "entailed")
104
  {
105
    d_which = TYPE_ENTAILMENT;
106
    d_entailment = ENTAILED;
107
  }
108
39
  else if (s == "not_entailed")
109
  {
110
    d_which = TYPE_ENTAILMENT;
111
    d_entailment = NOT_ENTAILED;
112
  }
113
39
  else if (s == "incomplete")
114
  {
115
    d_which = TYPE_SAT;
116
    d_sat = SAT_UNKNOWN;
117
    d_unknownExplanation = INCOMPLETE;
118
  }
119
39
  else if (s == "timeout")
120
  {
121
    d_which = TYPE_SAT;
122
    d_sat = SAT_UNKNOWN;
123
    d_unknownExplanation = TIMEOUT;
124
  }
125
39
  else if (s == "resourceout")
126
  {
127
    d_which = TYPE_SAT;
128
    d_sat = SAT_UNKNOWN;
129
    d_unknownExplanation = RESOURCEOUT;
130
  }
131
39
  else if (s == "memout")
132
  {
133
    d_which = TYPE_SAT;
134
    d_sat = SAT_UNKNOWN;
135
    d_unknownExplanation = MEMOUT;
136
  }
137
39
  else if (s == "interrupted")
138
  {
139
    d_which = TYPE_SAT;
140
    d_sat = SAT_UNKNOWN;
141
    d_unknownExplanation = INTERRUPTED;
142
  }
143
39
  else if (s.size() >= 7 && s.compare(0, 7, "unknown") == 0)
144
  {
145
39
    d_which = TYPE_SAT;
146
39
    d_sat = SAT_UNKNOWN;
147
  }
148
  else
149
  {
150
    IllegalArgument(s,
151
                    "expected satisfiability/entailment result, "
152
                    "instead got `%s'",
153
                    s.c_str());
154
  }
155
3504
}
156
157
12
Result::UnknownExplanation Result::whyUnknown() const {
158
12
  PrettyCheckArgument(isUnknown(), this,
159
                      "This result is not unknown, so the reason for "
160
                      "being unknown cannot be inquired of it");
161
12
  return d_unknownExplanation;
162
}
163
164
3597
bool Result::operator==(const Result& r) const {
165
3597
  if (d_which != r.d_which) {
166
    return false;
167
  }
168
3597
  if (d_which == TYPE_SAT) {
169
3597
    return d_sat == r.d_sat && (d_sat != SAT_UNKNOWN ||
170
3597
                                d_unknownExplanation == r.d_unknownExplanation);
171
  }
172
  if (d_which == TYPE_ENTAILMENT)
173
  {
174
    return d_entailment == r.d_entailment
175
           && (d_entailment != ENTAILMENT_UNKNOWN
176
               || d_unknownExplanation == r.d_unknownExplanation);
177
  }
178
  return false;
179
}
180
181
bool operator==(enum Result::Sat sr, const Result& r) { return r == sr; }
182
183
bool operator==(enum Result::Entailment e, const Result& r) { return r == e; }
184
bool operator!=(enum Result::Sat s, const Result& r) { return !(s == r); }
185
bool operator!=(enum Result::Entailment e, const Result& r)
186
{
187
  return !(e == r);
188
}
189
190
26504
Result Result::asSatisfiabilityResult() const {
191
26504
  if (d_which == TYPE_SAT) {
192
26502
    return *this;
193
  }
194
195
2
  if (d_which == TYPE_ENTAILMENT)
196
  {
197
    switch (d_entailment)
198
    {
199
      case NOT_ENTAILED: return Result(SAT, d_inputName);
200
201
      case ENTAILED: return Result(UNSAT, d_inputName);
202
203
      case ENTAILMENT_UNKNOWN:
204
        return Result(SAT_UNKNOWN, d_unknownExplanation, d_inputName);
205
206
      default: Unhandled() << d_entailment;
207
    }
208
  }
209
210
  // TYPE_NONE
211
2
  return Result(SAT_UNKNOWN, NO_STATUS, d_inputName);
212
}
213
214
89704
Result Result::asEntailmentResult() const
215
{
216
89704
  if (d_which == TYPE_ENTAILMENT)
217
  {
218
89072
    return *this;
219
  }
220
221
632
  if (d_which == TYPE_SAT) {
222
632
    switch (d_sat) {
223
216
      case SAT: return Result(NOT_ENTAILED, d_inputName);
224
225
413
      case UNSAT: return Result(ENTAILED, d_inputName);
226
227
3
      case SAT_UNKNOWN:
228
3
        return Result(ENTAILMENT_UNKNOWN, d_unknownExplanation, d_inputName);
229
230
      default: Unhandled() << d_sat;
231
    }
232
  }
233
234
  // TYPE_NONE
235
  return Result(ENTAILMENT_UNKNOWN, NO_STATUS, d_inputName);
236
}
237
238
10613
string Result::toString() const {
239
21226
  stringstream ss;
240
10613
  ss << *this;
241
21226
  return ss.str();
242
}
243
244
ostream& operator<<(ostream& out, enum Result::Sat s) {
245
  switch (s) {
246
    case Result::UNSAT:
247
      out << "UNSAT";
248
      break;
249
    case Result::SAT:
250
      out << "SAT";
251
      break;
252
    case Result::SAT_UNKNOWN:
253
      out << "SAT_UNKNOWN";
254
      break;
255
    default: Unhandled() << s;
256
  }
257
  return out;
258
}
259
260
ostream& operator<<(ostream& out, enum Result::Entailment e)
261
{
262
  switch (e)
263
  {
264
    case Result::NOT_ENTAILED: out << "NOT_ENTAILED"; break;
265
    case Result::ENTAILED: out << "ENTAILED"; break;
266
    case Result::ENTAILMENT_UNKNOWN: out << "ENTAILMENT_UNKNOWN"; break;
267
    default: Unhandled() << e;
268
  }
269
  return out;
270
}
271
272
8
ostream& operator<<(ostream& out, enum Result::UnknownExplanation e)
273
{
274
8
  switch (e)
275
  {
276
    case Result::REQUIRES_FULL_CHECK: out << "REQUIRES_FULL_CHECK"; break;
277
8
    case Result::INCOMPLETE: out << "INCOMPLETE"; break;
278
    case Result::TIMEOUT: out << "TIMEOUT"; break;
279
    case Result::RESOURCEOUT: out << "RESOURCEOUT"; break;
280
    case Result::MEMOUT: out << "MEMOUT"; break;
281
    case Result::INTERRUPTED: out << "INTERRUPTED"; break;
282
    case Result::NO_STATUS: out << "NO_STATUS"; break;
283
    case Result::UNSUPPORTED: out << "UNSUPPORTED"; break;
284
    case Result::OTHER: out << "OTHER"; break;
285
    case Result::UNKNOWN_REASON: out << "UNKNOWN_REASON"; break;
286
    default: Unhandled() << e;
287
  }
288
8
  return out;
289
}
290
291
10614
ostream& operator<<(ostream& out, const Result& r) {
292
10614
  r.toStream(out, language::SetLanguage::getLanguage(out));
293
10614
  return out;
294
} /* operator<<(ostream&, const Result&) */
295
296
10513
void Result::toStreamDefault(std::ostream& out) const {
297
10513
  if (getType() == Result::TYPE_SAT) {
298
9928
    switch (isSat()) {
299
4060
      case Result::UNSAT:
300
4060
        out << "unsat";
301
4060
        break;
302
5866
      case Result::SAT:
303
5866
        out << "sat";
304
5866
        break;
305
2
      case Result::SAT_UNKNOWN:
306
2
        out << "unknown";
307
2
        if (whyUnknown() != Result::UNKNOWN_REASON) {
308
2
          out << " (" << whyUnknown() << ")";
309
        }
310
2
        break;
311
    }
312
  } else {
313
585
    switch (isEntailed())
314
    {
315
204
      case Result::NOT_ENTAILED: out << "not_entailed"; break;
316
381
      case Result::ENTAILED: out << "entailed"; break;
317
      case Result::ENTAILMENT_UNKNOWN:
318
        out << "unknown";
319
        if (whyUnknown() != Result::UNKNOWN_REASON) {
320
          out << " (" << whyUnknown() << ")";
321
        }
322
        break;
323
    }
324
  }
325
10513
} /* Result::toStreamDefault() */
326
327
9488
void Result::toStreamSmt2(ostream& out) const {
328
9488
  if (getType() == Result::TYPE_SAT && isSat() == Result::SAT_UNKNOWN) {
329
59
    out << "unknown";
330
  } else {
331
9429
    toStreamDefault(out);
332
  }
333
9488
}
334
335
42
void Result::toStreamTptp(std::ostream& out) const {
336
42
  out << "% SZS status ";
337
42
  if (isSat() == Result::SAT) {
338
9
    out << "Satisfiable";
339
33
  } else if (isSat() == Result::UNSAT) {
340
9
    out << "Unsatisfiable";
341
  }
342
24
  else if (isEntailed() == Result::ENTAILED)
343
  {
344
16
    out << "Theorem";
345
  }
346
8
  else if (isEntailed() == Result::NOT_ENTAILED)
347
  {
348
6
    out << "CounterSatisfiable";
349
  }
350
  else
351
  {
352
2
    out << "GaveUp";
353
  }
354
42
  out << " for " << getInputName();
355
42
}
356
357
10614
void Result::toStream(std::ostream& out, OutputLanguage language) const {
358
10614
  switch (language) {
359
178
    case language::output::LANG_SYGUS_V2: toStreamSmt2(out); break;
360
42
    case language::output::LANG_TPTP:
361
42
      toStreamTptp(out);
362
42
      break;
363
10394
    default:
364
10394
      if (language::isOutputLang_smt2(language))
365
      {
366
9310
        toStreamSmt2(out);
367
      }
368
      else
369
      {
370
1084
        toStreamDefault(out);
371
      }
372
10394
      break;
373
  };
374
10614
}
375
376
28194
}  // namespace cvc5