GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/evaluator.cpp Lines: 405 497 81.5 %
Date: 2021-11-07 Branches: 712 1769 40.2 %

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
1684305
EvalResult::EvalResult(const EvalResult& other)
28
{
29
1684305
  d_tag = other.d_tag;
30
1684305
  switch (d_tag)
31
  {
32
304410
    case BOOL: d_bool = other.d_bool; break;
33
659160
    case BITVECTOR:
34
659160
      new (&d_bv) BitVector;
35
659160
      d_bv = other.d_bv;
36
659160
      break;
37
361482
    case RATIONAL:
38
361482
      new (&d_rat) Rational;
39
361482
      d_rat = other.d_rat;
40
361482
      break;
41
269143
    case STRING:
42
269143
      new (&d_str) String;
43
269143
      d_str = other.d_str;
44
269143
      break;
45
    case UCONST:
46
      new (&d_uc)
47
          UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
48
      break;
49
90110
    case INVALID: break;
50
  }
51
1684305
}
52
53
5710871
EvalResult& EvalResult::operator=(const EvalResult& other)
54
{
55
5710871
  if (this != &other)
56
  {
57
5710871
    d_tag = other.d_tag;
58
5710871
    switch (d_tag)
59
    {
60
1673948
      case BOOL: d_bool = other.d_bool; break;
61
2143624
      case BITVECTOR:
62
2143624
        new (&d_bv) BitVector;
63
2143624
        d_bv = other.d_bv;
64
2143624
        break;
65
1220278
      case RATIONAL:
66
1220278
        new (&d_rat) Rational;
67
1220278
        d_rat = other.d_rat;
68
1220278
        break;
69
331109
      case STRING:
70
331109
        new (&d_str) String;
71
331109
        d_str = other.d_str;
72
331109
        break;
73
4
      case UCONST:
74
8
        new (&d_uc)
75
8
            UninterpretedConstant(other.d_uc.getType(), other.d_uc.getIndex());
76
4
        break;
77
341908
      case INVALID: break;
78
    }
79
  }
80
5710871
  return *this;
81
}
82
83
25215386
EvalResult::~EvalResult()
84
{
85
12607693
  switch (d_tag)
86
  {
87
4912560
    case BITVECTOR:
88
    {
89
4912560
      d_bv.~BitVector();
90
4912560
      break;
91
    }
92
2342027
    case RATIONAL:
93
    {
94
2342027
      d_rat.~Rational();
95
2342027
      break;
96
    }
97
931247
    case STRING:
98
    {
99
931247
      d_str.~String();
100
931247
      break;
101
    }
102
8
    case UCONST:
103
    {
104
8
      d_uc.~UninterpretedConstant();
105
8
      break;
106
    }
107
4421851
    default: break;
108
  }
109
12607693
}
110
111
1640788
Node EvalResult::toNode() const
112
{
113
1640788
  NodeManager* nm = NodeManager::currentNM();
114
1640788
  switch (d_tag)
115
  {
116
151426
    case EvalResult::BOOL: return nm->mkConst(d_bool);
117
944948
    case EvalResult::BITVECTOR: return nm->mkConst(d_bv);
118
179346
    case EvalResult::RATIONAL: return nm->mkConst(d_rat);
119
275299
    case EvalResult::STRING: return nm->mkConst(d_str);
120
4
    case EvalResult::UCONST: return nm->mkConst(d_uc);
121
89765
    default:
122
    {
123
179530
      Trace("evaluator") << "Missing conversion from " << d_tag << " to node"
124
89765
                         << std::endl;
125
89765
      return Node();
126
    }
127
  }
128
}
129
130
37318
Evaluator::Evaluator(Rewriter* rr, uint32_t alphaCard)
131
37318
    : d_rr(rr), d_alphaCard(alphaCard)
132
{
133
37318
}
134
135
110568
Node Evaluator::eval(TNode n,
136
                     const std::vector<Node>& args,
137
                     const std::vector<Node>& vals) const
138
{
139
221136
  std::unordered_map<Node, Node> visited;
140
221136
  return eval(n, args, vals, visited);
141
}
142
1118298
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
2236596
  Trace("evaluator") << "Evaluating " << n << " under substitution " << args
148
2236596
                     << " " << vals << " with visited size = " << visited.size()
149
1118298
                     << std::endl;
150
2236596
  std::unordered_map<TNode, Node> evalAsNode;
151
2236596
  std::unordered_map<TNode, EvalResult> results;
152
  // add visited to results
153
1150207
  for (const std::pair<const Node, Node>& p : visited)
