GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/evaluator.cpp Lines: 387 494 78.3 %
Date: 2021-08-06 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
1637360
EvalResult::EvalResult(const EvalResult& other)
28
{
29
1637360
  d_tag = other.d_tag;
30
1637360
  switch (d_tag)
31
  {
32
343435
    case BOOL: d_bool = other.d_bool; break;
33
583469
    case BITVECTOR:
34
583469
      new (&d_bv) BitVector;
35
583469
      d_bv = other.d_bv;
36
583469
      break;
37
372882
    case RATIONAL:
38
372882
      new (&d_rat) Rational;
39
372882
      d_rat = other.d_rat;
40
372882
      break;
41
265006
    case STRING:
42
265006
      new (&d_str) String;
43
265006
      d_str = other.d_str;
44
265006
      break;
45
    case UCONST:
46
      new (&d_uc)
47
          UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
48
      break;
49
72568
    case INVALID: break;
50
  }
51
1637360
}
52
53
5887909
EvalResult& EvalResult::operator=(const EvalResult& other)
54
{
55
5887909
  if (this != &other)
56
  {
57
5887909
    d_tag = other.d_tag;
58
5887909
    switch (d_tag)
59
    {
60
2201172
      case BOOL: d_bool = other.d_bool; break;
61
1743294
      case BITVECTOR:
62
1743294
        new (&d_bv) BitVector;
63
1743294
        d_bv = other.d_bv;
64
1743294
        break;
65
1289954
      case RATIONAL:
66
1289954
        new (&d_rat) Rational;
67
1289954
        d_rat = other.d_rat;
68
1289954
        break;
69
318469
      case STRING:
70
318469
        new (&d_str) String;
71
318469
        d_str = other.d_str;
72
318469
        break;
73
      case UCONST:
74
        new (&d_uc)
75
            UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
76
        break;
77
335020
      case INVALID: break;
78
    }
79
  }
80
5887909
  return *this;
81
}
82
83
25535040
EvalResult::~EvalResult()
84
{
85
12767520
  switch (d_tag)
86
  {
87
4048207
    case BITVECTOR:
88
    {
89
4048207
      d_bv.~BitVector();
90
4048207
      break;
91
    }
92
2329234
    case RATIONAL:
93
    {
94
2329234
      d_rat.~Rational();
95
2329234
      break;
96
    }
97
901887
    case STRING:
98
    {
99
901887
      d_str.~String();
100
901887
      break;
101
    }
102
    case UCONST:
103
    {
104
      d_uc.~UninterpretedConstant();
105
      break;
106
    }
107
5488192
    default: break;
108
  }
109
12767520
}
110
111
1374002
Node EvalResult::toNode() const
112
{
113
1374002
  NodeManager* nm = NodeManager::currentNM();
114
1374002
  switch (d_tag)
115
  {
116
123393
    case EvalResult::BOOL: return nm->mkConst(d_bool);
117
806228
    case EvalResult::BITVECTOR: return nm->mkConst(d_bv);
118
104355
    case EvalResult::RATIONAL: return nm->mkConst(d_rat);
119
267609
    case EvalResult::STRING: return nm->mkConst(d_str);
120
    case EvalResult::UCONST: return nm->mkConst(d_uc);
121
72417
    default:
122
    {
123
144834
      Trace("evaluator") << "Missing conversion from " << d_tag << " to node"
124
72417
                         << std::endl;
125
72417
      return Node();
126
    }
127
  }
128
}
129
130
928902
Node Evaluator::eval(TNode n,
131
                     const std::vector<Node>& args,
132
                     const std::vector<Node>& vals,
133
                     bool useRewriter) const
134
{
135
1857804
  std::unordered_map<Node, Node> visited;
136
1857804
  return eval(n, args, vals, visited, useRewriter);
137
}
138
945542
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
1891084
  Trace("evaluator") << "Evaluating " << n << " under substitution " << args
145
1891084
                     << " " << vals << " with visited size = " << visited.size()
146
945542
                     << std::endl;
147
1891084
  std::unordered_map<TNode, Node> evalAsNode;
