1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Haniel Barbosa, 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 proof node to s-expression. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "proof/proof_node_to_sexpr.h" |
17 |
|
|
18 |
|
#include <iostream> |
19 |
|
#include <sstream> |
20 |
|
|
21 |
|
#include "options/proof_options.h" |
22 |
|
#include "proof/proof_node.h" |
23 |
|
|
24 |
|
using namespace cvc5::kind; |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
|
28 |
37589 |
ProofNodeToSExpr::ProofNodeToSExpr() |
29 |
|
{ |
30 |
37589 |
NodeManager* nm = NodeManager::currentNM(); |
31 |
37589 |
d_conclusionMarker = nm->mkBoundVar(":conclusion", nm->sExprType()); |
32 |
37589 |
d_argsMarker = nm->mkBoundVar(":args", nm->sExprType()); |
33 |
37589 |
} |
34 |
|
|
35 |
37589 |
Node ProofNodeToSExpr::convertToSExpr(const ProofNode* pn) |
36 |
|
{ |
37 |
37589 |
NodeManager* nm = NodeManager::currentNM(); |
38 |
37589 |
std::map<const ProofNode*, Node>::iterator it; |
39 |
75178 |
std::vector<const ProofNode*> visit; |
40 |
75178 |
std::vector<const ProofNode*> traversing; |
41 |
|
const ProofNode* cur; |
42 |
37589 |
visit.push_back(pn); |
43 |
441527 |
do |
44 |
|
{ |
45 |
479116 |
cur = visit.back(); |
46 |
479116 |
visit.pop_back(); |
47 |
479116 |
it = d_pnMap.find(cur); |
48 |
|
|
49 |
479116 |
if (it == d_pnMap.end()) |
50 |
|
{ |
51 |
239556 |
d_pnMap[cur] = Node::null(); |
52 |
239556 |
traversing.push_back(cur); |
53 |
239556 |
visit.push_back(cur); |
54 |
239556 |
const std::vector<std::shared_ptr<ProofNode>>& pc = cur->getChildren(); |
55 |
441527 |
for (const std::shared_ptr<ProofNode>& cp : pc) |
56 |
|
{ |
57 |
605913 |
if (std::find(traversing.begin(), traversing.end(), cp.get()) |
58 |
605913 |
!= traversing.end()) |
59 |
|
{ |
60 |
|
Unhandled() << "ProofNodeToSExpr::convertToSExpr: cyclic proof! (use " |
61 |
|
"--proof-eager-checking)" |
62 |
|
<< std::endl; |
63 |
|
return Node::null(); |
64 |
|
} |
65 |
201971 |
visit.push_back(cp.get()); |
66 |
|
} |
67 |
|
} |
68 |
239560 |
else if (it->second.isNull()) |
69 |
|
{ |
70 |
239556 |
Assert(!traversing.empty()); |
71 |
239556 |
traversing.pop_back(); |
72 |
479112 |
std::vector<Node> children; |
73 |
|
// add proof rule |
74 |
239556 |
children.push_back(getOrMkPfRuleVariable(cur->getRule())); |
75 |
479112 |
if (options::proofPrintConclusion()) |
76 |
|
{ |
77 |
|
children.push_back(d_conclusionMarker); |
78 |
|
children.push_back(cur->getResult()); |
79 |
|
} |
80 |
239556 |
const std::vector<std::shared_ptr<ProofNode>>& pc = cur->getChildren(); |
81 |
441527 |
for (const std::shared_ptr<ProofNode>& cp : pc) |
82 |
|
{ |
83 |
201971 |
it = d_pnMap.find(cp.get()); |
84 |
201971 |
Assert(it != d_pnMap.end()); |
85 |
201971 |
Assert(!it->second.isNull()); |
86 |
201971 |
children.push_back(it->second); |
87 |
|
} |
88 |
|
// add arguments |
89 |
239556 |
const std::vector<Node>& args = cur->getArguments(); |
90 |
239556 |
if (!args.empty()) |
91 |
|
{ |
92 |
220527 |
children.push_back(d_argsMarker); |
93 |
|
// needed to ensure builtin operators are not treated as operators |
94 |
|
// this can be the case for CONG where d_args may contain a builtin |
95 |
|
// operator |
96 |
441054 |
std::vector<Node> argsSafe; |
97 |
478706 |
for (const Node& a : args) |
98 |
|
{ |
99 |
516358 |
Node av = a; |
100 |
516358 |
if (a.getNumChildren() == 0 |
101 |
516358 |
&& NodeManager::operatorToKind(a) != UNDEFINED_KIND) |
102 |
|
{ |
103 |
|
av = getOrMkNodeVariable(a); |
104 |
|
} |
105 |
258179 |
argsSafe.push_back(av); |
106 |
|
} |
107 |
441054 |
Node argsC = nm->mkNode(SEXPR, argsSafe); |
108 |
220527 |
children.push_back(argsC); |
109 |
|
} |
110 |
239556 |
d_pnMap[cur] = nm->mkNode(SEXPR, children); |
111 |
|
} |
112 |
479116 |
} while (!visit.empty()); |
113 |
37589 |
Assert(d_pnMap.find(pn) != d_pnMap.end()); |
114 |
37589 |
Assert(!d_pnMap.find(pn)->second.isNull()); |
115 |
37589 |
return d_pnMap[pn]; |
116 |
|
} |
117 |
|
|
118 |
239556 |
Node ProofNodeToSExpr::getOrMkPfRuleVariable(PfRule r) |
119 |
|
{ |
120 |
239556 |
std::map<PfRule, Node>::iterator it = d_pfrMap.find(r); |
121 |
239556 |
if (it != d_pfrMap.end()) |
122 |
|
{ |
123 |
69849 |
return it->second; |
124 |
|
} |
125 |
339414 |
std::stringstream ss; |
126 |
169707 |
ss << r; |
127 |
169707 |
NodeManager* nm = NodeManager::currentNM(); |
128 |
339414 |
Node var = nm->mkBoundVar(ss.str(), nm->sExprType()); |
129 |
169707 |
d_pfrMap[r] = var; |
130 |
169707 |
return var; |
131 |
|
} |
132 |
|
|
133 |
|
Node ProofNodeToSExpr::getOrMkNodeVariable(Node n) |
134 |
|
{ |
135 |
|
std::map<Node, Node>::iterator it = d_nodeMap.find(n); |
136 |
|
if (it != d_nodeMap.end()) |
137 |
|
{ |
138 |
|
return it->second; |
139 |
|
} |
140 |
|
std::stringstream ss; |
141 |
|
ss << n; |
142 |
|
NodeManager* nm = NodeManager::currentNM(); |
143 |
|
Node var = nm->mkBoundVar(ss.str(), nm->sExprType()); |
144 |
|
d_nodeMap[n] = var; |
145 |
|
return var; |
146 |
|
} |
147 |
|
|
148 |
268842 |
} // namespace cvc5 |