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 "expr/proof_node_to_sexpr.h" |
17 |
|
|
18 |
|
#include <iostream> |
19 |
|
#include <sstream> |
20 |
|
|
21 |
|
#include "expr/proof_node.h" |
22 |
|
#include "options/proof_options.h" |
23 |
|
|
24 |
|
using namespace cvc5::kind; |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
|
28 |
32818 |
ProofNodeToSExpr::ProofNodeToSExpr() |
29 |
|
{ |
30 |
32818 |
NodeManager* nm = NodeManager::currentNM(); |
31 |
32818 |
d_conclusionMarker = nm->mkBoundVar(":conclusion", nm->sExprType()); |
32 |
32818 |
d_argsMarker = nm->mkBoundVar(":args", nm->sExprType()); |
33 |
32818 |
} |
34 |
|
|
35 |
32818 |
Node ProofNodeToSExpr::convertToSExpr(const ProofNode* pn) |
36 |
|
{ |
37 |
32818 |
NodeManager* nm = NodeManager::currentNM(); |
38 |
32818 |
std::map<const ProofNode*, Node>::iterator it; |
39 |
65636 |
std::vector<const ProofNode*> visit; |
40 |
65636 |
std::vector<const ProofNode*> traversing; |
41 |
|
const ProofNode* cur; |
42 |
32818 |
visit.push_back(pn); |
43 |
384344 |
do |
44 |
|
{ |
45 |
417162 |
cur = visit.back(); |
46 |
417162 |
visit.pop_back(); |
47 |
417162 |
it = d_pnMap.find(cur); |
48 |
|
|
49 |
417162 |
if (it == d_pnMap.end()) |
50 |
|
{ |
51 |
208579 |
d_pnMap[cur] = Node::null(); |
52 |
208579 |
traversing.push_back(cur); |
53 |
208579 |
visit.push_back(cur); |
54 |
208579 |
const std::vector<std::shared_ptr<ProofNode>>& pc = cur->getChildren(); |
55 |
384344 |
for (const std::shared_ptr<ProofNode>& cp : pc) |
56 |
|
{ |
57 |
527295 |
if (std::find(traversing.begin(), traversing.end(), cp.get()) |
58 |
527295 |
!= traversing.end()) |
59 |
|
{ |
60 |
|
Unhandled() << "ProofNodeToSExpr::convertToSExpr: cyclic proof! (use " |
61 |
|
"--proof-eager-checking)" |
62 |
|
<< std::endl; |
63 |
|
return Node::null(); |
64 |
|
} |
65 |
175765 |
visit.push_back(cp.get()); |
66 |
|
} |
67 |
|
} |
68 |
208583 |
else if (it->second.isNull()) |
69 |
|
{ |
70 |
208579 |
Assert(!traversing.empty()); |
71 |
208579 |
traversing.pop_back(); |
72 |
417158 |
std::vector<Node> children; |
73 |
|
// add proof rule |
74 |
208579 |
children.push_back(getOrMkPfRuleVariable(cur->getRule())); |
75 |
417158 |
if (options::proofPrintConclusion()) |
76 |
|
{ |
77 |
|
children.push_back(d_conclusionMarker); |
78 |
|
children.push_back(cur->getResult()); |
79 |
|
} |
80 |
208579 |
const std::vector<std::shared_ptr<ProofNode>>& pc = cur->getChildren(); |
81 |
384344 |
for (const std::shared_ptr<ProofNode>& cp : pc) |
82 |
|
{ |
83 |
175765 |
it = d_pnMap.find(cp.get()); |
84 |
175765 |
Assert(it != d_pnMap.end()); |
85 |
175765 |
Assert(!it->second.isNull()); |
86 |
175765 |
children.push_back(it->second); |
87 |
|
} |
88 |
|
// add arguments |
89 |
208579 |
const std::vector<Node>& args = cur->getArguments(); |
90 |
208579 |
if (!args.empty()) |
91 |
|
{ |
92 |
191700 |
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 |
383400 |
std::vector<Node> argsSafe; |
97 |
416260 |
for (const Node& a : args) |
98 |
|
{ |
99 |
449120 |
Node av = a; |
100 |
449120 |
if (a.getNumChildren() == 0 |
101 |
449120 |
&& NodeManager::operatorToKind(a) != UNDEFINED_KIND) |
102 |
|
{ |
103 |
|
av = getOrMkNodeVariable(a); |
104 |
|
} |
105 |
224560 |
argsSafe.push_back(av); |
106 |
|
} |
107 |
383400 |
Node argsC = nm->mkNode(SEXPR, argsSafe); |
108 |
191700 |
children.push_back(argsC); |
109 |
|
} |
110 |
208579 |
d_pnMap[cur] = nm->mkNode(SEXPR, children); |
111 |
|
} |
112 |
417162 |
} while (!visit.empty()); |
113 |
32818 |
Assert(d_pnMap.find(pn) != d_pnMap.end()); |
114 |
32818 |
Assert(!d_pnMap.find(pn)->second.isNull()); |
115 |
32818 |
return d_pnMap[pn]; |
116 |
|
} |
117 |
|
|
118 |
208579 |
Node ProofNodeToSExpr::getOrMkPfRuleVariable(PfRule r) |
119 |
|
{ |
120 |
208579 |
std::map<PfRule, Node>::iterator it = d_pfrMap.find(r); |
121 |
208579 |
if (it != d_pfrMap.end()) |
122 |
|
{ |
123 |
60121 |
return it->second; |
124 |
|
} |
125 |
296916 |
std::stringstream ss; |
126 |
148458 |
ss << r; |
127 |
148458 |
NodeManager* nm = NodeManager::currentNM(); |
128 |
296916 |
Node var = nm->mkBoundVar(ss.str(), nm->sExprType()); |
129 |
148458 |
d_pfrMap[r] = var; |
130 |
148458 |
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 |
236770 |
} // namespace cvc5 |