148
1891084
  std::unordered_map<TNode, EvalResult> results;
149
  // add visited to results
150
966354
  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
945542
  Trace("evaluator") << "Run eval internal..." << std::endl;
168
945542
  Node ret = evalInternal(n, args, vals, evalAsNode, results, useRewriter).toNode();
169
  // if we failed to evaluate
170
945542
  if (ret.isNull() && useRewriter)
171
  {
172
    // should be stored in the evaluation-as-node map
173
72417
    std::unordered_map<TNode, Node>::iterator itn = evalAsNode.find(n);
174
72417
    Assert(itn != evalAsNode.end());
175
72417
    ret = Rewriter::rewrite(itn->second);
176
  }
177
  // should be the same as substitution + rewriting, or possibly null if
178
  // useRewriter is false
179
945542
  Assert((ret.isNull() && !useRewriter)
180
         || ret
181
                == Rewriter::rewrite(n.substitute(
182
                       args.begin(), args.end(), vals.begin(), vals.end())));
183
1891084
  return ret;
184
}
185
186
966354
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
1932708
  std::vector<TNode> queue;
195
966354
  queue.emplace_back(n);
196
966354
  std::unordered_map<TNode, EvalResult>::iterator itr;
197
198
19047972
  while (queue.size() != 0)
199
  {
200
17509676
    TNode currNode = queue.back();
201
202
9424361
    if (results.find(currNode) != results.end())
203
    {
204
383552
      queue.pop_back();
205
383552
      continue;
206
    }
207
208
8657257
    bool doProcess = true;
209
8657257
    bool isVar = false;
210
8657257
    bool doEval = true;
211
8657257
    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
1601042
      isVar = true;
216
1601042
      doEval = false;
217
    }
218
7056215
    else if (currNode.getMetaKind() == kind::metakind::PARAMETERIZED)
219
    {
220
639122
      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
319561
      if (!op.isConst())
224
      {
225
146000
        itr = results.find(op);
226
146000
        if (itr == results.end())
227
        {
228
61391
          queue.emplace_back(op);
229
61391
          doProcess = false;
230
        }
231
84609
        else if (itr->second.d_tag == EvalResult::INVALID)
232
        {
233
84609
          doEval = false;
234
        }
235
      }
236
    }
237
25949838
    for (const auto& currNodeChild : currNode)
238
    {
239
17292581
      itr = results.find(currNodeChild);
240
17292581
      if (itr == results.end())
241
      {
242
5222904
        queue.emplace_back(currNodeChild);
243
5222904
        doProcess = false;
244
      }
245
12069677
      else if (itr->second.d_tag == EvalResult::INVALID)
246
      {
247
        // we cannot evaluate since there was an invalid child
248
310533
        doEval = false;
249
      }
250
    }
251
17314514
    Trace("evaluator") << "Evaluator: visit " << currNode
252
8657257
                       << ", process = " << doProcess
253
8657257
                       << ", evaluate = " << doEval << std::endl;
254
255
8657257
    if (doProcess)
