GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/evaluator.cpp Lines: 387 494 78.3 %
Date: 2021-05-22 Branches: 694 1777 39.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andres Noetzli, 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
 * The Evaluator class.
14
 */
15
16
#include "theory/evaluator.h"
17
18
#include "theory/bv/theory_bv_utils.h"
19
#include "theory/rewriter.h"
20
#include "theory/strings/theory_strings_utils.h"
21
#include "theory/theory.h"
22
#include "util/integer.h"
23
24
namespace cvc5 {
25
namespace theory {
26
27
1069594
EvalResult::EvalResult(const EvalResult& other)
28
{
29
1069594
  d_tag = other.d_tag;
30
1069594
  switch (d_tag)
31
  {
32
98208
    case BOOL: d_bool = other.d_bool; break;
33
581864
    case BITVECTOR:
34
581864
      new (&d_bv) BitVector;
35
581864
      d_bv = other.d_bv;
36
581864
      break;
37
54115
    case RATIONAL:
38
54115
      new (&d_rat) Rational;
39
54115
      d_rat = other.d_rat;
40
54115
      break;
41
264988
    case STRING:
42
264988
      new (&d_str) String;
43
264988
      d_str = other.d_str;
44
264988
      break;
45
    case UCONST:
46
      new (&d_uc)
47
          UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
48
      break;
49
70419
    case INVALID: break;
50
  }
51
1069594
}
52
53
2914337
EvalResult& EvalResult::operator=(const EvalResult& other)
54
{
55
2914337
  if (this != &other)
56
  {
57
2914337
    d_tag = other.d_tag;
58
2914337
    switch (d_tag)
59
    {
60
235345
      case BOOL: d_bool = other.d_bool; break;
61
1739221
      case BITVECTOR:
62
1739221
        new (&d_bv) BitVector;
63
1739221
        d_bv = other.d_bv;
64
1739221
        break;
65
301627
      case RATIONAL:
66
301627
        new (&d_rat) Rational;
67
301627
        d_rat = other.d_rat;
68
301627
        break;
69
318448
      case STRING:
70
318448
        new (&d_str) String;
71
318448
        d_str = other.d_str;
72
318448
        break;
73
      case UCONST:
74
        new (&d_uc)
75
            UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
76
        break;
77
319696
      case INVALID: break;
78
    }
79
  }
80
2914337
  return *this;
81
}
82
83
13718796
EvalResult::~EvalResult()
84
{
85
6859398
  switch (d_tag)
86
  {
87
4038993
    case BITVECTOR:
88
    {
89
4038993
      d_bv.~BitVector();
90
4038993
      break;
91
    }
92
640069
    case RATIONAL:
93
    {
94
640069
      d_rat.~Rational();
95
640069
      break;
96
    }
97
901827
    case STRING:
98
    {
99
901827
      d_str.~String();
100
901827
      break;
101
    }
102
    case UCONST:
103
    {
104
      d_uc.~UninterpretedConstant();
105
      break;
106
    }
107
1278509
    default: break;
108
  }
109
6859398
}
110
111
1350517
Node EvalResult::toNode() const
112
{
113
1350517
  NodeManager* nm = NodeManager::currentNM();
114
1350517
  switch (d_tag)
115
  {
116
107855
    case EvalResult::BOOL: return nm->mkConst(d_bool);
117
805664
    case EvalResult::BITVECTOR: return nm->mkConst(d_bv);
118
99105
    case EvalResult::RATIONAL: return nm->mkConst(d_rat);
119
267625
    case EvalResult::STRING: return nm->mkConst(d_str);
120
    case EvalResult::UCONST: return nm->mkConst(d_uc);
121
70268
    default:
122
    {
123
140536
      Trace("evaluator") << "Missing conversion from " << d_tag << " to node"
124
70268
                         << std::endl;
125
70268
      return Node();
126
    }
127
  }
128
}
129
130
910526
Node Evaluator::eval(TNode n,
131
                     const std::vector<Node>& args,
132
                     const std::vector<Node>& vals,
133
                     bool useRewriter) const
134
{
135
1821052
  std::unordered_map<Node, Node> visited;
136
1821052
  return eval(n, args, vals, visited, useRewriter);
137
}
138
927204
Node Evaluator::eval(TNode n,
139
                     const std::vector<Node>& args,
140
                     const std::vector<Node>& vals,
141
                     const std::unordered_map<Node, Node>& visited,
142
                     bool useRewriter) const
143
{
144
1854408
  Trace("evaluator") << "Evaluating " << n << " under substitution " << args
145
1854408
                     << " " << vals << " with visited size = " << visited.size()
146
927204
                     << std::endl;
147
1854408
  std::unordered_map<TNode, Node> evalAsNode;
148
1854408
  std::unordered_map<TNode, EvalResult> results;
149
  // add visited to results
150
948016
  for (const std::pair<const Node, Node>& p : visited)
151
  {
152
20812
    Trace("evaluator") << "Add " << p.first << " == " << p.second << std::endl;
153
20812
    results[p.first] = evalInternal(p.second, args, vals, evalAsNode, results, useRewriter);
154
20812
    if (results[p.first].d_tag == EvalResult::INVALID)
155
    {
156
      // could not evaluate, use the evalAsNode map
157
151
      std::unordered_map<TNode, Node>::iterator itn = evalAsNode.find(p.second);
158
151
      Assert(itn != evalAsNode.end());
159
302
      Node val = itn->second;
160
151
      if (useRewriter)
161
      {
162
151
        val = Rewriter::rewrite(val);
163
      }
164
151
      evalAsNode[p.first] = val;
165
    }
166
  }
167
927204
  Trace("evaluator") << "Run eval internal..." << std::endl;
168
927204
  Node ret = evalInternal(n, args, vals, evalAsNode, results, useRewriter).toNode();
169
  // if we failed to evaluate
170
927204
  if (ret.isNull() && useRewriter)
171
  {
172
    // should be stored in the evaluation-as-node map
173
70268
    std::unordered_map<TNode, Node>::iterator itn = evalAsNode.find(n);
174
70268
    Assert(itn != evalAsNode.end());
175
70268
    ret = Rewriter::rewrite(itn->second);
176
  }
177
  // should be the same as substitution + rewriting, or possibly null if
178
  // useRewriter is false
179
927204
  Assert((ret.isNull() && !useRewriter)
180
         || ret
181
                == Rewriter::rewrite(n.substitute(
182
                       args.begin(), args.end(), vals.begin(), vals.end())));
183
1854408
  return ret;
184
}
185
186
948016
EvalResult Evaluator::evalInternal(
187
    TNode n,
188
    const std::vector<Node>& args,
189
    const std::vector<Node>& vals,
190
    std::unordered_map<TNode, Node>& evalAsNode,
191
    std::unordered_map<TNode, EvalResult>& results,
192
    bool useRewriter) const
193
{
194
1896032
  std::vector<TNode> queue;
195
948016
  queue.emplace_back(n);
196
948016
  std::unordered_map<TNode, EvalResult>::iterator itr;
197
198
9829036
  while (queue.size() != 0)
199
  {
200
8379976
    TNode currNode = queue.back();
201
202
4767136
    if (results.find(currNode) != results.end())
203
    {
204
326626
      queue.pop_back();
205
326626
      continue;
206
    }
207
208
4113884
    bool doProcess = true;
209
4113884
    bool isVar = false;
210
4113884
    bool doEval = true;
211
4113884
    if (currNode.isVar())
212
    {
213
      // we do not evaluate if we are a variable, instead we look for the
214
      // variable in args below
215
946465
      isVar = true;
216
946465
      doEval = false;
217
    }
218
3167419
    else if (currNode.getMetaKind() == kind::metakind::PARAMETERIZED)
219
    {
220
607672
      TNode op = currNode.getOperator();
221
      // Certain nodes are parameterized with constant operators, including
222
      // bitvector extract. These operators do not need to be evaluated.
223
303836
      if (!op.isConst())
224
      {
225
130586
        itr = results.find(op);
226
130586
        if (itr == results.end())
227
        {
228
54247
          queue.emplace_back(op);
229
54247
          doProcess = false;
230
        }
231
76339
        else if (itr->second.d_tag == EvalResult::INVALID)
232
        {
233
76339
          doEval = false;
234
        }
235
      }
236
    }
237
8952587
    for (const auto& currNodeChild : currNode)
238
    {
239
4838703
      itr = results.find(currNodeChild);
240
4838703
      if (itr == results.end())
241
      {
242
2217888
        queue.emplace_back(currNodeChild);
243
2217888
        doProcess = false;
244
      }
245
2620815
      else if (itr->second.d_tag == EvalResult::INVALID)
246
      {
247
        // we cannot evaluate since there was an invalid child
248
303288
        doEval = false;
249
      }
250
    }
251
8227768
    Trace("evaluator") << "Evaluator: visit " << currNode
252
4113884
                       << ", process = " << doProcess
253
4113884
                       << ", evaluate = " << doEval << std::endl;
254
255
4113884
    if (doProcess)
256
    {
257
2893525
      queue.pop_back();
258
259
5612632
      Node currNodeVal = currNode;
260
      // whether we need to reconstruct the current node in the case of failure
261
2893525
      bool needsReconstruct = true;
262
263
      // The code below should either:
264
      // (1) store a valid EvalResult into results[currNode], or
265
      // (2) store an invalid EvalResult into results[currNode] and
266
      // store the result of substitution + rewriting currNode { args -> vals }
267
      // into evalAsNode[currNode].
268
269
      // If we did not successfully evaluate all children, or are a variable
270
2893525
      if (!doEval)
271
      {
272
1136682
        if (isVar)
273
        {
274
946465
          const auto& it = std::find(args.begin(), args.end(), currNode);
275
1006504
          if (it == args.end())
276
          {
277
            // variable with no substitution is itself
278
60039
            evalAsNode[currNode] = currNode;
279
60039
            results[currNode] = EvalResult();
280
60039
            continue;
281
          }
282
886426
          ptrdiff_t pos = std::distance(args.begin(), it);
283
886426
          currNodeVal = vals[pos];
284
          // Don't need to rewrite since range of substitution should already
285
          // be normalized.
286
        }
287
        else
288
        {
289
          // Reconstruct the node with a combination of the children that
290
          // successfully evaluated, and the children that did not.
291
190217
          Trace("evaluator") << "Evaluator: collect arguments" << std::endl;
292
190217
          currNodeVal = reconstruct(currNodeVal, results, evalAsNode);
293
190217
          if (useRewriter)
294
          {
295
            // Rewrite the result now, if we use the rewriter. We will see below
296
            // if we are able to turn it into a valid EvalResult.
297
190217
            currNodeVal = Rewriter::rewrite(currNodeVal);
298
          }
299
        }
300
1076643
        needsReconstruct = false;
301
2153286
        Trace("evaluator") << "Evaluator: now after substitution + rewriting: "
302
1076643
                           << currNodeVal << std::endl;
303
1191022
        if (currNodeVal.getNumChildren() > 0)
304
        {
305
          // We may continue with a valid EvalResult at this point only if
306
          // we have no children. We must otherwise fail here since some of
307
          // our children may not have successful evaluations.
308
114379
          results[currNode] = EvalResult();
309
114379
          evalAsNode[currNode] = currNodeVal;
310
114379
          continue;
311
        }
312
        // Otherwise, we may be able to turn the overall result into an
313
        // valid EvalResult and continue. We fallthrough and continue with the
314
        // block of code below.
315
      }
316
317
2719107
      Trace("evaluator") << "Current node val : " << currNodeVal << std::endl;
318
319
2719107
      switch (currNodeVal.getKind())
320
      {
321
        // APPLY_UF is a special case where we look up the operator and apply
322
        // beta reduction if possible
323
        case kind::APPLY_UF:
324
        {
325
          Trace("evaluator") << "Evaluate " << currNode << std::endl;
326
          TNode op = currNode.getOperator();
327
          Assert(evalAsNode.find(op) != evalAsNode.end());
328
          // no function can be a valid EvalResult
329
          op = evalAsNode[op];
330
          Trace("evaluator") << "Operator evaluated to " << op << std::endl;
331
          if (op.getKind() != kind::LAMBDA)
332
          {
333
            // this node is not evaluatable due to operator, must add to
334
            // evalAsNode
335
            results[currNode] = EvalResult();
336
            evalAsNode[currNode] = reconstruct(currNode, results, evalAsNode);
337
            continue;
338
          }
339
          // Create a copy of the current substitutions
340
          std::vector<Node> lambdaArgs(args);
341
          std::vector<Node> lambdaVals(vals);
342
343
          // Add the values for the arguments of the lambda as substitutions at
344
          // the beginning of the vector to shadow variables from outer scopes
345
          // with the same name
346
          for (const auto& lambdaArg : op[0])
347
          {
348
            lambdaArgs.insert(lambdaArgs.begin(), lambdaArg);
349
          }
350
351
          for (const auto& lambdaVal : currNode)
352
          {
353
            lambdaVals.insert(lambdaVals.begin(), results[lambdaVal].toNode());
354
          }
355
356
          // Lambdas are evaluated in a recursive fashion because each
357
          // evaluation requires different substitutions. We use a fresh cache
358
          // since the evaluation of op[1] is under a new substitution and thus
359
          // should not be cached. We could alternatively copy evalAsNode to
360
          // evalAsNodeC but favor avoiding this copy for performance reasons.
361
          std::unordered_map<TNode, Node> evalAsNodeC;
362
          std::unordered_map<TNode, EvalResult> resultsC;
363
          results[currNode] = evalInternal(op[1],
364
                                           lambdaArgs,
365
                                           lambdaVals,
366
                                           evalAsNodeC,
367
                                           resultsC,
368
                                           useRewriter);
369
          Trace("evaluator") << "Evaluated via arguments to "
370
                             << results[currNode].d_tag << std::endl;
371
          if (results[currNode].d_tag == EvalResult::INVALID)
372
          {
373
            // evaluation was invalid, we take the node of op[1] as the result
374
            evalAsNode[currNode] = evalAsNodeC[op[1]];
375
            Trace("evaluator")
376
                << "Take node evaluation: " << evalAsNodeC[op[1]] << std::endl;
377
          }
378
        }
379
        break;
380
33972
        case kind::CONST_BOOLEAN:
381
33972
          results[currNode] = EvalResult(currNodeVal.getConst<bool>());
382
33972
          break;
383
384
41817
        case kind::NOT:
385
        {
386
41817
          results[currNode] = EvalResult(!(results[currNode[0]].d_bool));
387
41817
          break;
388
        }
389
390
9711
        case kind::AND:
391
        {
392
9711
          bool res = results[currNode[0]].d_bool;
393
23613
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
394
          {
395
13902
            res = res && results[currNode[i]].d_bool;
396
          }
397
9711
          results[currNode] = EvalResult(res);
398
9711
          break;
399
        }
400
401
15363
        case kind::OR:
402
        {
403
15363
          bool res = results[currNode[0]].d_bool;
404
63861
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
405
          {
406
48498
            res = res || results[currNode[i]].d_bool;
407
          }
408
15363
          results[currNode] = EvalResult(res);
409
15363
          break;
410
        }
411
412
240903
        case kind::CONST_RATIONAL:
413
        {
414
240903
          const Rational& r = currNodeVal.getConst<Rational>();
415
240903
          results[currNode] = EvalResult(r);
416
240903
          break;
417
        }
418
        case kind::UNINTERPRETED_CONSTANT:
419
        {
420
          const UninterpretedConstant& uc =
421
              currNodeVal.getConst<UninterpretedConstant>();
422
          results[currNode] = EvalResult(uc);
423
          break;
424
        }
425
22063
        case kind::PLUS:
426
        {
427
44126
          Rational res = results[currNode[0]].d_rat;
428
48456
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
429
          {
430
26393
            res = res + results[currNode[i]].d_rat;
431
          }
432
22063
          results[currNode] = EvalResult(res);
433
22063
          break;
434
        }
435
436
2214
        case kind::MINUS:
437
        {
438
2214
          const Rational& x = results[currNode[0]].d_rat;
439
2214
          const Rational& y = results[currNode[1]].d_rat;
440
2214
          results[currNode] = EvalResult(x - y);
441
2214
          break;
442
        }
443
444
        case kind::UMINUS:
445
        {
446
          const Rational& x = results[currNode[0]].d_rat;
447
          results[currNode] = EvalResult(-x);
448
          break;
449
        }
450
18386
        case kind::MULT:
451
        case kind::NONLINEAR_MULT:
452
        {
453
36772
          Rational res = results[currNode[0]].d_rat;
454
36784
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
455
          {
456
18398
            res = res * results[currNode[i]].d_rat;
457
          }
458
18386
          results[currNode] = EvalResult(res);
459
18386
          break;
460
        }
461
462
22434
        case kind::GEQ:
463
        {
464
22434
          const Rational& x = results[currNode[0]].d_rat;
465
22434
          const Rational& y = results[currNode[1]].d_rat;
466
22434
          results[currNode] = EvalResult(x >= y);
467
22434
          break;
468
        }
469
14823
        case kind::LEQ:
470
        {
471
14823
          const Rational& x = results[currNode[0]].d_rat;
472
14823
          const Rational& y = results[currNode[1]].d_rat;
473
14823
          results[currNode] = EvalResult(x <= y);
474
14823
          break;
475
        }
476
17379
        case kind::GT:
477
        {
478
17379
          const Rational& x = results[currNode[0]].d_rat;
479
17379
          const Rational& y = results[currNode[1]].d_rat;
480
17379
          results[currNode] = EvalResult(x > y);
481
17379
          break;
482
        }
483
18729
        case kind::LT:
484
        {
485
18729
          const Rational& x = results[currNode[0]].d_rat;
486
18729
          const Rational& y = results[currNode[1]].d_rat;
487
18729
          results[currNode] = EvalResult(x < y);
488
18729
          break;
489
        }
490
        case kind::ABS:
491
        {
492
          const Rational& x = results[currNode[0]].d_rat;
493
          results[currNode] = EvalResult(x.abs());
494
          break;
495
        }
496
290157
        case kind::CONST_STRING:
497
290157
          results[currNode] = EvalResult(currNodeVal.getConst<String>());
498
290157
          break;
499
500
24433
        case kind::STRING_CONCAT:
501
        {
502
48866
          String res = results[currNode[0]].d_str;
503
48893
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
504
          {
505
24460
            res = res.concat(results[currNode[i]].d_str);
506
          }
507
24433
          results[currNode] = EvalResult(res);
508
24433
          break;
509
        }
510
511
749
        case kind::STRING_LENGTH:
512
        {
513
749
          const String& s = results[currNode[0]].d_str;
514
749
          results[currNode] = EvalResult(Rational(s.size()));
515
749
          break;
516
        }
517
518
3459
        case kind::STRING_SUBSTR:
519
        {
520
3459
          const String& s = results[currNode[0]].d_str;
521
6918
          Integer s_len(s.size());
522
6918
          Integer i = results[currNode[1]].d_rat.getNumerator();
523
6918
          Integer j = results[currNode[2]].d_rat.getNumerator();
524
525
3459
          if (i.strictlyNegative() || j.strictlyNegative() || i >= s_len)
526
          {
527
597
            results[currNode] = EvalResult(String(""));
528
          }
529
2862
          else if (i + j > s_len)
530
          {
531
225
            results[currNode] =
532
450
                EvalResult(s.suffix((s_len - i).toUnsignedInt()));
533
          }
534
          else
535
          {
536
2637
            results[currNode] =
537
5274
                EvalResult(s.substr(i.toUnsignedInt(), j.toUnsignedInt()));
538
          }
539
3459
          break;
540
        }
541
542
        case kind::STRING_UPDATE:
543
        {
544
          const String& s = results[currNode[0]].d_str;
545
          Integer s_len(s.size());
546
          Integer i = results[currNode[1]].d_rat.getNumerator();
547
          const String& t = results[currNode[2]].d_str;
548
549
          if (i.strictlyNegative() || i >= s_len)
550
          {
551
            results[currNode] = EvalResult(s);
552
          }
553
          else
554
          {
555
            results[currNode] = EvalResult(s.update(i.toUnsignedInt(), t));
556
          }
557
          break;
558
        }
559
        case kind::STRING_CHARAT:
560
        {
561
          const String& s = results[currNode[0]].d_str;
562
          Integer s_len(s.size());
563
          Integer i = results[currNode[1]].d_rat.getNumerator();
564
          if (i.strictlyNegative() || i >= s_len)
565
          {
566
            results[currNode] = EvalResult(String(""));
567
          }
568
          else
569
          {
570
            results[currNode] = EvalResult(s.substr(i.toUnsignedInt(), 1));
571
          }
572
          break;
573
        }
574
575
279
        case kind::STRING_STRCTN:
576
        {
577
279
          const String& s = results[currNode[0]].d_str;
578
279
          const String& t = results[currNode[1]].d_str;
579
279
          results[currNode] = EvalResult(s.find(t) != std::string::npos);
580
279
          break;
581
        }
582
583
8
        case kind::STRING_STRIDOF:
584
        {
585
8
          const String& s = results[currNode[0]].d_str;
586
16
          Integer s_len(s.size());
587
8
          const String& x = results[currNode[1]].d_str;
588
16
          Integer i = results[currNode[2]].d_rat.getNumerator();
589
590
8
          if (i.strictlyNegative())
591
          {
592
            results[currNode] = EvalResult(Rational(-1));
593
          }
594
          else
595
          {
596
8
            size_t r = s.find(x, i.toUnsignedInt());
597
8
            if (r == std::string::npos)
598
            {
599
6
              results[currNode] = EvalResult(Rational(-1));
600
            }
601
            else
602
            {
603
2
              results[currNode] = EvalResult(Rational(r));
604
            }
605
          }
606
8
          break;
607
        }
608
609
339
        case kind::STRING_STRREPL:
610
        {
611
339
          const String& s = results[currNode[0]].d_str;
612
339
          const String& x = results[currNode[1]].d_str;
613
339
          const String& y = results[currNode[2]].d_str;
614
339
          results[currNode] = EvalResult(s.replace(x, y));
615
339
          break;
616
        }
617
618
        case kind::STRING_PREFIX:
619
        {
620
          const String& t = results[currNode[0]].d_str;
621
          const String& s = results[currNode[1]].d_str;
622
          if (s.size() < t.size())
623
          {
624
            results[currNode] = EvalResult(false);
625
          }
626
          else
627
          {
628
            results[currNode] = EvalResult(s.prefix(t.size()) == t);
629
          }
630
          break;
631
        }
632
633
        case kind::STRING_SUFFIX:
634
        {
635
          const String& t = results[currNode[0]].d_str;
636
          const String& s = results[currNode[1]].d_str;
637
          if (s.size() < t.size())
638
          {
639
            results[currNode] = EvalResult(false);
640
          }
641
          else
642
          {
643
            results[currNode] = EvalResult(s.suffix(t.size()) == t);
644
          }
645
          break;
646
        }
647
648
3
        case kind::STRING_ITOS:
649
        {
650
6
          Integer i = results[currNode[0]].d_rat.getNumerator();
651
3
          if (i.strictlyNegative())
652
          {
653
1
            results[currNode] = EvalResult(String(""));
654
          }
655
          else
656
          {
657
2
            results[currNode] = EvalResult(String(i.toString()));
658
          }
659
3
          break;
660
        }
661
662
        case kind::STRING_STOI:
663
        {
664
          const String& s = results[currNode[0]].d_str;
665
          if (s.isNumber())
666
          {
667
            results[currNode] = EvalResult(Rational(s.toNumber()));
668
          }
669
          else
670
          {
671
            results[currNode] = EvalResult(Rational(-1));
672
          }
673
          break;
674
        }
675
676
        case kind::STRING_FROM_CODE:
677
        {
678
          Integer i = results[currNode[0]].d_rat.getNumerator();
679
          if (i >= 0 && i < strings::utils::getAlphabetCardinality())
680
          {
681
            std::vector<unsigned> svec = {i.toUnsignedInt()};
682
            results[currNode] = EvalResult(String(svec));
683
          }
684
          else
685
          {
686
            results[currNode] = EvalResult(String(""));
687
          }
688
          break;
689
        }
690
691
4
        case kind::STRING_TO_CODE:
692
        {
693
4
          const String& s = results[currNode[0]].d_str;
694
4
          if (s.size() == 1)
695
          {
696
2
            results[currNode] = EvalResult(Rational(s.getVec()[0]));
697
          }
698
          else
699
          {
700
2
            results[currNode] = EvalResult(Rational(-1));
701
          }
702
4
          break;
703
        }
704
705
1034486
        case kind::CONST_BITVECTOR:
706
1034486
          results[currNode] = EvalResult(currNodeVal.getConst<BitVector>());
707
1034486
          break;
708
709
77850
        case kind::BITVECTOR_NOT:
710
77850
          results[currNode] = EvalResult(~results[currNode[0]].d_bv);
711
77850
          break;
712
713
32149
        case kind::BITVECTOR_NEG:
714
32149
          results[currNode] = EvalResult(-results[currNode[0]].d_bv);
715
32149
          break;
716
717
103554
        case kind::BITVECTOR_EXTRACT:
718
        {
719
103554
          unsigned lo = bv::utils::getExtractLow(currNodeVal);
720
103554
          unsigned hi = bv::utils::getExtractHigh(currNodeVal);
721
103554
          results[currNode] =
722
207108
              EvalResult(results[currNode[0]].d_bv.extract(hi, lo));
723
103554
          break;
724
        }
725
726
68354
        case kind::BITVECTOR_CONCAT:
727
        {
728
136708
          BitVector res = results[currNode[0]].d_bv;
729
140748
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
730
          {
731
72394
            res = res.concat(results[currNode[i]].d_bv);
732
          }
733
68354
          results[currNode] = EvalResult(res);
734
68354
          break;
735
        }
736
737
55251
        case kind::BITVECTOR_ADD:
738
        {
739
110502
          BitVector res = results[currNode[0]].d_bv;
740
110502
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
741
          {
742
55251
            res = res + results[currNode[i]].d_bv;
743
          }
744
55251
          results[currNode] = EvalResult(res);
745
55251
          break;
746
        }
747
748
81498
        case kind::BITVECTOR_MULT:
749
        {
750
162996
          BitVector res = results[currNode[0]].d_bv;
751
174554
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
752
          {
753
93056
            res = res * results[currNode[i]].d_bv;
754
          }
755
81498
          results[currNode] = EvalResult(res);
756
81498
          break;
757
        }
758
70380
        case kind::BITVECTOR_AND:
759
        {
760
140760
          BitVector res = results[currNode[0]].d_bv;
761
140949
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
762
          {
763
70569
            res = res & results[currNode[i]].d_bv;
764
          }
765
70380
          results[currNode] = EvalResult(res);
766
70380
          break;
767
        }
768
769
143891
        case kind::BITVECTOR_OR:
770
        {
771
287782
          BitVector res = results[currNode[0]].d_bv;
772
312356
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
773
          {
774
168465
            res = res | results[currNode[i]].d_bv;
775
          }
776
143891
          results[currNode] = EvalResult(res);
777
143891
          break;
778
        }
779
780
103
        case kind::BITVECTOR_XOR:
781
        {
782
206
          BitVector res = results[currNode[0]].d_bv;
783
206
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
784
          {
785
103
            res = res ^ results[currNode[i]].d_bv;
786
          }
787
103
          results[currNode] = EvalResult(res);
788
103
          break;
789
        }
790
24149
        case kind::BITVECTOR_UDIV:
791
        {
792
48298
          BitVector res = results[currNode[0]].d_bv;
793
24149
          res = res.unsignedDivTotal(results[currNode[1]].d_bv);
794
24149
          results[currNode] = EvalResult(res);
795
24149
          break;
796
        }
797
26243
        case kind::BITVECTOR_UREM:
798
        {
799
52486
          BitVector res = results[currNode[0]].d_bv;
800
26243
          res = res.unsignedRemTotal(results[currNode[1]].d_bv);
801
26243
          results[currNode] = EvalResult(res);
802
26243
          break;
803
        }
804
805
60789
        case kind::EQUAL:
806
        {
807
121578
          EvalResult lhs = results[currNode[0]];
808
121578
          EvalResult rhs = results[currNode[1]];
809
810
60789
          switch (lhs.d_tag)
811
          {
812
660
            case EvalResult::BOOL:
813
            {
814
660
              results[currNode] = EvalResult(lhs.d_bool == rhs.d_bool);
815
660
              break;
816
            }
817
818
40673
            case EvalResult::BITVECTOR:
819
            {
820
40673
              results[currNode] = EvalResult(lhs.d_bv == rhs.d_bv);
821
40673
              break;
822
            }
823
824
18925
            case EvalResult::RATIONAL:
825
            {
826
18925
              results[currNode] = EvalResult(lhs.d_rat == rhs.d_rat);
827
18925
              break;
828
            }
829
830
531
            case EvalResult::STRING:
831
            {
832
531
              results[currNode] = EvalResult(lhs.d_str == rhs.d_str);
833
531
              break;
834
            }
835
            case EvalResult::UCONST:
836
            {
837
              results[currNode] = EvalResult(lhs.d_uc == rhs.d_uc);
838
              break;
839
            }
840
841
            default:
842
            {
843
              Trace("evaluator") << "Theory " << Theory::theoryOf(currNode[0])
844
                                 << " not supported" << std::endl;
845
              results[currNode] = EvalResult();
846
              evalAsNode[currNode] =
847
                  needsReconstruct ? reconstruct(currNode, results, evalAsNode)
848
                                   : currNodeVal;
849
              break;
850
            }
851
          }
852
853
60789
          break;
854
        }
855
856
18058
        case kind::ITE:
857
        {
858
18058
          if (results[currNode[0]].d_bool)
859
          {
860
9598
            results[currNode] = results[currNode[1]];
861
          }
862
          else
863
          {
864
8460
            results[currNode] = results[currNode[2]];
865
          }
866
18058
          break;
867
        }
868
869
145127
        default:
870
        {
871
290254
          Trace("evaluator") << "Kind " << currNodeVal.getKind()
872
145127
                             << " not supported" << std::endl;
873
145127
          results[currNode] = EvalResult();
874
145127
          evalAsNode[currNode] =
875
290254
              needsReconstruct ? reconstruct(currNode, results, evalAsNode)
876
                               : currNodeVal;
877
        }
878
      }
879
    }
880
  }
881
882
1896032
  return results[n];
883
}
884
885
322513
Node Evaluator::reconstruct(TNode n,
886
                            std::unordered_map<TNode, EvalResult>& eresults,
887
                            std::unordered_map<TNode, Node>& evalAsNode) const
888
{
889
322513
  if (n.getNumChildren() == 0)
890
  {
891
3281
    return n;
892
  }
893
319232
  Trace("evaluator") << "Evaluator: reconstruct " << n << std::endl;
894
319232
  NodeManager* nm = NodeManager::currentNM();
895
319232
  std::unordered_map<TNode, EvalResult>::iterator itr;
896
319232
  std::unordered_map<TNode, Node>::iterator itn;
897
638464
  std::vector<Node> echildren;
898
319232
  if (n.getMetaKind() == kind::metakind::PARAMETERIZED)
899
  {
900
128120
    TNode op = n.getOperator();
901
64060
    if (op.isConst())
902
    {
903
196
      echildren.push_back(op);
904
    }
905
    else
906
    {
907
63864
      itr = eresults.find(op);
908
63864
      Assert(itr != eresults.end());
909
63864
      if (itr->second.d_tag == EvalResult::INVALID)
910
      {
911
        // could not evaluate the operator, look in the node cache
912
63864
        itn = evalAsNode.find(op);
913
63864
        Assert(itn != evalAsNode.end());
914
63864
        echildren.push_back(itn->second);
915
      }
916
      else
917
      {
918
        // otherwise, use the evaluation of the operator
919
        echildren.push_back(itr->second.toNode());
920
      }
921
    }
922
  }
923
997753
  for (const auto& currNodeChild : n)
924
  {
925
678521
    itr = eresults.find(currNodeChild);
926
678521
    Assert(itr != eresults.end());
927
678521
    if (itr->second.d_tag == EvalResult::INVALID)
928
    {
929
      // could not evaluate this child, look in the node cache
930
255208
      itn = evalAsNode.find(currNodeChild);
931
255208
      Assert(itn != evalAsNode.end());
932
255208
      echildren.push_back(itn->second);
933
    }
934
    else
935
    {
936
      // otherwise, use the evaluation
937
423313
      echildren.push_back(itr->second.toNode());
938
    }
939
  }
940
  // The value is the result of our (partially) successful evaluation
941
  // of the children.
942
638464
  Node nn = nm->mkNode(n.getKind(), echildren);
943
319232
  Trace("evaluator") << "Evaluator: reconstructed " << nn << std::endl;
944
  // Return node, without rewriting. Notice we do not need to substitute here
945
  // since all substitutions should already have been applied recursively.
946
319232
  return nn;
947
}
948
949
}  // namespace theory
950
28194
}  // namespace cvc5