1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Tim King, Haniel Barbosa, Mathias Preiner |
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 |
|
* [[ Add one-line brief description here ]] |
14 |
|
* |
15 |
|
* [[ Add lengthier description here ]] |
16 |
|
* \todo document this file |
17 |
|
*/ |
18 |
|
|
19 |
|
#include "theory/arith/callbacks.h" |
20 |
|
|
21 |
|
#include "expr/skolem_manager.h" |
22 |
|
#include "proof/proof_node.h" |
23 |
|
#include "theory/arith/theory_arith_private.h" |
24 |
|
|
25 |
|
namespace cvc5 { |
26 |
|
namespace theory { |
27 |
|
namespace arith { |
28 |
|
|
29 |
15273 |
SetupLiteralCallBack::SetupLiteralCallBack(TheoryArithPrivate& ta) |
30 |
15273 |
: d_arith(ta) |
31 |
15273 |
{} |
32 |
21922 |
void SetupLiteralCallBack::operator()(TNode lit){ |
33 |
43844 |
TNode atom = (lit.getKind() == kind::NOT) ? lit[0] : lit; |
34 |
21922 |
if(!d_arith.isSetup(atom)){ |
35 |
21922 |
d_arith.setupAtom(atom); |
36 |
|
} |
37 |
21922 |
} |
38 |
|
|
39 |
15273 |
DeltaComputeCallback::DeltaComputeCallback(const TheoryArithPrivate& ta) |
40 |
15273 |
: d_ta(ta) |
41 |
15273 |
{} |
42 |
59076 |
Rational DeltaComputeCallback::operator()() const{ |
43 |
59076 |
return d_ta.deltaValueForTotalOrder(); |
44 |
|
} |
45 |
|
|
46 |
61092 |
TempVarMalloc::TempVarMalloc(TheoryArithPrivate& ta) |
47 |
61092 |
: d_ta(ta) |
48 |
61092 |
{} |
49 |
|
ArithVar TempVarMalloc::request(){ |
50 |
|
NodeManager* nm = NodeManager::currentNM(); |
51 |
|
SkolemManager* sm = nm->getSkolemManager(); |
52 |
|
Node skolem = sm->mkDummySkolem("tmpVar", nm->realType()); |
53 |
|
return d_ta.requestArithVar(skolem, false, true); |
54 |
|
} |
55 |
|
void TempVarMalloc::release(ArithVar v){ |
56 |
|
d_ta.releaseArithVar(v); |
57 |
|
} |
58 |
|
|
59 |
15273 |
BasicVarModelUpdateCallBack::BasicVarModelUpdateCallBack(TheoryArithPrivate& ta) |
60 |
15273 |
: d_ta(ta) |
61 |
15273 |
{} |
62 |
8271146 |
void BasicVarModelUpdateCallBack::operator()(ArithVar x){ |
63 |
8271146 |
d_ta.signal(x); |
64 |
8271146 |
} |
65 |
|
|
66 |
76365 |
RaiseConflict::RaiseConflict(TheoryArithPrivate& ta) |
67 |
76365 |
: d_ta(ta) |
68 |
76365 |
{} |
69 |
|
|
70 |
84620 |
void RaiseConflict::raiseConflict(ConstraintCP c, InferenceId id) const{ |
71 |
84620 |
Assert(c->inConflict()); |
72 |
84620 |
d_ta.raiseConflict(c, id); |
73 |
84620 |
} |
74 |
|
|
75 |
61092 |
FarkasConflictBuilder::FarkasConflictBuilder(bool produceProofs) |
76 |
|
: d_farkas(), |
77 |
|
d_constraints(), |
78 |
|
d_consequent(NullConstraint), |
79 |
|
d_consequentSet(false), |
80 |
61092 |
d_produceProofs(produceProofs) |
81 |
|
{ |
82 |
61092 |
reset(); |
83 |
61092 |
} |
84 |
|
|
85 |
973778 |
bool FarkasConflictBuilder::underConstruction() const{ |
86 |
973778 |
return d_consequent != NullConstraint; |
87 |
|
} |
88 |
|
|
89 |
84620 |
bool FarkasConflictBuilder::consequentIsSet() const{ |
90 |
84620 |
return d_consequentSet; |
91 |
|
} |
92 |
|
|
93 |
145712 |
void FarkasConflictBuilder::reset(){ |
94 |
145712 |
d_consequent = NullConstraint; |
95 |
145712 |
d_constraints.clear(); |
96 |
145712 |
d_consequentSet = false; |
97 |
145712 |
if (d_produceProofs) |
98 |
|
{ |
99 |
60842 |
d_farkas.clear(); |
100 |
|
} |
101 |
145712 |
Assert(!underConstruction()); |
102 |
145712 |
} |
103 |
|
|
104 |
|
/* Adds a constraint to the constraint under construction. */ |
105 |
1078215 |
void FarkasConflictBuilder::addConstraint(ConstraintCP c, const Rational& fc){ |
106 |
1078215 |
Assert( |
107 |
|
!d_produceProofs |
108 |
|
|| (!underConstruction() && d_constraints.empty() && d_farkas.empty()) |
109 |
|
|| (underConstruction() && d_constraints.size() + 1 == d_farkas.size())); |
110 |
1078215 |
Assert(d_produceProofs || d_farkas.empty()); |
111 |
1078215 |
Assert(c->isTrue()); |
112 |
|
|
113 |
1078215 |
if(d_consequent == NullConstraint){ |
114 |
84620 |
d_consequent = c; |
115 |
|
} else { |
116 |
993595 |
d_constraints.push_back(c); |
117 |
|
} |
118 |
1078215 |
if (d_produceProofs) |
119 |
|
{ |
120 |
230350 |
d_farkas.push_back(fc); |
121 |
|
} |
122 |
1078215 |
Assert(!d_produceProofs || d_constraints.size() + 1 == d_farkas.size()); |
123 |
1078215 |
Assert(d_produceProofs || d_farkas.empty()); |
124 |
1078215 |
} |
125 |
|
|
126 |
1078215 |
void FarkasConflictBuilder::addConstraint(ConstraintCP c, const Rational& fc, const Rational& mult){ |
127 |
1078215 |
Assert(!mult.isZero()); |
128 |
1078215 |
if (d_produceProofs && !mult.isOne()) |
129 |
|
{ |
130 |
223686 |
Rational prod = fc * mult; |
131 |
111843 |
addConstraint(c, prod); |
132 |
|
} |
133 |
|
else |
134 |
|
{ |
135 |
966372 |
addConstraint(c, fc); |
136 |
|
} |
137 |
1078215 |
} |
138 |
|
|
139 |
84620 |
void FarkasConflictBuilder::makeLastConsequent(){ |
140 |
84620 |
Assert(!d_consequentSet); |
141 |
84620 |
Assert(underConstruction()); |
142 |
|
|
143 |
84620 |
if(d_constraints.empty()){ |
144 |
|
// no-op |
145 |
3806 |
d_consequentSet = true; |
146 |
|
} else { |
147 |
80814 |
Assert(d_consequent != NullConstraint); |
148 |
80814 |
ConstraintCP last = d_constraints.back(); |
149 |
80814 |
d_constraints.back() = d_consequent; |
150 |
80814 |
d_consequent = last; |
151 |
80814 |
if (d_produceProofs) |
152 |
|
{ |
153 |
28018 |
std::swap(d_farkas.front(), d_farkas.back()); |
154 |
|
} |
155 |
80814 |
d_consequentSet = true; |
156 |
|
} |
157 |
|
|
158 |
84620 |
Assert(!d_consequent->negationHasProof()); |
159 |
84620 |
Assert(d_consequentSet); |
160 |
84620 |
} |
161 |
|
|
162 |
|
/* Turns the vector under construction into a conflict */ |
163 |
84620 |
ConstraintCP FarkasConflictBuilder::commitConflict(){ |
164 |
84620 |
Assert(underConstruction()); |
165 |
84620 |
Assert(!d_constraints.empty()); |
166 |
84620 |
Assert( |
167 |
|
!d_produceProofs |
168 |
|
|| (!underConstruction() && d_constraints.empty() && d_farkas.empty()) |
169 |
|
|| (underConstruction() && d_constraints.size() + 1 == d_farkas.size())); |
170 |
84620 |
Assert(d_produceProofs || d_farkas.empty()); |
171 |
84620 |
Assert(d_consequentSet); |
172 |
|
|
173 |
84620 |
ConstraintP not_c = d_consequent->getNegation(); |
174 |
84620 |
RationalVectorCP coeffs = d_produceProofs ? &d_farkas : nullptr; |
175 |
84620 |
not_c->impliedByFarkas(d_constraints, coeffs, true ); |
176 |
|
|
177 |
84620 |
reset(); |
178 |
84620 |
Assert(!underConstruction()); |
179 |
84620 |
Assert(not_c->inConflict()); |
180 |
84620 |
Assert(!d_consequentSet); |
181 |
84620 |
return not_c; |
182 |
|
} |
183 |
|
|
184 |
15273 |
RaiseEqualityEngineConflict::RaiseEqualityEngineConflict(TheoryArithPrivate& ta) |
185 |
15273 |
: d_ta(ta) |
186 |
15273 |
{} |
187 |
|
|
188 |
|
/* If you are not an equality engine, don't use this! */ |
189 |
2496 |
void RaiseEqualityEngineConflict::raiseEEConflict( |
190 |
|
Node n, std::shared_ptr<ProofNode> pf) const |
191 |
|
{ |
192 |
2496 |
d_ta.raiseBlackBoxConflict(n, pf); |
193 |
2496 |
} |
194 |
|
|
195 |
15273 |
BoundCountingLookup::BoundCountingLookup(TheoryArithPrivate& ta) |
196 |
15273 |
: d_ta(ta) |
197 |
15273 |
{} |
198 |
|
|
199 |
|
const BoundsInfo& BoundCountingLookup::boundsInfo(ArithVar basic) const{ |
200 |
|
return d_ta.boundsInfo(basic); |
201 |
|
} |
202 |
|
|
203 |
|
BoundCounts BoundCountingLookup::atBounds(ArithVar basic) const{ |
204 |
|
return boundsInfo(basic).atBounds(); |
205 |
|
} |
206 |
|
BoundCounts BoundCountingLookup::hasBounds(ArithVar basic) const { |
207 |
|
return boundsInfo(basic).hasBounds(); |
208 |
|
} |
209 |
|
|
210 |
|
} // namespace arith |
211 |
|
} // namespace theory |
212 |
31137 |
} // namespace cvc5 |