1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* 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 |
|
* Implementation of datatypes proof checker. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/datatypes/proof_checker.h" |
17 |
|
|
18 |
|
#include "expr/dtype_cons.h" |
19 |
|
#include "theory/datatypes/theory_datatypes_utils.h" |
20 |
|
#include "theory/rewriter.h" |
21 |
|
|
22 |
|
namespace cvc5 { |
23 |
|
namespace theory { |
24 |
|
namespace datatypes { |
25 |
|
|
26 |
3600 |
void DatatypesProofRuleChecker::registerTo(ProofChecker* pc) |
27 |
|
{ |
28 |
3600 |
pc->registerChecker(PfRule::DT_UNIF, this); |
29 |
3600 |
pc->registerChecker(PfRule::DT_INST, this); |
30 |
3600 |
pc->registerChecker(PfRule::DT_COLLAPSE, this); |
31 |
3600 |
pc->registerChecker(PfRule::DT_SPLIT, this); |
32 |
3600 |
pc->registerChecker(PfRule::DT_CLASH, this); |
33 |
|
// trusted rules |
34 |
3600 |
pc->registerTrustedChecker(PfRule::DT_TRUST, this, 2); |
35 |
3600 |
} |
36 |
|
|
37 |
9300 |
Node DatatypesProofRuleChecker::checkInternal(PfRule id, |
38 |
|
const std::vector<Node>& children, |
39 |
|
const std::vector<Node>& args) |
40 |
|
{ |
41 |
9300 |
NodeManager* nm = NodeManager::currentNM(); |
42 |
9300 |
if (id == PfRule::DT_UNIF) |
43 |
|
{ |
44 |
702 |
Assert(children.size() == 1); |
45 |
702 |
Assert(args.size() == 1); |
46 |
|
uint32_t i; |
47 |
1404 |
if (children[0].getKind() != kind::EQUAL |
48 |
1404 |
|| children[0][0].getKind() != kind::APPLY_CONSTRUCTOR |
49 |
1404 |
|| children[0][1].getKind() != kind::APPLY_CONSTRUCTOR |
50 |
1404 |
|| children[0][0].getOperator() != children[0][1].getOperator() |
51 |
2106 |
|| !getUInt32(args[0], i)) |
52 |
|
{ |
53 |
|
return Node::null(); |
54 |
|
} |
55 |
702 |
if (i >= children[0][0].getNumChildren()) |
56 |
|
{ |
57 |
|
return Node::null(); |
58 |
|
} |
59 |
702 |
Assert(children[0][0].getNumChildren() == children[0][1].getNumChildren()); |
60 |
702 |
return children[0][0][i].eqNode(children[0][1][i]); |
61 |
|
} |
62 |
8598 |
else if (id == PfRule::DT_INST) |
63 |
|
{ |
64 |
3167 |
Assert(children.empty()); |
65 |
3167 |
Assert(args.size() == 2); |
66 |
6334 |
Node t = args[0]; |
67 |
6334 |
TypeNode tn = t.getType(); |
68 |
|
uint32_t i; |
69 |
3167 |
if (!tn.isDatatype() || !getUInt32(args[1], i)) |
70 |
|
{ |
71 |
|
return Node::null(); |
72 |
|
} |
73 |
3167 |
const DType& dt = tn.getDType(); |
74 |
3167 |
if (i >= dt.getNumConstructors()) |
75 |
|
{ |
76 |
|
return Node::null(); |
77 |
|
} |
78 |
6334 |
Node tester = utils::mkTester(t, i, dt); |
79 |
6334 |
Node ticons = Rewriter::rewrite(utils::getInstCons(t, dt, i)); |
80 |
3167 |
return tester.eqNode(t.eqNode(ticons)); |
81 |
|
} |
82 |
5431 |
else if (id == PfRule::DT_COLLAPSE) |
83 |
|
{ |
84 |
3652 |
Assert(children.empty()); |
85 |
3652 |
Assert(args.size() == 1); |
86 |
7304 |
Node t = args[0]; |
87 |
7304 |
if (t.getKind() != kind::APPLY_SELECTOR_TOTAL |
88 |
7304 |
|| t[0].getKind() != kind::APPLY_CONSTRUCTOR) |
89 |
|
{ |
90 |
|
return Node::null(); |
91 |
|
} |
92 |
7304 |
Node selector = t.getOperator(); |
93 |
3652 |
size_t constructorIndex = utils::indexOf(t[0].getOperator()); |
94 |
3652 |
const DType& dt = utils::datatypeOf(selector); |
95 |
3652 |
const DTypeConstructor& dtc = dt[constructorIndex]; |
96 |
3652 |
int selectorIndex = dtc.getSelectorIndexInternal(selector); |
97 |
|
Node r = |
98 |
7304 |
selectorIndex < 0 ? t.getType().mkGroundTerm() : t[0][selectorIndex]; |
99 |
3652 |
return t.eqNode(r); |
100 |
|
} |
101 |
1779 |
else if (id == PfRule::DT_SPLIT) |
102 |
|
{ |
103 |
1324 |
Assert(children.empty()); |
104 |
1324 |
Assert(args.size() == 1); |
105 |
2648 |
TypeNode tn = args[0].getType(); |
106 |
1324 |
if (!tn.isDatatype()) |
107 |
|
{ |
108 |
|
return Node::null(); |
109 |
|
} |
110 |
1324 |
const DType& dt = tn.getDType(); |
111 |
1324 |
return utils::mkSplit(args[0], dt); |
112 |
|
} |
113 |
455 |
else if (id == PfRule::DT_CLASH) |
114 |
|
{ |
115 |
|
Assert(children.size() == 2); |
116 |
|
Assert(args.empty()); |
117 |
|
if (children[0].getKind() != kind::APPLY_TESTER |
118 |
|
|| children[1].getKind() != kind::APPLY_TESTER |
119 |
|
|| children[0][0] != children[1][0] || children[0] == children[1]) |
120 |
|
{ |
121 |
|
return Node::null(); |
122 |
|
} |
123 |
|
return nm->mkConst(false); |
124 |
|
} |
125 |
455 |
else if (id == PfRule::DT_TRUST) |
126 |
|
{ |
127 |
455 |
Assert(!args.empty()); |
128 |
455 |
Assert(args[0].getType().isBoolean()); |
129 |
455 |
return args[0]; |
130 |
|
} |
131 |
|
// no rule |
132 |
|
return Node::null(); |
133 |
|
} |
134 |
|
|
135 |
|
} // namespace datatypes |
136 |
|
} // namespace theory |
137 |
28191 |
} // namespace cvc5 |