154
  {
155
31909
    Trace("evaluator") << "Add " << p.first << " == " << p.second << std::endl;
156
31909
    results[p.first] = evalInternal(p.second, args, vals, evalAsNode, results);
157
31909
    if (results[p.first].d_tag == EvalResult::INVALID)
158
    {
159
      // could not evaluate, use the evalAsNode map
160
345
      std::unordered_map<TNode, Node>::iterator itn = evalAsNode.find(p.second);
161
345
      Assert(itn != evalAsNode.end());
162
690
      Node val = itn->second;
163
345
      if (d_rr != nullptr)
164
      {
165
345
        val = d_rr->rewrite(val);
166
      }
167
345
      evalAsNode[p.first] = val;
168
    }
169
  }
170
1118298
  Trace("evaluator") << "Run eval internal..." << std::endl;
171
1118298
  Node ret = evalInternal(n, args, vals, evalAsNode, results).toNode();
172
  // if we failed to evaluate
173
1118298
  if (ret.isNull() && d_rr != nullptr)
174
  {
175
    // should be stored in the evaluation-as-node map
176
86699
    std::unordered_map<TNode, Node>::iterator itn = evalAsNode.find(n);
177
86699
    Assert(itn != evalAsNode.end());
178
86699
    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
1118298
  Assert((ret.isNull() && d_rr == nullptr)
183
         || ret
184
                == d_rr->rewrite(n.substitute(
185
                    args.begin(), args.end(), vals.begin(), vals.end())));
186
2236596
  return ret;
187
}
188
189
1150207
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
2300414
  std::vector<TNode> queue;
197
1150207
  queue.emplace_back(n);
198
1150207
  std::unordered_map<TNode, EvalResult>::iterator itr;
199
200
18811897
  while (queue.size() != 0)
201
  {
202
17006918
    TNode currNode = queue.back();
203
204
9321326
    if (results.find(currNode) != results.end())
205
    {
206
490481
      queue.pop_back();
207
490481
      continue;
208
    }
209
210
8340364
    bool doProcess = true;
211
8340364
    bool isVar = false;
212
8340364
    bool doEval = true;
213
8340364
    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
1637777
      isVar = true;
218
1637777
      doEval = false;
219
    }
220
6702587
    else if (currNode.getMetaKind() == kind::metakind::PARAMETERIZED)
221
    {
222
577932
      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
288966
      if (!op.isConst())
226
      {
227
104346
        itr = results.find(op);
228
104346
        if (itr == results.end())
229
        {
230
46844
          queue.emplace_back(op);
231
46844
          doProcess = false;
232
        }
233
57502
        else if (itr->second.d_tag == EvalResult::INVALID)
234
        {
235
57502
          doEval = false;
236
        }
237
      }
238
    }
239
23335402
    for (const auto& currNodeChild : currNode)
240
    {
241
14995038
      itr = results.find(currNodeChild);
242
14995038
      if (itr == results.end())
243
      {
244
4972392
        queue.emplace_back(currNodeChild);
245
4972392
        doProcess = false;
246
      }
247
10022646
      else if (itr->second.d_tag == EvalResult::INVALID)
248
      {
249
        // we cannot evaluate since there was an invalid child
250
288782
        doEval = false;
251
      }
252
    }
253
16680728
    Trace("evaluator") << "Evaluator: visit " << currNode
254
8340364
                       << ", process = " << doProcess
255
8340364
                       << ", evaluate = " << doEval << std::endl;
256
257
8340364
    if (doProcess)
