Skip to content

Commit 872cab4

Browse files
committed
Remove bv_utils::set_equal as it ought to be avoided
Instead of the dance of creating free variables and then setting them equal to the result of some circuit just pass in the known output signals and create the circuit using those directly.
1 parent ba0d94c commit 872cab4

File tree

8 files changed

+77
-12
lines changed

8 files changed

+77
-12
lines changed

src/solvers/flattening/bv_utils.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,6 @@ literalt bv_utilst::is_one(const bvt &bv)
2828
return prop.land(is_zero(tmp), bv[0]);
2929
}
3030

31-
void bv_utilst::set_equal(const bvt &a, const bvt &b)
32-
{
33-
PRECONDITION(a.size() == b.size());
34-
for(std::size_t i=0; i<a.size(); i++)
35-
prop.set_equal(a[i], b[i]);
36-
}
37-
3831
bvt bv_utilst::extract(const bvt &a, std::size_t first, std::size_t last)
3932
{
4033
// preconditions

src/solvers/flattening/bv_utils.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ class bv_utilst
196196
return result;
197197
}
198198

199-
void set_equal(const bvt &a, const bvt &b);
200-
201199
// if cond holds, a has to be equal to b
202200
void cond_implies_equal(literalt cond, const bvt &a, const bvt &b);
203201

src/solvers/flattening/equality.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ void equalityt::add_equality_constraints(const typestructt &typestruct)
124124
const bvt &bv1=eq_bvs[it->first.first];
125125
const bvt &bv2=eq_bvs[it->first.second];
126126

127-
prop.set_equal(bv_utils.equal(bv1, bv2), it->second);
127+
bvt equal_bv;
128+
equal_bv.resize(bv1.size());
129+
130+
for(std::size_t i = 0; i < bv1.size(); i++)
131+
equal_bv[i] = prop.lequal(bv1[i], bv2[i]);
132+
133+
prop.gate_bv_and(equal_bv, it->second);
128134
}
129135
}

src/solvers/prop/prop.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class propt
3232
virtual literalt land(literalt a, literalt b)=0;
3333
virtual literalt lor(literalt a, literalt b)=0;
3434
virtual literalt land(const bvt &bv)=0;
35+
virtual void gate_bv_and(const bvt &bv, literalt output) = 0;
3536
virtual literalt lor(const bvt &bv)=0;
3637
virtual literalt lxor(literalt a, literalt b)=0;
3738
virtual literalt lxor(const bvt &bv)=0;

src/solvers/refinement/refine_arithmetic.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ void bv_refinementt::check_SAT(approximationt &a)
270270
UNREACHABLE;
271271

272272
CHECK_RETURN(r.size()==res.size());
273-
bv_utils.set_equal(r, res);
273+
for(std::size_t i = 0; i < r.size(); i++)
274+
prop.set_equal(r[i], res[i]);
274275
}
275276
}
276277
else if(type.id()==ID_signedbv ||
@@ -338,7 +339,9 @@ void bv_refinementt::check_SAT(approximationt &a)
338339
else
339340
UNREACHABLE;
340341

341-
bv_utils.set_equal(r, a.result_bv);
342+
CHECK_RETURN(r.size() == a.result_bv.size());
343+
for(std::size_t i = 0; i < r.size(); i++)
344+
prop.set_equal(r[i], a.result_bv[i]);
342345
}
343346
else
344347
UNREACHABLE;

src/solvers/sat/cnf.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,64 @@ literalt cnft::land(const bvt &bv)
196196
return literal;
197197
}
198198

199+
/// Tseitin encoding of conjunction between multiple literals
200+
/// \param bv: Any number of inputs to the AND gate
201+
/// \param output: Output signal of the circuit
202+
void cnft::gate_bv_and(const bvt &bv, literalt output)
203+
{
204+
if(bv.empty())
205+
{
206+
lcnf({output});
207+
return;
208+
}
209+
if(bv.size() == 1)
210+
{
211+
lcnf(bv[0], !output);
212+
lcnf(!bv[0], output);
213+
return;
214+
}
215+
if(bv.size() == 2)
216+
{
217+
gate_and(bv[0], bv[1], output);
218+
return;
219+
}
220+
221+
for(const auto &l : bv)
222+
{
223+
if(l.is_false())
224+
{
225+
lcnf({!output});
226+
return;
227+
}
228+
}
229+
230+
if(is_all(bv, const_literal(true)))
231+
{
232+
lcnf({output});
233+
return;
234+
}
235+
236+
bvt new_bv = eliminate_duplicates(bv);
237+
238+
bvt lits(2);
239+
lits[1] = neg(output);
240+
241+
for(const auto &l : new_bv)
242+
{
243+
lits[0] = pos(l);
244+
lcnf(lits);
245+
}
246+
247+
lits.clear();
248+
lits.reserve(new_bv.size() + 1);
249+
250+
for(const auto &l : new_bv)
251+
lits.push_back(neg(l));
252+
253+
lits.push_back(pos(output));
254+
lcnf(lits);
255+
}
256+
199257
/// Tseitin encoding of disjunction between multiple literals
200258
/// \par parameters: Any number of inputs to the OR gate
201259
/// \return Output signal of the OR gate as literal

src/solvers/sat/cnf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class cnft:public propt
2828
virtual literalt land(literalt a, literalt b) override;
2929
virtual literalt lor(literalt a, literalt b) override;
3030
virtual literalt land(const bvt &bv) override;
31+
void gate_bv_and(const bvt &bv, literalt output) override;
3132
virtual literalt lor(const bvt &bv) override;
3233
virtual literalt lxor(const bvt &bv) override;
3334
virtual literalt lxor(literalt a, literalt b) override;

unit/solvers/bdd/miniBDD/miniBDD.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ class bdd_propt : public propt
8282
return to_literal(result);
8383
}
8484

85+
void gate_bv_and(const bvt &bv, literalt output) override
86+
{
87+
UNREACHABLE;
88+
}
89+
8590
literalt lor(const bvt &bv) override
8691
{
8792
mini_bddt result = mgr.False();

0 commit comments

Comments
 (0)