Skip to content

Commit b1b1a35

Browse files
committed
add nand_exprt, nor_exprt, xnor_exprt, bitnand_exprt, bitnor_exprt
This adds classes for the nand, nor, bitnand, and bitnor expressions, documenting already existing expressions. This furthermore adds a class for the new xnor expression, to mirror the existing bitxnor expression. The comments clarify the meaning when those expressions are not binary.
1 parent fd13d3a commit b1b1a35

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed

src/util/bitvector_expr.h

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

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

203246
/// \brief Bit-wise XNOR
247+
/// When given one operand, this is equivalent to the bit-wise negation.
248+
/// When given three or more operands, this is equivalent to the bit-wise
249+
/// negation of the bitxor expression with the same operands.
204250
class bitxnor_exprt : public multi_ary_exprt
205251
{
206252
public:
207253
bitxnor_exprt(exprt _op0, exprt _op1)
208254
: multi_ary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
209255
{
210256
}
257+
258+
bitxnor_exprt(exprt::operandst _operands, typet _type)
259+
: multi_ary_exprt(ID_bitxnor, std::move(_operands), std::move(_type))
260+
{
261+
}
211262
};
212263

213264
template <>
@@ -275,6 +326,49 @@ inline bitand_exprt &to_bitand_expr(exprt &expr)
275326
return static_cast<bitand_exprt &>(expr);
276327
}
277328

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

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

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

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

21862222
/// \brief Boolean implication
21872223
class implies_exprt:public binary_exprt
@@ -2290,6 +2326,42 @@ inline or_exprt &to_or_expr(exprt &expr)
22902326
return static_cast<or_exprt &>(expr);
22912327
}
22922328

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

22942366
/// \brief Boolean XOR
22952367
class xor_exprt:public multi_ary_exprt
@@ -2332,6 +2404,50 @@ inline xor_exprt &to_xor_expr(exprt &expr)
23322404
}
23332405

23342406

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

0 commit comments

Comments
 (0)