258
    {
259
5678962
      queue.pop_back();
260
261
11193633
      Node currNodeVal = currNode;
262
      // whether we need to reconstruct the current node in the case of failure
263
5678962
      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
5678962
      if (!doEval)
273
      {
274
1842481
        if (isVar)
275
        {
276
1637777
          const auto& it = std::find(args.begin(), args.end(), currNode);
277
1697701
          if (it == args.end())
278
          {
279
            // variable with no substitution is itself
280
59924
            evalAsNode[currNode] = currNode;
281
59924
            results[currNode] = EvalResult();
282
59924
            continue;
283
          }
284
1577853
          ptrdiff_t pos = std::distance(args.begin(), it);
285
1577853
          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
204704
          Trace("evaluator") << "Evaluator: collect arguments" << std::endl;
294
204704
          currNodeVal = reconstruct(currNodeVal, results, evalAsNode);
295
204704
          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
198956
            currNodeVal = d_rr->rewrite(currNodeVal);
300
          }
301
        }
302
1782557
        needsReconstruct = false;
303
3565114
        Trace("evaluator") << "Evaluator: now after substitution + rewriting: "
304
1782557
                           << currNodeVal << std::endl;
305
1886924
        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
104367
          results[currNode] = EvalResult();
311
104367
          evalAsNode[currNode] = currNodeVal;
312
104367
          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
5514671
      Trace("evaluator") << "Current node val : " << currNodeVal << std::endl;
320
321
5514671
      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
384649
        case kind::CONST_BOOLEAN:
379
384649
          results[currNode] = EvalResult(currNodeVal.getConst<bool>());
380
384649
          break;
381
382
456072
        case kind::NOT:
383
        {
384
456072
          results[currNode] = EvalResult(!(results[currNode[0]].d_bool));
385
456072
          break;
386
        }
387
388
301308
        case kind::AND:
389
        {
390
301308
          bool res = results[currNode[0]].d_bool;
391
2714838
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
392
          {
393
2413530
            res = res && results[currNode[i]].d_bool;
394
          }
395
301308
          results[currNode] = EvalResult(res);
396
301308
          break;
397
        }
398
399
74037
        case kind::OR:
400
        {
401
74037
          bool res = results[currNode[0]].d_bool;
402
595128
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
403
          {
404
521091
            res = res || results[currNode[i]].d_bool;
405
          }
406
74037
          results[currNode] = EvalResult(res);
407
74037
          break;
408
        }
409
410
535335
        case kind::CONST_RATIONAL:
411
        {
412
535335
          const Rational& r = currNodeVal.getConst<Rational>();
413
535335
          results[currNode] = EvalResult(r);
414
535335
          break;
415
        }
416
4
        case kind::UNINTERPRETED_CONSTANT:
417
        {
418
          const UninterpretedConstant& uc =
419
4
              currNodeVal.getConst<UninterpretedConstant>();
420
4
          results[currNode] = EvalResult(uc);
421
4
          break;
422
        }
423
163447
        case kind::PLUS:
424
        {
425
326894
          Rational res = results[currNode[0]].d_rat;
426
367352
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
427
          {
428
203905
            res = res + results[currNode[i]].d_rat;
429
          }
430
163447
          results[currNode] = EvalResult(res);
431
163447
          break;
432
        }
433
434
6891
        case kind::MINUS:
435
        {
436
6891
          const Rational& x = results[currNode[0]].d_rat;
437
6891
          const Rational& y = results[currNode[1]].d_rat;
438
6891
          results[currNode] = EvalResult(x - y);
439
6891
          break;
440
        }
441
442
28
        case kind::UMINUS:
443
        {
444
28
          const Rational& x = results[currNode[0]].d_rat;
445
28
          results[currNode] = EvalResult(-x);
446
28
          break;
447
        }
448
53016
        case kind::MULT:
449
        case kind::NONLINEAR_MULT:
450
        {
451
106032
          Rational res = results[currNode[0]].d_rat;
452
106056
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
453
          {
454
53040
            res = res * results[currNode[i]].d_rat;
455
          }
456
53016
          results[currNode] = EvalResult(res);
457
53016
          break;
458
        }
459
460
136456
        case kind::GEQ:
461
        {
462
136456
          const Rational& x = results[currNode[0]].d_rat;
463
136456
          const Rational& y = results[currNode[1]].d_rat;
464
136456
          results[currNode] = EvalResult(x >= y);
465
136456
          break;
466
        }
467
16477
        case kind::LEQ:
468
        {
469
16477
          const Rational& x = results[currNode[0]].d_rat;
470
16477
          const Rational& y = results[currNode[1]].d_rat;
471
16477
          results[currNode] = EvalResult(x <= y);
472
16477
          break;
473
        }
474
14816
        case kind::GT:
475
        {
476
14816
          const Rational& x = results[currNode[0]].d_rat;
477
14816
          const Rational& y = results[currNode[1]].d_rat;
478
14816
          results[currNode] = EvalResult(x > y);
479
14816
          break;
480
        }
481
18490
        case kind::LT:
482
        {
483
18490
          const Rational& x = results[currNode[0]].d_rat;
484
18490
          const Rational& y = results[currNode[1]].d_rat;
485
18490
          results[currNode] = EvalResult(x < y);
486
18490
          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
299512
        case kind::CONST_STRING:
495
299512
          results[currNode] = EvalResult(currNodeVal.getConst<String>());
496
299512
          break;
497
498
24756
        case kind::STRING_CONCAT:
499
        {
500
49512
          String res = results[currNode[0]].d_str;
501
49554
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
502
          {
503
24798
            res = res.concat(results[currNode[i]].d_str);
504
          }
505
24756
          results[currNode] = EvalResult(res);
506
24756
          break;
507
        }
508
509
1538
        case kind::STRING_LENGTH:
510
        {
511
1538
          const String& s = results[currNode[0]].d_str;
512
1538
          results[currNode] = EvalResult(Rational(s.size()));
513
1538
          break;
514
        }
515
516
6466
        case kind::STRING_SUBSTR:
517
        {
518
6466
          const String& s = results[currNode[0]].d_str;
519
12932
          Integer s_len(s.size());
520
12932
          Integer i = results[currNode[1]].d_rat.getNumerator();
521
12932
          Integer j = results[currNode[2]].d_rat.getNumerator();
522
523
6466
          if (i.strictlyNegative() || j.strictlyNegative() || i >= s_len)
524
          {
525
830
            results[currNode] = EvalResult(String(""));
526
          }
527
5636
          else if (i + j > s_len)
528
          {
529
444
            results[currNode] =
530
888
                EvalResult(s.suffix((s_len - i).toUnsignedInt()));
531
          }
532
          else
533
          {
534
5192
            results[currNode] =
535
10384
                EvalResult(s.substr(i.toUnsignedInt(), j.toUnsignedInt()));
536
          }
537
6466
          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
558
        case kind::STRING_CONTAINS:
574
        {
575
558
          const String& s = results[currNode[0]].d_str;
576
558
          const String& t = results[currNode[1]].d_str;
577
558
          results[currNode] = EvalResult(s.find(t) != std::string::npos);
578
558
          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
1244987
        case kind::CONST_BITVECTOR:
704
1244987
          results[currNode] = EvalResult(currNodeVal.getConst<BitVector>());
705
1244987
          break;
706
707
104079
        case kind::BITVECTOR_NOT:
708
104079
          results[currNode] = EvalResult(~results[currNode[0]].d_bv);
709
104079
          break;
710
711
37851
        case kind::BITVECTOR_NEG:
712
37851
          results[currNode] = EvalResult(-results[currNode[0]].d_bv);
713
37851
          break;
714
715
100088
        case kind::BITVECTOR_EXTRACT:
716
        {
717
100088
          unsigned lo = bv::utils::getExtractLow(currNodeVal);
718
100088
          unsigned hi = bv::utils::getExtractHigh(currNodeVal);
719
100088
          results[currNode] =
720
200176
              EvalResult(results[currNode[0]].d_bv.extract(hi, lo));
721
100088
          break;
722
        }
723
724
80041
        case kind::BITVECTOR_CONCAT:
725
        {
726
160082
          BitVector res = results[currNode[0]].d_bv;
727
168116
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
728
          {
729
88075
            res = res.concat(results[currNode[i]].d_bv);
730
          }
731
80041
          results[currNode] = EvalResult(res);
732
80041
          break;
733
        }
734
735
65845
        case kind::BITVECTOR_ADD:
736
        {
737
131690
          BitVector res = results[currNode[0]].d_bv;
738
131690
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
739
          {
740
65845
            res = res + results[currNode[i]].d_bv;
741
          }
742
65845
          results[currNode] = EvalResult(res);
743
65845
          break;
744
        }
745
746
115187
        case kind::BITVECTOR_MULT:
747
        {
748
230374
          BitVector res = results[currNode[0]].d_bv;
749
247331
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
750
          {
751
132144
            res = res * results[currNode[i]].d_bv;
752
          }
753
115187
          results[currNode] = EvalResult(res);
754
115187
          break;
755
        }
756
93936
        case kind::BITVECTOR_AND:
757
        {
758
187872
          BitVector res = results[currNode[0]].d_bv;
759
188250
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
760
          {
761
94314
            res = res & results[currNode[i]].d_bv;
762
          }
763
93936
          results[currNode] = EvalResult(res);
764
93936
          break;
765
        }
766
767
165166
        case kind::BITVECTOR_OR:
768
        {
769
330332
          BitVector res = results[currNode[0]].d_bv;
770
367193
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
771
          {
772
202027
            res = res | results[currNode[i]].d_bv;
773
          }
774
165166
          results[currNode] = EvalResult(res);
775
165166
          break;
776
        }
777
778
184
        case kind::BITVECTOR_XOR:
779
        {
780
368
          BitVector res = results[currNode[0]].d_bv;
781
368
          for (size_t i = 1, end = currNode.getNumChildren(); i < end; i++)
782
          {
783
184
            res = res ^ results[currNode[i]].d_bv;
784
          }
785
184
          results[currNode] = EvalResult(res);
786
184
          break;
787
        }
788
49186
        case kind::BITVECTOR_UDIV:
789
        {
790
98372
          BitVector res = results[currNode[0]].d_bv;
791
49186
          res = res.unsignedDivTotal(results[currNode[1]].d_bv);
792
49186
          results[currNode] = EvalResult(res);
793
49186
          break;
794
        }
795
53226
        case kind::BITVECTOR_UREM:
796
        {
797
106452
          BitVector res = results[currNode[0]].d_bv;
798
53226
          res = res.unsignedRemTotal(results[currNode[1]].d_bv);
799
53226
          results[currNode] = EvalResult(res);
800
53226
          break;
801
        }
802
803
267049
        case kind::EQUAL:
804
        {
805
534098
          EvalResult lhs = results[currNode[0]];
806
534098
          EvalResult rhs = results[currNode[1]];
807
808
267049
          switch (lhs.d_tag)
809
          {
810
82183
            case EvalResult::BOOL:
811
            {
812
82183
              results[currNode] = EvalResult(lhs.d_bool == rhs.d_bool);
813
82183
              break;
814
            }
815
816
42183
            case EvalResult::BITVECTOR:
817
            {
818
42183
              results[currNode] = EvalResult(lhs.d_bv == rhs.d_bv);
819
42183
              break;
820
            }
821
822
141567
            case EvalResult::RATIONAL:
823
            {
824
141567
              results[currNode] = EvalResult(lhs.d_rat == rhs.d_rat);
825
141567
              break;
826
            }
827
828
1116
            case EvalResult::STRING:
829
            {
830
1116
              results[currNode] = EvalResult(lhs.d_str == rhs.d_str);
831
1116
              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
267049
          break;
852
        }
853
854
466445
        case kind::ITE:
855
        {
856
466445
          if (results[currNode[0]].d_bool)
857
          {
858
165769
            results[currNode] = results[currNode[1]];
859
          }
860
          else
861
          {
862
300676
            results[currNode] = results[currNode[2]];
863
          }
864
466445
          break;
865
        }
866
867
177272
        default:
868
        {
869
354544
          Trace("evaluator") << "Kind " << currNodeVal.getKind()
870
177272
                             << " not supported" << std::endl;
871
177272
          results[currNode] = EvalResult();
872
177272
          evalAsNode[currNode] =
873
354544
              needsReconstruct ? reconstruct(currNode, results, evalAsNode)
874
                               : currNodeVal;
875
        }
876
      }
877
    }
878
  }
879
880
2300414
  return results[n];
881
}
882
883
368463
Node Evaluator::reconstruct(TNode n,
884
                            std::unordered_map<TNode, EvalResult>& eresults,
885
                            std::unordered_map<TNode, Node>& evalAsNode) const
886
{
887
368463
  if (n.getNumChildren() == 0)
888
  {
889
4340
    return n;
890
  }
891
364123
  Trace("evaluator") << "Evaluator: reconstruct " << n << std::endl;
892
364123
  NodeManager* nm = NodeManager::currentNM();
893
364123
  std::unordered_map<TNode, EvalResult>::iterator itr;
894
364123
  std::unordered_map<TNode, Node>::iterator itn;
895
728246
  std::vector<Node> echildren;
896
364123
  if (n.getMetaKind() == kind::metakind::PARAMETERIZED)
897
  {
898
105080
    TNode op = n.getOperator();
899
52540
    if (op.isConst())
900
    {
901
2358
      echildren.push_back(op);
902
    }
903
    else
904
    {
905
50182
      itr = eresults.find(op);
906
50182
      Assert(itr != eresults.end());
907
50182
      if (itr->second.d_tag == EvalResult::INVALID)
908
      {
909
        // could not evaluate the operator, look in the node cache
910
50182
        itn = evalAsNode.find(op);
911
50182
        Assert(itn != evalAsNode.end());
912
50182
        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
1140267
  for (const auto& currNodeChild : n)
922
  {
923
776144
    itr = eresults.find(currNodeChild);
924
776144
    Assert(itr != eresults.end());
925
776144
    if (itr->second.d_tag == EvalResult::INVALID)
926
    {
927
      // could not evaluate this child, look in the node cache
928
253654
      itn = evalAsNode.find(currNodeChild);
929
253654
      Assert(itn != evalAsNode.end());
930
253654
      echildren.push_back(itn->second);
931
    }
932
    else
933
    {
934
      // otherwise, use the evaluation
935
522490
      echildren.push_back(itr->second.toNode());
936
    }
937
  }
938
  // The value is the result of our (partially) successful evaluation
939
  // of the children.
940
728246
  Node nn = nm->mkNode(n.getKind(), echildren);
941
364123
  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
364123
  return nn;
945
}
946
947
}  // namespace theory
948
31137
}  // namespace cvc5