1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Gereon Kremer, 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 |
|
* Arrays inference manager. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "theory/arrays/inference_manager.h" |
17 |
|
|
18 |
|
#include "options/smt_options.h" |
19 |
|
#include "theory/builtin/proof_checker.h" |
20 |
|
#include "theory/theory.h" |
21 |
|
#include "theory/theory_state.h" |
22 |
|
#include "theory/uf/equality_engine.h" |
23 |
|
|
24 |
|
using namespace cvc5::kind; |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
namespace theory { |
28 |
|
namespace arrays { |
29 |
|
|
30 |
9940 |
InferenceManager::InferenceManager(Env& env, |
31 |
|
Theory& t, |
32 |
|
TheoryState& state, |
33 |
9940 |
ProofNodeManager* pnm) |
34 |
|
: TheoryInferenceManager(env, t, state, pnm, "theory::arrays::", false), |
35 |
|
d_lemmaPg(pnm ? new EagerProofGenerator( |
36 |
2486 |
pnm, userContext(), "ArrayLemmaProofGenerator") |
37 |
12426 |
: nullptr) |
38 |
|
{ |
39 |
9940 |
} |
40 |
|
|
41 |
15650 |
bool InferenceManager::assertInference(TNode atom, |
42 |
|
bool polarity, |
43 |
|
InferenceId id, |
44 |
|
TNode reason, |
45 |
|
PfRule pfr) |
46 |
|
{ |
47 |
31300 |
Trace("arrays-infer") << "TheoryArrays::assertInference: " |
48 |
31300 |
<< (polarity ? Node(atom) : atom.notNode()) << " by " |
49 |
15650 |
<< reason << "; " << id << std::endl; |
50 |
15650 |
Assert(atom.getKind() == EQUAL); |
51 |
|
// if proofs are enabled, we determine which proof rule to add, otherwise |
52 |
|
// we simply assert the internal fact |
53 |
15650 |
if (isProofEnabled()) |
54 |
|
{ |
55 |
1900 |
Node fact = polarity ? Node(atom) : atom.notNode(); |
56 |
1900 |
std::vector<Node> children; |
57 |
1900 |
std::vector<Node> args; |
58 |
|
// convert to proof rule application |
59 |
950 |
convert(pfr, fact, reason, children, args); |
60 |
950 |
return assertInternalFact(atom, polarity, id, pfr, children, args); |
61 |
|
} |
62 |
14700 |
return assertInternalFact(atom, polarity, id, reason); |
63 |
|
} |
64 |
|
|
65 |
5961 |
bool InferenceManager::arrayLemma( |
66 |
|
Node conc, InferenceId id, Node exp, PfRule pfr, LemmaProperty p) |
67 |
|
{ |
68 |
11922 |
Trace("arrays-infer") << "TheoryArrays::arrayLemma: " << conc << " by " << exp |
69 |
5961 |
<< "; " << id << std::endl; |
70 |
5961 |
NodeManager* nm = NodeManager::currentNM(); |
71 |
5961 |
if (isProofEnabled()) |
72 |
|
{ |
73 |
690 |
std::vector<Node> children; |
74 |
690 |
std::vector<Node> args; |
75 |
|
// convert to proof rule application |
76 |
345 |
convert(pfr, conc, exp, children, args); |
77 |
|
// make the trusted lemma based on the eager proof generator and send |
78 |
690 |
TrustNode tlem = d_lemmaPg->mkTrustNode(conc, pfr, children, args); |
79 |
345 |
return trustedLemma(tlem, id, p); |
80 |
|
} |
81 |
|
// send lemma without proofs |
82 |
11232 |
Node lem = nm->mkNode(IMPLIES, exp, conc); |
83 |
5616 |
return lemma(lem, id, p); |
84 |
|
} |
85 |
|
|
86 |
1295 |
void InferenceManager::convert(PfRule& id, |
87 |
|
Node conc, |
88 |
|
Node exp, |
89 |
|
std::vector<Node>& children, |
90 |
|
std::vector<Node>& args) |
91 |
|
{ |
92 |
|
// note that children must contain something equivalent to exp, |
93 |
|
// regardless of the PfRule. |
94 |
1295 |
switch (id) |
95 |
|
{ |
96 |
119 |
case PfRule::MACRO_SR_PRED_INTRO: |
97 |
119 |
Assert(exp.isConst()); |
98 |
119 |
args.push_back(conc); |
99 |
119 |
break; |
100 |
858 |
case PfRule::ARRAYS_READ_OVER_WRITE: |
101 |
858 |
if (exp.isConst()) |
102 |
|
{ |
103 |
|
// Premise can be shown by rewriting, use standard predicate intro rule. |
104 |
|
// This is the case where we have 2 constant indices. |
105 |
51 |
id = PfRule::MACRO_SR_PRED_INTRO; |
106 |
51 |
args.push_back(conc); |
107 |
|
} |
108 |
|
else |
109 |
|
{ |
110 |
807 |
children.push_back(exp); |
111 |
807 |
args.push_back(conc[0]); |
112 |
|
} |
113 |
858 |
break; |
114 |
|
case PfRule::ARRAYS_READ_OVER_WRITE_CONTRA: children.push_back(exp); break; |
115 |
127 |
case PfRule::ARRAYS_READ_OVER_WRITE_1: |
116 |
127 |
Assert(exp.isConst()); |
117 |
127 |
args.push_back(conc[0]); |
118 |
127 |
break; |
119 |
191 |
case PfRule::ARRAYS_EXT: children.push_back(exp); break; |
120 |
|
default: |
121 |
|
if (id != PfRule::THEORY_INFERENCE) |
122 |
|
{ |
123 |
|
Assert(false) << "Unknown rule " << id << "\n"; |
124 |
|
} |
125 |
|
children.push_back(exp); |
126 |
|
args.push_back(conc); |
127 |
|
args.push_back( |
128 |
|
builtin::BuiltinProofRuleChecker::mkTheoryIdNode(THEORY_ARRAYS)); |
129 |
|
id = PfRule::THEORY_INFERENCE; |
130 |
|
break; |
131 |
|
} |
132 |
1295 |
} |
133 |
|
|
134 |
|
} // namespace arrays |
135 |
|
} // namespace theory |
136 |
29574 |
} // namespace cvc5 |