Skip to content

Commit 1aa8d41

Browse files
authored
Merge pull request #8531 from diffblue/bitnand_bitnor
add nand_exprt, nor_exprt, xnor_exprt, bitnand_exprt, bitnor_exprt
2 parents fd13d3a + 740f399 commit 1aa8d41

File tree

3 files changed

+215
-0
lines changed

3 files changed

+215
-0
lines changed

src/util/bitvector_expr.h

+97
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,50 @@ inline bitor_exprt &to_bitor_expr(exprt &expr)
160160
return static_cast<bitor_exprt &>(expr);
161161
}
162162

163+
/// \brief Bit-wise NOR
164+
///
165+
/// When given one operand, this is equivalent to the bit-wise negation.
166+
/// When given three or more operands, this is equivalent to the bit-wise
167+
/// negation of the bitand expression with the same operands.
168+
class bitnor_exprt : public multi_ary_exprt
169+
{
170+
public:
171+
bitnor_exprt(exprt _op0, exprt _op1)
172+
: multi_ary_exprt(std::move(_op0), ID_bitnor, std::move(_op1))
173+
{
174+
}
175+
176+
bitnor_exprt(exprt::operandst _operands, typet _type)
177+
: multi_ary_exprt(ID_bitnor, std::move(_operands), std::move(_type))
178+
{
179+
}
180+
};
181+
182+
template <>
183+
inline bool can_cast_expr<bitnor_exprt>(const exprt &base)
184+
{
185+
return base.id() == ID_bitnor;
186+
}
187+
188+
/// \brief Cast an exprt to a \ref bitnor_exprt
189+
///
190+
/// \a expr must be known to be \ref bitnor_exprt.
191+
///
192+
/// \param expr: Source expression
193+
/// \return Object of type \ref bitnor_exprt
194+
inline const bitnor_exprt &to_bitnor_expr(const exprt &expr)
195+
{
196+
PRECONDITION(expr.id() == ID_bitnor);
197+
return static_cast<const bitnor_exprt &>(expr);
198+
}
199+
200+
/// \copydoc to_bitnor_expr(const exprt &)
201+
inline bitnor_exprt &to_bitnor_expr(exprt &expr)
202+
{
203+
PRECONDITION(expr.id() == ID_bitnor);
204+
return static_cast<bitnor_exprt &>(expr);
205+
}
206+
163207
/// \brief Bit-wise XOR
164208
class bitxor_exprt : public multi_ary_exprt
165209
{
@@ -201,13 +245,22 @@ inline bitxor_exprt &to_bitxor_expr(exprt &expr)
201245
}
202246

203247
/// \brief Bit-wise XNOR
248+
///
249+
/// When given one operand, this is equivalent to the bit-wise negation.
250+
/// When given three or more operands, this is equivalent to the bit-wise
251+
/// negation of the bitxor expression with the same operands.
204252
class bitxnor_exprt : public multi_ary_exprt
205253
{
206254
public:
207255
bitxnor_exprt(exprt _op0, exprt _op1)
208256
: multi_ary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
209257
{
210258
}
259+
260+
bitxnor_exprt(exprt::operandst _operands, typet _type)
261+
: multi_ary_exprt(ID_bitxnor, std::move(_operands), std::move(_type))
262+
{
263+
}
211264
};
212265

213266
template <>
@@ -275,6 +328,50 @@ inline bitand_exprt &to_bitand_expr(exprt &expr)
275328
return static_cast<bitand_exprt &>(expr);
276329
}
277330

331+
/// \brief Bit-wise NAND
332+
///
333+
/// When given one operand, this is equivalent to the bit-wise negation.
334+
/// When given three or more operands, this is equivalent to the bit-wise
335+
/// negation of the bitand expression with the same operands.
336+
class bitnand_exprt : public multi_ary_exprt
337+
{
338+
public:
339+
bitnand_exprt(exprt _op0, exprt _op1)
340+
: multi_ary_exprt(std::move(_op0), ID_bitnand, std::move(_op1))
341+
{
342+
}
343+
344+
bitnand_exprt(exprt::operandst _operands, typet _type)
345+
: multi_ary_exprt(ID_bitnand, std::move(_operands), std::move(_type))
346+
{
347+
}
348+
};
349+
350+
template <>
351+
inline bool can_cast_expr<bitnand_exprt>(const exprt &base)
352+
{
353+
return base.id() == ID_bitnand;
354+
}
355+
356+
/// \brief Cast an exprt to a \ref bitnand_exprt
357+
///
358+
/// \a expr must be known to be \ref bitnand_exprt.
359+
///
360+
/// \param expr: Source expression
361+
/// \return Object of type \ref bitnand_exprt
362+
inline const bitnand_exprt &to_bitnand_expr(const exprt &expr)
363+
{
364+
PRECONDITION(expr.id() == ID_bitnand);
365+
return static_cast<const bitnand_exprt &>(expr);
366+
}
367+
368+
/// \copydoc to_bitnand_expr(const exprt &)
369+
inline bitnand_exprt &to_bitnand_expr(exprt &expr)
370+
{
371+
PRECONDITION(expr.id() == ID_bitnand);
372+
return static_cast<bitnand_exprt &>(expr);
373+
}
374+
278375
/// \brief A base class for shift and rotate operators
279376
class shift_exprt : public binary_exprt
280377
{

src/util/irep_ids.def

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ IREP_ID_ONE(nand)
4848
IREP_ID_ONE(or)
4949
IREP_ID_ONE(nor)
5050
IREP_ID_ONE(xor)
51+
IREP_ID_ONE(xnor)
5152
IREP_ID_ONE(not)
5253
IREP_ID_ONE(bitand)
5354
IREP_ID_ONE(bitor)

src/util/std_expr.h

+117
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,43 @@ inline and_exprt &to_and_expr(exprt &expr)
21822182
return static_cast<and_exprt &>(expr);
21832183
}
21842184

