GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/proof/conv_proof_generator.cpp Lines: 266 315 84.4 %
Date: 2021-09-15 Branches: 561 1597 35.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Aina Niemetz
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
 * Implementation of term conversion proof generator utility.
14
 */
15
16
#include "proof/conv_proof_generator.h"
17
18
#include <sstream>
19
20
#include "expr/term_context.h"
21
#include "expr/term_context_stack.h"
22
#include "proof/proof_checker.h"
23
#include "proof/proof_node.h"
24
#include "proof/proof_node_algorithm.h"
25
26
using namespace cvc5::kind;
27
28
namespace cvc5 {
29
30
102171
std::ostream& operator<<(std::ostream& out, TConvPolicy tcpol)
31
{
32
102171
  switch (tcpol)
33
  {
34
91433
    case TConvPolicy::FIXPOINT: out << "FIXPOINT"; break;
35
10738
    case TConvPolicy::ONCE: out << "ONCE"; break;
36
    default: out << "TConvPolicy:unknown"; break;
37
  }
38
102171
  return out;
39
}
40
41
102171
std::ostream& operator<<(std::ostream& out, TConvCachePolicy tcpol)
42
{
43
102171
  switch (tcpol)
44
  {
45
64152
    case TConvCachePolicy::STATIC: out << "STATIC"; break;
46
    case TConvCachePolicy::DYNAMIC: out << "DYNAMIC"; break;
47
38019
    case TConvCachePolicy::NEVER: out << "NEVER"; break;
48
    default: out << "TConvCachePolicy:unknown"; break;
49
  }
50
102171
  return out;
51
}
52
53
38166
TConvProofGenerator::TConvProofGenerator(ProofNodeManager* pnm,
54
                                         context::Context* c,
55
                                         TConvPolicy pol,
56
                                         TConvCachePolicy cpol,
57
                                         std::string name,
58
                                         TermContext* tccb,
59
38166
                                         bool rewriteOps)
60
76332
    : d_proof(pnm, nullptr, c, name + "::LazyCDProof"),
61
      d_preRewriteMap(c ? c : &d_context),
62
      d_postRewriteMap(c ? c : &d_context),
63
      d_policy(pol),
64
      d_cpolicy(cpol),
65
      d_name(name),
66
      d_tcontext(tccb),
67
114498
      d_rewriteOps(rewriteOps)
68
{
69
38166
}
70
71
63800
TConvProofGenerator::~TConvProofGenerator() {}
72
73
593782
void TConvProofGenerator::addRewriteStep(Node t,
74
                                         Node s,
75
                                         ProofGenerator* pg,
76
                                         bool isPre,
77
                                         PfRule trustId,
78
                                         bool isClosed,
79
                                         uint32_t tctx)
80
{
81
1187564
  Node eq = registerRewriteStep(t, s, tctx, isPre);
82
593782
  if (!eq.isNull())
83
  {
84
593678
    d_proof.addLazyStep(eq, pg, trustId, isClosed);
85
  }
86
593782
}
87
88
void TConvProofGenerator::addRewriteStep(
89
    Node t, Node s, ProofStep ps, bool isPre, uint32_t tctx)
90
{
91
  Node eq = registerRewriteStep(t, s, tctx, isPre);
92
  if (!eq.isNull())
93
  {
94
    d_proof.addStep(eq, ps);
95
  }
96
}
97
98
355847
void TConvProofGenerator::addRewriteStep(Node t,
99
                                         Node s,
100
                                         PfRule id,
101
                                         const std::vector<Node>& children,
102
                                         const std::vector<Node>& args,
103
                                         bool isPre,
104
                                         uint32_t tctx)
105
{
106
711694
  Node eq = registerRewriteStep(t, s, tctx, isPre);
107
355847
  if (!eq.isNull())
108
  {
109
250421
    d_proof.addStep(eq, id, children, args);
110
  }
111
355847
}
112
113
bool TConvProofGenerator::hasRewriteStep(Node t,
114
                                         uint32_t tctx,
115
                                         bool isPre) const
116
{
117
  return !getRewriteStep(t, tctx, isPre).isNull();
118
}
119
120
Node TConvProofGenerator::getRewriteStep(Node t,
121
                                         uint32_t tctx,
122
                                         bool isPre) const
123
{
124
  Node thash = t;
125
  if (d_tcontext != nullptr)
126
  {
127
    thash = TCtxNode::computeNodeHash(t, tctx);
128
  }
129
  return getRewriteStepInternal(thash, isPre);
130
}
131
132
949629
Node TConvProofGenerator::registerRewriteStep(Node t,
133
                                              Node s,
134
                                              uint32_t tctx,
135
                                              bool isPre)
136
{
137
949629
  Assert(!t.isNull());
138
949629
  Assert(!s.isNull());
139
140
949629
  if (t == s)
141
  {
142
1
    return Node::null();
143
  }
144
1899256
  Node thash = t;
145
949628
  if (d_tcontext != nullptr)
146
  {
147
81048
    thash = TCtxNode::computeNodeHash(t, tctx);
148
  }
149
  else
150
  {
151
    // don't use term context ids if not using term context
152
868580
    Assert(tctx == 0);
153
  }
154
  // should not rewrite term to two different things
155
949628
  if (!getRewriteStepInternal(thash, isPre).isNull())
156
  {
157
211058
    Assert(getRewriteStepInternal(thash, isPre) == s)
158
105529
        << identify() << " rewriting " << t << " to both " << s << " and "
159
105529
        << getRewriteStepInternal(thash, isPre);
160
105529
    return Node::null();
161
  }
162
844099
  NodeNodeMap& rm = isPre ? d_preRewriteMap : d_postRewriteMap;
163
844099
  rm[thash] = s;
164
844099
  if (d_cpolicy == TConvCachePolicy::DYNAMIC)
165
  {
166
    // clear the cache
167
    d_cache.clear();
168
  }
169
844099
  return t.eqNode(s);
170
}
171
172
93714
std::shared_ptr<ProofNode> TConvProofGenerator::getProofFor(Node f)
173
{
174
187428
  Trace("tconv-pf-gen") << "TConvProofGenerator::getProofFor: " << identify()
175
93714
                        << ": " << f << std::endl;
176
93714
  if (f.getKind() != EQUAL)
177
  {
178
    std::stringstream serr;
179
    serr << "TConvProofGenerator::getProofFor: " << identify()
180
         << ": fail, non-equality " << f;
181
    Unhandled() << serr.str();
182
    Trace("tconv-pf-gen") << serr.str() << std::endl;
183
    return nullptr;
184
  }
185
  // we use the existing proofs
186
  LazyCDProof lpf(
187
187428
      d_proof.getManager(), &d_proof, nullptr, d_name + "::LazyCDProof");
188
93714
  if (f[0] == f[1])
189
  {
190
    // assertion failure in debug
191
    Assert(false) << "TConvProofGenerator::getProofFor: " << identify()
192
                  << ": don't ask for trivial proofs";
193
    lpf.addStep(f, PfRule::REFL, {}, {f[0]});
194
  }
195
  else
196
  {
197
187428
    Node conc = getProofForRewriting(f[0], lpf, d_tcontext);
198
93714
    if (conc != f)
199
    {
200
      bool debugTraceEnabled = Trace.isOn("tconv-pf-gen-debug");
201
      Assert(conc.getKind() == EQUAL && conc[0] == f[0]);
202
      std::stringstream serr;
203
      serr << "TConvProofGenerator::getProofFor: " << toStringDebug()
204
           << ": failed, mismatch";
205
      if (!debugTraceEnabled)
206
      {
207
        serr << " (see -t tconv-pf-gen-debug for details)";
208
      }
209
      serr << std::endl;
210
      serr << "                   source: " << f[0] << std::endl;
211
      serr << "     requested conclusion: " << f[1] << std::endl;
212
      serr << "conclusion from generator: " << conc[1] << std::endl;
213
214
      if (debugTraceEnabled)
215
      {
216
        Trace("tconv-pf-gen-debug") << "Rewrite steps:" << std::endl;
217
        for (size_t r = 0; r < 2; r++)
218
        {
219
          const NodeNodeMap& rm = r == 0 ? d_preRewriteMap : d_postRewriteMap;
220
          serr << "Rewrite steps (" << (r == 0 ? "pre" : "post")
221
               << "):" << std::endl;
222
          for (NodeNodeMap::const_iterator it = rm.begin(); it != rm.end();
223
               ++it)
224
          {
225
            serr << (*it).first << " -> " << (*it).second << std::endl;
226
          }
227
        }
228
      }
229
      Unhandled() << serr.str();
230
      return nullptr;
231
    }
232
  }
233
187428
  std::shared_ptr<ProofNode> pfn = lpf.getProofFor(f);
234
93714
  Trace("tconv-pf-gen") << "... success" << std::endl;
235
93714
  Assert(pfn != nullptr);
236
93714
  Trace("tconv-pf-gen-debug-pf") << "... proof is " << *pfn << std::endl;
237
93714
  return pfn;
238
}
239
240
8457
std::shared_ptr<ProofNode> TConvProofGenerator::getProofForRewriting(Node n)
241
{
242
  LazyCDProof lpf(
243
16914
      d_proof.getManager(), &d_proof, nullptr, d_name + "::LazyCDProofRew");
244
16914
  Node conc = getProofForRewriting(n, lpf, d_tcontext);
245
8457
  if (conc[1] == n)
246
  {
247
    // assertion failure in debug
248
    Assert(false) << "TConvProofGenerator::getProofForRewriting: " << identify()
249
                  << ": don't ask for trivial proofs";
250
    lpf.addStep(conc, PfRule::REFL, {}, {n});
251
  }
252
8457
  std::shared_ptr<ProofNode> pfn = lpf.getProofFor(conc);
253
8457
  Assert(pfn != nullptr);
254
8457
  Trace("tconv-pf-gen-debug-pf") << "... proof is " << *pfn << std::endl;
255
16914
  return pfn;
256
}
257
258
102171
Node TConvProofGenerator::getProofForRewriting(Node t,
259
                                               LazyCDProof& pf,
260
                                               TermContext* tctx)
261
{
262
102171
  NodeManager* nm = NodeManager::currentNM();
263
  // Invariant: if visited[hash(t)] = s or rewritten[hash(t)] = s and t,s are
264
  // distinct, then pf is able to generate a proof of t=s. We must
265
  // Node in the domains of the maps below due to hashing creating new (SEXPR)
266
  // nodes.
267
268
  // the final rewritten form of terms
269
204342
  std::unordered_map<Node, Node> visited;
270
  // the rewritten form of terms we have processed so far
271
204342
  std::unordered_map<Node, Node> rewritten;
272
102171
  std::unordered_map<Node, Node>::iterator it;
273
102171
  std::unordered_map<Node, Node>::iterator itr;
274
102171
  std::map<Node, std::shared_ptr<ProofNode> >::iterator itc;
275
204342
  Trace("tconv-pf-gen-rewrite")
276
204342
      << "TConvProofGenerator::getProofForRewriting: " << toStringDebug()
277
102171
      << std::endl;
278
102171
  Trace("tconv-pf-gen-rewrite") << "Input: " << t << std::endl;
279
  // if provided, we use term context for cache
280
204342
  std::shared_ptr<TCtxStack> visitctx;
281
  // otherwise, visit is used if we don't have a term context
282
204342
  std::vector<TNode> visit;
283
204342
  Node tinitialHash;
284
102171
  if (tctx != nullptr)
285
  {
286
19202
    visitctx = std::make_shared<TCtxStack>(tctx);
287
19202
    visitctx->pushInitial(t);
288
19202
    tinitialHash = TCtxNode::computeNodeHash(t, tctx->initialValue());
289
  }
290
  else
291
  {
292
82969
    visit.push_back(t);
293
82969
    tinitialHash = t;
294
  }
295
204342
  Node cur;
296
102171
  uint32_t curCVal = 0;
297
204342
  Node curHash;
298
4679371
  do
299
  {
300
    // pop the top element
301
4781542
    if (tctx != nullptr)
302
    {
303
1489732
      std::pair<Node, uint32_t> curPair = visitctx->getCurrent();
304
744866
      cur = curPair.first;
305
744866
      curCVal = curPair.second;
306
744866
      curHash = TCtxNode::computeNodeHash(cur, curCVal);
307
744866
      visitctx->pop();
308
    }
309
    else
310
    {
311
4036676
      cur = visit.back();
312
4036676
      curHash = cur;
313
4036676
      visit.pop_back();
314
    }
315
4781542
    Trace("tconv-pf-gen-rewrite") << "* visit : " << curHash << std::endl;
316
    // has the proof for cur been cached?
317
4781542
    itc = d_cache.find(curHash);
318
4781542
    if (itc != d_cache.end())
319
    {
320
1712576
      Node res = itc->second->getResult();
321
856288
      Assert(res.getKind() == EQUAL);
322
856288
      Assert(!res[1].isNull());
323
856288
      visited[curHash] = res[1];
324
856288
      pf.addProof(itc->second);
325
856288
      continue;
326
    }
327
3925254
    it = visited.find(curHash);
328
3925254
    if (it == visited.end())
329
    {
330
1598331
      Trace("tconv-pf-gen-rewrite") << "- previsit" << std::endl;
331
1598331
      visited[curHash] = Node::null();
332
      // did we rewrite the current node (at pre-rewrite)?
333
3196662
      Node rcur = getRewriteStepInternal(curHash, true);
334
1598331
      if (!rcur.isNull())
335
      {
336
339410
        Trace("tconv-pf-gen-rewrite")
337
169705
            << "*** " << curHash << " prerewrites to " << rcur << std::endl;
338
        // d_proof has a proof of cur = rcur. Hence there is nothing
339
        // to do here, as pf will reference d_proof to get its proof.
340
169705
        if (d_policy == TConvPolicy::FIXPOINT)
341
        {
342
          // It may be the case that rcur also rewrites, thus we cannot assign
343
          // the final rewritten form for cur yet. Instead we revisit cur after
344
          // finishing visiting rcur.
345
159688
          rewritten[curHash] = rcur;
346
159688
          if (tctx != nullptr)
347
          {
348
49236
            visitctx->push(cur, curCVal);
349
49236
            visitctx->push(rcur, curCVal);
350
          }
351
          else
352
          {
353
110452
            visit.push_back(cur);
354
110452
            visit.push_back(rcur);
355
          }
356
        }
357
        else
358
        {
359
10017
          Assert(d_policy == TConvPolicy::ONCE);
360
20034
          Trace("tconv-pf-gen-rewrite") << "-> (once, prewrite) " << curHash
361
10017
                                        << " = " << rcur << std::endl;
362
          // not rewriting again, rcur is final
363
10017
          Assert(!rcur.isNull());
364
10017
          visited[curHash] = rcur;
365
10017
          doCache(curHash, cur, rcur, pf);
366
        }
367
      }
368
1428626
      else if (tctx != nullptr)
369
      {
370
266914
        visitctx->push(cur, curCVal);
371
        // visit operator if apply uf
372
266914
        if (d_rewriteOps && cur.getKind() == APPLY_UF)
373
        {
374
          visitctx->pushOp(cur, curCVal);
375
        }
376
266914
        visitctx->pushChildren(cur, curCVal);
377
      }
378
      else
379
      {
380
1161712
        visit.push_back(cur);
381
        // visit operator if apply uf
382
1161712
        if (d_rewriteOps && cur.getKind() == APPLY_UF)
383
        {
384
74459
          visit.push_back(cur.getOperator());
385
        }
386
1161712
        visit.insert(visit.end(), cur.begin(), cur.end());
387
      }
388
    }
389
2326923
    else if (it->second.isNull())
390
    {
391
1686235
      itr = rewritten.find(curHash);
392
1686235
      if (itr != rewritten.end())
393
      {
394
        // only can generate partially rewritten nodes when rewrite again is
395
        // true.
396
303057
        Assert(d_policy != TConvPolicy::ONCE);
397
        // if it was rewritten, check the status of the rewritten node,
398
        // which should be finished now
399
606114
        Node rcur = itr->second;
400
606114
        Trace("tconv-pf-gen-rewrite")
401
303057
            << "- postvisit, previously rewritten to " << rcur << std::endl;
402
606114
        Node rcurHash = rcur;
403
303057
        if (tctx != nullptr)
404
        {
405
53029
          rcurHash = TCtxNode::computeNodeHash(rcur, curCVal);
406
        }
407
303057
        Assert(cur != rcur);
408
        // the final rewritten form of cur is the final form of rcur
409
606114
        Node rcurFinal = visited[rcurHash];
410
303057
        Assert(!rcurFinal.isNull());
411
303057
        if (rcurFinal != rcur)
412
        {
413
          // must connect via TRANS
414
221174
          std::vector<Node> pfChildren;
415
110587
          pfChildren.push_back(cur.eqNode(rcur));
416
110587
          pfChildren.push_back(rcur.eqNode(rcurFinal));
417
221174
          Node result = cur.eqNode(rcurFinal);
418
110587
          pf.addStep(result, PfRule::TRANS, pfChildren, {});
419
        }
420
606114
        Trace("tconv-pf-gen-rewrite")
421
303057
            << "-> (rewritten postrewrite) " << curHash << " = " << rcurFinal
422
303057
            << std::endl;
423
303057
        visited[curHash] = rcurFinal;
424
303057
        doCache(curHash, cur, rcurFinal, pf);
425
      }
426
      else
427
      {
428
1383178
        Trace("tconv-pf-gen-rewrite") << "- postvisit" << std::endl;
429
2766356
        Node ret = cur;
430
2766356
        Node retHash = curHash;
431
1383178
        bool childChanged = false;
432
2766356
        std::vector<Node> children;
433
1383178
        Kind ck = cur.getKind();
434
1383178
        if (d_rewriteOps && ck == APPLY_UF)
435
        {
436
          // the operator of APPLY_UF is visited
437
148918
          Node cop = cur.getOperator();
438
74459
          if (tctx != nullptr)
439
          {
440
            uint32_t coval = tctx->computeValueOp(cur, curCVal);
441
            Node coHash = TCtxNode::computeNodeHash(cop, coval);
442
            it = visited.find(coHash);
443
          }
444
          else
445
          {
446
74459
            it = visited.find(cop);
447
          }
448
74459
          Assert(it != visited.end());
449
74459
          Assert(!it->second.isNull());
450
74459
          childChanged = childChanged || cop != it->second;
451
148918
          children.push_back(it->second);
452
        }
453
1308719
        else if (cur.getMetaKind() == metakind::PARAMETERIZED)
454
        {
455
          // all other parametrized operators are unchanged
456
80260
          children.push_back(cur.getOperator());
457
        }
458
        // get the results of the children
459
1383178
        if (tctx != nullptr)
460
        {
461
617497
          for (size_t i = 0, nchild = cur.getNumChildren(); i < nchild; i++)
462
          {
463
703750
            Node cn = cur[i];
464
351875
            uint32_t cnval = tctx->computeValue(cur, curCVal, i);
465
703750
            Node cnHash = TCtxNode::computeNodeHash(cn, cnval);
466
351875
            it = visited.find(cnHash);
467
351875
            Assert(it != visited.end());
468
351875
            Assert(!it->second.isNull());
469
351875
            childChanged = childChanged || cn != it->second;
470
351875
            children.push_back(it->second);
471
          }
472
        }
473
        else
474
        {
475
          // can use simple loop if not term-context-sensitive
476
3223277
          for (const Node& cn : cur)
477
          {
478
2105721
            it = visited.find(cn);
479
2105721
            Assert(it != visited.end());
480
2105721
            Assert(!it->second.isNull());
481
2105721
            childChanged = childChanged || cn != it->second;
482
2105721
            children.push_back(it->second);
483
          }
484
        }
485
1383178
        if (childChanged)
486
        {
487
342117
          ret = nm->mkNode(ck, children);
488
342117
          rewritten[curHash] = ret;
489
          // congruence to show (cur = ret)
490
342117
          PfRule congRule = PfRule::CONG;
491
684234
          std::vector<Node> pfChildren;
492
684234
          std::vector<Node> pfArgs;
493
342117
          pfArgs.push_back(ProofRuleChecker::mkKindNode(ck));
494
342117
          if (ck == APPLY_UF && children[0] != cur.getOperator())
495
          {
496
            // use HO_CONG if the operator changed
497
200
            congRule = PfRule::HO_CONG;
498
200
            pfChildren.push_back(cur.getOperator().eqNode(children[0]));
499
          }
500
341917
          else if (kind::metaKindOf(ck) == kind::metakind::PARAMETERIZED)
501
          {
502
23002
            pfArgs.push_back(cur.getOperator());
503
          }
504
1159944
          for (size_t i = 0, size = cur.getNumChildren(); i < size; i++)
505
          {
506
817827
            if (cur[i] == ret[i])
507
            {
508
              // ensure REFL proof for unchanged children
509
224292
              pf.addStep(cur[i].eqNode(cur[i]), PfRule::REFL, {}, {cur[i]});
510
            }
511
817827
            pfChildren.push_back(cur[i].eqNode(ret[i]));
512
          }
513
684234
          Node result = cur.eqNode(ret);
514
342117
          pf.addStep(result, congRule, pfChildren, pfArgs);
515
          // must update the hash
516
342117
          retHash = ret;
517
342117
          if (tctx != nullptr)
518
          {
519
89908
            retHash = TCtxNode::computeNodeHash(ret, curCVal);
520
          }
521
        }
522
1041061
        else if (tctx != nullptr)
523
        {
524
          // now we need the hash
525
175714
          retHash = TCtxNode::computeNodeHash(cur, curCVal);
526
        }
527
        // did we rewrite ret (at post-rewrite)?
528
2766356
        Node rret = getRewriteStepInternal(retHash, false);
529
1383178
        if (!rret.isNull() && d_policy == TConvPolicy::FIXPOINT)
530
        {
531
195842
          Trace("tconv-pf-gen-rewrite")
532
97921
              << "*** " << retHash << " postrewrites to " << rret << std::endl;
533
          // d_proof should have a proof of ret = rret, hence nothing to do
534
          // here, for the same reasons as above. It also may be the case that
535
          // rret rewrites, hence we must revisit ret.
536
97921
          rewritten[retHash] = rret;
537
97921
          if (tctx != nullptr)
538
          {
539
2501
            if (cur != ret)
540
            {
541
1293
              visitctx->push(cur, curCVal);
542
            }
543
2501
            visitctx->push(ret, curCVal);
544
2501
            visitctx->push(rret, curCVal);
545
          }
546
          else
547
          {
548
95420
            if (cur != ret)
549
            {
550
60157
              visit.push_back(cur);
551
            }
552
95420
            visit.push_back(ret);
553
95420
            visit.push_back(rret);
554
          }
555
        }
556
        else
557
        {
558
          // If we changed due to congruence, and then rewrote, then we
559
          // require a trans step to connect here
560
1285257
          if (!rret.isNull() && childChanged)
561
          {
562
12506
            std::vector<Node> pfChildren;
563
6253
            pfChildren.push_back(cur.eqNode(ret));
564
6253
            pfChildren.push_back(ret.eqNode(rret));
565
12506
            Node result = cur.eqNode(rret);
566
6253
            pf.addStep(result, PfRule::TRANS, pfChildren, {});
567
          }
568
          // take its rewrite if it rewrote and we have ONCE rewriting policy
569
1285257
          ret = rret.isNull() ? ret : rret;
570
2570514
          Trace("tconv-pf-gen-rewrite")
571
1285257
              << "-> (postrewrite) " << curHash << " = " << ret << std::endl;
572
          // it is final
573
1285257
          Assert(!ret.isNull());
574
1285257
          visited[curHash] = ret;
575
1285257
          doCache(curHash, cur, ret, pf);
576
        }
577
      }
578
    }
579
    else
580
    {
581
640688
      Trace("tconv-pf-gen-rewrite") << "- already visited" << std::endl;
582
    }
583
4781542
  } while (!(tctx != nullptr ? visitctx->empty() : visit.empty()));
584
102171
  Assert(visited.find(tinitialHash) != visited.end());
585
102171
  Assert(!visited.find(tinitialHash)->second.isNull());
586
204342
  Trace("tconv-pf-gen-rewrite")
587
102171
      << "...finished, return " << visited[tinitialHash] << std::endl;
588
  // return the conclusion of the overall proof
589
204342
  return t.eqNode(visited[tinitialHash]);
590
}
591
592
1598331
void TConvProofGenerator::doCache(Node curHash,
593
                                  Node cur,
594
                                  Node r,
595
                                  LazyCDProof& pf)
596
{
597
1598331
  if (d_cpolicy != TConvCachePolicy::NEVER)
598
  {
599
1153544
    Node eq = cur.eqNode(r);
600
576772
    d_cache[curHash] = pf.getProofFor(eq);
601
  }
602
1598331
}
603
604
4036666
Node TConvProofGenerator::getRewriteStepInternal(Node t, bool isPre) const
605
{
606
4036666
  const NodeNodeMap& rm = isPre ? d_preRewriteMap : d_postRewriteMap;
607
4036666
  NodeNodeMap::const_iterator it = rm.find(t);
608
4036666
  if (it == rm.end())
609
  {
610
3546779
    return Node::null();
611
  }
612
489887
  return (*it).second;
613
}
614
302774
std::string TConvProofGenerator::identify() const { return d_name; }
615
616
102171
std::string TConvProofGenerator::toStringDebug() const
617
{
618
204342
  std::stringstream ss;
619
204342
  ss << identify() << " (policy=" << d_policy << ", cache policy=" << d_cpolicy
620
102171
     << (d_tcontext != nullptr ? ", term-context-sensitive" : "") << ")";
621
204342
  return ss.str();
622
}
623
624
29577
}  // namespace cvc5