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/proof_node.h" |
22 |
|
#include "expr/skolem_manager.h" |
23 |
|
#include "theory/arith/proof_macros.h" |
24 |
|
#include "theory/arith/theory_arith_private.h" |
25 |
|
|
26 |
|
namespace cvc5 { |
27 |
|
namespace theory { |
28 |
|
namespace arith { |
29 |
|
|
30 |
9459 |
SetupLiteralCallBack::SetupLiteralCallBack(TheoryArithPrivate& ta) |
31 |
9459 |
: d_arith(ta) |
32 |
9459 |
{} |
33 |
16610 |
void SetupLiteralCallBack::operator()(TNode lit){ |
34 |
33220 |
TNode atom = (lit.getKind() == kind::NOT) ? lit[0] : lit; |
35 |
16610 |
if(!d_arith.isSetup(atom)){ |
36 |
16610 |
d_arith.setupAtom(atom); |
37 |
|
} |
38 |
16610 |
} |
39 |
|
|
40 |
9459 |
DeltaComputeCallback::DeltaComputeCallback(const TheoryArithPrivate& ta) |
41 |
9459 |
: d_ta(ta) |
42 |
9459 |
{} |
43 |
11891 |
Rational DeltaComputeCallback::operator()() const{ |
44 |
11891 |
return d_ta.deltaValueForTotalOrder(); |
45 |
|
} |
46 |
|
|
47 |
37836 |
TempVarMalloc::TempVarMalloc(TheoryArithPrivate& ta) |
48 |
37836 |
: d_ta(ta) |
49 |
37836 |
{} |
50 |
|
ArithVar TempVarMalloc::request(){ |
51 |
|
NodeManager* nm = NodeManager::currentNM(); |
52 |
|
SkolemManager* sm = nm->getSkolemManager(); |
53 |
|
Node skolem = sm->mkDummySkolem("tmpVar", nm->realType()); |
54 |
|
return d_ta.requestArithVar(skolem, false, true); |
55 |
|
} |
56 |
|
void TempVarMalloc::release(ArithVar v){ |
57 |
|
d_ta.releaseArithVar(v); |
58 |
|
} |
59 |
|
|
60 |
9459 |
BasicVarModelUpdateCallBack::BasicVarModelUpdateCallBack(TheoryArithPrivate& ta) |
61 |
9459 |
: d_ta(ta) |
62 |
9459 |
{} |
63 |
5514177 |
void BasicVarModelUpdateCallBack::operator()(ArithVar x){ |
64 |
5514177 |
d_ta.signal(x); |
65 |
5514177 |
} |
66 |
|
|
67 |
47295 |
RaiseConflict::RaiseConflict(TheoryArithPrivate& ta) |
68 |
47295 |
: d_ta(ta) |
69 |
47295 |
{} |
70 |
|
|
71 |
56207 |
void RaiseConflict::raiseConflict(ConstraintCP c, InferenceId id) const{ |
72 |
56207 |
Assert(c->inConflict()); |
73 |
56207 |
d_ta.raiseConflict(c, id); |
74 |
56207 |
} |
75 |
|
|
76 |
37836 |
FarkasConflictBuilder::FarkasConflictBuilder() |
77 |
|
: d_farkas() |
78 |
|
, d_constraints() |
79 |
|
, d_consequent(NullConstraint) |
80 |
37836 |
, d_consequentSet(false) |
81 |
|
{ |
82 |
37836 |
reset(); |
83 |
37836 |
} |
84 |
|
|
85 |
713129 |
bool FarkasConflictBuilder::underConstruction() const{ |
86 |
713129 |
return d_consequent != NullConstraint; |
87 |
|
} |
88 |
|
|
89 |
56207 |
bool FarkasConflictBuilder::consequentIsSet() const{ |
90 |
56207 |
return d_consequentSet; |
91 |
|
} |
92 |
|
|
93 |
94043 |
void FarkasConflictBuilder::reset(){ |
94 |
94043 |
d_consequent = NullConstraint; |
95 |
94043 |
d_constraints.clear(); |
96 |
94043 |
d_consequentSet = false; |
97 |
94043 |
ARITH_PROOF(d_farkas.clear()); |
98 |
94043 |
Assert(!underConstruction()); |
99 |
94043 |
} |
100 |
|
|
101 |
|
/* Adds a constraint to the constraint under construction. */ |
102 |
831001 |
void FarkasConflictBuilder::addConstraint(ConstraintCP c, const Rational& fc){ |
103 |
831001 |
Assert( |
104 |
|
!ARITH_PROOF_ON() |
105 |
|
|| (!underConstruction() && d_constraints.empty() && d_farkas.empty()) |
106 |
|
|| (underConstruction() && d_constraints.size() + 1 == d_farkas.size())); |
107 |
831001 |
Assert(ARITH_PROOF_ON() || d_farkas.empty()); |
108 |
831001 |
Assert(c->isTrue()); |
109 |
|
|
110 |
831001 |
if(d_consequent == NullConstraint){ |
111 |
56207 |
d_consequent = c; |
112 |
|
} else { |
113 |
774794 |
d_constraints.push_back(c); |
114 |
|
} |
115 |
831001 |
ARITH_PROOF(d_farkas.push_back(fc)); |
116 |
831001 |
Assert(!ARITH_PROOF_ON() || d_constraints.size() + 1 == d_farkas.size()); |
117 |
831001 |
Assert(ARITH_PROOF_ON() || d_farkas.empty()); |
118 |
831001 |
} |
119 |
|
|
120 |
831001 |
void FarkasConflictBuilder::addConstraint(ConstraintCP c, const Rational& fc, const Rational& mult){ |
121 |
831001 |
Assert(!mult.isZero()); |
122 |
831001 |
if (ARITH_PROOF_ON() && !mult.isOne()) |
123 |
|
{ |
124 |
171518 |
Rational prod = fc * mult; |
125 |
85759 |
addConstraint(c, prod); |
126 |
|
} |
127 |
|
else |
128 |
|
{ |
129 |
745242 |
addConstraint(c, fc); |
130 |
|
} |
131 |
831001 |
} |
132 |
|
|
133 |
56207 |
void FarkasConflictBuilder::makeLastConsequent(){ |
134 |
56207 |
Assert(!d_consequentSet); |
135 |
56207 |
Assert(underConstruction()); |
136 |
|
|
137 |
56207 |
if(d_constraints.empty()){ |
138 |
|
// no-op |
139 |
2176 |
d_consequentSet = true; |
140 |
|
} else { |
141 |
54031 |
Assert(d_consequent != NullConstraint); |
142 |
54031 |
ConstraintCP last = d_constraints.back(); |
143 |
54031 |
d_constraints.back() = d_consequent; |
144 |
54031 |
d_consequent = last; |
145 |
54031 |
ARITH_PROOF(std::swap(d_farkas.front(), d_farkas.back())); |
146 |
54031 |
d_consequentSet = true; |
147 |
|
} |
148 |
|
|
149 |
56207 |
Assert(!d_consequent->negationHasProof()); |
150 |
56207 |
Assert(d_consequentSet); |
151 |
56207 |
} |
152 |
|
|
153 |
|
/* Turns the vector under construction into a conflict */ |
154 |
56207 |
ConstraintCP FarkasConflictBuilder::commitConflict(){ |
155 |
56207 |
Assert(underConstruction()); |
156 |
56207 |
Assert(!d_constraints.empty()); |
157 |
56207 |
Assert( |
158 |
|
!ARITH_PROOF_ON() |
159 |
|
|| (!underConstruction() && d_constraints.empty() && d_farkas.empty()) |
160 |
|
|| (underConstruction() && d_constraints.size() + 1 == d_farkas.size())); |
161 |
56207 |
Assert(ARITH_PROOF_ON() || d_farkas.empty()); |
162 |
56207 |
Assert(d_consequentSet); |
163 |
|
|
164 |
56207 |
ConstraintP not_c = d_consequent->getNegation(); |
165 |
56207 |
RationalVectorCP coeffs = ARITH_NULLPROOF(&d_farkas); |
166 |
56207 |
not_c->impliedByFarkas(d_constraints, coeffs, true ); |
167 |
|
|
168 |
56207 |
reset(); |
169 |
56207 |
Assert(!underConstruction()); |
170 |
56207 |
Assert(not_c->inConflict()); |
171 |
56207 |
Assert(!d_consequentSet); |
172 |
56207 |
return not_c; |
173 |
|
} |
174 |
|
|
175 |
9459 |
RaiseEqualityEngineConflict::RaiseEqualityEngineConflict(TheoryArithPrivate& ta) |
176 |
9459 |
: d_ta(ta) |
177 |
9459 |
{} |
178 |
|
|
179 |
|
/* If you are not an equality engine, don't use this! */ |
180 |
1943 |
void RaiseEqualityEngineConflict::raiseEEConflict( |
181 |
|
Node n, std::shared_ptr<ProofNode> pf) const |
182 |
|
{ |
183 |
1943 |
d_ta.raiseBlackBoxConflict(n, pf); |
184 |
1943 |
} |
185 |
|
|
186 |
9459 |
BoundCountingLookup::BoundCountingLookup(TheoryArithPrivate& ta) |
187 |
9459 |
: d_ta(ta) |
188 |
9459 |
{} |
189 |
|
|
190 |
|
const BoundsInfo& BoundCountingLookup::boundsInfo(ArithVar basic) const{ |
191 |
|
return d_ta.boundsInfo(basic); |
192 |
|
} |
193 |
|
|
194 |
|
BoundCounts BoundCountingLookup::atBounds(ArithVar basic) const{ |
195 |
|
return boundsInfo(basic).atBounds(); |
196 |
|
} |
197 |
|
BoundCounts BoundCountingLookup::hasBounds(ArithVar basic) const { |
198 |
|
return boundsInfo(basic).hasBounds(); |
199 |
|
} |
200 |
|
|
201 |
|
} // namespace arith |
202 |
|
} // namespace theory |
203 |
28191 |
} // namespace cvc5 |