summaryrefslogtreecommitdiff
path: root/src/smt/preprocess_proof_generator.cpp
blob: 969ffa9bbedd3835f4d2f2444367927eddba71dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*********************                                                        */
/*! \file preprocess_proof_generator.cpp
 ** \verbatim
 ** Top contributors (to current version):
 **   Andrew Reynolds
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
 ** in the top-level source directory) and their institutional affiliations.
 ** All rights reserved.  See the file COPYING in the top-level source
 ** directory for licensing information.\endverbatim
 **
 ** \brief The implementation of the module for proofs for preprocessing in an
 ** SMT engine.
 **/

#include "smt/preprocess_proof_generator.h"

#include "expr/proof.h"
#include "theory/rewriter.h"

namespace CVC4 {
namespace smt {

PreprocessProofGenerator::PreprocessProofGenerator(ProofNodeManager* pnm)
    : d_pnm(pnm)
{
}

void PreprocessProofGenerator::notifyNewAssert(Node n, ProofGenerator* pg)
{
  Trace("smt-proof-pp-debug") << "- notifyNewAssert: " << n << std::endl;
  d_src[n] = theory::TrustNode::mkTrustLemma(n, pg);
}

void PreprocessProofGenerator::notifyPreprocessed(Node n,
                                                  Node np,
                                                  ProofGenerator* pg)
{
  // only keep if indeed it rewrote
  if (n != np)
  {
    Trace("smt-proof-pp-debug")
        << "- notifyPreprocessed: " << n << "..." << np << std::endl;
    d_src[np] = theory::TrustNode::mkTrustRewrite(n, np, pg);
  }
}

std::shared_ptr<ProofNode> PreprocessProofGenerator::getProofFor(Node f)
{
  std::map<Node, theory::TrustNode>::iterator it = d_src.find(f);
  if (it == d_src.end())
  {
    // could be an assumption, return nullptr
    return nullptr;
  }
  // make CDProof to construct the proof below
  CDProof cdp(d_pnm);

  Node curr = f;
  std::vector<Node> transChildren;
  bool success;
  do
  {
    success = false;
    if (it != d_src.end())
    {
      Assert(it->second.getNode() == curr);
      bool proofStepProcessed = false;
      std::shared_ptr<ProofNode> pfr = it->second.toProofNode();
      if (pfr != nullptr)
      {
        Assert(pfr->getResult() == it->second.getProven());
        cdp.addProof(pfr);
        proofStepProcessed = true;
      }

      if (it->second.getKind() == theory::TrustNodeKind::REWRITE)
      {
        Node eq = it->second.getProven();
        Assert(eq.getKind() == kind::EQUAL);
        if (!proofStepProcessed)
        {
          // maybe its just a simple rewrite?
          if (eq[1] == theory::Rewriter::rewrite(eq[0]))
          {
            cdp.addStep(eq, PfRule::REWRITE, {}, {eq[0]});
            proofStepProcessed = true;
          }
        }
        transChildren.push_back(eq);
        // continue with source
        curr = eq[0];
        success = true;
        // find the next node
        it = d_src.find(curr);
      }
      else
      {
        Assert(it->second.getKind() == theory::TrustNodeKind::LEMMA);
      }

      if (!proofStepProcessed)
      {
        // add trusted step
        Node proven = it->second.getProven();
        cdp.addStep(proven, PfRule::PREPROCESS, {}, {proven});
      }
    }
  } while (success);

  Assert(curr != f);
  // prove ( curr == f )
  Node fullRewrite = curr.eqNode(f);
  if (transChildren.size() >= 2)
  {
    cdp.addStep(fullRewrite, PfRule::TRANS, transChildren, {});
  }
  // prove f
  cdp.addStep(f, PfRule::EQ_RESOLVE, {curr, fullRewrite}, {});

  // overall, proof is:
  //        --------- from proof generator       ---------- from proof generator
  //        F_1 = F_2          ...               F_{n-1} = F_n
  // ---?   -------------------------------------------------- TRANS
  // F_1    F_1 = F_n
  // ---------------- EQ_RESOLVE
  // F_n
  // Note F_1 may have been given a proof if it was not an input assumption.

  return cdp.getProofFor(f);
}

std::string PreprocessProofGenerator::identify() const
{
  return "PreprocessProofGenerator";
}

}  // namespace smt
}  // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback