GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/evaluator.cpp Lines: 389 497 78.3 %
Date: 2021-09-29 Branches: 696 1769 39.3 %

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