256
    {
257
5867097
      queue.pop_back();
258
259
11545804
      Node currNodeVal = currNode;
260
      // whether we need to reconstruct the current node in the case of failure
261
5867097
      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
5867097
      if (!doEval)
271
      {
272
1799297
        if (isVar)
273
        {
274
1601042
          const auto& it = std::find(args.begin(), args.end(), currNode);
275
1667942
          if (it == args.end())
276
          {
277
            // variable with no substitution is itself
278
66900
            evalAsNode[currNode] = currNode;
279
66900
            results[currNode] = EvalResult();
280
66900
            continue;
281
          }
282
1534142
          ptrdiff_t pos = std::distance(args.begin(), it);
283
1534142
          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
198255
          Trace("evaluator") << "Evaluator: collect arguments" << std::endl;
292
198255
          currNodeVal = reconstruct(currNodeVal, results, evalAsNode);
293
198255
          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
198255
            currNodeVal = Rewriter::rewrite(currNodeVal);
298
          }
299
        }
300
1732397
        needsReconstruct = false;
301
3464794
        Trace("evaluator") << "Evaluator: now after substitution + rewriting: "
302
1732397
                           << currNodeVal << std::endl;
303
1853887
        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
121490
          results[currNode] = EvalResult();
309
121490
          evalAsNode[currNode] = currNodeVal;
310
121490
          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
5678707
      Trace("evaluator") << "Current node val : " << currNodeVal << std::endl;
318
319
5678707
      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
517085
        case kind::CONST_BOOLEAN:
381
517085
          results[currNode] = EvalResult(currNodeVal.getConst<bool>());
382
517085
          break;
383
384
631462
        case kind::NOT:
385
        {
386
631462
          results[currNode] = EvalResult(!(results[currNode[0]].d_bool));
387
631462
          break;
388
        }
389
390
417195
        case kind::AND:
391
        {
392
417195
          bool res = results[currNode[0]].d_bool;
393
3861581
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
394
          {
395
3444386
            res = res && results[currNode[i]].d_bool;
396
          }
397
417195
          results[currNode] = EvalResult(res);
398
417195
          break;
399
        }
400
401
84451
        case kind::OR:
402
        {
403
84451
          bool res = results[currNode[0]].d_bool;
404
797037
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
405
          {
406
712586
            res = res || results[currNode[i]].d_bool;
407
          }
408
84451
          results[currNode] = EvalResult(res);
409
84451
          break;
410
        }
411
412
460879
        case kind::CONST_RATIONAL:
413
        {
414
460879
          const Rational& r = currNodeVal.getConst<Rational>();
415
460879
          results[currNode] = EvalResult(r);
416
460879
          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
175649
        case kind::PLUS:
426
        {
427
351298
          Rational res = results[currNode[0]].d_rat;
428
399628
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
429
          {
430
223979
            res = res + results[currNode[i]].d_rat;
431
          }
432
175649
          results[currNode] = EvalResult(res);
433
175649
          break;
434
        }
435
436
2213
        case kind::MINUS:
437
        {
438
2213
          const Rational& x = results[currNode[0]].d_rat;
439
2213
          const Rational& y = results[currNode[1]].d_rat;
440
2213
          results[currNode] = EvalResult(x - y);
441
2213
          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
26879
        case kind::MULT:
451
        case kind::NONLINEAR_MULT:
452
        {
453
53758
          Rational res = results[currNode[0]].d_rat;
454
53770
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
455
          {
456
26891
            res = res * results[currNode[i]].d_rat;
457
          }
458
26879
          results[currNode] = EvalResult(res);
459
26879
          break;
460
        }
461
462
160615
        case kind::GEQ:
463
        {
464
160615
          const Rational& x = results[currNode[0]].d_rat;
465
160615
          const Rational& y = results[currNode[1]].d_rat;
466
160615
          results[currNode] = EvalResult(x >= y);
467
160615
          break;
468
        }
469
15162
        case kind::LEQ:
470
        {
471
15162
          const Rational& x = results[currNode[0]].d_rat;
472
15162
          const Rational& y = results[currNode[1]].d_rat;
473
15162
          results[currNode] = EvalResult(x <= y);
474
15162
          break;
475
        }
476
18877
        case kind::GT:
477
        {
478
18877
          const Rational& x = results[currNode[0]].d_rat;
479
18877
          const Rational& y = results[currNode[1]].d_rat;
480
18877
          results[currNode] = EvalResult(x > y);
481
18877
          break;
482
        }
483
20499
        case kind::LT:
484
        {
485
20499
          const Rational& x = results[currNode[0]].d_rat;
486
20499
          const Rational& y = results[currNode[1]].d_rat;
487
20499
          results[currNode] = EvalResult(x < y);
488
20499
          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
290174
        case kind::CONST_STRING:
497
290174
          results[currNode] = EvalResult(currNodeVal.getConst<String>());
498
290174
          break;
499
500
24420
        case kind::STRING_CONCAT:
501
        {
502
48840
          String res = results[currNode[0]].d_str;
503
48867
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
504
          {
505
24447
            res = res.concat(results[currNode[i]].d_str);
506
          }
507
24420
          results[currNode] = EvalResult(res);
508
24420
          break;
509
        }
510
511
766
        case kind::STRING_LENGTH:
512
        {
513
766
          const String& s = results[currNode[0]].d_str;
514
766
          results[currNode] = EvalResult(Rational(s.size()));
515
766
          break;
516
        }
517
518
3476
        case kind::STRING_SUBSTR:
519
        {
520
3476
          const String& s = results[currNode[0]].d_str;
521
6952
          Integer s_len(s.size());
522
6952
          Integer i = results[currNode[1]].d_rat.getNumerator();
523
6952
          Integer j = results[currNode[2]].d_rat.getNumerator();
524
525
3476
          if (i.strictlyNegative() || j.strictlyNegative() || i >= s_len)
526
          {
527
614
            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
3476
          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_CONTAINS:
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_INDEXOF:
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_REPLACE:
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
1035975
        case kind::CONST_BITVECTOR:
706
1035975
          results[currNode] = EvalResult(currNodeVal.getConst<BitVector>());
707
1035975
          break;
708
709
77910
        case kind::BITVECTOR_NOT:
710
77910
          results[currNode] = EvalResult(~results[currNode[0]].d_bv);
711
77910
          break;
712
713
32845
        case kind::BITVECTOR_NEG:
714
32845
          results[currNode] = EvalResult(-results[currNode[0]].d_bv);
715
32845
          break;
716
717
103971
        case kind::BITVECTOR_EXTRACT:
718
        {
719
103971
          unsigned lo = bv::utils::getExtractLow(currNodeVal);
720
103971
          unsigned hi = bv::utils::getExtractHigh(currNodeVal);
721
103971
          results[currNode] =
722
207942
              EvalResult(results[currNode[0]].d_bv.extract(hi, lo));
723
103971
          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
55301
        case kind::BITVECTOR_ADD:
738
        {
739
110602
          BitVector res = results[currNode[0]].d_bv;
740
110602
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
741
          {
742
55301
            res = res + results[currNode[i]].d_bv;
743
          }
744
55301
          results[currNode] = EvalResult(res);
745
55301
          break;
746
        }
747
748
81496
        case kind::BITVECTOR_MULT:
749
        {
750
162992
          BitVector res = results[currNode[0]].d_bv;
751
174550
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
752
          {
753
93054
            res = res * results[currNode[i]].d_bv;
754
          }
755
81496
          results[currNode] = EvalResult(res);
756
81496
          break;
757
        }
758
70400
        case kind::BITVECTOR_AND:
759
        {
760
140800
          BitVector res = results[currNode[0]].d_bv;
761
140989
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
762
          {
763
70589
            res = res & results[currNode[i]].d_bv;
764
          }
765
70400
          results[currNode] = EvalResult(res);
766
70400
          break;
767
        }
768
769
143966
        case kind::BITVECTOR_OR:
770
        {
771
287932
          BitVector res = results[currNode[0]].d_bv;
772
312506
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
773
          {
774
168540
            res = res | results[currNode[i]].d_bv;
775
          }
776
143966
          results[currNode] = EvalResult(res);
777
143966
          break;
778
        }
779
780
114
        case kind::BITVECTOR_XOR:
781
        {
782
228
          BitVector res = results[currNode[0]].d_bv;
783
228
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
784
          {
785
114
            res = res ^ results[currNode[i]].d_bv;
786
          }
787
114
          results[currNode] = EvalResult(res);
788
114
          break;
789
        }
790
24542
        case kind::BITVECTOR_UDIV:
791
        {
792
49084
          BitVector res = results[currNode[0]].d_bv;
793
24542
          res = res.unsignedDivTotal(results[currNode[1]].d_bv);
794
24542
          results[currNode] = EvalResult(res);
795
24542
          break;
796
        }
797
26570
        case kind::BITVECTOR_UREM:
798
        {
799
53140
          BitVector res = results[currNode[0]].d_bv;
800
26570
          res = res.unsignedRemTotal(results[currNode[1]].d_bv);
801
26570
          results[currNode] = EvalResult(res);
802
26570
          break;
803
        }
804
805
335503
        case kind::EQUAL:
806
        {
807
671006
          EvalResult lhs = results[currNode[0]];
808
671006
          EvalResult rhs = results[currNode[1]];
809
810
335503
          switch (lhs.d_tag)
811
          {
812
115657
            case EvalResult::BOOL:
813
            {
814
115657
              results[currNode] = EvalResult(lhs.d_bool == rhs.d_bool);
815
115657
              break;
816
            }
817
818
41069
            case EvalResult::BITVECTOR:
819
            {
820
41069
              results[currNode] = EvalResult(lhs.d_bv == rhs.d_bv);
821
41069
              break;
822
            }
823
824
178229
            case EvalResult::RATIONAL:
825
            {
826
178229
              results[currNode] = EvalResult(lhs.d_rat == rhs.d_rat);
827
178229
              break;
828
            }
829
830
548
            case EvalResult::STRING:
831
            {
832
548
              results[currNode] = EvalResult(lhs.d_str == rhs.d_str);
833
548
              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
335503
          break;
854
        }
855
856
624846
        case kind::ITE:
857
        {
858
624846
          if (results[currNode[0]].d_bool)
859
          {
860
219658
            results[currNode] = results[currNode[1]];
861
          }
862
          else
863
          {
864
405188
            results[currNode] = results[currNode[2]];
865
          }
866
624846
          break;
867
        }
868
869
146479
        default:
870
        {
871
292958
          Trace("evaluator") << "Kind " << currNodeVal.getKind()
872
146479
                             << " not supported" << std::endl;
873
146479
          results[currNode] = EvalResult();
874
146479
          evalAsNode[currNode] =
875
292958
              needsReconstruct ? reconstruct(currNode, results, evalAsNode)
876
                               : currNodeVal;
877
        }
878
      }
879
    }
880
  }
881
882
1932708
  return results[n];
883
}
884
885
331607
Node Evaluator::reconstruct(TNode n,
886
                            std::unordered_map<TNode, EvalResult>& eresults,
887
                            std::unordered_map<TNode, Node>& evalAsNode) const
888
{
889
331607
  if (n.getNumChildren() == 0)
890
  {
891
3328
    return n;
892
  }
893
328279
  Trace("evaluator") << "Evaluator: reconstruct " << n << std::endl;
894
328279
  NodeManager* nm = NodeManager::currentNM();
895
328279
  std::unordered_map<TNode, EvalResult>::iterator itr;
896
328279
  std::unordered_map<TNode, Node>::iterator itn;
897
656558
  std::vector<Node> echildren;
898
328279
  if (n.getMetaKind() == kind::metakind::PARAMETERIZED)
899
  {
900
143524
    TNode op = n.getOperator();
901
71762
    if (op.isConst())
902
    {
903
143
      echildren.push_back(op);
904
    }
905
    else
906
    {
907
71619
      itr = eresults.find(op);
908
71619
      Assert(itr != eresults.end());
909
71619
      if (itr->second.d_tag == EvalResult::INVALID)
910
      {
911
        // could not evaluate the operator, look in the node cache
912
71619
        itn = evalAsNode.find(op);
913
71619
        Assert(itn != evalAsNode.end());
914
71619
        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
1018788
  for (const auto& currNodeChild : n)
924
  {
925
690509
    itr = eresults.find(currNodeChild);
926
690509
    Assert(itr != eresults.end());
927
690509
    if (itr->second.d_tag == EvalResult::INVALID)
928
    {
929
      // could not evaluate this child, look in the node cache
930
262049
      itn = evalAsNode.find(currNodeChild);
931
262049
      Assert(itn != evalAsNode.end());
932
262049
      echildren.push_back(itn->second);
933
    }
934
    else
935
    {
936
      // otherwise, use the evaluation
937
428460
      echildren.push_back(itr->second.toNode());
938
    }
939
  }
940
  // The value is the result of our (partially) successful evaluation
941
  // of the children.
942
656558
  Node nn = nm->mkNode(n.getKind(), echildren);
943
328279
  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
328279
  return nn;
947
}
948
949
}  // namespace theory
950
29322
}  // namespace cvc5