2185+
/// \brief Boolean NAND
2186+
///
2187+
/// When given one operand, this is equivalent to the negation.
2188+
/// When given three or more operands, this is equivalent to the negation
2189+
/// of the and expression with the same operands.
2190+
class nand_exprt : public multi_ary_exprt
2191+
{
2192+
public:
2193+
nand_exprt(exprt op0, exprt op1)
2194+
: multi_ary_exprt(std::move(op0), ID_nand, std::move(op1), bool_typet())
2195+
{
2196+
}
2197+
2198+
explicit nand_exprt(exprt::operandst _operands)
2199+
: multi_ary_exprt(ID_nand, std::move(_operands), bool_typet())
2200+
{
2201+
}
2202+
};
2203+
2204+
/// \brief Cast an exprt to a \ref nand_exprt
2205+
///
2206+
/// \a expr must be known to be \ref nand_exprt.
2207+
///
2208+
/// \param expr: Source expression
2209+
/// \return Object of type \ref nand_exprt
2210+
inline const nand_exprt &to_nand_expr(const exprt &expr)
2211+
{
2212+
PRECONDITION(expr.id() == ID_nand);
2213+
return static_cast<const nand_exprt &>(expr);
2214+
}
2215+
2216+
/// \copydoc to_nand_expr(const exprt &)
2217+
inline nand_exprt &to_nand_expr(exprt &expr)
2218+
{
2219+
PRECONDITION(expr.id() == ID_nand);
2220+
return static_cast<nand_exprt &>(expr);
2221+
}
21852222

21862223
/// \brief Boolean implication
21872224
class implies_exprt:public binary_exprt
@@ -2290,6 +2327,43 @@ inline or_exprt &to_or_expr(exprt &expr)
22902327
return static_cast<or_exprt &>(expr);
22912328
}
22922329

2330+
/// \brief Boolean NOR
2331+
///
2332+
/// When given one operand, this is equivalent to the negation.
2333+
/// When given three or more operands, this is equivalent to the negation
2334+
/// of the and expression with the same operands.
2335+
class nor_exprt : public multi_ary_exprt
2336+
{
2337+
public:
2338+
nor_exprt(exprt op0, exprt op1)
2339+
: multi_ary_exprt(std::move(op0), ID_nor, std::move(op1), bool_typet())
2340+
{
2341+
}
2342+
2343+
explicit nor_exprt(exprt::operandst _operands)
2344+
: multi_ary_exprt(ID_nor, std::move(_operands), bool_typet())
2345+
{
2346+
}
2347+
};
2348+
2349+
/// \brief Cast an exprt to a \ref nor_exprt
2350+
///
2351+
/// \a expr must be known to be \ref nor_exprt.
2352+
///
2353+
/// \param expr: Source expression
2354+
/// \return Object of type \ref nor_exprt
2355+
inline const nor_exprt &to_nor_expr(const exprt &expr)
2356+
{
2357+
PRECONDITION(expr.id() == ID_nor);
2358+
return static_cast<const nor_exprt &>(expr);
2359+
}
2360+
2361+
/// \copydoc to_nor_expr(const exprt &)
2362+
inline nor_exprt &to_nor_expr(exprt &expr)
2363+
{
2364+
PRECONDITION(expr.id() == ID_nor);
2365+
return static_cast<nor_exprt &>(expr);
2366+
}
22932367

22942368
/// \brief Boolean XOR
22952369
class xor_exprt:public multi_ary_exprt
@@ -2331,6 +2405,49 @@ inline xor_exprt &to_xor_expr(exprt &expr)
23312405
return static_cast<xor_exprt &>(expr);
23322406
}
23332407

2408+
/// \brief Boolean XNOR
2409+
///
2410+
/// When given one operand, this is equivalent to the negation.
2411+
/// When given three or more operands, this is equivalent to the negation
2412+
/// of the xor expression with the same operands.
2413+
class xnor_exprt : public multi_ary_exprt
2414+
{
2415+
public:
2416+
xnor_exprt(exprt _op0, exprt _op1)
2417+
: multi_ary_exprt(std::move(_op0), ID_xnor, std::move(_op1), bool_typet())
2418+
{
2419+
}
2420+
2421+
explicit xnor_exprt(exprt::operandst _operands)
2422+
: multi_ary_exprt(ID_xnor, std::move(_operands), bool_typet())
2423+
{
2424+
}
2425+
};
2426+
2427+
template <>
2428+
inline bool can_cast_expr<xnor_exprt>(const exprt &base)
2429+
{
2430+
return base.id() == ID_xnor;
2431+
}
2432+
2433+
/// \brief Cast an exprt to a \ref xnor_exprt
2434+
///
2435+
/// \a expr must be known to be \ref xnor_exprt.
2436+
///
2437+
/// \param expr: Source expression
2438+
/// \return Object of type \ref xnor_exprt
2439+
inline const xnor_exprt &to_xnor_expr(const exprt &expr)
2440+
{
2441+
PRECONDITION(expr.id() == ID_xnor);
2442+
return static_cast<const xnor_exprt &>(expr);
2443+
}
2444+
2445+
/// \copydoc to_xnor_expr(const exprt &)
2446+
inline xnor_exprt &to_xnor_expr(exprt &expr)
2447+
{
2448+
PRECONDITION(expr.id() == ID_xnor);
2449+
return static_cast<xnor_exprt &>(expr);
2450+
}
23342451

23352452
/// \brief Boolean negation
23362453
class not_exprt:public unary_exprt

0 commit comments

Comments
 (0)