From b70513a08b2082f2bf7d3c494de6c2059cc3a72c Mon Sep 17 00:00:00 2001 From: Daniel Neville Date: Fri, 16 Jun 2017 13:58:31 +0100 Subject: [PATCH 01/35] (INT) Interval operations (INT) Interval values --- src/util/Makefile | 1 + src/util/interval.cpp | 1880 ++++++++++++++++++++++++++++ src/util/interval.h | 361 ++++++ src/util/interval_template.h | 16 +- src/util/irep_ids.def | 3 + unit/Makefile | 8 + unit/util/interval/add.cpp | 107 ++ unit/util/interval/bitwise.cpp | 44 + unit/util/interval/comparisons.cpp | 143 +++ unit/util/interval/divide.cpp | 0 unit/util/interval/get_extreme.cpp | 167 +++ unit/util/interval/modulo.cpp | 59 + unit/util/interval/multiply.cpp | 161 +++ unit/util/interval/shift.cpp | 44 + unit/util/interval/subtract.cpp | 106 ++ 15 files changed, 3095 insertions(+), 5 deletions(-) create mode 100644 src/util/interval.cpp create mode 100644 src/util/interval.h create mode 100644 unit/util/interval/add.cpp create mode 100644 unit/util/interval/bitwise.cpp create mode 100644 unit/util/interval/comparisons.cpp create mode 100644 unit/util/interval/divide.cpp create mode 100644 unit/util/interval/get_extreme.cpp create mode 100644 unit/util/interval/modulo.cpp create mode 100644 unit/util/interval/multiply.cpp create mode 100644 unit/util/interval/shift.cpp create mode 100644 unit/util/interval/subtract.cpp diff --git a/src/util/Makefile b/src/util/Makefile index 2f3eda6a6b0..2c4b4de1f58 100644 --- a/src/util/Makefile +++ b/src/util/Makefile @@ -106,6 +106,7 @@ SRC = allocate_objects.cpp \ version.cpp \ xml.cpp \ xml_irep.cpp \ + interval.cpp \ # Empty last line INCLUDES= -I .. diff --git a/src/util/interval.cpp b/src/util/interval.cpp new file mode 100644 index 00000000000..ea35a08e2e1 --- /dev/null +++ b/src/util/interval.cpp @@ -0,0 +1,1880 @@ +/* + * interval.cpp + * + * Created on: 16 Jun 2017 + * Author: dan + */ + +/* + * + * Types: Should we store a type for the entire interval? + * IMO: I think YES (for the case where we have -inf -> inf, we don't know otherwise + * + * This initial implementation only implements support for integers. + */ + +#include "interval.h" + +#include +#include +#include +#include +#include +#include + +const exprt& constant_interval_exprt::get_lower() const +{ + return op0(); +} + +const exprt& constant_interval_exprt::get_upper() const +{ + return op1(); +} + + + +//make clean -s && make -j 7 CXX="/usr/local/bin/ccache g++" -s && ./unit_tests + +const constant_interval_exprt constant_interval_exprt::unary_plus() const +{ + return *this; +} + +const constant_interval_exprt constant_interval_exprt::unary_minus() const +{ + if(is_constant()) + { + handle_constants(unary_minus_exprt()); + } + + exprt lower; + exprt upper; + + if(is_max()) + { + lower=min(); + } + else + { + lower = simplified_expr(unary_minus_exprt(get_upper())); + } + + if(is_min()) + { + upper=max(); + } + else + { + upper = simplified_expr(unary_minus_exprt(get_lower())); + } + + return constant_interval_exprt(lower, upper); +} + +const constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, plus_exprt()); + } + + exprt lower = min(); + exprt upper = max(); + + if(is_max(get_upper()) || is_max(o.get_upper())) + { + upper = max_exprt(type()); + } + else + { + assert(!is_max(get_upper()) && !is_max(o.get_upper())); + upper = simplified_expr(plus_exprt(get_upper(), o.get_upper())); + } + + if(is_min(get_lower()) || is_min(o.get_lower())) + { + lower = min_exprt(type()); + } + else + { + assert(!is_min(get_lower()) && !is_min(o.get_lower())); + lower = simplified_expr(plus_exprt(get_lower(), o.get_lower())); + } + + return simplified_interval(lower, upper); +} + +const constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, minus_exprt()); + } + + // e.g. [t.u - o.l, t.l - o.u] + return plus(o.unary_minus().swap()); +} + +const constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, mult_exprt()); + } + + mult_exprt operation; + operation.type()=type(); + return get_extremes(*this, o, operation); +} + +const constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, div_exprt()); + } + + // If other might be division by zero, set everything to top. + if(o.contains_zero()) + { + return top(); + } + + div_exprt operation; + return get_extremes(*this, o, operation); +} + +const constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt& o) const +{ + // SEE https://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers + + if(o.is_constant() && is_constant()) + { + handle_constants(o, mod_exprt()); + } + + if(o.is_bottom()) + { + return top(); + } + + // If the RHS is 1, or -1 (signed only), then return zero. + if(o == constant_interval_exprt(from_integer(1, o.type())) || + (o.is_signed() && o == constant_interval_exprt(from_integer(-1, o.type())))) + { + return constant_interval_exprt(zero()); + } + + // If other might be modulo by zero, set everything to top. + if(o.contains_zero()) + { + return top(); + } + + if(is_zero()) + { + return constant_interval_exprt(zero()); + } + + exprt lower=min(); + exprt upper=max(); + + // Positive case (cannot have zero on RHS). + // 10 % 5 = [0, 4], 3 % 5 = [0, 3] + if(!is_negative() && o.is_positive()) + { + lower=zero(); + upper=get_min(get_upper(), o.decrement().get_upper()); + } + + // [-5, 5] % [3] + if(is_negative(get_lower()) && is_positive(get_upper())) + { + assert(contains_zero()); + + // This can be done more accurately. + lower=get_min(o.get_lower(), get_lower()); + upper=get_max(o.get_upper(), get_upper()); + } + + if(is_negative() && o.is_negative()) + { + lower=get_min(o.get_lower(), o.get_lower()); + upper=zero(); + } + + return constant_interval_exprt(lower, upper); +} + + +const tvt constant_interval_exprt::is_true() const +{ + // tvt not + return !is_false(); +} + +const tvt constant_interval_exprt::is_false() const +{ + if(equal(constant_interval_exprt(zero())).is_true()) + { + return tvt(true); + } + + if(contains(constant_interval_exprt(zero()))) + { + assert(is_positive(get_upper()) || is_negative(get_lower())); + return tvt::unknown(); + } + + return tvt(false); +} + +const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& o) const +{ + tvt a = is_true(); + tvt b = o.is_true(); + + return (a || b); +} + +const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& o) const +{ + return (is_true() && o.is_true()); +} + +const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& o) const +{ + return ( + (is_true() && !o.is_true()) || + (!is_true() && o.is_true()) + ); +} + +const tvt constant_interval_exprt::logical_not() const +{ + if(is_true().is_true()) + { + return tvt(false); + } + + if(is_false().is_true()) + { + return tvt(true); + } + + return tvt::unknown(); +} + + +const constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, shl_exprt()); + } + + if(is_negative(o.get_lower())) + { + return top(); + } + + shl_exprt operation; + operation.type()=type(); + return get_extremes(*this, o, operation); +} + +// Arithmetic +const constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, ashr_exprt()); + } + + if(is_negative(o.get_lower())) + { + return top(); + } + + ashr_exprt operation; + operation.type()=type(); + return get_extremes(*this, o, operation); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, bitxor_exprt()); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, bitor_exprt()); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt& o) const +{ + if(o.is_constant() && is_constant()) + { + handle_constants(o, bitand_exprt()); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_not() const +{ + if(is_constant()) + { + handle_constants(bitnot_exprt()); + } + + return top(); +} + +tvt constant_interval_exprt::less_than(const constant_interval_exprt &o) const +{ + // [get_lower, get_upper] < [o.get_lower(), o.get_upper()] + if(is_constant() && o.is_constant()) + { + return tvt(less_than(get_lower(), o.get_lower())); + } + + if(less_than(get_upper(), o.get_lower())) + { + return tvt(true); + } + + if(greater_than(get_lower(), o.get_upper())) + { + return tvt(false); + } + + return tvt::unknown(); +} + +tvt constant_interval_exprt::greater_than(const constant_interval_exprt& o) const +{ + return o.less_than(*this); +} + +tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt& o) const +{ + if(is_constant() && o.is_constant()) + { + return tvt(less_than_or_equal(get_lower(), o.get_lower())); + } + + // [get_lower, get_upper] <= [o.get_lower(), o.get_upper()] + if(less_than_or_equal(get_upper(), o.get_lower())) + { + return tvt(true); + } + + if(greater_than(get_lower(), o.get_upper())) + { + return tvt(false); + } + + return tvt::unknown(); +} + +tvt constant_interval_exprt::greater_than_or_equal(const constant_interval_exprt& o) const +{ + return o.less_than_or_equal(*this); +} + +tvt constant_interval_exprt::equal(const constant_interval_exprt& o) const +{ + if(is_constant() && o.is_constant()) + { + return tvt(equal(get_lower(), o.get_lower())); + } + + if(equal(get_upper(), o.get_upper()) && equal(get_upper(), o.get_upper())) + { + return tvt(true); + } + + if(less_than(o).is_true() || greater_than(o).is_true() || o.less_than(*this).is_true() || o.greater_than(*this).is_true()) + { + return tvt(false); + } + + // Don't know. Could have [3, 5] == [4] (not equal) + return tvt::unknown(); +} + +tvt constant_interval_exprt::not_equal(const constant_interval_exprt& o) const +{ + return !equal(o); +} + +const constant_interval_exprt constant_interval_exprt::increment() const +{ + return plus(constant_interval_exprt(from_integer(mp_integer(1), type()))); + +} + +const constant_interval_exprt constant_interval_exprt::decrement() const +{ + return minus(constant_interval_exprt(from_integer(mp_integer(1), type()))); +} + +const constant_interval_exprt constant_interval_exprt::get_extremes( + const constant_interval_exprt &a, + const constant_interval_exprt &b, + const exprt operation) +{ + constant_interval_exprt result; + + std::vector results; + + results.push_back( + generate_expression(a.get_lower(), b.get_lower(), operation)); + results.push_back( + generate_expression(a.get_lower(), b.get_upper(), operation)); + results.push_back( + generate_expression(a.get_upper(), b.get_lower(), operation)); + results.push_back( + generate_expression(a.get_upper(), b.get_upper(), operation)); + + + for(auto result: results) + { + if(!is_extreme(result) && contains_extreme(result)) + { + return constant_interval_exprt(result.type()); + } + } + + exprt min=get_min(results); + exprt max=get_max(results); + + return simplified_interval(min, max); +} + +exprt constant_interval_exprt::get_extreme(std::vector values, bool min_value) +{ + symbol_tablet symbol_table; + namespacet ns(symbol_table); // Empty + + if(values.size() == 0) + { + return nil_exprt(); + } + + if(values.size() == 1) + { + return *(values.begin()); + } + + if(values.size() == 2) + { + if(min_value) + { + return get_min(values.front(), values.back()); + } + else + { + return get_max(values.front(), values.back()); + } + } + + typet type=values.begin()->type(); + + for(auto v: values) + { + if((min_value && is_min(v)) || (!min_value && is_max(v))) + { + return v; + } + } + + for(auto left: values) + { + bool all_left_OP_right = true; + + for(auto right: values) + { + if((min_value && less_than_or_equal(left, right)) || (!min_value && greater_than_or_equal(left, right))) + { + continue; + } + + all_left_OP_right = false; + break; + } + + if(all_left_OP_right) + { + return left; + } + } + + /* Return top */ + if(min_value) + { + return min_exprt(type); + } + else + { + return max_exprt(type); + } + + assert(0); +} + + + +exprt constant_interval_exprt::generate_expression(const exprt& a, const exprt& b, const exprt &operation) +{ + if(operation.id() == ID_mult) + { + return generate_multiply_expression(a, b, operation); + } + + if(operation.id() == ID_div) + { + return generate_division_expression(a, b, operation); + } + + if(operation.id() == ID_mod) + { + return generate_modulo_expression(a, b, operation); + } + + if(operation.id() == ID_shl || operation.id() == ID_ashr) + { + return generate_shift_expression(a, b, operation); + } + + assert(0 && "Not yet implemented!"); +} + +exprt constant_interval_exprt::generate_multiply_expression(const exprt& a, const exprt& b, + exprt operation) +{ + assert(operation.id() == ID_mult); + assert(operation.type().is_not_nil() && is_numeric(operation.type())); + + if(is_max(a)) + { + return generate_multiply_expression_max(b); + } + + if(is_max(b)) + { + return generate_multiply_expression_max(a); + } + + if(is_min(a)) + { + return generate_multiply_expression_min(a, b); + } + + if(is_min(b)) + { + return generate_multiply_expression_min(b, a); + } + + assert(!is_extreme(a) && !is_extreme(b)); + + operation.copy_to_operands(a, b); + return simplified_expr(operation); +} + + +exprt constant_interval_exprt::generate_multiply_expression_max(const exprt &expr) +{ + if(is_max (expr)) + { + return max_exprt(expr); + } + + if(is_min (expr)) + { + if(is_negative(expr)) + { + return min_exprt(expr); + } + else + { + assert(!is_positive(expr) && "Min value cannot be >0."); + assert(is_zero(expr) && "Non-negative MIN must be zero."); + + return expr; + } + } + + assert(!is_extreme(expr)); + + if(is_negative (expr)) + { + return min_exprt(expr); + } + + if(is_zero (expr)) + { + return expr; + } + + if(is_positive (expr)) + { + return max_exprt(expr); + } + + assert(0 && "Unreachable."); + return nil_exprt(); +} + +exprt constant_interval_exprt::generate_multiply_expression_min(const exprt &min, const exprt &other) +{ + assert(is_min(min)); + + if(is_max(other)) + { + if(is_negative(min)) + { + return min_exprt(min); + } + else + { + assert(!is_positive(min) && "Min value cannot be >0."); + assert(is_zero(min) && "Non-negative MIN must be zero."); + + return min; + } + } + + if(is_min(other)) + { + assert(!is_positive(min) && !is_positive(other) && "Min value cannot be >0."); + assert(is_negative(other) || is_zero(other)); + + if(is_negative(min) && is_negative(other)) + { + return max_exprt(min); + } + + assert(is_zero(min) || is_zero(other)); + return (is_zero(min) ? min : other); + } + + assert(0 && "Unreachable."); + return nil_exprt(); +} + + + +exprt constant_interval_exprt::generate_division_expression(const exprt& a, const exprt& b, + exprt operation) +{ + assert(operation.id() == ID_div); + assert(operation.type().is_not_nil() && is_numeric(operation.type())); + + assert(!is_zero(b)); + + if(b.is_one()) + { + return a; + } + + if(is_max(a)) + { + if(is_negative(b)) + { + return min_exprt(a); + } + + return a; + } + + if(is_min(a)) + { + if(is_negative(b)) + { + return max_exprt(a); + } + + return a; + } + + assert(!is_extreme(a)); + + if(is_max(b)) + { + return zero(b); + } + + if(is_min(b)) + { + assert(is_signed(b)); + return zero(b); + } + + assert(!is_extreme(a) && !is_extreme(b)); + + assert(!operation.has_operands()); + operation.copy_to_operands(a, b); + return simplified_expr(operation); +} + +exprt constant_interval_exprt::generate_modulo_expression(const exprt& a, const exprt& b, + exprt operation) +{ + assert(operation.id() == ID_mod); + assert(operation.type().is_not_nil() && is_numeric(operation.type())); + + assert(!is_zero(b)); + + if(b.is_one()) + { + return a; + } + + if(is_max(a)) + { + if(is_negative(b)) + { + return min_exprt(a); + } + + return a; + } + + if(is_min(a)) + { + if(is_negative(b)) + { + return max_exprt(a); + } + + return a; + } + + assert(!is_extreme(a)); + + if(is_max(b)) + { + return zero(b); + } + + if(is_min(b)) + { + assert(is_signed(b)); + return zero(b); + } + + assert(!is_extreme(a) && !is_extreme(b)); + + assert(!operation.has_operands()); + operation.copy_to_operands(a, b); + return simplified_expr(operation); +} + +const constant_interval_exprt constant_interval_exprt::eval(const exprt& expr) +{ + const irep_idt &id = expr.id(); + + if(id == ID_unary_plus) + { + return unary_plus(); + } + if(id == ID_unary_minus) + { + return unary_minus(); + } + if(id == ID_bitnot) + { + return bitwise_not(); + } + if(id == ID_not) + { + //return logical_not(); + return top(); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::eval(const exprt& expr, const constant_interval_exprt& o) +{ + const irep_idt &id = expr.id(); + + if(id == ID_plus) + { + return plus(o); + } + if(id == ID_minus) + { + return unary_minus(o); + } + if(id == ID_mult) + { + return multiply(o); + } + if(id == ID_div) + { + return divide(o); + } + if(id == ID_mod) + { + return modulo(o); + } + if(id == ID_shl) + { + return left_shift(o); + } + if(id == ID_ashr) + { + return right_shift(o); + } + if(id == ID_bitor) + { + return bitwise_or(o); + } + if(id == ID_bitand) + { + return bitwise_and(o); + } + if(id == ID_bitxor) + { + return bitwise_xor(o); + } + if(id == ID_lt) + { + return tv_to_interval(less_than(o)); + } + if(id == ID_le) + { + return tv_to_interval(less_than_or_equal(o)); + } + if(id == ID_gt) + { + return tv_to_interval(greater_than(o)); + } + if(id == ID_ge) + { + return tv_to_interval(greater_than_or_equal(o)); + } + if(id == ID_equal) + { + return tv_to_interval(equal(o)); + } + if(id == ID_notequal) + { + return tv_to_interval(not_equal(o)); + } + if(id == ID_and) + { + return tv_to_interval(logical_and(o)); + } + if(id == ID_or) + { + return tv_to_interval(logical_or(o)); + } + if(id == ID_xor) + { + return tv_to_interval(logical_xor(o)); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) const +{ + if(tv.is_true()) + { + return constant_interval_exprt(from_integer(1, type())); + } + if(tv.is_false()) + { + return constant_interval_exprt(zero()); + } + + assert(tv.is_unknown()); + return top(); +} + +exprt constant_interval_exprt::generate_shift_expression(const exprt& a, const exprt& b, + exprt operation) +{ + assert(operation.id() == ID_shl || operation.id() == ID_ashr); + + if(is_zero(a) || is_zero(b)) + { + // Shifting zero does nothing. + // Shifting BY zero also does nothing. + return a; + } + + // Should be caught at an earlier stage. + assert(!is_negative(b)); + + if(is_max(a)) + { + return a; + } + + if(is_min(a)) + { + return a; + } + + if(is_max(b)) + { + return min_exprt(b); + } + + assert(!is_extreme(a) && !is_extreme(b)); + + operation.op0()=a; + operation.op1()=b; + return simplified_expr(operation); +} + +const constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const +{ + if(is_constant()) + { + expr.type()=type(); + expr.copy_to_operands(get_lower()); + + return constant_interval_exprt(simplified_expr(expr)); + } + + return top(); +} + +const constant_interval_exprt constant_interval_exprt::handle_constants(const constant_interval_exprt &o, exprt expr) const +{ + if(is_constant() && o.is_constant()) + { + expr.type()=type(); + expr.copy_to_operands(get_lower(), o.get_lower()); + return constant_interval_exprt(simplified_expr(expr)); + } + + return top(); +} + +exprt constant_interval_exprt::get_max(const exprt &a, const exprt &b) +{ + return greater_than(a, b) ? a : b; +} + +exprt constant_interval_exprt::get_min(const exprt &a, const exprt &b) +{ + return less_than(a, b) ? a : b; +} + +exprt constant_interval_exprt::get_min(std::vector &values) +{ + return get_extreme(values, true); +} + +exprt constant_interval_exprt::get_max(std::vector &values) +{ + return get_extreme(values, false); +} + +/* we don't simplify in the constructor otherwise */ +const constant_interval_exprt constant_interval_exprt::simplified_interval(exprt &l, exprt &r) +{ + return constant_interval_exprt(simplified_expr(l), simplified_expr(r)); +} + +exprt constant_interval_exprt::simplified_expr(exprt expr) +{ + symbol_tablet symbol_table; + const namespacet ns(symbol_table); + + assert(!contains_extreme(expr)); + + return simplify_expr(expr, ns); +} + + +constant_exprt constant_interval_exprt::zero(const typet& type) +{ + constant_exprt zero = from_integer(mp_integer(0), type); + assert(zero.is_zero()); // NOT is_zero(zero) (inf. recursion + return zero; +} + +constant_exprt constant_interval_exprt::zero(const exprt& expr) +{ + return zero(expr.type()); +} + +constant_exprt constant_interval_exprt::zero(const constant_interval_exprt &interval) +{ + return zero(interval.type()); +} + +constant_exprt constant_interval_exprt::zero() const +{ + return zero(type()); +} + +min_exprt constant_interval_exprt::min() const +{ + return min_exprt(type()); +} + +max_exprt constant_interval_exprt::max() const +{ + return max_exprt(type()); +} + +bool constant_interval_exprt::is_top() const +{ + return (is_min() && is_max()); +} + +bool constant_interval_exprt::is_bottom() const +{ + // This should ONLY happen for bottom. + return is_min(get_upper()) || is_max(get_lower()); +} + +const constant_interval_exprt constant_interval_exprt::top(const typet &type) +{ + return constant_interval_exprt(type); +} + +const constant_interval_exprt constant_interval_exprt::bottom(const typet &type) +{ + return constant_interval_exprt(max_exprt(type), min_exprt(type)); +} + +const constant_interval_exprt constant_interval_exprt::top() const +{ + return constant_interval_exprt(type()); +} + +const constant_interval_exprt constant_interval_exprt::bottom() const +{ + return bottom(type()); +} + +const constant_interval_exprt constant_interval_exprt::swap(constant_interval_exprt &i) +{ + return constant_interval_exprt(i.get_upper(), i.get_lower()); +} + +const constant_interval_exprt constant_interval_exprt::swap() const +{ + return constant_interval_exprt(get_lower(), get_upper()); +} + +/* Helpers */ + +bool constant_interval_exprt::is_int() const +{ + return is_int(type()); +} + +bool constant_interval_exprt::is_float() const +{ + return is_float(type()); +} + +bool constant_interval_exprt::is_numeric(const typet &type) +{ + return is_int(type) || is_float(type); +} + +bool constant_interval_exprt::is_numeric() const +{ + return is_numeric(type()); +} + +bool constant_interval_exprt::is_numeric(const exprt &expr) +{ + return is_numeric(expr.type()); +} + +bool constant_interval_exprt::is_numeric(const constant_interval_exprt &interval) +{ + return interval.is_numeric(); +} + +bool constant_interval_exprt::is_int(const typet &type) +{ + return (is_signed(type) || is_unsigned(type)); +} + +bool constant_interval_exprt::is_float(const typet &src) +{ + return src.id() == ID_floatbv; +} + +bool constant_interval_exprt::is_int(const exprt &expr) +{ + return is_int(expr.type()); +} + +bool constant_interval_exprt::is_int(const constant_interval_exprt &interval) +{ + return interval.is_int(); +} + +bool constant_interval_exprt::is_float(const exprt &expr) +{ + return is_float(expr.type()); +} + +bool constant_interval_exprt::is_float(const constant_interval_exprt &interval) +{ + return interval.is_float(); +} + + +bool constant_interval_exprt::is_bitvector(const typet &t) +{ + return t.id() == ID_bv || t.id() == ID_signedbv || t.id() == ID_unsignedbv + || t.id() == ID_pointer || t.id() == ID_bool; +} + +bool constant_interval_exprt::is_signed(const typet &t) +{ + return t.id() == ID_signedbv; +} + +bool constant_interval_exprt::is_unsigned(const typet &t) +{ + return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_pointer + || t.id() == ID_bool; +} + +bool constant_interval_exprt::is_signed(const constant_interval_exprt &interval) +{ + return is_signed(interval.type()); +} + +bool constant_interval_exprt::is_unsigned(const constant_interval_exprt &interval) +{ + return is_unsigned(interval.type()); +} + +bool constant_interval_exprt::is_bitvector(const constant_interval_exprt &interval) +{ + return is_bitvector(interval.type()); +} + +bool constant_interval_exprt::is_signed(const exprt &expr) +{ + return is_signed(expr.type()); +} + +bool constant_interval_exprt::is_unsigned(const exprt &expr) +{ + return is_unsigned(expr.type()); +} + +bool constant_interval_exprt::is_bitvector(const exprt &expr) +{ + return is_bitvector(expr.type()); +} + +bool constant_interval_exprt::is_signed() const +{ + return is_signed(type()); +} + +bool constant_interval_exprt::is_unsigned() const +{ + return is_unsigned(type()); +} + +bool constant_interval_exprt::is_bitvector() const +{ + return is_bitvector(type()); +} + +bool constant_interval_exprt::is_extreme(const exprt &expr) +{ + return (is_max(expr) || is_min(expr)); +} + +bool constant_interval_exprt::is_extreme(const exprt &expr1, const exprt &expr2) +{ + return is_extreme(expr1) || is_extreme(expr2); +} + +bool constant_interval_exprt::is_max() const +{ + return is_max(get_upper()); +} + +bool constant_interval_exprt::is_min() const +{ + return is_min(get_lower()); +} + +bool constant_interval_exprt::is_max(const exprt &expr) +{ + return expr.id() == ID_max; +} + +bool constant_interval_exprt::is_min(const exprt &expr) +{ + return expr.id() == ID_min; +} + +bool constant_interval_exprt::is_positive(const exprt &expr) +{ + exprt simplified=simplified_expr(expr); + + if(expr.is_nil() || !simplified.is_constant() || expr.get(ID_value) == "") + { + return false; + } + + if(is_unsigned(expr) || is_max(expr)) + { + return true; + } + + assert(is_signed(expr)); + // Floats later + + if(is_min(expr)) + { + return false; + } + + return greater_than(expr, zero(expr)); +} + +bool constant_interval_exprt::is_zero(const exprt &expr) +{ + if(is_min(expr)) + { + if(is_unsigned(expr)) + { + return true; + } + else + { + return false; + } + } + + if(is_max(expr)) + { + return false; + } + + assert(!is_max(expr) && !is_min(expr)); + + if(expr.is_zero()) + { + return true; + } + + return equal(expr, zero(expr)); +} + +bool constant_interval_exprt::is_negative(const exprt &expr) +{ + if(is_unsigned(expr) || is_max(expr)) + { + return false; + } + + assert(is_signed(expr)); + + if(is_min(expr)) + { + return true; + } + + assert(!is_extreme(expr)); + + return less_than(expr, zero(expr)); +} + +exprt constant_interval_exprt::abs(const exprt &expr) +{ + if(is_signed(expr) && is_min(expr)) + { + return max_exprt(expr); + } + + if(is_max(expr) || is_unsigned(expr) || is_zero(expr) || is_positive(expr)) + { + return expr; + } + + return simplified_expr(unary_minus_exprt(expr)); +} + + +bool constant_interval_exprt::equal(const exprt& a, const exprt& b) +{ + if(a == b) + { + return true; + } + + if(!is_numeric(a) || !is_numeric(b)) + { + // Best we can do now is a==b?, but this is covered by the above, so always false. + assert(!(a == b)); + return false; + } + + if(is_max(a) && is_max(b)) + { + return true; + } + + exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; + exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; + + // CANNOT use is_zero(X) but can use X.is_zero(); + if((is_min(l) && is_min(r))) + { + return true; + } + + if((is_max(l) && !is_max(r)) || (is_min(l) && !is_min(r)) || + (is_max(r) && !is_max(l)) || (is_min(r) && !is_min(l))) + { + return false; + } + + assert(!is_extreme(l, r)); + + return simplified_expr(equal_exprt(l, r)).is_true(); +} + +// TODO: Signed/unsigned comparisons. +bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) +{ + if(!is_numeric(a) || !is_numeric(b)) + { + return false; + } + + exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; + exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; + + if(is_max(l)) + { + return false; + } + + assert(!is_max(l)); + + if(is_min(r)) + { + // Can't be smaller than min. + return false; + } + + assert(!is_max(l) && !is_min(r)); + + if(is_min(l)) + { + assert(!is_min(r)); + return true; + } + + assert(!is_max(l) && !is_min(r) && !is_min(l)); + + if(is_max(r)) + { + // If r is max, then l is less, unless l is max. + return !is_max(l); + } + + assert(!is_max(l) && !is_min(r) && !is_min(l) && !is_max(r)); + + assert(!is_extreme(l, r)); + + return simplified_expr(binary_relation_exprt(l, ID_lt, r)).is_true(); +} + +bool constant_interval_exprt::greater_than(const exprt &a, const exprt &b) +{ + return less_than(b, a); + +// if(!is_numeric(a) || !is_numeric(b)) +// { +// return false; +// } +// +// exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; +// exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; +// +// if(is_max(l) && !is_max(r)) +// { +// return true; +// } +// +// if((is_max(l) && is_max(r)) || (is_min(l) && is_min(r))) +// { +// return false; +// } +// +// if(is_min(l) && is_max(r)) +// { +// return false; +// } +// +// assert(!is_extreme(l) && !is_extreme(r)); +// +// return simplified_expr(binary_relation_exprt(l, ID_gt, r)).is_true(); +} + +bool constant_interval_exprt::less_than_or_equal(const exprt& a, const exprt& b) +{ + return less_than(a, b) || equal(a, b); +} + +bool constant_interval_exprt::greater_than_or_equal(const exprt& a, const exprt& b) +{ + return greater_than(a, b) || equal(a, b); +} + +bool constant_interval_exprt::not_equal(const exprt &a, const exprt &b) +{ + return !equal(a, b); +} + +bool constant_interval_exprt::contains(const constant_interval_exprt& interval) const +{ + // [a, b] Contains [c, d] If c >= a and d <= b. + return( + less_than_or_equal(interval.get_upper(), get_upper()) + && + greater_than_or_equal(interval.get_lower(), get_lower()) + ); +} + + +std::string constant_interval_exprt::to_string() const +{ + std::stringstream out; + + out << dstringt("["); + + if(!is_min()) + { + if(is_bitvector(get_lower())) + { + out << binary2integer(get_lower().get(ID_value).c_str(), 2); + } + else + { + out << get_lower().get(ID_value); + } + } + else + { + if(is_signed(get_lower())) + { + out << dstringt("MIN"); + } + else + { + out << dstringt("0"); + } + } + + out << dstringt(","); + + if(!is_max()) + { + if(is_bitvector(get_upper())) + { + out << binary2integer(get_upper().get(ID_value).c_str(), 2); + } + else + { + out << get_upper().get(ID_value); + } + } + else + out << dstringt("MAX"); + + out << dstringt("]"); + + return out.str(); +} + +std::ostream& operator <<(std::ostream& out, + const constant_interval_exprt& i) +{ + out << i.to_string(); + + return out; +} + +bool operator< (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.less_than(rhs).is_true(); +} + +bool operator> (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.greater_than(rhs).is_true(); +} + +bool operator<=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.less_than_or_equal(rhs).is_true(); +} + +bool operator>=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.greater_than(rhs).is_true(); +} + +bool operator==(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.equal(rhs).is_true(); +} + +bool operator!=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.not_equal(rhs).is_true(); +} + +const constant_interval_exprt operator+(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.unary_plus(rhs); +} + +const constant_interval_exprt operator-(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.minus(rhs); +} + +const constant_interval_exprt operator/(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.divide(rhs); +} + +const constant_interval_exprt operator*(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.multiply(rhs); +} + +const constant_interval_exprt operator%(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.modulo(rhs); +} + +const constant_interval_exprt operator&(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.bitwise_and(rhs); +} + +const constant_interval_exprt operator|(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.bitwise_or(rhs); +} + +const constant_interval_exprt operator^(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.bitwise_xor(rhs); +} + +const constant_interval_exprt operator!(const constant_interval_exprt &lhs) +{ + return lhs.bitwise_not(); +} + +const constant_interval_exprt operator<<(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.left_shift(rhs); +} + +const constant_interval_exprt operator>>(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +{ + return lhs.right_shift(rhs); +} + +const constant_interval_exprt constant_interval_exprt::unary_plus(const constant_interval_exprt &a) +{ + return a.unary_plus(); +} + +const constant_interval_exprt constant_interval_exprt::unary_minus(const constant_interval_exprt &a) +{ + return a.unary_minus(); +} + +/* Binary */ +const constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.plus(b); +} + +const constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.minus(b); +} + +const constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.multiply(b); +} + +const constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.divide(b); +} + +const constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.modulo(b); +} + +/* Binary shifts */ +const constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.left_shift(b); +} + +const constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.right_shift(b); +} + +/* Unary bitwise */ +const constant_interval_exprt constant_interval_exprt::bitwise_not(const constant_interval_exprt &a) +{ + return a.bitwise_not(); +} + +/* Binary bitwise */ +const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.bitwise_xor(b); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.bitwise_or(b); +} + +const constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.bitwise_and(b); +} + +tvt constant_interval_exprt::less_than(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.less_than(b); +} + +tvt constant_interval_exprt::greater_than(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.greater_than(b); +} + +tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.less_than_or_equal(b); +} + +tvt constant_interval_exprt::greater_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.greater_than_or_equal(b); +} + +tvt constant_interval_exprt::equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.equal(b); +} + +tvt constant_interval_exprt::not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +{ + return a.equal(b); +} + +const constant_interval_exprt constant_interval_exprt::increment(const constant_interval_exprt &a) +{ + return a.increment(); +} + +const constant_interval_exprt constant_interval_exprt::decrement(const constant_interval_exprt &a) +{ + return a.decrement(); +} + +bool constant_interval_exprt::is_empty(const constant_interval_exprt &a) +{ + return a.is_empty(); +} + +bool constant_interval_exprt::is_constant(const constant_interval_exprt &a) +{ + return a.is_constant(); +} + +bool constant_interval_exprt::is_top(const constant_interval_exprt &a) +{ + return a.is_top(); +} + +bool constant_interval_exprt::is_bottom(const constant_interval_exprt &a) +{ + return a.is_bottom(); +} + +bool constant_interval_exprt::is_min(const constant_interval_exprt &a) +{ + return a.is_min(); +} + +bool constant_interval_exprt::is_max(const constant_interval_exprt &a) +{ + return a.is_max(); +} + +bool constant_interval_exprt::contains_extreme(const exprt expr) +{ + forall_operands(it, expr) + { + if(is_extreme(*it)) + { + return true; + } + + if(it->has_operands()) + { + return contains_extreme(*it); + } + } + + return false; +} + +bool constant_interval_exprt::contains_extreme(const exprt expr1, const exprt expr2) +{ + return contains_extreme(expr1) || contains_extreme(expr2); +} + +bool constant_interval_exprt::is_empty() const +{ + if(greater_than(get_lower(), get_upper())) + { + return false; + } + + return true; +} + +bool constant_interval_exprt::is_constant() const +{ + return !is_extreme(get_lower()) && !is_extreme(get_upper()) && equal(get_lower(), get_upper()); +} + +bool constant_interval_exprt::contains_zero() const +{ + if(!is_numeric()) + { + return false; + } + + if(get_lower().is_zero() || get_upper().is_zero()) + { + return true; + } + + if(is_unsigned() && is_min(get_lower())) + { + return true; + } + + if(less_than_or_equal(get_lower(), zero()) && greater_than_or_equal(get_upper(), zero())) + { + return true; + } + + return false; +} + + +bool constant_interval_exprt::is_positive(const constant_interval_exprt& interval) +{ + return interval.is_positive(); +} + +bool constant_interval_exprt::is_zero(const constant_interval_exprt& interval) +{ + return interval.is_zero(); +} + +bool constant_interval_exprt::is_negative(const constant_interval_exprt& interval) +{ + return interval.is_negative(); +} + +bool constant_interval_exprt::is_positive() const +{ + return is_positive(get_lower()) && is_positive(get_upper()); +} + +bool constant_interval_exprt::is_zero() const +{ + return is_zero(get_lower()) && is_zero(get_upper()); +} + +bool constant_interval_exprt::is_negative() const +{ + return is_negative(get_lower()) && is_negative(get_upper()); +} + +const constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv) +{ + return interval.tv_to_interval(tv); +} + +const tvt constant_interval_exprt::is_true(const constant_interval_exprt& a) +{ + return a.is_true(); +} + +const tvt constant_interval_exprt::is_false(const constant_interval_exprt& a) +{ + return a.is_false(); +} + +const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& a, const constant_interval_exprt& b) +{ + return a.logical_and(b); +} + +const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& a, const constant_interval_exprt& b) +{ + return a.logical_or(b); +} + +const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& a, const constant_interval_exprt& b) +{ + return a.logical_xor(b); +} + +const tvt constant_interval_exprt::logical_not(const constant_interval_exprt& a) +{ + return a.logical_not(); +} + diff --git a/src/util/interval.h b/src/util/interval.h new file mode 100644 index 00000000000..8668f1ff213 --- /dev/null +++ b/src/util/interval.h @@ -0,0 +1,361 @@ +/* + * interval.h + * + * Created on: 16 Jun 2017 + * Author: dan + */ + +#ifndef SRC_ANALYSES_INTERVAL_H_ +#define SRC_ANALYSES_INTERVAL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * + * Upper set = Specific max (otherwise INF) + * Lower set = Specific min (otherwise INF) + */ + +class max_exprt:public exprt +{ +public: + explicit max_exprt(const typet &_type): + exprt(ID_max, _type) + { + } + + explicit max_exprt(const exprt &_expr): + exprt(ID_max, _expr.type()) + { + } +}; + +class min_exprt:public exprt +{ +public: + explicit min_exprt(const typet &_type): + exprt(ID_min, _type) + { + } + + explicit min_exprt(const exprt &_expr): + exprt(ID_min, _expr.type()) + { + } +}; + + + +class constant_interval_exprt : public binary_exprt +{ +public: + constant_interval_exprt(exprt lower, exprt upper, typet type) + : binary_exprt(lower, ID_constant_interval, upper, type) + { + PRECONDITION(lower.type() == upper.type() && type == lower.type()); + } + + constant_interval_exprt(): + constant_interval_exprt(min_exprt(nil_typet()), max_exprt(nil_typet()), nil_typet()) + { + + } + + explicit constant_interval_exprt(const exprt &x): + constant_interval_exprt(x, x, x.type()) + { + + } + + constant_interval_exprt(const typet type): + constant_interval_exprt(min_exprt(type), max_exprt(type), type) + { + } + + constant_interval_exprt(const exprt &lower, const exprt &upper): + constant_interval_exprt(lower, upper, lower.type()) + { + + } + + /* Naming scheme + * is_[X]? Returns bool / tvt + * get_[X]? Returns relevant object + * [X] Generator of some object. + * generate_[X] generator used for evaluation + */ + + /* Getters */ + const exprt &get_lower() const; + const exprt &get_upper() const; + + /** SET OF ARITHMETIC OPERATORS */ + const constant_interval_exprt handle_constants(exprt expr) const; + const constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; + + const constant_interval_exprt eval(const exprt &expr); + const constant_interval_exprt eval(const exprt &expr, const constant_interval_exprt &o); + + /* Unary arithmetic */ + const constant_interval_exprt unary_plus() const; + const constant_interval_exprt unary_minus() const; + + /* Logical */ + const tvt is_true() const; + const tvt is_false() const; + + const tvt logical_and(const constant_interval_exprt& o) const; + const tvt logical_or(const constant_interval_exprt &o) const; + const tvt logical_xor(const constant_interval_exprt &o) const; + const tvt logical_not() const; + + const constant_interval_exprt tv_to_interval(const tvt &tv) const; + + /* Binary */ + const constant_interval_exprt plus(const constant_interval_exprt &o) const; + const constant_interval_exprt minus(const constant_interval_exprt &o) const; + const constant_interval_exprt multiply(const constant_interval_exprt &o) const; + const constant_interval_exprt divide(const constant_interval_exprt &o) const; + const constant_interval_exprt modulo(const constant_interval_exprt &o) const; + + /* Binary shifts */ + const constant_interval_exprt left_shift(const constant_interval_exprt &o) const; + const constant_interval_exprt right_shift(const constant_interval_exprt &o) const; + + /* Unary bitwise */ + const constant_interval_exprt bitwise_not() const; + + /* Binary bitwise */ + const constant_interval_exprt bitwise_xor(const constant_interval_exprt &o) const; + const constant_interval_exprt bitwise_or(const constant_interval_exprt &o) const; + const constant_interval_exprt bitwise_and(const constant_interval_exprt &o) const; + + tvt less_than(const constant_interval_exprt &o) const; + tvt greater_than(const constant_interval_exprt &o) const; + tvt less_than_or_equal(const constant_interval_exprt &o) const; + tvt greater_than_or_equal(const constant_interval_exprt &o) const; + tvt equal(const constant_interval_exprt &o) const; + tvt not_equal(const constant_interval_exprt &o) const; + + const constant_interval_exprt increment() const; + const constant_interval_exprt decrement() const; + + bool is_empty() const; + bool is_constant() const; + /** END SET OF ARITHMETIC OPERATORS */ + +// tvt contains(constant_interval_exprt &o) const; + + /* SET OF EXPR COMPARATORS */ + static bool equal(const exprt &a, const exprt &b); + static bool not_equal(const exprt &a, const exprt &b); + static bool less_than(const exprt &a, const exprt &b); + static bool less_than_or_equal(const exprt &a, const exprt &b); + static bool greater_than(const exprt &a, const exprt &b); + static bool greater_than_or_equal(const exprt &a, const exprt &b); + /* END SET OF EXPR COMPS */ + + /* INTERVAL COMPARISONS, returns tvt.is_true(). False cannot be trusted + * (could be false or unknown, either use less_than, etc method or use the correct + * operator)! */ + friend bool operator< (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator> (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator<=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator>=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator==(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator!=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + + /* Operator override for intervals */ + friend const constant_interval_exprt operator+(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator-(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator/(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator*(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator%(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator!(const constant_interval_exprt &lhs); + friend const constant_interval_exprt operator&(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator|(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator^(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator<<(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator>>(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + + friend std::ostream& operator<< (std::ostream& out, const constant_interval_exprt &i); + std::string to_string() const; + + + /* Now static equivalents! */ + static const tvt is_true(const constant_interval_exprt &a); + static const tvt is_false(const constant_interval_exprt &a); + + static const tvt logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const tvt logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const tvt logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const tvt logical_not(const constant_interval_exprt &a); + + static const constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv); + + static const constant_interval_exprt unary_plus(const constant_interval_exprt &a); + static const constant_interval_exprt unary_minus(const constant_interval_exprt &a); + + /* Binary */ + static const constant_interval_exprt plus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt minus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt multiply(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt divide(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt modulo(const constant_interval_exprt &a, const constant_interval_exprt &b); + + /* Binary shifts */ + static const constant_interval_exprt left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); + + /* Unary bitwise */ + static const constant_interval_exprt bitwise_not(const constant_interval_exprt &a); + + /* Binary bitwise */ + static const constant_interval_exprt bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b); + static const constant_interval_exprt bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b); + + static tvt less_than(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt greater_than(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt less_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt greater_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + + static const constant_interval_exprt increment(const constant_interval_exprt &a); + static const constant_interval_exprt decrement(const constant_interval_exprt &a); + + static bool is_empty(const constant_interval_exprt &a); + static bool is_constant(const constant_interval_exprt &a); + + static bool is_top(const constant_interval_exprt &a); + static bool is_bottom(const constant_interval_exprt &a); + + static bool is_min(const constant_interval_exprt &a); + static bool is_max(const constant_interval_exprt &a); + /* End static equivalents */ + + + + + + bool is_top() const; + bool is_bottom() const; + static const constant_interval_exprt top(const typet &type); + static const constant_interval_exprt bottom(const typet &type); + const constant_interval_exprt top() const; + const constant_interval_exprt bottom() const; + + bool is_min() const; + bool is_max() const; + static bool is_min(const exprt &expr); + static bool is_max(const exprt &expr); + + /* Generate min and max exprt according to current type */ + min_exprt min() const; + max_exprt max() const; + + constant_exprt zero() const; + static constant_exprt zero(const typet &type); + static constant_exprt zero(const exprt &expr); + static constant_exprt zero(const constant_interval_exprt &interval); + + /* Private? */ + static const constant_interval_exprt get_extremes(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs, const exprt operation); + static exprt get_extreme(std::vector values, bool min = true); + static exprt get_max(const exprt &a, const exprt &b); + static exprt get_min(const exprt &a, const exprt &b); + static exprt get_min(std::vector &values); + static exprt get_max(std::vector &values); + + /* we don't simplify in the constructor otherwise */ + static const constant_interval_exprt simplified_interval(exprt &l, exprt &r); + static exprt simplified_expr(exprt expr); + + /* Swap lower and upper! */ + const constant_interval_exprt swap() const; + static const constant_interval_exprt swap(constant_interval_exprt &i); + /* Helpers */ + /* Four common params: self, static: type, expr, interval */ + + bool is_numeric() const; + static bool is_numeric(const typet &type); + static bool is_numeric(const exprt &expr); + static bool is_numeric(const constant_interval_exprt &interval); + + bool is_int() const; + static bool is_int(const typet &type); + static bool is_int(const exprt &expr); + static bool is_int(const constant_interval_exprt &interval); + + bool is_float() const; + static bool is_float(const typet &type); + static bool is_float(const exprt &expr); + static bool is_float(const constant_interval_exprt &interval); + + bool is_bitvector() const; + static bool is_bitvector(const typet &type); + static bool is_bitvector(const constant_interval_exprt &interval); + static bool is_bitvector(const exprt &expr); + + bool is_signed() const; + static bool is_signed(const typet &type); + static bool is_signed(const exprt &expr); + static bool is_signed(const constant_interval_exprt &interval); + + bool is_unsigned() const; + static bool is_unsigned(const typet &type); + static bool is_unsigned(const exprt &expr); + static bool is_unsigned(const constant_interval_exprt &interval); + + bool contains_zero() const; + bool contains(const constant_interval_exprt &interval) const; + + static bool is_extreme(const exprt &expr); + static bool is_extreme(const exprt &expr1, const exprt &expr2); + + static bool contains_extreme(const exprt expr); + static bool contains_extreme(const exprt expr1, const exprt expr2); + + bool is_positive() const; + static bool is_positive(const exprt &expr); + static bool is_positive(const constant_interval_exprt &interval); + + bool is_zero() const; + static bool is_zero(const exprt &expr); + static bool is_zero(const constant_interval_exprt &interval); + + bool is_negative() const; + static bool is_negative(const exprt &expr); + static bool is_negative(const constant_interval_exprt &interval); + + static exprt abs(const exprt &expr); + +private: + + static exprt generate_expression(const exprt &a, const exprt &b, const exprt &operation); + static exprt generate_multiply_expression(const exprt &a, const exprt &b, exprt operation); + static exprt generate_multiply_expression_max(const exprt &expr); + static exprt generate_multiply_expression_min(const exprt &min, const exprt &other); + static exprt generate_division_expression(const exprt &a, const exprt &b, exprt operation); + static exprt generate_modulo_expression(const exprt &a, const exprt &b, exprt operation); + static exprt generate_shift_expression(const exprt &a, const exprt &b, exprt operation); +}; + +inline const constant_interval_exprt& to_constant_interval_expr(const exprt& expr) { + PRECONDITION(expr.id() == ID_constant_interval); + return static_cast(expr); +} + +#endif /* SRC_ANALYSES_INTERVAL_H_ */ diff --git a/src/util/interval_template.h b/src/util/interval_template.h index c6a3e64b0ef..a8d4dc01867 100644 --- a/src/util/interval_template.h +++ b/src/util/interval_template.h @@ -230,16 +230,22 @@ template std::ostream &operator << (std::ostream &out, const interval_templatet &i) { if(i.lower_set) - out << '[' << i.lower; + { + out << dstringt("["); + out << i.lower; + } else - out << ")-INF"; + out << dstringt(")-INF"); - out << ','; + out << dstringt(","); if(i.upper_set) - out << i.upper << ']'; + { + out << i.upper; + out << dstringt("]"); + } else - out << "+INF("; + out << dstringt("+INF("); return out; } diff --git a/src/util/irep_ids.def b/src/util/irep_ids.def index 2e286e0ba64..5b705b2adff 100644 --- a/src/util/irep_ids.def +++ b/src/util/irep_ids.def @@ -834,6 +834,9 @@ IREP_ID_ONE(statement_list_reset) IREP_ID_ONE(statement_list_not) IREP_ID_ONE(statement_list_instruction) IREP_ID_ONE(statement_list_instructions) +IREP_ID_ONE(max) +IREP_ID_ONE(min) +IREP_ID_ONE(constant_interval) // Projects depending on this code base that wish to extend the list of // available ids should provide a file local_irep_ids.def in their source tree diff --git a/unit/Makefile b/unit/Makefile index ed549005358..c22e07f423b 100644 --- a/unit/Makefile +++ b/unit/Makefile @@ -72,6 +72,14 @@ SRC += analyses/ai/ai.cpp \ util/format_number_range.cpp \ util/get_base_name.cpp \ util/graph.cpp \ + util/interval/multiply.cpp \ + util/interval/add.cpp \ + util/interval/get_extreme.cpp \ + util/interval/subtract.cpp \ + util/interval/modulo.cpp \ + util/interval/shift.cpp \ + util/interval/comparisons.cpp \ + util/interval/bitwise.cpp \ util/interval_constraint.cpp \ util/interval_union.cpp \ util/irep.cpp \ diff --git a/unit/util/interval/add.cpp b/unit/util/interval/add.cpp new file mode 100644 index 00000000000..16626e9cf10 --- /dev/null +++ b/unit/util/interval/add.cpp @@ -0,0 +1,107 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("add interval domain", + "[core][analyses][interval][add]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + source_locationt source_location; + + std::map values; + + for(int i = -100; i <= 100; i++) + { + values[i] = from_integer(mp_integer(i), type); + } + + WHEN("Both are positive [2,4]+[6,8]") + { + interval_exprt left(values[2], values[4]); + interval_exprt right(values[6], values[8]); + + interval_exprt result = left.plus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 2); + REQUIRE(V(left.get_upper()) == 4); + REQUIRE(V(right.get_lower()) == 6); + REQUIRE(V(right.get_upper()) == 8); + } + + + THEN("The result is [8, 12]") + { + REQUIRE(V(result.get_lower()) == 8); + REQUIRE(V(result.get_upper()) == 12); + } + } + + WHEN("One contains infinite [2,4]+[6,INF]") + { + interval_exprt left(values[2], values[4]); + interval_exprt right(values[6], max_exprt(type)); + + interval_exprt result = left.plus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 2); + REQUIRE(V(left.get_upper()) == 4); + REQUIRE(V(right.get_lower()) == 6); + REQUIRE(right.is_max()); + } + + CAPTURE(result); + + THEN("The result is [8, MAX]") + { + REQUIRE(V(result.get_lower()) == 8); + REQUIRE(result.is_max()); + } + } + + WHEN("Both contain infinite [2,INF]+[6,INF]") + { + interval_exprt left(values[2], max_exprt(type)); + interval_exprt right(values[6], max_exprt(type)); + + interval_exprt result = left.plus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 2); + REQUIRE(left.is_max()); + REQUIRE(V(right.get_lower()) == 6); + REQUIRE(right.is_max()); + } + + CAPTURE(result); + + THEN("The result is [8, MAX]") + { + REQUIRE(V(result.get_lower()) == 8); + REQUIRE(result.is_max()); + } + } + } +} diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp new file mode 100644 index 00000000000..79f1f3f23ca --- /dev/null +++ b/unit/util/interval/bitwise.cpp @@ -0,0 +1,44 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("bitwise interval domain", + "[core][analyses][interval][bitwise]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + source_locationt source_location; + + std::map values; + + for(int i = -100; i <= 100; i++) + { + values[i] = from_integer(mp_integer(i), type); + } + + WHEN("Something") + { + THEN("Something else") + { + REQUIRE(true); + } + } + } +} diff --git a/unit/util/interval/comparisons.cpp b/unit/util/interval/comparisons.cpp new file mode 100644 index 00000000000..24400da0e0d --- /dev/null +++ b/unit/util/interval/comparisons.cpp @@ -0,0 +1,143 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("comparison interval domain", + "[core][analyses][interval][comparison]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + const typet t=type; + + source_locationt source_location; + + std::map v; + + for(int i = -100; i <= 100; i++) + { + v[i] = from_integer(mp_integer(i), type); + } + + WHEN("<, >, <=, >=, ==, != are tested on expressions") + { + THEN("Require correctness") + { + REQUIRE(interval_exprt::less_than(v[0], v[1])); + REQUIRE(interval_exprt::less_than(v[1], v[2])); + REQUIRE(interval_exprt::less_than(v[1], v[100])); + + REQUIRE(interval_exprt::less_than(v[-10], v[1])); + REQUIRE_FALSE(interval_exprt::less_than(v[-10], v[-100])); + REQUIRE(interval_exprt::less_than(v[-10], v[-5])); + REQUIRE(interval_exprt::less_than(v[-10], max_exprt(t))); + REQUIRE(interval_exprt::less_than(v[10], max_exprt(t))); + REQUIRE(interval_exprt::less_than(v[0], max_exprt(t))); + + REQUIRE_FALSE(interval_exprt::less_than(v[-10], min_exprt(t))); + REQUIRE_FALSE(interval_exprt::less_than(v[10], min_exprt(t))); + REQUIRE_FALSE(interval_exprt::less_than(v[0], min_exprt(t))); + + REQUIRE_FALSE(interval_exprt::less_than(min_exprt(t), min_exprt(t))); + REQUIRE_FALSE(interval_exprt::less_than(max_exprt(t), min_exprt(t))); + REQUIRE_FALSE(interval_exprt::less_than(max_exprt(t), max_exprt(t))); + REQUIRE(interval_exprt::less_than(min_exprt(t), max_exprt(t))); + + REQUIRE(interval_exprt::equal(min_exprt(t), min_exprt(t))); + REQUIRE(interval_exprt::not_equal(max_exprt(t), min_exprt(t))); + REQUIRE(interval_exprt::equal(max_exprt(t), max_exprt(t))); + REQUIRE(interval_exprt::not_equal(min_exprt(t), max_exprt(t))); + } + + THEN("") + { + REQUIRE_FALSE(interval_exprt::greater_than(v[0], v[1])); + REQUIRE_FALSE(interval_exprt::greater_than(v[1], v[2])); + REQUIRE_FALSE(interval_exprt::greater_than(v[1], v[100])); + + REQUIRE_FALSE(interval_exprt::greater_than(v[-10], v[1])); + REQUIRE(interval_exprt::greater_than(v[-10], v[-100])); + REQUIRE_FALSE(interval_exprt::greater_than(v[-10], v[-5])); + REQUIRE_FALSE(interval_exprt::greater_than(v[-10], max_exprt(t))); + REQUIRE_FALSE(interval_exprt::greater_than(v[10], max_exprt(t))); + REQUIRE_FALSE(interval_exprt::greater_than(v[0], max_exprt(t))); + + REQUIRE(interval_exprt::greater_than(v[-10], min_exprt(t))); + REQUIRE(interval_exprt::greater_than(v[10], min_exprt(t))); + REQUIRE(interval_exprt::greater_than(v[0], min_exprt(t))); + + REQUIRE_FALSE(interval_exprt::greater_than(min_exprt(t), min_exprt(t))); + REQUIRE(interval_exprt::greater_than_or_equal(min_exprt(t), min_exprt(t))); + + REQUIRE(interval_exprt::greater_than(max_exprt(t), min_exprt(t))); + REQUIRE(interval_exprt::greater_than_or_equal(max_exprt(t), min_exprt(t))); + + REQUIRE_FALSE(interval_exprt::greater_than(max_exprt(t), max_exprt(t))); + + REQUIRE_FALSE(interval_exprt::greater_than(min_exprt(t), max_exprt(t))); + } + } + + WHEN("<, >, <=, >=, ==, != are tested on intervals") + { + THEN("Require correctness") + { + CHECK(interval_exprt(v[10], v[20]) < interval_exprt(v[30], v[40])); + REQUIRE_FALSE(interval_exprt(v[10], v[30]) < interval_exprt(v[30], v[40])); + REQUIRE_FALSE(interval_exprt(v[10], v[20]) > interval_exprt(v[30], v[40])); + } + + THEN("[10, 29] < [30, 40] == true, [10, 30] < [30, 40] == unknown, [10, 31] < [30, 40] == unknown") + { + CHECK(interval_exprt(v[10], v[29]).less_than(interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(interval_exprt(v[10], v[30]).less_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(interval_exprt(v[10], v[31]).less_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + + CHECK(interval_exprt(v[30], v[40]).less_than(interval_exprt(v[10], v[29])) == tvt(false)); + + } + + + THEN("[10, 29] > [30, 40] == false, [10, 30] > [30, 40] == unknown, [10, 31] > [30, 40] == unknown") + { + CHECK(interval_exprt(v[10], v[29]).greater_than(interval_exprt(v[30], v[40])) == tvt(false)); + CHECK(interval_exprt(v[10], v[29]).greater_than(interval_exprt(v[30], v[40])) == + interval_exprt(v[30], v[40]).less_than(interval_exprt(v[10], v[29]))); + + + CHECK(interval_exprt(v[10], v[30]).greater_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(interval_exprt(v[10], v[31]).greater_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + } + + THEN("[10, 29] <= [30, 40] == true, [10, 30] <= [30, 40] == true, [10, 31] <- [30, 40] == unknown") + { + CHECK(interval_exprt(v[10], v[29]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(interval_exprt(v[10], v[30]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(interval_exprt(v[10], v[31]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); + } + + THEN("[10, 29] >= [30, 40] == false, [10, 30] >= [30, 40] == unknown, [10, 31] >= [30, 40] == unknown") + { + CHECK(interval_exprt(v[10], v[29]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt(false)); + CHECK(interval_exprt(v[10], v[30]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(interval_exprt(v[10], v[31]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); + } + } + } +} diff --git a/unit/util/interval/divide.cpp b/unit/util/interval/divide.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/unit/util/interval/get_extreme.cpp b/unit/util/interval/get_extreme.cpp new file mode 100644 index 00000000000..ce63dfd7121 --- /dev/null +++ b/unit/util/interval/get_extreme.cpp @@ -0,0 +1,167 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("get extreme exprt value", + "[core][analyses][interval][get_extreme]") +{ + GIVEN("A selection of constant_exprts in a std::vector and map") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + std::map values; + std::vector ve; + + for(int i = -100; i <= 100; i++) + { + values[i]=from_integer(mp_integer(i), type); + ve.push_back(from_integer(mp_integer(i), type)); +// values[i] = constant_exprt(std::to_string(i), integer_typet());; +// ve.push_back(exprt(constant_exprt(std::to_string(i), integer_typet()))); + } + + WHEN("-20 <= 20 is tested") + { + binary_predicate_exprt op1(values[-20], ID_le, values[20]); + bool interval_eval = interval_exprt::less_than_or_equal(values[-20], values[20]); + simplify(op1, ns); + + THEN("Require it is TRUE") + { + REQUIRE(op1.is_true()); + REQUIRE(interval_eval); + } + } + + + WHEN("20 <= -20 is tested") + { + binary_predicate_exprt op1(values[20], ID_le, values[-20]); + bool interval_eval = interval_exprt::less_than_or_equal(values[20], values[-20]); + simplify(op1, ns); + + THEN("Require it is FALSE") + { + REQUIRE(op1.is_false()); + REQUIRE_FALSE(interval_eval); + } + } + + WHEN("-20 <= -20 is tested") + { + binary_predicate_exprt op1(values[-20], ID_le, values[-20]); + bool interval_eval = interval_exprt::less_than_or_equal(values[-20], values[-20]); + + simplify(op1, ns); + + THEN("Require it is TRUE") + { + REQUIRE(op1.is_true()); + REQUIRE(interval_eval); + REQUIRE(interval_exprt::equal(values[1], values[1])); + } + } + + WHEN("Two are selected and min found [20, -20]") + { + std::vector selected = { values[20], values[-20] }; + + exprt min = interval_exprt::get_extreme(selected, true); + exprt max = interval_exprt::get_extreme(selected, false); + + THEN("Min (-20) and max (20) are verified") + { + CAPTURE(min.pretty()); + + REQUIRE(V(min) == -20); + REQUIRE(V(max) == 20); + } + } + + WHEN("Four are selected and min found [-20, 0, 20, 50]") + { + std::vector selected = { values[-20], values[0], values[50], values[20] }; + + exprt min = interval_exprt::get_extreme(selected, true); + exprt max = interval_exprt::get_extreme(selected, false); + + + THEN("Min (-20) and max (50) are verified") + { + REQUIRE(V(min) == -20); + REQUIRE(V(max) == 50); + } + } + + WHEN("One is selected [-100]") + { + std::vector selected = { values[-100] }; + + exprt min = interval_exprt::get_extreme(selected, true); + exprt max = interval_exprt::get_extreme(selected, false); + + THEN("Max (-100) and min (-100) are verified") + { + REQUIRE(V(min) == -100); + REQUIRE(V(max) == -100); + } + } + + WHEN("Five are selected [20, 30, 15, 0, -100]") + { + std::vector selected = { values[20], values[30], values[15], values[0], values[-100] }; + + + exprt min = interval_exprt::get_extreme(selected, true); + exprt max = interval_exprt::get_extreme(selected, false); + + THEN("Max (30) and min (-100) are verified") + { + REQUIRE(V(min) == -100); + REQUIRE(V(max) == 30); + } + } + + WHEN("All from [-100:100] are selected") + { + exprt min = interval_exprt::get_extreme(ve, true); + exprt max = interval_exprt::get_extreme(ve, false); + + THEN("Max (100) and min (-100) are verified") + { + REQUIRE(V(min) == -100); + REQUIRE(V(max) == 100); + } + } + + WHEN("All from [-100:100] are shuffled and selected") + { + std::random_shuffle(ve.begin(), ve.end()); + + exprt min = interval_exprt::get_extreme(ve, true); + exprt max = interval_exprt::get_extreme(ve, false); + + THEN("Max (100) and min (-100) are verified") + { + REQUIRE(V(min) == -100); + REQUIRE(V(max) == 100); + } + } + } +} diff --git a/unit/util/interval/modulo.cpp b/unit/util/interval/modulo.cpp new file mode 100644 index 00000000000..94090acd494 --- /dev/null +++ b/unit/util/interval/modulo.cpp @@ -0,0 +1,59 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("modulo interval domain", + "[core][analyses][interval][modulo]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + source_locationt source_location; + + std::map v; + + for(int i = -100; i <= 100; i++) + { + v[i] = from_integer(mp_integer(i), type); + } + + WHEN("Positive RHS") + { + + THEN("Ensure result is consistent.") + { + REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[5], v[5])) == interval_exprt(v[0], v[4])); + REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[4], v[5])) == interval_exprt(v[0], v[4])); + REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); + REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[-5], v[5])) == interval_exprt::top(type)); + + REQUIRE(interval_exprt(v[-10], v[20]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); + REQUIRE(interval_exprt(v[-20], v[-10]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); + + REQUIRE(interval_exprt(v[-20], v[-10]).modulo(interval_exprt(v[1], v[1])) == interval_exprt(v[0])); + + REQUIRE(interval_exprt(v[30], v[50]).modulo(interval_exprt(v[2], v[2])) == interval_exprt(v[0], v[1])); + + // Problems + REQUIRE(interval_exprt(v[30], max_exprt(type)).modulo(interval_exprt(v[2], v[2])) == interval_exprt(v[0], v[1])); + + } + } + } +} diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp new file mode 100644 index 00000000000..e4427138a0d --- /dev/null +++ b/unit/util/interval/multiply.cpp @@ -0,0 +1,161 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + +SCENARIO("multiply interval domain", + "[core][analyses][interval][multiply]") +{ + GIVEN("A selection of constant_exprts in a std::vector and map") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + std::map values; + std::vector ve; + + for(int i = -100; i <= 100; i++) + { + values[i] = from_integer(mp_integer(i), type); + ve.push_back(exprt(from_integer(mp_integer(i), type))); + } + + + WHEN("Both are positive [2,5]*[7,11]") + { + interval_exprt a(values[2], values[5]); + interval_exprt b(values[7], values[11]); + + interval_exprt result = a.multiply(b); + + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == 2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(V(b.get_upper()) == 11); + } + + CAPTURE(result); + + THEN("The result is [14, 55]") + { + CHECK(V(result.get_lower()) == 14); + CHECK(V(result.get_upper()) == 55); + } + } + + WHEN("One is entirely negative [-2,-5]*[7,11]") + { + interval_exprt a(values[-2], values[-5]); + interval_exprt b(values[7], values[11]); + + interval_exprt result = a.multiply(b); + + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -2); + CHECK(V(a.get_upper()) == -5); + CHECK(V(b.get_lower()) == 7); + CHECK(V(b.get_upper()) == 11); + } + + CAPTURE(result); + + + THEN("The result is [-55, -14]") + { + CHECK(V(result.get_lower()) == mp_integer(-55)); + CHECK(V(result.get_upper()) == -14); + } + } + + WHEN("Range contains and extends from zero [-2,5]*[7,11]") + { + interval_exprt a(values[-2], values[5]); + interval_exprt b(values[7], values[11]); + + interval_exprt result = a.multiply(b); + + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(V(b.get_upper()) == 11); + } + + CAPTURE(result); + + + THEN("The result is [-22, 55]") + { + CHECK(V(result.get_lower()) == mp_integer(-22)); + CHECK(V(result.get_upper()) == 55); + } + } + + + WHEN("One domain is infinite and other crosses zero [-2,5]*[7,INF]") + { + interval_exprt a(values[-2], values[5]); + interval_exprt b(values[7], max_exprt(type)); + + interval_exprt result = a.multiply(b); + + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(interval_exprt::is_max(b.get_upper())); + } + + CAPTURE(result); + + THEN("The result is [-INF, INF]") + { + CHECK(interval_exprt::is_max(result.get_upper())); + CHECK(interval_exprt::is_min(result.get_lower())); + } + } + + + WHEN("One domain is infinite and other is positive [2,5]*[7,INF]") + { + interval_exprt a(values[2], values[5]); + interval_exprt b(values[7], max_exprt(type)); + interval_exprt result = a.multiply(b); + + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == 2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(b.is_max()); + } + + THEN("The result is [14, INF]") + { + CAPTURE(result); + + CHECK(result.is_max()); + CHECK(V(result.get_lower()) == 14); + } + } + } + + +} diff --git a/unit/util/interval/shift.cpp b/unit/util/interval/shift.cpp new file mode 100644 index 00000000000..06c412a1331 --- /dev/null +++ b/unit/util/interval/shift.cpp @@ -0,0 +1,44 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("shift interval domain", + "[core][analyses][interval][shift]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + source_locationt source_location; + + std::map v; + + for(int i = -100; i <= 100; i++) + { + v[i] = from_integer(mp_integer(i), type); + } + + WHEN("Something") + { + THEN("Something else") + { + REQUIRE(interval_exprt(v[4], v[8]).left_shift(interval_exprt(v[1])) == interval_exprt(v[8], v[16])); + } + } + } +} diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp new file mode 100644 index 00000000000..c12d4b65820 --- /dev/null +++ b/unit/util/interval/subtract.cpp @@ -0,0 +1,106 @@ +/*******************************************************************\ + Module: Unit tests for variable/sensitivity/abstract_object::merge + Author: DiffBlue Limited. All rights reserved. +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) +#define V_(X) (binary2integer(X.c_str(), 2)) + + +SCENARIO("subtract interval domain", + "[core][analyses][interval][subtract]") +{ + GIVEN("Two simple signed intervals") + { + const typet type=signedbv_typet(32); + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + source_locationt source_location; + + std::map values; + + for(int i = -100; i <= 100; i++) + { + values[i] = from_integer(mp_integer(i), type); + } + + WHEN("The result is positive [6,8]-[2,4]") + { + interval_exprt left(values[6], values[8]); + interval_exprt right(values[2], values[4]); + + interval_exprt result = left.minus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 6); + REQUIRE(V(left.get_upper()) == 8); + REQUIRE(V(right.get_lower()) == 2); + REQUIRE(V(right.get_upper()) == 4); + } + + THEN("The result is [2, 6]") + { + REQUIRE(V(result.get_lower()) == 2); + REQUIRE(V(result.get_upper()) == 6); + } + } + + WHEN("One contains infinite [2,4]-[6,INF]") + { + interval_exprt left(values[2], values[4]); + interval_exprt right(values[6], max_exprt(type)); + + interval_exprt result = left.minus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 2); + REQUIRE(V(left.get_upper()) == 4); + REQUIRE(V(right.get_lower()) == 6); + REQUIRE(right.is_max()); + } + + CAPTURE(result); + + THEN("The result is [MIN, -2]") + { + REQUIRE(V(result.get_upper()) == -2); + REQUIRE(result.is_min()); + } + } + + WHEN("Both contain infinite [2,INF]-[6,INF]") + { + interval_exprt left(values[2], max_exprt(type)); + interval_exprt right(values[6], max_exprt(type)); + + interval_exprt result = left.minus(right); + + THEN("Domain is consistent") + { + REQUIRE(V(left.get_lower()) == 2); + REQUIRE(left.is_max()); + REQUIRE(V(right.get_lower()) == 6); + REQUIRE(right.is_max()); + } + + CAPTURE(result); + + THEN("The result is [MIN, MAX]") + { + REQUIRE(result.is_max()); + REQUIRE(result.is_min()); + } + } + } +} From a003056be1824302ac93018322aa49364bfe090d Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 9 May 2018 15:34:20 +0100 Subject: [PATCH 02/35] (INT) Fix broken interval unit tests --- unit/util/interval/add.cpp | 22 ++--- unit/util/interval/bitwise.cpp | 4 +- unit/util/interval/comparisons.cpp | 124 ++++++++++++++--------------- unit/util/interval/get_extreme.cpp | 36 ++++----- unit/util/interval/modulo.cpp | 22 ++--- unit/util/interval/multiply.cpp | 40 +++++----- unit/util/interval/shift.cpp | 6 +- unit/util/interval/subtract.cpp | 22 ++--- 8 files changed, 138 insertions(+), 138 deletions(-) diff --git a/unit/util/interval/add.cpp b/unit/util/interval/add.cpp index 16626e9cf10..09b9392333c 100644 --- a/unit/util/interval/add.cpp +++ b/unit/util/interval/add.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -35,10 +35,10 @@ SCENARIO("add interval domain", WHEN("Both are positive [2,4]+[6,8]") { - interval_exprt left(values[2], values[4]); - interval_exprt right(values[6], values[8]); + constant_interval_exprt left(values[2], values[4]); + constant_interval_exprt right(values[6], values[8]); - interval_exprt result = left.plus(right); + constant_interval_exprt result = left.plus(right); THEN("Domain is consistent") { @@ -58,10 +58,10 @@ SCENARIO("add interval domain", WHEN("One contains infinite [2,4]+[6,INF]") { - interval_exprt left(values[2], values[4]); - interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(values[2], values[4]); + constant_interval_exprt right(values[6], max_exprt(type)); - interval_exprt result = left.plus(right); + constant_interval_exprt result = left.plus(right); THEN("Domain is consistent") { @@ -82,10 +82,10 @@ SCENARIO("add interval domain", WHEN("Both contain infinite [2,INF]+[6,INF]") { - interval_exprt left(values[2], max_exprt(type)); - interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(values[2], max_exprt(type)); + constant_interval_exprt right(values[6], max_exprt(type)); - interval_exprt result = left.plus(right); + constant_interval_exprt result = left.plus(right); THEN("Domain is consistent") { diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp index 79f1f3f23ca..41a7f33dc6b 100644 --- a/unit/util/interval/bitwise.cpp +++ b/unit/util/interval/bitwise.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include diff --git a/unit/util/interval/comparisons.cpp b/unit/util/interval/comparisons.cpp index 24400da0e0d..0cf001b78c2 100644 --- a/unit/util/interval/comparisons.cpp +++ b/unit/util/interval/comparisons.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -39,58 +39,58 @@ SCENARIO("comparison interval domain", { THEN("Require correctness") { - REQUIRE(interval_exprt::less_than(v[0], v[1])); - REQUIRE(interval_exprt::less_than(v[1], v[2])); - REQUIRE(interval_exprt::less_than(v[1], v[100])); - - REQUIRE(interval_exprt::less_than(v[-10], v[1])); - REQUIRE_FALSE(interval_exprt::less_than(v[-10], v[-100])); - REQUIRE(interval_exprt::less_than(v[-10], v[-5])); - REQUIRE(interval_exprt::less_than(v[-10], max_exprt(t))); - REQUIRE(interval_exprt::less_than(v[10], max_exprt(t))); - REQUIRE(interval_exprt::less_than(v[0], max_exprt(t))); - - REQUIRE_FALSE(interval_exprt::less_than(v[-10], min_exprt(t))); - REQUIRE_FALSE(interval_exprt::less_than(v[10], min_exprt(t))); - REQUIRE_FALSE(interval_exprt::less_than(v[0], min_exprt(t))); - - REQUIRE_FALSE(interval_exprt::less_than(min_exprt(t), min_exprt(t))); - REQUIRE_FALSE(interval_exprt::less_than(max_exprt(t), min_exprt(t))); - REQUIRE_FALSE(interval_exprt::less_than(max_exprt(t), max_exprt(t))); - REQUIRE(interval_exprt::less_than(min_exprt(t), max_exprt(t))); - - REQUIRE(interval_exprt::equal(min_exprt(t), min_exprt(t))); - REQUIRE(interval_exprt::not_equal(max_exprt(t), min_exprt(t))); - REQUIRE(interval_exprt::equal(max_exprt(t), max_exprt(t))); - REQUIRE(interval_exprt::not_equal(min_exprt(t), max_exprt(t))); + REQUIRE(constant_interval_exprt::less_than(v[0], v[1])); + REQUIRE(constant_interval_exprt::less_than(v[1], v[2])); + REQUIRE(constant_interval_exprt::less_than(v[1], v[100])); + + REQUIRE(constant_interval_exprt::less_than(v[-10], v[1])); + REQUIRE_FALSE(constant_interval_exprt::less_than(v[-10], v[-100])); + REQUIRE(constant_interval_exprt::less_than(v[-10], v[-5])); + REQUIRE(constant_interval_exprt::less_than(v[-10], max_exprt(t))); + REQUIRE(constant_interval_exprt::less_than(v[10], max_exprt(t))); + REQUIRE(constant_interval_exprt::less_than(v[0], max_exprt(t))); + + REQUIRE_FALSE(constant_interval_exprt::less_than(v[-10], min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::less_than(v[10], min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::less_than(v[0], min_exprt(t))); + + REQUIRE_FALSE(constant_interval_exprt::less_than(min_exprt(t), min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(t), min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(t), max_exprt(t))); + REQUIRE(constant_interval_exprt::less_than(min_exprt(t), max_exprt(t))); + + REQUIRE(constant_interval_exprt::equal(min_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::not_equal(max_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::equal(max_exprt(t), max_exprt(t))); + REQUIRE(constant_interval_exprt::not_equal(min_exprt(t), max_exprt(t))); } THEN("") { - REQUIRE_FALSE(interval_exprt::greater_than(v[0], v[1])); - REQUIRE_FALSE(interval_exprt::greater_than(v[1], v[2])); - REQUIRE_FALSE(interval_exprt::greater_than(v[1], v[100])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[0], v[1])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[1], v[2])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[1], v[100])); - REQUIRE_FALSE(interval_exprt::greater_than(v[-10], v[1])); - REQUIRE(interval_exprt::greater_than(v[-10], v[-100])); - REQUIRE_FALSE(interval_exprt::greater_than(v[-10], v[-5])); - REQUIRE_FALSE(interval_exprt::greater_than(v[-10], max_exprt(t))); - REQUIRE_FALSE(interval_exprt::greater_than(v[10], max_exprt(t))); - REQUIRE_FALSE(interval_exprt::greater_than(v[0], max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], v[1])); + REQUIRE(constant_interval_exprt::greater_than(v[-10], v[-100])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], v[-5])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[10], max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(v[0], max_exprt(t))); - REQUIRE(interval_exprt::greater_than(v[-10], min_exprt(t))); - REQUIRE(interval_exprt::greater_than(v[10], min_exprt(t))); - REQUIRE(interval_exprt::greater_than(v[0], min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(v[-10], min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(v[10], min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(v[0], min_exprt(t))); - REQUIRE_FALSE(interval_exprt::greater_than(min_exprt(t), min_exprt(t))); - REQUIRE(interval_exprt::greater_than_or_equal(min_exprt(t), min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than_or_equal(min_exprt(t), min_exprt(t))); - REQUIRE(interval_exprt::greater_than(max_exprt(t), min_exprt(t))); - REQUIRE(interval_exprt::greater_than_or_equal(max_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(max_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than_or_equal(max_exprt(t), min_exprt(t))); - REQUIRE_FALSE(interval_exprt::greater_than(max_exprt(t), max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(max_exprt(t), max_exprt(t))); - REQUIRE_FALSE(interval_exprt::greater_than(min_exprt(t), max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(t), max_exprt(t))); } } @@ -98,45 +98,45 @@ SCENARIO("comparison interval domain", { THEN("Require correctness") { - CHECK(interval_exprt(v[10], v[20]) < interval_exprt(v[30], v[40])); - REQUIRE_FALSE(interval_exprt(v[10], v[30]) < interval_exprt(v[30], v[40])); - REQUIRE_FALSE(interval_exprt(v[10], v[20]) > interval_exprt(v[30], v[40])); + CHECK(constant_interval_exprt(v[10], v[20]) < constant_interval_exprt(v[30], v[40])); + REQUIRE_FALSE(constant_interval_exprt(v[10], v[30]) < constant_interval_exprt(v[30], v[40])); + REQUIRE_FALSE(constant_interval_exprt(v[10], v[20]) > constant_interval_exprt(v[30], v[40])); } THEN("[10, 29] < [30, 40] == true, [10, 30] < [30, 40] == unknown, [10, 31] < [30, 40] == unknown") { - CHECK(interval_exprt(v[10], v[29]).less_than(interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(interval_exprt(v[10], v[30]).less_than(interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(interval_exprt(v[10], v[31]).less_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[29]).less_than(constant_interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(constant_interval_exprt(v[10], v[30]).less_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[31]).less_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(interval_exprt(v[30], v[40]).less_than(interval_exprt(v[10], v[29])) == tvt(false)); + CHECK(constant_interval_exprt(v[30], v[40]).less_than(constant_interval_exprt(v[10], v[29])) == tvt(false)); } THEN("[10, 29] > [30, 40] == false, [10, 30] > [30, 40] == unknown, [10, 31] > [30, 40] == unknown") { - CHECK(interval_exprt(v[10], v[29]).greater_than(interval_exprt(v[30], v[40])) == tvt(false)); - CHECK(interval_exprt(v[10], v[29]).greater_than(interval_exprt(v[30], v[40])) == - interval_exprt(v[30], v[40]).less_than(interval_exprt(v[10], v[29]))); + CHECK(constant_interval_exprt(v[10], v[29]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt(false)); + CHECK(constant_interval_exprt(v[10], v[29]).greater_than(constant_interval_exprt(v[30], v[40])) == + constant_interval_exprt(v[30], v[40]).less_than(constant_interval_exprt(v[10], v[29]))); - CHECK(interval_exprt(v[10], v[30]).greater_than(interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(interval_exprt(v[10], v[31]).greater_than(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[30]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[31]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); } THEN("[10, 29] <= [30, 40] == true, [10, 30] <= [30, 40] == true, [10, 31] <- [30, 40] == unknown") { - CHECK(interval_exprt(v[10], v[29]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(interval_exprt(v[10], v[30]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(interval_exprt(v[10], v[31]).less_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[29]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(constant_interval_exprt(v[10], v[30]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(true)); + CHECK(constant_interval_exprt(v[10], v[31]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); } THEN("[10, 29] >= [30, 40] == false, [10, 30] >= [30, 40] == unknown, [10, 31] >= [30, 40] == unknown") { - CHECK(interval_exprt(v[10], v[29]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt(false)); - CHECK(interval_exprt(v[10], v[30]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(interval_exprt(v[10], v[31]).greater_than_or_equal(interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[29]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(false)); + CHECK(constant_interval_exprt(v[10], v[30]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(v[10], v[31]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); } } } diff --git a/unit/util/interval/get_extreme.cpp b/unit/util/interval/get_extreme.cpp index ce63dfd7121..e54698d8990 100644 --- a/unit/util/interval/get_extreme.cpp +++ b/unit/util/interval/get_extreme.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -39,7 +39,7 @@ SCENARIO("get extreme exprt value", WHEN("-20 <= 20 is tested") { binary_predicate_exprt op1(values[-20], ID_le, values[20]); - bool interval_eval = interval_exprt::less_than_or_equal(values[-20], values[20]); + bool interval_eval = constant_interval_exprt::less_than_or_equal(values[-20], values[20]); simplify(op1, ns); THEN("Require it is TRUE") @@ -53,7 +53,7 @@ SCENARIO("get extreme exprt value", WHEN("20 <= -20 is tested") { binary_predicate_exprt op1(values[20], ID_le, values[-20]); - bool interval_eval = interval_exprt::less_than_or_equal(values[20], values[-20]); + bool interval_eval = constant_interval_exprt::less_than_or_equal(values[20], values[-20]); simplify(op1, ns); THEN("Require it is FALSE") @@ -66,7 +66,7 @@ SCENARIO("get extreme exprt value", WHEN("-20 <= -20 is tested") { binary_predicate_exprt op1(values[-20], ID_le, values[-20]); - bool interval_eval = interval_exprt::less_than_or_equal(values[-20], values[-20]); + bool interval_eval = constant_interval_exprt::less_than_or_equal(values[-20], values[-20]); simplify(op1, ns); @@ -74,7 +74,7 @@ SCENARIO("get extreme exprt value", { REQUIRE(op1.is_true()); REQUIRE(interval_eval); - REQUIRE(interval_exprt::equal(values[1], values[1])); + REQUIRE(constant_interval_exprt::equal(values[1], values[1])); } } @@ -82,8 +82,8 @@ SCENARIO("get extreme exprt value", { std::vector selected = { values[20], values[-20] }; - exprt min = interval_exprt::get_extreme(selected, true); - exprt max = interval_exprt::get_extreme(selected, false); + exprt min = constant_interval_exprt::get_extreme(selected, true); + exprt max = constant_interval_exprt::get_extreme(selected, false); THEN("Min (-20) and max (20) are verified") { @@ -98,8 +98,8 @@ SCENARIO("get extreme exprt value", { std::vector selected = { values[-20], values[0], values[50], values[20] }; - exprt min = interval_exprt::get_extreme(selected, true); - exprt max = interval_exprt::get_extreme(selected, false); + exprt min = constant_interval_exprt::get_extreme(selected, true); + exprt max = constant_interval_exprt::get_extreme(selected, false); THEN("Min (-20) and max (50) are verified") @@ -113,8 +113,8 @@ SCENARIO("get extreme exprt value", { std::vector selected = { values[-100] }; - exprt min = interval_exprt::get_extreme(selected, true); - exprt max = interval_exprt::get_extreme(selected, false); + exprt min = constant_interval_exprt::get_extreme(selected, true); + exprt max = constant_interval_exprt::get_extreme(selected, false); THEN("Max (-100) and min (-100) are verified") { @@ -128,8 +128,8 @@ SCENARIO("get extreme exprt value", std::vector selected = { values[20], values[30], values[15], values[0], values[-100] }; - exprt min = interval_exprt::get_extreme(selected, true); - exprt max = interval_exprt::get_extreme(selected, false); + exprt min = constant_interval_exprt::get_extreme(selected, true); + exprt max = constant_interval_exprt::get_extreme(selected, false); THEN("Max (30) and min (-100) are verified") { @@ -140,8 +140,8 @@ SCENARIO("get extreme exprt value", WHEN("All from [-100:100] are selected") { - exprt min = interval_exprt::get_extreme(ve, true); - exprt max = interval_exprt::get_extreme(ve, false); + exprt min = constant_interval_exprt::get_extreme(ve, true); + exprt max = constant_interval_exprt::get_extreme(ve, false); THEN("Max (100) and min (-100) are verified") { @@ -154,8 +154,8 @@ SCENARIO("get extreme exprt value", { std::random_shuffle(ve.begin(), ve.end()); - exprt min = interval_exprt::get_extreme(ve, true); - exprt max = interval_exprt::get_extreme(ve, false); + exprt min = constant_interval_exprt::get_extreme(ve, true); + exprt max = constant_interval_exprt::get_extreme(ve, false); THEN("Max (100) and min (-100) are verified") { diff --git a/unit/util/interval/modulo.cpp b/unit/util/interval/modulo.cpp index 94090acd494..b74569b69b1 100644 --- a/unit/util/interval/modulo.cpp +++ b/unit/util/interval/modulo.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -38,20 +38,20 @@ SCENARIO("modulo interval domain", THEN("Ensure result is consistent.") { - REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[5], v[5])) == interval_exprt(v[0], v[4])); - REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[4], v[5])) == interval_exprt(v[0], v[4])); - REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); - REQUIRE(interval_exprt(v[10], v[20]).modulo(interval_exprt(v[-5], v[5])) == interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[5], v[5])) == constant_interval_exprt(v[0], v[4])); + REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[4], v[5])) == constant_interval_exprt(v[0], v[4])); + REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[-5], v[5])) == constant_interval_exprt::top(type)); - REQUIRE(interval_exprt(v[-10], v[20]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); - REQUIRE(interval_exprt(v[-20], v[-10]).modulo(interval_exprt(v[0], v[5])) == interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(v[-10], v[20]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(v[-20], v[-10]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); - REQUIRE(interval_exprt(v[-20], v[-10]).modulo(interval_exprt(v[1], v[1])) == interval_exprt(v[0])); + REQUIRE(constant_interval_exprt(v[-20], v[-10]).modulo(constant_interval_exprt(v[1], v[1])) == constant_interval_exprt(v[0])); - REQUIRE(interval_exprt(v[30], v[50]).modulo(interval_exprt(v[2], v[2])) == interval_exprt(v[0], v[1])); + REQUIRE(constant_interval_exprt(v[30], v[50]).modulo(constant_interval_exprt(v[2], v[2])) == constant_interval_exprt(v[0], v[1])); // Problems - REQUIRE(interval_exprt(v[30], max_exprt(type)).modulo(interval_exprt(v[2], v[2])) == interval_exprt(v[0], v[1])); + REQUIRE(constant_interval_exprt(v[30], max_exprt(type)).modulo(constant_interval_exprt(v[2], v[2])) == constant_interval_exprt(v[0], v[1])); } } diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index e4427138a0d..bdcc50acee6 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -35,10 +35,10 @@ SCENARIO("multiply interval domain", WHEN("Both are positive [2,5]*[7,11]") { - interval_exprt a(values[2], values[5]); - interval_exprt b(values[7], values[11]); + constant_interval_exprt a(values[2], values[5]); + constant_interval_exprt b(values[7], values[11]); - interval_exprt result = a.multiply(b); + constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { @@ -59,10 +59,10 @@ SCENARIO("multiply interval domain", WHEN("One is entirely negative [-2,-5]*[7,11]") { - interval_exprt a(values[-2], values[-5]); - interval_exprt b(values[7], values[11]); + constant_interval_exprt a(values[-2], values[-5]); + constant_interval_exprt b(values[7], values[11]); - interval_exprt result = a.multiply(b); + constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { @@ -84,10 +84,10 @@ SCENARIO("multiply interval domain", WHEN("Range contains and extends from zero [-2,5]*[7,11]") { - interval_exprt a(values[-2], values[5]); - interval_exprt b(values[7], values[11]); + constant_interval_exprt a(values[-2], values[5]); + constant_interval_exprt b(values[7], values[11]); - interval_exprt result = a.multiply(b); + constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { @@ -110,34 +110,34 @@ SCENARIO("multiply interval domain", WHEN("One domain is infinite and other crosses zero [-2,5]*[7,INF]") { - interval_exprt a(values[-2], values[5]); - interval_exprt b(values[7], max_exprt(type)); + constant_interval_exprt a(values[-2], values[5]); + constant_interval_exprt b(values[7], max_exprt(type)); - interval_exprt result = a.multiply(b); + constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { CHECK(V(a.get_lower()) == -2); CHECK(V(a.get_upper()) == 5); CHECK(V(b.get_lower()) == 7); - CHECK(interval_exprt::is_max(b.get_upper())); + CHECK(constant_interval_exprt::is_max(b.get_upper())); } CAPTURE(result); THEN("The result is [-INF, INF]") { - CHECK(interval_exprt::is_max(result.get_upper())); - CHECK(interval_exprt::is_min(result.get_lower())); + CHECK(constant_interval_exprt::is_max(result.get_upper())); + CHECK(constant_interval_exprt::is_min(result.get_lower())); } } WHEN("One domain is infinite and other is positive [2,5]*[7,INF]") { - interval_exprt a(values[2], values[5]); - interval_exprt b(values[7], max_exprt(type)); - interval_exprt result = a.multiply(b); + constant_interval_exprt a(values[2], values[5]); + constant_interval_exprt b(values[7], max_exprt(type)); + constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { diff --git a/unit/util/interval/shift.cpp b/unit/util/interval/shift.cpp index 06c412a1331..7247eddf2dc 100644 --- a/unit/util/interval/shift.cpp +++ b/unit/util/interval/shift.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -37,7 +37,7 @@ SCENARIO("shift interval domain", { THEN("Something else") { - REQUIRE(interval_exprt(v[4], v[8]).left_shift(interval_exprt(v[1])) == interval_exprt(v[8], v[16])); + REQUIRE(constant_interval_exprt(v[4], v[8]).left_shift(constant_interval_exprt(v[1])) == constant_interval_exprt(v[8], v[16])); } } } diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index c12d4b65820..f07caf09ea9 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -3,9 +3,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ -#include +#include -#include +#include #include #include #include @@ -35,10 +35,10 @@ SCENARIO("subtract interval domain", WHEN("The result is positive [6,8]-[2,4]") { - interval_exprt left(values[6], values[8]); - interval_exprt right(values[2], values[4]); + constant_interval_exprt left(values[6], values[8]); + constant_interval_exprt right(values[2], values[4]); - interval_exprt result = left.minus(right); + constant_interval_exprt result = left.minus(right); THEN("Domain is consistent") { @@ -57,10 +57,10 @@ SCENARIO("subtract interval domain", WHEN("One contains infinite [2,4]-[6,INF]") { - interval_exprt left(values[2], values[4]); - interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(values[2], values[4]); + constant_interval_exprt right(values[6], max_exprt(type)); - interval_exprt result = left.minus(right); + constant_interval_exprt result = left.minus(right); THEN("Domain is consistent") { @@ -81,10 +81,10 @@ SCENARIO("subtract interval domain", WHEN("Both contain infinite [2,INF]-[6,INF]") { - interval_exprt left(values[2], max_exprt(type)); - interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(values[2], max_exprt(type)); + constant_interval_exprt right(values[6], max_exprt(type)); - interval_exprt result = left.minus(right); + constant_interval_exprt result = left.minus(right); THEN("Domain is consistent") { From 59422190ab148333bf3737d443915c1873b1443b Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 11:18:18 +0100 Subject: [PATCH 03/35] (INT) Remove unnecessary construction of dstring Also fix wrong placing of parentheses in output --- src/util/interval_template.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/util/interval_template.h b/src/util/interval_template.h index a8d4dc01867..43349080529 100644 --- a/src/util/interval_template.h +++ b/src/util/interval_template.h @@ -231,21 +231,21 @@ std::ostream &operator << (std::ostream &out, const interval_templatet &i) { if(i.lower_set) { - out << dstringt("["); + out << "["; out << i.lower; } else - out << dstringt(")-INF"); + out << "(-INF"; - out << dstringt(","); + out << ","; if(i.upper_set) { out << i.upper; - out << dstringt("]"); + out << "]"; } else - out << dstringt("+INF("); + out << "+INF)"; return out; } From b7a71230d266c41d9de36e823feee4075fe92625 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 12:23:56 +0100 Subject: [PATCH 04/35] (INT) Rename interval is_constant to is_single_value_interval As it stands in conflicted with the method from exprt --- src/util/interval.cpp | 40 ++++++++++++++++++++-------------------- src/util/interval.h | 4 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index ea35a08e2e1..51f858c4faa 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -43,7 +43,7 @@ const constant_interval_exprt constant_interval_exprt::unary_plus() const const constant_interval_exprt constant_interval_exprt::unary_minus() const { - if(is_constant()) + if(is_single_value_interval()) { handle_constants(unary_minus_exprt()); } @@ -74,7 +74,7 @@ const constant_interval_exprt constant_interval_exprt::unary_minus() const const constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, plus_exprt()); } @@ -107,7 +107,7 @@ const constant_interval_exprt constant_interval_exprt::plus(const constant_inter const constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, minus_exprt()); } @@ -118,7 +118,7 @@ const constant_interval_exprt constant_interval_exprt::minus(const constant_inte const constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, mult_exprt()); } @@ -130,7 +130,7 @@ const constant_interval_exprt constant_interval_exprt::multiply(const constant_i const constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, div_exprt()); } @@ -149,7 +149,7 @@ const constant_interval_exprt constant_interval_exprt::modulo(const constant_int { // SEE https://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, mod_exprt()); } @@ -269,7 +269,7 @@ const tvt constant_interval_exprt::logical_not() const const constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, shl_exprt()); } @@ -287,7 +287,7 @@ const constant_interval_exprt constant_interval_exprt::left_shift(const constant // Arithmetic const constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, ashr_exprt()); } @@ -304,7 +304,7 @@ const constant_interval_exprt constant_interval_exprt::right_shift(const constan const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, bitxor_exprt()); } @@ -314,7 +314,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constan const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, bitor_exprt()); } @@ -324,7 +324,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant const constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt& o) const { - if(o.is_constant() && is_constant()) + if(o.is_single_value_interval() && is_single_value_interval()) { handle_constants(o, bitand_exprt()); } @@ -334,7 +334,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_and(const constan const constant_interval_exprt constant_interval_exprt::bitwise_not() const { - if(is_constant()) + if(is_single_value_interval()) { handle_constants(bitnot_exprt()); } @@ -345,7 +345,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_not() const tvt constant_interval_exprt::less_than(const constant_interval_exprt &o) const { // [get_lower, get_upper] < [o.get_lower(), o.get_upper()] - if(is_constant() && o.is_constant()) + if(is_single_value_interval() && o.is_single_value_interval()) { return tvt(less_than(get_lower(), o.get_lower())); } @@ -370,7 +370,7 @@ tvt constant_interval_exprt::greater_than(const constant_interval_exprt& o) cons tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt& o) const { - if(is_constant() && o.is_constant()) + if(is_single_value_interval() && o.is_single_value_interval()) { return tvt(less_than_or_equal(get_lower(), o.get_lower())); } @@ -396,7 +396,7 @@ tvt constant_interval_exprt::greater_than_or_equal(const constant_interval_exprt tvt constant_interval_exprt::equal(const constant_interval_exprt& o) const { - if(is_constant() && o.is_constant()) + if(is_single_value_interval() && o.is_single_value_interval()) { return tvt(equal(get_lower(), o.get_lower())); } @@ -946,7 +946,7 @@ exprt constant_interval_exprt::generate_shift_expression(const exprt& a, const e const constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const { - if(is_constant()) + if(is_single_value_interval()) { expr.type()=type(); expr.copy_to_operands(get_lower()); @@ -959,7 +959,7 @@ const constant_interval_exprt constant_interval_exprt::handle_constants(exprt ex const constant_interval_exprt constant_interval_exprt::handle_constants(const constant_interval_exprt &o, exprt expr) const { - if(is_constant() && o.is_constant()) + if(is_single_value_interval() && o.is_single_value_interval()) { expr.type()=type(); expr.copy_to_operands(get_lower(), o.get_lower()); @@ -1724,9 +1724,9 @@ bool constant_interval_exprt::is_empty(const constant_interval_exprt &a) return a.is_empty(); } -bool constant_interval_exprt::is_constant(const constant_interval_exprt &a) +bool constant_interval_exprt::is_single_value_interval(const constant_interval_exprt &a) { - return a.is_constant(); + return a.is_single_value_interval(); } bool constant_interval_exprt::is_top(const constant_interval_exprt &a) @@ -1782,7 +1782,7 @@ bool constant_interval_exprt::is_empty() const return true; } -bool constant_interval_exprt::is_constant() const +bool constant_interval_exprt::is_single_value_interval() const { return !is_extreme(get_lower()) && !is_extreme(get_upper()) && equal(get_lower(), get_upper()); } diff --git a/src/util/interval.h b/src/util/interval.h index 8668f1ff213..75d87b8539c 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -152,7 +152,7 @@ class constant_interval_exprt : public binary_exprt const constant_interval_exprt decrement() const; bool is_empty() const; - bool is_constant() const; + bool is_single_value_interval() const; /** END SET OF ARITHMETIC OPERATORS */ // tvt contains(constant_interval_exprt &o) const; @@ -237,7 +237,7 @@ class constant_interval_exprt : public binary_exprt static const constant_interval_exprt decrement(const constant_interval_exprt &a); static bool is_empty(const constant_interval_exprt &a); - static bool is_constant(const constant_interval_exprt &a); + static bool is_single_value_interval(const constant_interval_exprt &a); static bool is_top(const constant_interval_exprt &a); static bool is_bottom(const constant_interval_exprt &a); From 848b97647dbe1b892ad4ee6856d469bec218df75 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 12:39:02 +0100 Subject: [PATCH 05/35] (INT) Rename is_true and is_false in interval expressions So they don't conflict with the exprt methods --- src/util/interval.cpp | 24 ++++++++++++------------ src/util/interval.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 51f858c4faa..501d7ff3ac0 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -208,13 +208,13 @@ const constant_interval_exprt constant_interval_exprt::modulo(const constant_int } -const tvt constant_interval_exprt::is_true() const +const tvt constant_interval_exprt::is_definitely_true() const { // tvt not - return !is_false(); + return !is_definitely_false(); } -const tvt constant_interval_exprt::is_false() const +const tvt constant_interval_exprt::is_definitely_false() const { if(equal(constant_interval_exprt(zero())).is_true()) { @@ -232,33 +232,33 @@ const tvt constant_interval_exprt::is_false() const const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& o) const { - tvt a = is_true(); - tvt b = o.is_true(); + tvt a = is_definitely_true(); + tvt b = o.is_definitely_true(); return (a || b); } const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& o) const { - return (is_true() && o.is_true()); + return (is_definitely_true() && o.is_definitely_true()); } const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& o) const { return ( - (is_true() && !o.is_true()) || - (!is_true() && o.is_true()) + (is_definitely_true() && !o.is_definitely_true()) || + (!is_definitely_true() && o.is_definitely_true()) ); } const tvt constant_interval_exprt::logical_not() const { - if(is_true().is_true()) + if(is_definitely_true().is_true()) { return tvt(false); } - if(is_false().is_true()) + if(is_definitely_false().is_true()) { return tvt(true); } @@ -1850,12 +1850,12 @@ const constant_interval_exprt tv_to_interval(const constant_interval_exprt &inte const tvt constant_interval_exprt::is_true(const constant_interval_exprt& a) { - return a.is_true(); + return a.is_definitely_true(); } const tvt constant_interval_exprt::is_false(const constant_interval_exprt& a) { - return a.is_false(); + return a.is_definitely_false(); } const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& a, const constant_interval_exprt& b) diff --git a/src/util/interval.h b/src/util/interval.h index 75d87b8539c..d28b2bd4e6c 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -112,8 +112,8 @@ class constant_interval_exprt : public binary_exprt const constant_interval_exprt unary_minus() const; /* Logical */ - const tvt is_true() const; - const tvt is_false() const; + const tvt is_definitely_true() const; + const tvt is_definitely_false() const; const tvt logical_and(const constant_interval_exprt& o) const; const tvt logical_or(const constant_interval_exprt &o) const; From ff3dd1f2d7d7dc02e13daa79ac002f5e670ae947 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 12:40:42 +0100 Subject: [PATCH 06/35] (INT) Make eval take an identifier instead of an exprt --- src/util/interval.cpp | 85 +++++++++++++++++++++---------------------- src/util/interval.h | 4 +- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 501d7ff3ac0..e10ece02090 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -783,10 +783,8 @@ exprt constant_interval_exprt::generate_modulo_expression(const exprt& a, const return simplified_expr(operation); } -const constant_interval_exprt constant_interval_exprt::eval(const exprt& expr) +const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) { - const irep_idt &id = expr.id(); - if(id == ID_unary_plus) { return unary_plus(); @@ -808,85 +806,84 @@ const constant_interval_exprt constant_interval_exprt::eval(const exprt& expr) return top(); } -const constant_interval_exprt constant_interval_exprt::eval(const exprt& expr, const constant_interval_exprt& o) +const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &binary_operator, + const constant_interval_exprt &other) { - const irep_idt &id = expr.id(); - - if(id == ID_plus) + if(binary_operator == ID_plus) { - return plus(o); + return plus(other); } - if(id == ID_minus) + if(binary_operator == ID_minus) { - return unary_minus(o); + return unary_minus(other); } - if(id == ID_mult) + if(binary_operator == ID_mult) { - return multiply(o); + return multiply(other); } - if(id == ID_div) + if(binary_operator == ID_div) { - return divide(o); + return divide(other); } - if(id == ID_mod) + if(binary_operator == ID_mod) { - return modulo(o); + return modulo(other); } - if(id == ID_shl) + if(binary_operator == ID_shl) { - return left_shift(o); + return left_shift(other); } - if(id == ID_ashr) + if(binary_operator == ID_ashr) { - return right_shift(o); + return right_shift(other); } - if(id == ID_bitor) + if(binary_operator == ID_bitor) { - return bitwise_or(o); + return bitwise_or(other); } - if(id == ID_bitand) + if(binary_operator == ID_bitand) { - return bitwise_and(o); + return bitwise_and(other); } - if(id == ID_bitxor) + if(binary_operator == ID_bitxor) { - return bitwise_xor(o); + return bitwise_xor(other); } - if(id == ID_lt) + if(binary_operator == ID_lt) { - return tv_to_interval(less_than(o)); + return tv_to_interval(less_than(other)); } - if(id == ID_le) + if(binary_operator == ID_le) { - return tv_to_interval(less_than_or_equal(o)); + return tv_to_interval(less_than_or_equal(other)); } - if(id == ID_gt) + if(binary_operator == ID_gt) { - return tv_to_interval(greater_than(o)); + return tv_to_interval(greater_than(other)); } - if(id == ID_ge) + if(binary_operator == ID_ge) { - return tv_to_interval(greater_than_or_equal(o)); + return tv_to_interval(greater_than_or_equal(other)); } - if(id == ID_equal) + if(binary_operator == ID_equal) { - return tv_to_interval(equal(o)); + return tv_to_interval(equal(other)); } - if(id == ID_notequal) + if(binary_operator == ID_notequal) { - return tv_to_interval(not_equal(o)); + return tv_to_interval(not_equal(other)); } - if(id == ID_and) + if(binary_operator == ID_and) { - return tv_to_interval(logical_and(o)); + return tv_to_interval(logical_and(other)); } - if(id == ID_or) + if(binary_operator == ID_or) { - return tv_to_interval(logical_or(o)); + return tv_to_interval(logical_or(other)); } - if(id == ID_xor) + if(binary_operator == ID_xor) { - return tv_to_interval(logical_xor(o)); + return tv_to_interval(logical_xor(other)); } return top(); diff --git a/src/util/interval.h b/src/util/interval.h index d28b2bd4e6c..4be3044d3b4 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -104,8 +104,8 @@ class constant_interval_exprt : public binary_exprt const constant_interval_exprt handle_constants(exprt expr) const; const constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; - const constant_interval_exprt eval(const exprt &expr); - const constant_interval_exprt eval(const exprt &expr, const constant_interval_exprt &o); + const constant_interval_exprt eval(const irep_idt &unary_operator); + const constant_interval_exprt eval(const irep_idt &binary_operator, const constant_interval_exprt &o); /* Unary arithmetic */ const constant_interval_exprt unary_plus() const; From fe65713da81fcf495986fb65747b0772ea8e9bfb Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 12:42:46 +0100 Subject: [PATCH 07/35] (INT) Make constructors take constant references instead of values Also, mark them as explicit where appropriate and add some documentation --- src/util/interval.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/util/interval.h b/src/util/interval.h index 4be3044d3b4..5c34ad091f8 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -21,12 +21,7 @@ #include #include -/* - * - * Upper set = Specific max (otherwise INF) - * Lower set = Specific min (otherwise INF) - */ - +/// +∞ upper bound for intervals class max_exprt:public exprt { public: @@ -41,6 +36,7 @@ class max_exprt:public exprt } }; +/// -∞ upper bound for intervals class min_exprt:public exprt { public: @@ -56,14 +52,19 @@ class min_exprt:public exprt }; - +/// Represents an interval of values. +/// Bounds should be constant expressions +/// or min_exprt for the lower bound +/// or max_exprt for the upper bound +/// Also, lower bound should always be <= upper bound class constant_interval_exprt : public binary_exprt { public: - constant_interval_exprt(exprt lower, exprt upper, typet type) + constant_interval_exprt(const exprt &lower, const exprt &upper, typet type) : binary_exprt(lower, ID_constant_interval, upper, type) { - PRECONDITION(lower.type() == upper.type() && type == lower.type()); + PRECONDITION(type == upper.type()); + PRECONDITION(type == lower.type()); } constant_interval_exprt(): @@ -73,12 +74,12 @@ class constant_interval_exprt : public binary_exprt } explicit constant_interval_exprt(const exprt &x): - constant_interval_exprt(x, x, x.type()) + constant_interval_exprt(x, x, x.type()) { } - constant_interval_exprt(const typet type): + explicit constant_interval_exprt(const typet &type): constant_interval_exprt(min_exprt(type), max_exprt(type), type) { } From bff9516221b58f5d603eb4e5a0d173cc94379af0 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 12:45:46 +0100 Subject: [PATCH 08/35] (INT) Apply clang-format --- src/util/interval.cpp | 14 +++++++------- src/util/interval.h | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index e10ece02090..28bdfed0f0e 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -207,7 +207,6 @@ const constant_interval_exprt constant_interval_exprt::modulo(const constant_int return constant_interval_exprt(lower, upper); } - const tvt constant_interval_exprt::is_definitely_true() const { // tvt not @@ -246,9 +245,8 @@ const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& o) const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& o) const { return ( - (is_definitely_true() && !o.is_definitely_true()) || - (!is_definitely_true() && o.is_definitely_true()) - ); + (is_definitely_true() && !o.is_definitely_true()) || + (!is_definitely_true() && o.is_definitely_true())); } const tvt constant_interval_exprt::logical_not() const @@ -806,8 +804,9 @@ const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) return top(); } -const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &binary_operator, - const constant_interval_exprt &other) +const constant_interval_exprt constant_interval_exprt::eval( + const irep_idt &binary_operator, + const constant_interval_exprt &other) { if(binary_operator == ID_plus) { @@ -1721,7 +1720,8 @@ bool constant_interval_exprt::is_empty(const constant_interval_exprt &a) return a.is_empty(); } -bool constant_interval_exprt::is_single_value_interval(const constant_interval_exprt &a) +bool constant_interval_exprt::is_single_value_interval( + const constant_interval_exprt &a) { return a.is_single_value_interval(); } diff --git a/src/util/interval.h b/src/util/interval.h index 5c34ad091f8..2521da82c01 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -51,7 +51,6 @@ class min_exprt:public exprt } }; - /// Represents an interval of values. /// Bounds should be constant expressions /// or min_exprt for the lower bound @@ -73,14 +72,14 @@ class constant_interval_exprt : public binary_exprt } - explicit constant_interval_exprt(const exprt &x): - constant_interval_exprt(x, x, x.type()) + explicit constant_interval_exprt(const exprt &x) + : constant_interval_exprt(x, x, x.type()) { } - explicit constant_interval_exprt(const typet &type): - constant_interval_exprt(min_exprt(type), max_exprt(type), type) + explicit constant_interval_exprt(const typet &type) + : constant_interval_exprt(min_exprt(type), max_exprt(type), type) { } @@ -106,7 +105,8 @@ class constant_interval_exprt : public binary_exprt const constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; const constant_interval_exprt eval(const irep_idt &unary_operator); - const constant_interval_exprt eval(const irep_idt &binary_operator, const constant_interval_exprt &o); + const constant_interval_exprt + eval(const irep_idt &binary_operator, const constant_interval_exprt &o); /* Unary arithmetic */ const constant_interval_exprt unary_plus() const; From 0ed412ff4fad0bfae6e486d661126f93d92a3842 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 14:07:45 +0100 Subject: [PATCH 09/35] (INT) Remove unnecessary constant specifier from value returning functions --- src/util/interval.cpp | 124 +++++++++++++++++++++++------------------- src/util/interval.h | 115 +++++++++++++++++++-------------------- 2 files changed, 123 insertions(+), 116 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 28bdfed0f0e..8d96a72ea82 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -36,12 +36,12 @@ const exprt& constant_interval_exprt::get_upper() const //make clean -s && make -j 7 CXX="/usr/local/bin/ccache g++" -s && ./unit_tests -const constant_interval_exprt constant_interval_exprt::unary_plus() const +constant_interval_exprt constant_interval_exprt::unary_plus() const { return *this; } -const constant_interval_exprt constant_interval_exprt::unary_minus() const +constant_interval_exprt constant_interval_exprt::unary_minus() const { if(is_single_value_interval()) { @@ -72,7 +72,7 @@ const constant_interval_exprt constant_interval_exprt::unary_minus() const return constant_interval_exprt(lower, upper); } -const constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -105,7 +105,7 @@ const constant_interval_exprt constant_interval_exprt::plus(const constant_inter return simplified_interval(lower, upper); } -const constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -116,7 +116,7 @@ const constant_interval_exprt constant_interval_exprt::minus(const constant_inte return plus(o.unary_minus().swap()); } -const constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -128,7 +128,7 @@ const constant_interval_exprt constant_interval_exprt::multiply(const constant_i return get_extremes(*this, o, operation); } -const constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -145,7 +145,7 @@ const constant_interval_exprt constant_interval_exprt::divide(const constant_int return get_extremes(*this, o, operation); } -const constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &o) const { // SEE https://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers @@ -207,13 +207,13 @@ const constant_interval_exprt constant_interval_exprt::modulo(const constant_int return constant_interval_exprt(lower, upper); } -const tvt constant_interval_exprt::is_definitely_true() const +tvt constant_interval_exprt::is_definitely_true() const { // tvt not return !is_definitely_false(); } -const tvt constant_interval_exprt::is_definitely_false() const +tvt constant_interval_exprt::is_definitely_false() const { if(equal(constant_interval_exprt(zero())).is_true()) { @@ -229,7 +229,7 @@ const tvt constant_interval_exprt::is_definitely_false() const return tvt(false); } -const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& o) const +tvt constant_interval_exprt::logical_or(const constant_interval_exprt &o) const { tvt a = is_definitely_true(); tvt b = o.is_definitely_true(); @@ -237,19 +237,19 @@ const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& o) return (a || b); } -const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& o) const +tvt constant_interval_exprt::logical_and(const constant_interval_exprt &o) const { return (is_definitely_true() && o.is_definitely_true()); } -const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& o) const +tvt constant_interval_exprt::logical_xor(const constant_interval_exprt &o) const { return ( (is_definitely_true() && !o.is_definitely_true()) || (!is_definitely_true() && o.is_definitely_true())); } -const tvt constant_interval_exprt::logical_not() const +tvt constant_interval_exprt::logical_not() const { if(is_definitely_true().is_true()) { @@ -265,7 +265,7 @@ const tvt constant_interval_exprt::logical_not() const } -const constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -283,7 +283,7 @@ const constant_interval_exprt constant_interval_exprt::left_shift(const constant } // Arithmetic -const constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -300,7 +300,7 @@ const constant_interval_exprt constant_interval_exprt::right_shift(const constan return get_extremes(*this, o, operation); } -const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -310,7 +310,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constan return top(); } -const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -320,7 +320,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant return top(); } -const constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt& o) const +constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -330,7 +330,7 @@ const constant_interval_exprt constant_interval_exprt::bitwise_and(const constan return top(); } -const constant_interval_exprt constant_interval_exprt::bitwise_not() const +constant_interval_exprt constant_interval_exprt::bitwise_not() const { if(is_single_value_interval()) { @@ -418,21 +418,21 @@ tvt constant_interval_exprt::not_equal(const constant_interval_exprt& o) const return !equal(o); } -const constant_interval_exprt constant_interval_exprt::increment() const +constant_interval_exprt constant_interval_exprt::increment() const { return plus(constant_interval_exprt(from_integer(mp_integer(1), type()))); } -const constant_interval_exprt constant_interval_exprt::decrement() const +constant_interval_exprt constant_interval_exprt::decrement() const { return minus(constant_interval_exprt(from_integer(mp_integer(1), type()))); } -const constant_interval_exprt constant_interval_exprt::get_extremes( - const constant_interval_exprt &a, - const constant_interval_exprt &b, - const exprt operation) +constant_interval_exprt constant_interval_exprt::get_extremes( + const constant_interval_exprt &a, + const constant_interval_exprt &b, + const exprt operation) { constant_interval_exprt result; @@ -781,7 +781,7 @@ exprt constant_interval_exprt::generate_modulo_expression(const exprt& a, const return simplified_expr(operation); } -const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) +constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) { if(id == ID_unary_plus) { @@ -804,7 +804,7 @@ const constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) return top(); } -const constant_interval_exprt constant_interval_exprt::eval( +constant_interval_exprt constant_interval_exprt::eval( const irep_idt &binary_operator, const constant_interval_exprt &other) { @@ -888,7 +888,7 @@ const constant_interval_exprt constant_interval_exprt::eval( return top(); } -const constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) const +constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) const { if(tv.is_true()) { @@ -940,7 +940,7 @@ exprt constant_interval_exprt::generate_shift_expression(const exprt& a, const e return simplified_expr(operation); } -const constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const +constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const { if(is_single_value_interval()) { @@ -953,7 +953,7 @@ const constant_interval_exprt constant_interval_exprt::handle_constants(exprt ex return top(); } -const constant_interval_exprt constant_interval_exprt::handle_constants(const constant_interval_exprt &o, exprt expr) const +constant_interval_exprt constant_interval_exprt::handle_constants(const constant_interval_exprt &o, exprt expr) const { if(is_single_value_interval() && o.is_single_value_interval()) { @@ -986,7 +986,7 @@ exprt constant_interval_exprt::get_max(std::vector &values) } /* we don't simplify in the constructor otherwise */ -const constant_interval_exprt constant_interval_exprt::simplified_interval(exprt &l, exprt &r) +constant_interval_exprt constant_interval_exprt::simplified_interval(exprt &l, exprt &r) { return constant_interval_exprt(simplified_expr(l), simplified_expr(r)); } @@ -1045,27 +1045,27 @@ bool constant_interval_exprt::is_bottom() const return is_min(get_upper()) || is_max(get_lower()); } -const constant_interval_exprt constant_interval_exprt::top(const typet &type) +constant_interval_exprt constant_interval_exprt::top(const typet &type) { return constant_interval_exprt(type); } -const constant_interval_exprt constant_interval_exprt::bottom(const typet &type) +constant_interval_exprt constant_interval_exprt::bottom(const typet &type) { return constant_interval_exprt(max_exprt(type), min_exprt(type)); } -const constant_interval_exprt constant_interval_exprt::top() const +constant_interval_exprt constant_interval_exprt::top() const { return constant_interval_exprt(type()); } -const constant_interval_exprt constant_interval_exprt::bottom() const +constant_interval_exprt constant_interval_exprt::bottom() const { return bottom(type()); } -const constant_interval_exprt constant_interval_exprt::swap(constant_interval_exprt &i) +constant_interval_exprt constant_interval_exprt::swap(constant_interval_exprt &i) { return constant_interval_exprt(i.get_upper(), i.get_lower()); } @@ -1606,71 +1606,81 @@ const constant_interval_exprt operator>>(const constant_interval_exprt &lhs, con return lhs.right_shift(rhs); } -const constant_interval_exprt constant_interval_exprt::unary_plus(const constant_interval_exprt &a) +constant_interval_exprt constant_interval_exprt::unary_plus(const constant_interval_exprt &a) { return a.unary_plus(); } -const constant_interval_exprt constant_interval_exprt::unary_minus(const constant_interval_exprt &a) +constant_interval_exprt constant_interval_exprt::unary_minus(const constant_interval_exprt &a) { return a.unary_minus(); } /* Binary */ -const constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.plus(b); } -const constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.minus(b); } -const constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.multiply(b); } -const constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.divide(b); } -const constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.modulo(b); } /* Binary shifts */ -const constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.left_shift(b); } -const constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.right_shift(b); } /* Unary bitwise */ -const constant_interval_exprt constant_interval_exprt::bitwise_not(const constant_interval_exprt &a) +constant_interval_exprt constant_interval_exprt::bitwise_not(const constant_interval_exprt &a) { return a.bitwise_not(); } /* Binary bitwise */ -const constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_xor(b); } -const constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_or(b); } -const constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_and(b); } @@ -1705,12 +1715,12 @@ tvt constant_interval_exprt::not_equal(const constant_interval_exprt &a, const c return a.equal(b); } -const constant_interval_exprt constant_interval_exprt::increment(const constant_interval_exprt &a) +constant_interval_exprt constant_interval_exprt::increment(const constant_interval_exprt &a) { return a.increment(); } -const constant_interval_exprt constant_interval_exprt::decrement(const constant_interval_exprt &a) +constant_interval_exprt constant_interval_exprt::decrement(const constant_interval_exprt &a) { return a.decrement(); } @@ -1845,32 +1855,32 @@ const constant_interval_exprt tv_to_interval(const constant_interval_exprt &inte return interval.tv_to_interval(tv); } -const tvt constant_interval_exprt::is_true(const constant_interval_exprt& a) +tvt constant_interval_exprt::is_true(const constant_interval_exprt &a) { return a.is_definitely_true(); } -const tvt constant_interval_exprt::is_false(const constant_interval_exprt& a) +tvt constant_interval_exprt::is_false(const constant_interval_exprt &a) { return a.is_definitely_false(); } -const tvt constant_interval_exprt::logical_and(const constant_interval_exprt& a, const constant_interval_exprt& b) +tvt constant_interval_exprt::logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b) { return a.logical_and(b); } -const tvt constant_interval_exprt::logical_or(const constant_interval_exprt& a, const constant_interval_exprt& b) +tvt constant_interval_exprt::logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b) { return a.logical_or(b); } -const tvt constant_interval_exprt::logical_xor(const constant_interval_exprt& a, const constant_interval_exprt& b) +tvt constant_interval_exprt::logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b) { return a.logical_xor(b); } -const tvt constant_interval_exprt::logical_not(const constant_interval_exprt& a) +tvt constant_interval_exprt::logical_not(const constant_interval_exprt &a) { return a.logical_not(); } diff --git a/src/util/interval.h b/src/util/interval.h index 2521da82c01..2ad8aed57c0 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -101,46 +101,46 @@ class constant_interval_exprt : public binary_exprt const exprt &get_upper() const; /** SET OF ARITHMETIC OPERATORS */ - const constant_interval_exprt handle_constants(exprt expr) const; - const constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; + constant_interval_exprt handle_constants(exprt expr) const; + constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; - const constant_interval_exprt eval(const irep_idt &unary_operator); - const constant_interval_exprt + constant_interval_exprt eval(const irep_idt &unary_operator); + constant_interval_exprt eval(const irep_idt &binary_operator, const constant_interval_exprt &o); /* Unary arithmetic */ - const constant_interval_exprt unary_plus() const; - const constant_interval_exprt unary_minus() const; + constant_interval_exprt unary_plus() const; + constant_interval_exprt unary_minus() const; /* Logical */ - const tvt is_definitely_true() const; - const tvt is_definitely_false() const; + tvt is_definitely_true() const; + tvt is_definitely_false() const; - const tvt logical_and(const constant_interval_exprt& o) const; - const tvt logical_or(const constant_interval_exprt &o) const; - const tvt logical_xor(const constant_interval_exprt &o) const; - const tvt logical_not() const; + tvt logical_and(const constant_interval_exprt &o) const; + tvt logical_or(const constant_interval_exprt &o) const; + tvt logical_xor(const constant_interval_exprt &o) const; + tvt logical_not() const; - const constant_interval_exprt tv_to_interval(const tvt &tv) const; + constant_interval_exprt tv_to_interval(const tvt &tv) const; /* Binary */ - const constant_interval_exprt plus(const constant_interval_exprt &o) const; - const constant_interval_exprt minus(const constant_interval_exprt &o) const; - const constant_interval_exprt multiply(const constant_interval_exprt &o) const; - const constant_interval_exprt divide(const constant_interval_exprt &o) const; - const constant_interval_exprt modulo(const constant_interval_exprt &o) const; + constant_interval_exprt plus(const constant_interval_exprt &o) const; + constant_interval_exprt minus(const constant_interval_exprt &o) const; + constant_interval_exprt multiply(const constant_interval_exprt &o) const; + constant_interval_exprt divide(const constant_interval_exprt &o) const; + constant_interval_exprt modulo(const constant_interval_exprt &o) const; /* Binary shifts */ - const constant_interval_exprt left_shift(const constant_interval_exprt &o) const; - const constant_interval_exprt right_shift(const constant_interval_exprt &o) const; + constant_interval_exprt left_shift(const constant_interval_exprt &o) const; + constant_interval_exprt right_shift(const constant_interval_exprt &o) const; /* Unary bitwise */ - const constant_interval_exprt bitwise_not() const; + constant_interval_exprt bitwise_not() const; /* Binary bitwise */ - const constant_interval_exprt bitwise_xor(const constant_interval_exprt &o) const; - const constant_interval_exprt bitwise_or(const constant_interval_exprt &o) const; - const constant_interval_exprt bitwise_and(const constant_interval_exprt &o) const; + constant_interval_exprt bitwise_xor(const constant_interval_exprt &o) const; + constant_interval_exprt bitwise_or(const constant_interval_exprt &o) const; + constant_interval_exprt bitwise_and(const constant_interval_exprt &o) const; tvt less_than(const constant_interval_exprt &o) const; tvt greater_than(const constant_interval_exprt &o) const; @@ -149,8 +149,8 @@ class constant_interval_exprt : public binary_exprt tvt equal(const constant_interval_exprt &o) const; tvt not_equal(const constant_interval_exprt &o) const; - const constant_interval_exprt increment() const; - const constant_interval_exprt decrement() const; + constant_interval_exprt increment() const; + constant_interval_exprt decrement() const; bool is_empty() const; bool is_single_value_interval() const; @@ -195,37 +195,37 @@ class constant_interval_exprt : public binary_exprt /* Now static equivalents! */ - static const tvt is_true(const constant_interval_exprt &a); - static const tvt is_false(const constant_interval_exprt &a); + static tvt is_true(const constant_interval_exprt &a); + static tvt is_false(const constant_interval_exprt &a); - static const tvt logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const tvt logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const tvt logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const tvt logical_not(const constant_interval_exprt &a); + static tvt logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt logical_not(const constant_interval_exprt &a); - static const constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv); + static constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv); - static const constant_interval_exprt unary_plus(const constant_interval_exprt &a); - static const constant_interval_exprt unary_minus(const constant_interval_exprt &a); + static constant_interval_exprt unary_plus(const constant_interval_exprt &a); + static constant_interval_exprt unary_minus(const constant_interval_exprt &a); /* Binary */ - static const constant_interval_exprt plus(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt minus(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt multiply(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt divide(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt modulo(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt plus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt minus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt multiply(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt divide(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt modulo(const constant_interval_exprt &a, const constant_interval_exprt &b); /* Binary shifts */ - static const constant_interval_exprt left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); /* Unary bitwise */ - static const constant_interval_exprt bitwise_not(const constant_interval_exprt &a); + static constant_interval_exprt bitwise_not(const constant_interval_exprt &a); /* Binary bitwise */ - static const constant_interval_exprt bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b); static tvt less_than(const constant_interval_exprt &a, const constant_interval_exprt &b); static tvt greater_than(const constant_interval_exprt &a, const constant_interval_exprt &b); @@ -234,8 +234,8 @@ class constant_interval_exprt : public binary_exprt static tvt equal(const constant_interval_exprt &a, const constant_interval_exprt &b); static tvt not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); - static const constant_interval_exprt increment(const constant_interval_exprt &a); - static const constant_interval_exprt decrement(const constant_interval_exprt &a); + static constant_interval_exprt increment(const constant_interval_exprt &a); + static constant_interval_exprt decrement(const constant_interval_exprt &a); static bool is_empty(const constant_interval_exprt &a); static bool is_single_value_interval(const constant_interval_exprt &a); @@ -247,16 +247,12 @@ class constant_interval_exprt : public binary_exprt static bool is_max(const constant_interval_exprt &a); /* End static equivalents */ - - - - bool is_top() const; bool is_bottom() const; - static const constant_interval_exprt top(const typet &type); - static const constant_interval_exprt bottom(const typet &type); - const constant_interval_exprt top() const; - const constant_interval_exprt bottom() const; + static constant_interval_exprt top(const typet &type); + static constant_interval_exprt bottom(const typet &type); + constant_interval_exprt top() const; + constant_interval_exprt bottom() const; bool is_min() const; bool is_max() const; @@ -273,7 +269,8 @@ class constant_interval_exprt : public binary_exprt static constant_exprt zero(const constant_interval_exprt &interval); /* Private? */ - static const constant_interval_exprt get_extremes(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs, const exprt operation); + static constant_interval_exprt get_extremes(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs, + const exprt operation); static exprt get_extreme(std::vector values, bool min = true); static exprt get_max(const exprt &a, const exprt &b); static exprt get_min(const exprt &a, const exprt &b); @@ -281,12 +278,12 @@ class constant_interval_exprt : public binary_exprt static exprt get_max(std::vector &values); /* we don't simplify in the constructor otherwise */ - static const constant_interval_exprt simplified_interval(exprt &l, exprt &r); + static constant_interval_exprt simplified_interval(exprt &l, exprt &r); static exprt simplified_expr(exprt expr); /* Swap lower and upper! */ const constant_interval_exprt swap() const; - static const constant_interval_exprt swap(constant_interval_exprt &i); + static constant_interval_exprt swap(constant_interval_exprt &i); /* Helpers */ /* Four common params: self, static: type, expr, interval */ From 6abdda2a05477fbead8a8a4d835b9a3bf0ec05c8 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 15:33:17 +0100 Subject: [PATCH 10/35] (INT) Use irep_idt in place of exprt when exprt isn't needed Also replace some asserts with INVARIANT, PRECONDITION or UNREACHABLE --- src/util/interval.cpp | 225 +++++++++++++++++++++--------------------- src/util/interval.h | 12 +-- 2 files changed, 116 insertions(+), 121 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 8d96a72ea82..b21864703fc 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -123,9 +123,7 @@ constant_interval_exprt constant_interval_exprt::multiply(const constant_interva handle_constants(o, mult_exprt()); } - mult_exprt operation; - operation.type()=type(); - return get_extremes(*this, o, operation); + return get_extremes(*this, o, ID_mult); } constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &o) const @@ -141,8 +139,7 @@ constant_interval_exprt constant_interval_exprt::divide(const constant_interval_ return top(); } - div_exprt operation; - return get_extremes(*this, o, operation); + return get_extremes(*this, o, ID_div); } constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &o) const @@ -277,9 +274,7 @@ constant_interval_exprt constant_interval_exprt::left_shift(const constant_inter return top(); } - shl_exprt operation; - operation.type()=type(); - return get_extremes(*this, o, operation); + return get_extremes(*this, o, ID_shl); } // Arithmetic @@ -295,9 +290,7 @@ constant_interval_exprt constant_interval_exprt::right_shift(const constant_inte return top(); } - ashr_exprt operation; - operation.type()=type(); - return get_extremes(*this, o, operation); + return get_extremes(*this, o, ID_ashr); } constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &o) const @@ -432,7 +425,7 @@ constant_interval_exprt constant_interval_exprt::decrement() const constant_interval_exprt constant_interval_exprt::get_extremes( const constant_interval_exprt &a, const constant_interval_exprt &b, - const exprt operation) + const irep_idt &operation) { constant_interval_exprt result; @@ -535,61 +528,60 @@ exprt constant_interval_exprt::get_extreme(std::vector values, bool min_v -exprt constant_interval_exprt::generate_expression(const exprt& a, const exprt& b, const exprt &operation) +exprt constant_interval_exprt::generate_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation) { - if(operation.id() == ID_mult) + if(operation == ID_mult) { - return generate_multiply_expression(a, b, operation); + return generate_multiply_expression(lhs, rhs); } - if(operation.id() == ID_div) + if(operation == ID_div) { - return generate_division_expression(a, b, operation); + return generate_division_expression(lhs, rhs); } - if(operation.id() == ID_mod) + if(operation == ID_mod) { - return generate_modulo_expression(a, b, operation); + return generate_modulo_expression(lhs, rhs); } - if(operation.id() == ID_shl || operation.id() == ID_ashr) + if(operation == ID_shl || operation == ID_ashr) { - return generate_shift_expression(a, b, operation); + return generate_shift_expression(lhs, rhs, operation); } - assert(0 && "Not yet implemented!"); + UNREACHABLE; } -exprt constant_interval_exprt::generate_multiply_expression(const exprt& a, const exprt& b, - exprt operation) +exprt constant_interval_exprt::generate_multiply_expression(const exprt &lower, const exprt &upper) { - assert(operation.id() == ID_mult); - assert(operation.type().is_not_nil() && is_numeric(operation.type())); + PRECONDITION(lower.type().is_not_nil() && is_numeric(lower.type())); - if(is_max(a)) + if(is_max(lower)) { - return generate_multiply_expression_max(b); + return generate_multiply_expression_max(upper); } - if(is_max(b)) + if(is_max(upper)) { - return generate_multiply_expression_max(a); + return generate_multiply_expression_max(lower); } - if(is_min(a)) + if(is_min(lower)) { - return generate_multiply_expression_min(a, b); + return generate_multiply_expression_min(lower, upper); } - if(is_min(b)) + if(is_min(upper)) { - return generate_multiply_expression_min(b, a); + return generate_multiply_expression_min(upper, lower); } - assert(!is_extreme(a) && !is_extreme(b)); + INVARIANT(!is_extreme(lower) && !is_extreme(upper), + "We ruled out extreme cases beforehand"); - operation.copy_to_operands(a, b); - return simplified_expr(operation); + auto result = mult_exprt(lower, upper); + return simplified_expr(result); } @@ -608,14 +600,15 @@ exprt constant_interval_exprt::generate_multiply_expression_max(const exprt &exp } else { - assert(!is_positive(expr) && "Min value cannot be >0."); - assert(is_zero(expr) && "Non-negative MIN must be zero."); + INVARIANT(!is_positive(expr), "Min value cannot be >0."); + INVARIANT(is_zero(expr), "Non-negative MIN must be zero."); return expr; } } - assert(!is_extreme(expr)); + INVARIANT(!is_extreme(expr), + "We ruled out extreme cases"); if(is_negative (expr)) { @@ -632,13 +625,13 @@ exprt constant_interval_exprt::generate_multiply_expression_max(const exprt &exp return max_exprt(expr); } - assert(0 && "Unreachable."); + UNREACHABLE; return nil_exprt(); } exprt constant_interval_exprt::generate_multiply_expression_min(const exprt &min, const exprt &other) { - assert(is_min(min)); + PRECONDITION(is_min(min)); if(is_max(other)) { @@ -648,8 +641,8 @@ exprt constant_interval_exprt::generate_multiply_expression_min(const exprt &min } else { - assert(!is_positive(min) && "Min value cannot be >0."); - assert(is_zero(min) && "Non-negative MIN must be zero."); + INVARIANT(!is_positive(min), "Min value cannot be >0."); + INVARIANT(is_zero(min), "Non-negative MIN must be zero."); return min; } @@ -657,128 +650,130 @@ exprt constant_interval_exprt::generate_multiply_expression_min(const exprt &min if(is_min(other)) { - assert(!is_positive(min) && !is_positive(other) && "Min value cannot be >0."); - assert(is_negative(other) || is_zero(other)); + INVARIANT(!is_positive(min) && !is_positive(other), "Min value cannot be >0."); + INVARIANT(is_negative(other) || is_zero(other), + "Other was established to be min value, which must be <= 0"); if(is_negative(min) && is_negative(other)) { return max_exprt(min); } - assert(is_zero(min) || is_zero(other)); + INVARIANT(is_zero(min) || is_zero(other), + "Min value must be <= 0"); return (is_zero(min) ? min : other); } - assert(0 && "Unreachable."); + UNREACHABLE; return nil_exprt(); } -exprt constant_interval_exprt::generate_division_expression(const exprt& a, const exprt& b, - exprt operation) +exprt constant_interval_exprt::generate_division_expression(const exprt &lhs, const exprt &rhs) { - assert(operation.id() == ID_div); - assert(operation.type().is_not_nil() && is_numeric(operation.type())); + PRECONDITION(lhs.type().is_not_nil() && is_numeric(lhs.type())); - assert(!is_zero(b)); + PRECONDITION(!is_zero(rhs)); - if(b.is_one()) + if(rhs.is_one()) { - return a; + return lhs; } - if(is_max(a)) + if(is_max(lhs)) { - if(is_negative(b)) + if(is_negative(rhs)) { - return min_exprt(a); + return min_exprt(lhs); } - return a; + return lhs; } - if(is_min(a)) + if(is_min(lhs)) { - if(is_negative(b)) + if(is_negative(rhs)) { - return max_exprt(a); + return max_exprt(lhs); } - return a; + return lhs; } - assert(!is_extreme(a)); + INVARIANT(!is_extreme(lhs), + "We ruled out extreme cases beforehand"); - if(is_max(b)) + if(is_max(rhs)) { - return zero(b); + return zero(rhs); } - if(is_min(b)) + if(is_min(rhs)) { - assert(is_signed(b)); - return zero(b); + INVARIANT(is_signed(rhs), + "We think this is a signed integer for some reason?"); + return zero(rhs); } - assert(!is_extreme(a) && !is_extreme(b)); + INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + "We ruled out extreme cases beforehand"); - assert(!operation.has_operands()); - operation.copy_to_operands(a, b); - return simplified_expr(operation); + auto div_expr = div_exprt(lhs, rhs); + return simplified_expr(div_expr); } -exprt constant_interval_exprt::generate_modulo_expression(const exprt& a, const exprt& b, - exprt operation) +exprt constant_interval_exprt::generate_modulo_expression(const exprt &lhs, const exprt &rhs) { - assert(operation.id() == ID_mod); - assert(operation.type().is_not_nil() && is_numeric(operation.type())); + PRECONDITION(lhs.type().is_not_nil() && is_numeric(lhs.type())); - assert(!is_zero(b)); + PRECONDITION(!is_zero(rhs)); - if(b.is_one()) + if(rhs.is_one()) { - return a; + return lhs; } - if(is_max(a)) + if(is_max(lhs)) { - if(is_negative(b)) + if(is_negative(rhs)) { - return min_exprt(a); + return min_exprt(lhs); } - return a; + return lhs; } - if(is_min(a)) + if(is_min(lhs)) { - if(is_negative(b)) + if(is_negative(rhs)) { - return max_exprt(a); + return max_exprt(lhs); } - return a; + return lhs; } - assert(!is_extreme(a)); + INVARIANT(!is_extreme(lhs), + "We rule out this case beforehand"); - if(is_max(b)) + if(is_max(rhs)) { - return zero(b); + return zero(rhs); } - if(is_min(b)) + if(is_min(rhs)) { - assert(is_signed(b)); - return zero(b); + INVARIANT(is_signed(rhs), + "We assume this is signed for some reason?"); + return zero(rhs); } - assert(!is_extreme(a) && !is_extreme(b)); + INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + "We ruled out extreme values beforehand"); - assert(!operation.has_operands()); - operation.copy_to_operands(a, b); - return simplified_expr(operation); + auto modulo_expr = mod_exprt(lhs,rhs); + return simplified_expr(modulo_expr); } constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) @@ -903,41 +898,41 @@ constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) c return top(); } -exprt constant_interval_exprt::generate_shift_expression(const exprt& a, const exprt& b, - exprt operation) +exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const exprt &rhs, + const irep_idt &operation) { - assert(operation.id() == ID_shl || operation.id() == ID_ashr); + PRECONDITION(operation == ID_shl || operation == ID_ashr); - if(is_zero(a) || is_zero(b)) + if(is_zero(lhs) || is_zero(rhs)) { // Shifting zero does nothing. // Shifting BY zero also does nothing. - return a; + return lhs; } - // Should be caught at an earlier stage. - assert(!is_negative(b)); + INVARIANT(!is_negative(rhs), + "Should be caught at an earlier stage."); - if(is_max(a)) + if(is_max(lhs)) { - return a; + return lhs; } - if(is_min(a)) + if(is_min(lhs)) { - return a; + return lhs; } - if(is_max(b)) + if(is_max(rhs)) { - return min_exprt(b); + return min_exprt(rhs); } - assert(!is_extreme(a) && !is_extreme(b)); + INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + "We ruled out extreme cases beforehand"); - operation.op0()=a; - operation.op1()=b; - return simplified_expr(operation); + auto shift_expr = shift_exprt(lhs, operation, rhs); + return simplified_expr(shift_expr); } constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const diff --git a/src/util/interval.h b/src/util/interval.h index 2ad8aed57c0..41644393d3e 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -270,7 +270,7 @@ class constant_interval_exprt : public binary_exprt /* Private? */ static constant_interval_exprt get_extremes(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs, - const exprt operation); + const irep_idt &operation); static exprt get_extreme(std::vector values, bool min = true); static exprt get_max(const exprt &a, const exprt &b); static exprt get_min(const exprt &a, const exprt &b); @@ -342,13 +342,13 @@ class constant_interval_exprt : public binary_exprt private: - static exprt generate_expression(const exprt &a, const exprt &b, const exprt &operation); - static exprt generate_multiply_expression(const exprt &a, const exprt &b, exprt operation); + static exprt generate_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation); + static exprt generate_multiply_expression(const exprt &lower, const exprt &upper); static exprt generate_multiply_expression_max(const exprt &expr); static exprt generate_multiply_expression_min(const exprt &min, const exprt &other); - static exprt generate_division_expression(const exprt &a, const exprt &b, exprt operation); - static exprt generate_modulo_expression(const exprt &a, const exprt &b, exprt operation); - static exprt generate_shift_expression(const exprt &a, const exprt &b, exprt operation); + static exprt generate_division_expression(const exprt &lhs, const exprt &rhs); + static exprt generate_modulo_expression(const exprt &lhs, const exprt &rhs); + static exprt generate_shift_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation); }; inline const constant_interval_exprt& to_constant_interval_expr(const exprt& expr) { From 38193e1ea28c855ab70e6a12eb065fec55f488ea Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 16:03:22 +0100 Subject: [PATCH 11/35] (INT) Cleanup to_string and operator<< for intervals Also left some comments for things that need to be cleaned up in the future --- src/util/interval.cpp | 50 +++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index b21864703fc..1b11fdae43a 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1461,57 +1461,61 @@ bool constant_interval_exprt::contains(const constant_interval_exprt& interval) std::string constant_interval_exprt::to_string() const { std::stringstream out; + out << *this; + return out.str(); +} - out << dstringt("["); +std::ostream& operator <<(std::ostream& out, + const constant_interval_exprt& i) +{ + out << "["; - if(!is_min()) + if(!i.is_min()) { - if(is_bitvector(get_lower())) + // FIXME Not everything that's a bitvector is also an integer + if(i.is_bitvector(i.get_lower())) { - out << binary2integer(get_lower().get(ID_value).c_str(), 2); + out << binary2integer(id2string(i.get_lower().get(ID_value)), i.is_signed()); } else { - out << get_lower().get(ID_value); + // TODO handle floating point numbers? + out << i.get_lower().get(ID_value); } } else { - if(is_signed(get_lower())) + if(i.is_signed(i.get_lower())) { - out << dstringt("MIN"); + out << "MIN"; } else { - out << dstringt("0"); + // FIXME Extremely sketchy, the opposite of + // FIXME "signed" isn't "unsigned" but + // FIXME "literally anything else" + out << "0"; } } - out << dstringt(","); + out << ","; - if(!is_max()) + // FIXME See comments on is_min + if(!i.is_max()) { - if(is_bitvector(get_upper())) + if(i.is_bitvector(i.get_upper())) { - out << binary2integer(get_upper().get(ID_value).c_str(), 2); + out << binary2integer(id2string(i.get_upper().get(ID_value)), i.is_signed()); } else { - out << get_upper().get(ID_value); + out << i.get_upper().get(ID_value); } } else - out << dstringt("MAX"); - - out << dstringt("]"); + out << "MAX"; - return out.str(); -} - -std::ostream& operator <<(std::ostream& out, - const constant_interval_exprt& i) -{ - out << i.to_string(); + out << "]"; return out; } From 8f3184281673443178fee8e46aed3cddff9fedc6 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 16:41:18 +0100 Subject: [PATCH 12/35] (INT) Give handle constants a better name --- src/util/interval.cpp | 43 ++++++++++++++++++------------------------- src/util/interval.h | 6 +++--- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 1b11fdae43a..cfab2cbab51 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -45,7 +45,7 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const { if(is_single_value_interval()) { - handle_constants(unary_minus_exprt()); + handle_constant_unary_expression(ID_unary_minus); } exprt lower; @@ -76,7 +76,7 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, plus_exprt()); + handle_constant_binary_expression(o, ID_plus); } exprt lower = min(); @@ -120,7 +120,7 @@ constant_interval_exprt constant_interval_exprt::multiply(const constant_interva { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, mult_exprt()); + handle_constant_binary_expression(o, ID_mult); } return get_extremes(*this, o, ID_mult); @@ -130,7 +130,7 @@ constant_interval_exprt constant_interval_exprt::divide(const constant_interval_ { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, div_exprt()); + handle_constant_binary_expression(o, ID_div); } // If other might be division by zero, set everything to top. @@ -148,7 +148,7 @@ constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_ if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, mod_exprt()); + handle_constant_binary_expression(o, ID_mod); } if(o.is_bottom()) @@ -266,7 +266,7 @@ constant_interval_exprt constant_interval_exprt::left_shift(const constant_inter { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, shl_exprt()); + handle_constant_binary_expression(o, ID_shl); } if(is_negative(o.get_lower())) @@ -282,7 +282,7 @@ constant_interval_exprt constant_interval_exprt::right_shift(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, ashr_exprt()); + handle_constant_binary_expression(o, ID_ashr); } if(is_negative(o.get_lower())) @@ -297,7 +297,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, bitxor_exprt()); + handle_constant_binary_expression(o, ID_bitxor); } return top(); @@ -307,7 +307,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_inter { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, bitor_exprt()); + handle_constant_binary_expression(o, ID_bitor); } return top(); @@ -317,7 +317,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, bitand_exprt()); + handle_constant_binary_expression(o, ID_bitand); } return top(); @@ -327,7 +327,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_not() const { if(is_single_value_interval()) { - handle_constants(bitnot_exprt()); + handle_constant_unary_expression(ID_bitnot); } return top(); @@ -935,29 +935,22 @@ exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const return simplified_expr(shift_expr); } -constant_interval_exprt constant_interval_exprt::handle_constants(exprt expr) const +constant_interval_exprt constant_interval_exprt::handle_constant_unary_expression(const irep_idt &op) const { if(is_single_value_interval()) { - expr.type()=type(); - expr.copy_to_operands(get_lower()); - + auto expr = unary_exprt(op, get_lower()); return constant_interval_exprt(simplified_expr(expr)); } - return top(); } -constant_interval_exprt constant_interval_exprt::handle_constants(const constant_interval_exprt &o, exprt expr) const +constant_interval_exprt constant_interval_exprt::handle_constant_binary_expression(const constant_interval_exprt &other, + const irep_idt &op) const { - if(is_single_value_interval() && o.is_single_value_interval()) - { - expr.type()=type(); - expr.copy_to_operands(get_lower(), o.get_lower()); - return constant_interval_exprt(simplified_expr(expr)); - } - - return top(); + PRECONDITION(is_single_value_interval() && other.is_single_value_interval()); + auto expr = binary_exprt(get_lower(), op, other.get_lower()); + return constant_interval_exprt(simplified_expr(expr)); } exprt constant_interval_exprt::get_max(const exprt &a, const exprt &b) diff --git a/src/util/interval.h b/src/util/interval.h index 41644393d3e..4aab1cb3637 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -101,8 +101,8 @@ class constant_interval_exprt : public binary_exprt const exprt &get_upper() const; /** SET OF ARITHMETIC OPERATORS */ - constant_interval_exprt handle_constants(exprt expr) const; - constant_interval_exprt handle_constants(const constant_interval_exprt &o, exprt expr) const; + constant_interval_exprt handle_constant_unary_expression(const irep_idt &op) const; + constant_interval_exprt handle_constant_binary_expression(const constant_interval_exprt &other, const irep_idt &) const; constant_interval_exprt eval(const irep_idt &unary_operator); constant_interval_exprt @@ -125,7 +125,7 @@ class constant_interval_exprt : public binary_exprt /* Binary */ constant_interval_exprt plus(const constant_interval_exprt &o) const; - constant_interval_exprt minus(const constant_interval_exprt &o) const; + constant_interval_exprt minus(const constant_interval_exprt &other) const; constant_interval_exprt multiply(const constant_interval_exprt &o) const; constant_interval_exprt divide(const constant_interval_exprt &o) const; constant_interval_exprt modulo(const constant_interval_exprt &o) const; From 9e2e1a93077cdef3b312a37f5c64120aae5c858a Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 16 May 2018 16:42:29 +0100 Subject: [PATCH 13/35] (INT) Remove swap function in intervals Also, refactor minus and correct a typo in the comments --- src/util/interval.cpp | 21 ++++++--------------- src/util/interval.h | 3 --- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index cfab2cbab51..37ec6cbbf35 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -105,15 +105,16 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex return simplified_interval(lower, upper); } -constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &o) const +constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &other) const { - if(o.is_single_value_interval() && is_single_value_interval()) + if(other.is_single_value_interval() && is_single_value_interval()) { - handle_constants(o, minus_exprt()); + handle_constant_binary_expression(other, ID_minus); } - // e.g. [t.u - o.l, t.l - o.u] - return plus(o.unary_minus().swap()); + // FIXME This is nonsense if the interval type is unsigned int + // [this.lower - other.upper, this.upper - other.lower] + return plus(other.unary_minus()); } constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &o) const @@ -1053,16 +1054,6 @@ constant_interval_exprt constant_interval_exprt::bottom() const return bottom(type()); } -constant_interval_exprt constant_interval_exprt::swap(constant_interval_exprt &i) -{ - return constant_interval_exprt(i.get_upper(), i.get_lower()); -} - -const constant_interval_exprt constant_interval_exprt::swap() const -{ - return constant_interval_exprt(get_lower(), get_upper()); -} - /* Helpers */ bool constant_interval_exprt::is_int() const diff --git a/src/util/interval.h b/src/util/interval.h index 4aab1cb3637..1e7866d297f 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -281,9 +281,6 @@ class constant_interval_exprt : public binary_exprt static constant_interval_exprt simplified_interval(exprt &l, exprt &r); static exprt simplified_expr(exprt expr); - /* Swap lower and upper! */ - const constant_interval_exprt swap() const; - static constant_interval_exprt swap(constant_interval_exprt &i); /* Helpers */ /* Four common params: self, static: type, expr, interval */ From fa720e9d5d1c4a5c5ed32e089c9b1811f45e1156 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Mon, 21 May 2018 16:22:17 +0100 Subject: [PATCH 14/35] (INT) Add additional unit tests for intervals --- unit/util/interval/subtract.cpp | 55 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index f07caf09ea9..9cbaf65a585 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -89,18 +89,65 @@ SCENARIO("subtract interval domain", THEN("Domain is consistent") { REQUIRE(V(left.get_lower()) == 2); - REQUIRE(left.is_max()); + REQUIRE(left.has_no_upper_bound()); REQUIRE(V(right.get_lower()) == 6); - REQUIRE(right.is_max()); + REQUIRE(right.has_no_upper_bound()); } CAPTURE(result); THEN("The result is [MIN, MAX]") { - REQUIRE(result.is_max()); - REQUIRE(result.is_min()); + REQUIRE(result.has_no_upper_bound()); + REQUIRE(result.has_no_lower_bound()); } } } } + +SCENARIO("Subtracting unsigned integers") +{ + WHEN("Subtracting two constant intervals") { + auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); + auto rhs = constant_interval_exprt(constant_exprt("0011", unsignedbv_typet(32))); + THEN("it should work") { + auto result = lhs.minus(rhs); + REQUIRE(result.is_single_value_interval()); + auto maybe_lower = numeric_cast(result.get_lower()); + REQUIRE(maybe_lower.has_value()); + REQUIRE(maybe_lower.value() == 7); + } + } + + WHEN("Subtracting zero from something") + { + auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); + auto rhs = constant_interval_exprt(constant_exprt("0", unsignedbv_typet(32))); + + THEN("it should not give a completely crazy result") + { + auto result = lhs.minus(rhs); + REQUIRE(result.is_single_value_interval()); + auto maybe_lower = numeric_cast(result.get_lower()); + REQUIRE(maybe_lower.has_value()); + REQUIRE(maybe_lower.value() == 10); + } + } + + WHEN("Subtracting an non-constant interval containing zero") + { + auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); + auto rhs = constant_interval_exprt(constant_exprt("0", unsignedbv_typet(32)), + constant_exprt("1", unsignedbv_typet(32))); + THEN("it should not give a completely crazy result") + { + auto result = lhs.minus(rhs); + auto maybe_lower = numeric_cast(result.get_lower()); + REQUIRE(maybe_lower.has_value()); + REQUIRE(maybe_lower.value() == 9); + auto maybe_upper = numeric_cast(result.get_upper()); + REQUIRE(maybe_upper.has_value()); + REQUIRE(maybe_upper.value() == 10); + } + } +} \ No newline at end of file From dfbe6c8daa103e19b751f65f04568ba0fea2fcb4 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Mon, 21 May 2018 17:09:30 +0100 Subject: [PATCH 15/35] (INT) Various code style fixes in intervals code --- src/util/interval.cpp | 121 ++++++++++++----------------- src/util/interval.h | 16 ++-- unit/util/interval/add.cpp | 12 +-- unit/util/interval/bitwise.cpp | 2 +- unit/util/interval/comparisons.cpp | 2 +- unit/util/interval/get_extreme.cpp | 2 +- unit/util/interval/modulo.cpp | 2 +- unit/util/interval/multiply.cpp | 6 +- unit/util/interval/shift.cpp | 2 +- unit/util/interval/subtract.cpp | 6 +- 10 files changed, 76 insertions(+), 95 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 37ec6cbbf35..1a2ab9d7754 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1,9 +1,10 @@ -/* - * interval.cpp - * - * Created on: 16 Jun 2017 - * Author: dan - */ +/*******************************************************************\ + + Module: intervals + + Author: Daniel Neville (2017), Diffblue Ltd + +\*******************************************************************/ /* * @@ -32,10 +33,6 @@ const exprt& constant_interval_exprt::get_upper() const return op1(); } - - -//make clean -s && make -j 7 CXX="/usr/local/bin/ccache g++" -s && ./unit_tests - constant_interval_exprt constant_interval_exprt::unary_plus() const { return *this; @@ -51,7 +48,7 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const exprt lower; exprt upper; - if(is_max()) + if(has_no_upper_bound()) { lower=min(); } @@ -60,7 +57,7 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const lower = simplified_expr(unary_minus_exprt(get_upper())); } - if(is_min()) + if(has_no_lower_bound()) { upper=max(); } @@ -88,7 +85,8 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex } else { - assert(!is_max(get_upper()) && !is_max(o.get_upper())); + INVARIANT(!is_max(get_upper()) && !is_max(o.get_upper()), + "We just excluded this case"); upper = simplified_expr(plus_exprt(get_upper(), o.get_upper())); } @@ -98,7 +96,8 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex } else { - assert(!is_min(get_lower()) && !is_min(o.get_lower())); + INVARIANT(!is_min(get_lower()) && !is_min(o.get_lower()), + "We just excluded that case"); lower = simplified_expr(plus_exprt(get_lower(), o.get_lower())); } @@ -112,7 +111,6 @@ constant_interval_exprt constant_interval_exprt::minus(const constant_interval_e handle_constant_binary_expression(other, ID_minus); } - // FIXME This is nonsense if the interval type is unsigned int // [this.lower - other.upper, this.upper - other.lower] return plus(other.unary_minus()); } @@ -189,8 +187,8 @@ constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_ // [-5, 5] % [3] if(is_negative(get_lower()) && is_positive(get_upper())) { - assert(contains_zero()); - + INVARIANT(contains_zero(), + "Zero should be between a negative and a positive value"); // This can be done more accurately. lower=get_min(o.get_lower(), get_lower()); upper=get_max(o.get_upper(), get_upper()); @@ -220,7 +218,9 @@ tvt constant_interval_exprt::is_definitely_false() const if(contains(constant_interval_exprt(zero()))) { - assert(is_positive(get_upper()) || is_negative(get_lower())); + INVARIANT(is_positive(get_upper()) || is_negative(get_lower()), + "If an interval contains zero its lower bound can't be positive" + " and its upper bound can't be negative"); return tvt::unknown(); } @@ -524,7 +524,7 @@ exprt constant_interval_exprt::get_extreme(std::vector values, bool min_v return max_exprt(type); } - assert(0); + UNREACHABLE; } @@ -895,7 +895,8 @@ constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) c return constant_interval_exprt(zero()); } - assert(tv.is_unknown()); + INVARIANT(tv.is_unknown(), + "We excluded the other cases"); return top(); } @@ -985,7 +986,7 @@ exprt constant_interval_exprt::simplified_expr(exprt expr) symbol_tablet symbol_table; const namespacet ns(symbol_table); - assert(!contains_extreme(expr)); + PRECONDITION(!contains_extreme(expr)); return simplify_expr(expr, ns); } @@ -994,7 +995,8 @@ exprt constant_interval_exprt::simplified_expr(exprt expr) constant_exprt constant_interval_exprt::zero(const typet& type) { constant_exprt zero = from_integer(mp_integer(0), type); - assert(zero.is_zero()); // NOT is_zero(zero) (inf. recursion + INVARIANT(zero.is_zero(), // NOT is_zero(zero) (inf. recursion) + "The value created from 0 should be zero"); return zero; } @@ -1025,7 +1027,7 @@ max_exprt constant_interval_exprt::max() const bool constant_interval_exprt::is_top() const { - return (is_min() && is_max()); + return (has_no_lower_bound() && has_no_upper_bound()); } bool constant_interval_exprt::is_bottom() const @@ -1189,12 +1191,12 @@ bool constant_interval_exprt::is_extreme(const exprt &expr1, const exprt &expr2) return is_extreme(expr1) || is_extreme(expr2); } -bool constant_interval_exprt::is_max() const +bool constant_interval_exprt::has_no_upper_bound() const { return is_max(get_upper()); } -bool constant_interval_exprt::is_min() const +bool constant_interval_exprt::has_no_lower_bound() const { return is_min(get_lower()); } @@ -1223,7 +1225,8 @@ bool constant_interval_exprt::is_positive(const exprt &expr) return true; } - assert(is_signed(expr)); + INVARIANT(is_signed(expr), + "Not implemented for floats"); // Floats later if(is_min(expr)) @@ -1253,7 +1256,8 @@ bool constant_interval_exprt::is_zero(const exprt &expr) return false; } - assert(!is_max(expr) && !is_min(expr)); + INVARIANT(!is_max(expr) && !is_min(expr), + "We excluded those cases"); if(expr.is_zero()) { @@ -1270,14 +1274,16 @@ bool constant_interval_exprt::is_negative(const exprt &expr) return false; } - assert(is_signed(expr)); + INVARIANT(is_signed(expr), + "We don't support anything other than integers yet"); if(is_min(expr)) { return true; } - assert(!is_extreme(expr)); + INVARIANT(!is_extreme(expr), + "We excluded these cases before"); return less_than(expr, zero(expr)); } @@ -1307,8 +1313,8 @@ bool constant_interval_exprt::equal(const exprt& a, const exprt& b) if(!is_numeric(a) || !is_numeric(b)) { - // Best we can do now is a==b?, but this is covered by the above, so always false. - assert(!(a == b)); + INVARIANT(!(a == b), + "Best we can do now is a==b?, but this is covered by the above, so always false"); return false; } @@ -1332,7 +1338,8 @@ bool constant_interval_exprt::equal(const exprt& a, const exprt& b) return false; } - assert(!is_extreme(l, r)); + INVARIANT(!is_extreme(l, r), + "We've excluded this before"); return simplified_expr(equal_exprt(l, r)).is_true(); } @@ -1353,7 +1360,8 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) return false; } - assert(!is_max(l)); + INVARIANT(!is_max(l), + "We've just excluded this case"); if(is_min(r)) { @@ -1361,15 +1369,16 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) return false; } - assert(!is_max(l) && !is_min(r)); + INVARIANT(!is_max(l) && !is_min(r), + "We've excluded these cases"); if(is_min(l)) { - assert(!is_min(r)); return true; } - assert(!is_max(l) && !is_min(r) && !is_min(l)); + INVARIANT(!is_max(l) && !is_min(r) && !is_min(l), + "These cases should have all been handled before this point"); if(is_max(r)) { @@ -1377,9 +1386,8 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) return !is_max(l); } - assert(!is_max(l) && !is_min(r) && !is_min(l) && !is_max(r)); - - assert(!is_extreme(l, r)); + INVARIANT(!is_extreme(l) && !is_extreme(r), + "We have excluded all of these cases in the code above"); return simplified_expr(binary_relation_exprt(l, ID_lt, r)).is_true(); } @@ -1387,33 +1395,6 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) bool constant_interval_exprt::greater_than(const exprt &a, const exprt &b) { return less_than(b, a); - -// if(!is_numeric(a) || !is_numeric(b)) -// { -// return false; -// } -// -// exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; -// exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; -// -// if(is_max(l) && !is_max(r)) -// { -// return true; -// } -// -// if((is_max(l) && is_max(r)) || (is_min(l) && is_min(r))) -// { -// return false; -// } -// -// if(is_min(l) && is_max(r)) -// { -// return false; -// } -// -// assert(!is_extreme(l) && !is_extreme(r)); -// -// return simplified_expr(binary_relation_exprt(l, ID_gt, r)).is_true(); } bool constant_interval_exprt::less_than_or_equal(const exprt& a, const exprt& b) @@ -1454,7 +1435,7 @@ std::ostream& operator <<(std::ostream& out, { out << "["; - if(!i.is_min()) + if(!i.has_no_lower_bound()) { // FIXME Not everything that's a bitvector is also an integer if(i.is_bitvector(i.get_lower())) @@ -1485,7 +1466,7 @@ std::ostream& operator <<(std::ostream& out, out << ","; // FIXME See comments on is_min - if(!i.is_max()) + if(!i.has_no_upper_bound()) { if(i.is_bitvector(i.get_upper())) { @@ -1731,12 +1712,12 @@ bool constant_interval_exprt::is_bottom(const constant_interval_exprt &a) bool constant_interval_exprt::is_min(const constant_interval_exprt &a) { - return a.is_min(); + return a.has_no_lower_bound(); } bool constant_interval_exprt::is_max(const constant_interval_exprt &a) { - return a.is_max(); + return a.has_no_upper_bound(); } bool constant_interval_exprt::contains_extreme(const exprt expr) diff --git a/src/util/interval.h b/src/util/interval.h index 1e7866d297f..25e1a2a097a 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -1,10 +1,10 @@ -/* - * interval.h - * - * Created on: 16 Jun 2017 - * Author: dan - */ +/*******************************************************************\ + Module: intervals + + Author: Daniel Neville (2017) + +\*******************************************************************/ #ifndef SRC_ANALYSES_INTERVAL_H_ #define SRC_ANALYSES_INTERVAL_H_ @@ -254,8 +254,8 @@ class constant_interval_exprt : public binary_exprt constant_interval_exprt top() const; constant_interval_exprt bottom() const; - bool is_min() const; - bool is_max() const; + bool has_no_lower_bound() const; + bool has_no_upper_bound() const; static bool is_min(const exprt &expr); static bool is_max(const exprt &expr); diff --git a/unit/util/interval/add.cpp b/unit/util/interval/add.cpp index 09b9392333c..d9c9ad23670 100644 --- a/unit/util/interval/add.cpp +++ b/unit/util/interval/add.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include @@ -68,7 +68,7 @@ SCENARIO("add interval domain", REQUIRE(V(left.get_lower()) == 2); REQUIRE(V(left.get_upper()) == 4); REQUIRE(V(right.get_lower()) == 6); - REQUIRE(right.is_max()); + REQUIRE(right.has_no_upper_bound()); } CAPTURE(result); @@ -76,7 +76,7 @@ SCENARIO("add interval domain", THEN("The result is [8, MAX]") { REQUIRE(V(result.get_lower()) == 8); - REQUIRE(result.is_max()); + REQUIRE(result.has_no_upper_bound()); } } @@ -90,9 +90,9 @@ SCENARIO("add interval domain", THEN("Domain is consistent") { REQUIRE(V(left.get_lower()) == 2); - REQUIRE(left.is_max()); + REQUIRE(left.has_no_upper_bound()); REQUIRE(V(right.get_lower()) == 6); - REQUIRE(right.is_max()); + REQUIRE(right.has_no_upper_bound()); } CAPTURE(result); @@ -100,7 +100,7 @@ SCENARIO("add interval domain", THEN("The result is [8, MAX]") { REQUIRE(V(result.get_lower()) == 8); - REQUIRE(result.is_max()); + REQUIRE(result.has_no_upper_bound()); } } } diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp index 41a7f33dc6b..c4838e9f147 100644 --- a/unit/util/interval/bitwise.cpp +++ b/unit/util/interval/bitwise.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include diff --git a/unit/util/interval/comparisons.cpp b/unit/util/interval/comparisons.cpp index 0cf001b78c2..afe4342e242 100644 --- a/unit/util/interval/comparisons.cpp +++ b/unit/util/interval/comparisons.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include diff --git a/unit/util/interval/get_extreme.cpp b/unit/util/interval/get_extreme.cpp index e54698d8990..b2fdb921f11 100644 --- a/unit/util/interval/get_extreme.cpp +++ b/unit/util/interval/get_extreme.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include diff --git a/unit/util/interval/modulo.cpp b/unit/util/interval/modulo.cpp index b74569b69b1..e17ed390e80 100644 --- a/unit/util/interval/modulo.cpp +++ b/unit/util/interval/modulo.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index bdcc50acee6..b1c1b1136bd 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include @@ -144,14 +144,14 @@ SCENARIO("multiply interval domain", CHECK(V(a.get_lower()) == 2); CHECK(V(a.get_upper()) == 5); CHECK(V(b.get_lower()) == 7); - CHECK(b.is_max()); + CHECK(b.has_no_upper_bound()); } THEN("The result is [14, INF]") { CAPTURE(result); - CHECK(result.is_max()); + CHECK(result.has_no_upper_bound()); CHECK(V(result.get_lower()) == 14); } } diff --git a/unit/util/interval/shift.cpp b/unit/util/interval/shift.cpp index 7247eddf2dc..a9238f37ae5 100644 --- a/unit/util/interval/shift.cpp +++ b/unit/util/interval/shift.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index 9cbaf65a585..22832e078ab 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -1,6 +1,6 @@ /*******************************************************************\ Module: Unit tests for variable/sensitivity/abstract_object::merge - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited \*******************************************************************/ #include @@ -67,7 +67,7 @@ SCENARIO("subtract interval domain", REQUIRE(V(left.get_lower()) == 2); REQUIRE(V(left.get_upper()) == 4); REQUIRE(V(right.get_lower()) == 6); - REQUIRE(right.is_max()); + REQUIRE(right.has_no_upper_bound()); } CAPTURE(result); @@ -75,7 +75,7 @@ SCENARIO("subtract interval domain", THEN("The result is [MIN, -2]") { REQUIRE(V(result.get_upper()) == -2); - REQUIRE(result.is_min()); + REQUIRE(result.has_no_lower_bound()); } } From c46f13ca96019151fb3d47ff1562e23995c7ca31 Mon Sep 17 00:00:00 2001 From: Fotis Koutoulakis Date: Wed, 23 May 2018 12:05:31 +0100 Subject: [PATCH 16/35] (INT) Fix eval handling of ID_not case in intervals And also add tests for it. --- src/util/interval.cpp | 30 +++++++++++++++++++++++++++-- src/util/interval.h | 2 ++ unit/util/interval/eval.cpp | 38 +++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 unit/util/interval/eval.cpp diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 1a2ab9d7754..49db714fb14 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -211,6 +211,18 @@ tvt constant_interval_exprt::is_definitely_true() const tvt constant_interval_exprt::is_definitely_false() const { + if(type().id() == ID_bool) + { + if(is_single_value_interval()) + { + return tvt(get_lower() == false_exprt()); + } + else + { + return tvt::unknown(); + } + } + if(equal(constant_interval_exprt(zero())).is_true()) { return tvt(true); @@ -793,8 +805,7 @@ constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) } if(id == ID_not) { - //return logical_not(); - return top(); + return tvt_to_interval(logical_not()); } return top(); @@ -1849,3 +1860,18 @@ tvt constant_interval_exprt::logical_not(const constant_interval_exprt &a) return a.logical_not(); } +constant_interval_exprt constant_interval_exprt::tvt_to_interval(const tvt &val) +{ + if(val.is_true()) + { + return constant_interval_exprt(true_exprt()); + } + else if(val.is_false()) + { + return constant_interval_exprt(false_exprt()); + } + else + { + return constant_interval_exprt(bool_typet()); + } +} diff --git a/src/util/interval.h b/src/util/interval.h index 25e1a2a097a..b6000c9b0bb 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -89,6 +89,8 @@ class constant_interval_exprt : public binary_exprt } + static constant_interval_exprt tvt_to_interval(const tvt &val); + /* Naming scheme * is_[X]? Returns bool / tvt * get_[X]? Returns relevant object diff --git a/unit/util/interval/eval.cpp b/unit/util/interval/eval.cpp new file mode 100644 index 00000000000..c364ac815b7 --- /dev/null +++ b/unit/util/interval/eval.cpp @@ -0,0 +1,38 @@ +/*******************************************************************\ + Module: Unit tests for intervals + Author: DiffBlue Limited +\*******************************************************************/ + +#include + +#include +#include +#include +#include +#include + +SCENARIO("Unary eval on intervals", "[core][analyses][interval][eval]") +{ + WHEN("Negating a boolean interval") + { + constant_interval_exprt true_interval = + constant_interval_exprt(true_exprt()); + constant_interval_exprt false_interval = + constant_interval_exprt(false_exprt()); + constant_interval_exprt bool_top_interval = + constant_interval_exprt(bool_typet()); + + THEN("True interval negated should equal the false interval") + { + REQUIRE(true_interval.eval(ID_not) == false_interval); + } + THEN("False interval negated should equal the true interval") + { + REQUIRE(false_interval.eval(ID_not) == true_interval); + } + THEN("An unknown boolean type should equal top (itself)") + { + REQUIRE(bool_top_interval.eval(ID_not) == bool_top_interval); + } + } +} From 1458656e392648de0cc7499235d999357c413ff1 Mon Sep 17 00:00:00 2001 From: Fotis Koutoulakis Date: Wed, 23 May 2018 14:38:58 +0100 Subject: [PATCH 17/35] (INT) Fix bitwise operators for intervals and add tests for them and eval. --- src/util/interval.cpp | 12 +++---- unit/util/interval/bitwise.cpp | 57 +++++++++++++++++++++++----------- unit/util/interval/eval.cpp | 27 ++++++++++++++++ 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 49db714fb14..dc3428e47f3 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -279,7 +279,7 @@ constant_interval_exprt constant_interval_exprt::left_shift(const constant_inter { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constant_binary_expression(o, ID_shl); + return handle_constant_binary_expression(o, ID_shl); } if(is_negative(o.get_lower())) @@ -295,7 +295,7 @@ constant_interval_exprt constant_interval_exprt::right_shift(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constant_binary_expression(o, ID_ashr); + return handle_constant_binary_expression(o, ID_ashr); } if(is_negative(o.get_lower())) @@ -310,7 +310,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constant_binary_expression(o, ID_bitxor); + return handle_constant_binary_expression(o, ID_bitxor); } return top(); @@ -320,7 +320,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_inter { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constant_binary_expression(o, ID_bitor); + return handle_constant_binary_expression(o, ID_bitor); } return top(); @@ -330,7 +330,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_inte { if(o.is_single_value_interval() && is_single_value_interval()) { - handle_constant_binary_expression(o, ID_bitand); + return handle_constant_binary_expression(o, ID_bitand); } return top(); @@ -340,7 +340,7 @@ constant_interval_exprt constant_interval_exprt::bitwise_not() const { if(is_single_value_interval()) { - handle_constant_unary_expression(ID_bitnot); + return handle_constant_unary_expression(ID_bitnot); } return top(); diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp index c4838e9f147..85b7b3f23e5 100644 --- a/unit/util/interval/bitwise.cpp +++ b/unit/util/interval/bitwise.cpp @@ -11,34 +11,55 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) - - SCENARIO("bitwise interval domain", "[core][analyses][interval][bitwise]") { - GIVEN("Two simple signed intervals") + WHEN("We have two unsigned single value intervals - 5 and 9") { - const typet type=signedbv_typet(32); - symbol_tablet symbol_table; - namespacet ns(symbol_table); + const unsignedbv_typet &unsigned_int = unsignedbv_typet(32); + constant_interval_exprt five = + constant_interval_exprt(from_integer(5, unsigned_int)); + constant_interval_exprt nine = + constant_interval_exprt(from_integer(9, unsigned_int)); - source_locationt source_location; + THEN("Bitwise or should yield bitwise representation of 13") + { + REQUIRE( + five.bitwise_or(nine) == + constant_interval_exprt(from_integer(13, unsigned_int))); + } - std::map values; + THEN("Bitwise and should yield bitwise representation of 1") + { + REQUIRE( + five.bitwise_and(nine) == + constant_interval_exprt(from_integer(1, unsigned_int))); + REQUIRE( + (five & nine) == + constant_interval_exprt(from_integer(1, unsigned_int))); + } + + THEN("Bitwise xor should yield bitwise representation of 12") + { + REQUIRE( + five.bitwise_xor(nine) == + constant_interval_exprt(from_integer(12, unsigned_int))); + } - for(int i = -100; i <= 100; i++) + THEN("Left shift on the 5 should produce 10") { - values[i] = from_integer(mp_integer(i), type); + REQUIRE( + five.left_shift( + constant_interval_exprt(from_integer(1, unsigned_int))) == + constant_interval_exprt(from_integer(10, unsigned_int))); } - WHEN("Something") + THEN("Right shift on the 5 should produce 2") { - THEN("Something else") - { - REQUIRE(true); - } + REQUIRE( + five.right_shift( + constant_interval_exprt(from_integer(1, unsigned_int))) == + constant_interval_exprt(from_integer(2, unsigned_int))); } } -} +} \ No newline at end of file diff --git a/unit/util/interval/eval.cpp b/unit/util/interval/eval.cpp index c364ac815b7..2490c9c19ee 100644 --- a/unit/util/interval/eval.cpp +++ b/unit/util/interval/eval.cpp @@ -35,4 +35,31 @@ SCENARIO("Unary eval on intervals", "[core][analyses][interval][eval]") REQUIRE(bool_top_interval.eval(ID_not) == bool_top_interval); } } + + WHEN("Unary operations to an interval") + { + constant_interval_exprt five = + constant_interval_exprt(from_integer(5, signedbv_typet(32))); + + THEN("When we apply unary addition to it, nothing should happen") + { + REQUIRE(five.eval(ID_unary_plus) == five); + } + + THEN("When we apply unary subtraction to it, it should be negated") + { + auto negated_val = + numeric_cast(five.eval(ID_unary_minus).get_lower()); + REQUIRE(negated_val.has_value()); + REQUIRE(negated_val.value() == -5); + } + + THEN("When we apply bitwise negation to it, is should be bitwise negated") + { + auto bitwise_negated_val = + numeric_cast(five.eval(ID_bitnot).get_lower()); + REQUIRE(bitwise_negated_val.has_value()); + REQUIRE(bitwise_negated_val.value() == (~5)); + } + } } From 6940fe228d572696b9e90407afa2b74f7c26362f Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 11:38:17 +0100 Subject: [PATCH 18/35] (INT) Make eval in constant_interval_exprt const --- src/util/interval.cpp | 4 ++-- src/util/interval.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index dc3428e47f3..8a682cc04a4 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -789,7 +789,7 @@ exprt constant_interval_exprt::generate_modulo_expression(const exprt &lhs, cons return simplified_expr(modulo_expr); } -constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) +constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) const { if(id == ID_unary_plus) { @@ -813,7 +813,7 @@ constant_interval_exprt constant_interval_exprt::eval(const irep_idt &id) constant_interval_exprt constant_interval_exprt::eval( const irep_idt &binary_operator, - const constant_interval_exprt &other) + const constant_interval_exprt &other) const { if(binary_operator == ID_plus) { diff --git a/src/util/interval.h b/src/util/interval.h index b6000c9b0bb..4107b3975f5 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -106,9 +106,9 @@ class constant_interval_exprt : public binary_exprt constant_interval_exprt handle_constant_unary_expression(const irep_idt &op) const; constant_interval_exprt handle_constant_binary_expression(const constant_interval_exprt &other, const irep_idt &) const; - constant_interval_exprt eval(const irep_idt &unary_operator); + constant_interval_exprt eval(const irep_idt &unary_operator) const; constant_interval_exprt - eval(const irep_idt &binary_operator, const constant_interval_exprt &o); + eval(const irep_idt &binary_operator, const constant_interval_exprt &o) const; /* Unary arithmetic */ constant_interval_exprt unary_plus() const; From 9972d79bb5dd2856a9abca625edae6f445d3a37e Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 15:40:10 +0100 Subject: [PATCH 19/35] (INT) Removed unimplemented function from util/interval.h --- src/util/interval.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/util/interval.h b/src/util/interval.h index 4107b3975f5..f5eb01f2b07 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -205,8 +205,6 @@ class constant_interval_exprt : public binary_exprt static tvt logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); static tvt logical_not(const constant_interval_exprt &a); - static constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv); - static constant_interval_exprt unary_plus(const constant_interval_exprt &a); static constant_interval_exprt unary_minus(const constant_interval_exprt &a); From 7235a3050d8798e148efa9b16c8be7ecc694893f Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 16:50:35 +0100 Subject: [PATCH 20/35] (INT) accept false of ID_bool as valid zero value --- src/util/interval.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 8a682cc04a4..65535615c35 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1002,12 +1002,11 @@ exprt constant_interval_exprt::simplified_expr(exprt expr) return simplify_expr(expr, ns); } - constant_exprt constant_interval_exprt::zero(const typet& type) { constant_exprt zero = from_integer(mp_integer(0), type); - INVARIANT(zero.is_zero(), // NOT is_zero(zero) (inf. recursion) - "The value created from 0 should be zero"); + INVARIANT(zero.is_zero() || (type.id() == ID_bool && zero.is_false()), + "The value created from 0 should be zero or false"); return zero; } From 6497477d5e938b5fb94519f179934f937c475dba Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 16:56:06 +0100 Subject: [PATCH 21/35] (INT) Add ID_bool type preconditions to logical interval operations --- src/util/interval.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 65535615c35..c8215a78540 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -241,6 +241,9 @@ tvt constant_interval_exprt::is_definitely_false() const tvt constant_interval_exprt::logical_or(const constant_interval_exprt &o) const { + PRECONDITION(type().id() == ID_bool); + PRECONDITION(o.type().id() == ID_bool); + tvt a = is_definitely_true(); tvt b = o.is_definitely_true(); @@ -249,11 +252,17 @@ tvt constant_interval_exprt::logical_or(const constant_interval_exprt &o) const tvt constant_interval_exprt::logical_and(const constant_interval_exprt &o) const { + PRECONDITION(type().id() == ID_bool); + PRECONDITION(o.type().id() == ID_bool); + return (is_definitely_true() && o.is_definitely_true()); } tvt constant_interval_exprt::logical_xor(const constant_interval_exprt &o) const { + PRECONDITION(type().id() == ID_bool); + PRECONDITION(o.type().id() == ID_bool); + return ( (is_definitely_true() && !o.is_definitely_true()) || (!is_definitely_true() && o.is_definitely_true())); @@ -261,6 +270,8 @@ tvt constant_interval_exprt::logical_xor(const constant_interval_exprt &o) const tvt constant_interval_exprt::logical_not() const { + PRECONDITION(type().id() == ID_bool); + if(is_definitely_true().is_true()) { return tvt(false); From d8c1e02a33d9743335d990121740e91ddf9f00be Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 17:09:53 +0100 Subject: [PATCH 22/35] (INT) use tvt_to_interval instead of tv_to_interval in constant_interval_exprt --- src/util/interval.cpp | 39 +++++++++------------------------------ src/util/interval.h | 2 -- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index c8215a78540..0ff702ae641 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -868,60 +868,44 @@ constant_interval_exprt constant_interval_exprt::eval( } if(binary_operator == ID_lt) { - return tv_to_interval(less_than(other)); + return tvt_to_interval(less_than(other)); } if(binary_operator == ID_le) { - return tv_to_interval(less_than_or_equal(other)); + return tvt_to_interval(less_than_or_equal(other)); } if(binary_operator == ID_gt) { - return tv_to_interval(greater_than(other)); + return tvt_to_interval(greater_than(other)); } if(binary_operator == ID_ge) { - return tv_to_interval(greater_than_or_equal(other)); + return tvt_to_interval(greater_than_or_equal(other)); } if(binary_operator == ID_equal) { - return tv_to_interval(equal(other)); + return tvt_to_interval(equal(other)); } if(binary_operator == ID_notequal) { - return tv_to_interval(not_equal(other)); + return tvt_to_interval(not_equal(other)); } if(binary_operator == ID_and) { - return tv_to_interval(logical_and(other)); + return tvt_to_interval(logical_and(other)); } if(binary_operator == ID_or) { - return tv_to_interval(logical_or(other)); + return tvt_to_interval(logical_or(other)); } if(binary_operator == ID_xor) { - return tv_to_interval(logical_xor(other)); + return tvt_to_interval(logical_xor(other)); } return top(); } -constant_interval_exprt constant_interval_exprt::tv_to_interval(const tvt &tv) const -{ - if(tv.is_true()) - { - return constant_interval_exprt(from_integer(1, type())); - } - if(tv.is_false()) - { - return constant_interval_exprt(zero()); - } - - INVARIANT(tv.is_unknown(), - "We excluded the other cases"); - return top(); -} - exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation) { @@ -1835,11 +1819,6 @@ bool constant_interval_exprt::is_negative() const return is_negative(get_lower()) && is_negative(get_upper()); } -const constant_interval_exprt tv_to_interval(const constant_interval_exprt &interval, const tvt &tv) -{ - return interval.tv_to_interval(tv); -} - tvt constant_interval_exprt::is_true(const constant_interval_exprt &a) { return a.is_definitely_true(); diff --git a/src/util/interval.h b/src/util/interval.h index f5eb01f2b07..8423c63b5c1 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -123,8 +123,6 @@ class constant_interval_exprt : public binary_exprt tvt logical_xor(const constant_interval_exprt &o) const; tvt logical_not() const; - constant_interval_exprt tv_to_interval(const tvt &tv) const; - /* Binary */ constant_interval_exprt plus(const constant_interval_exprt &o) const; constant_interval_exprt minus(const constant_interval_exprt &other) const; From 19dbd4cf4be38f1c4462dd10419cd93e0c468976 Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 29 May 2018 17:28:22 +0100 Subject: [PATCH 23/35] (INT) Handle typecasts in constant_interval_exprt --- src/util/interval.cpp | 11 +++++++++++ src/util/interval.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 0ff702ae641..cb670e45282 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1585,6 +1585,17 @@ constant_interval_exprt constant_interval_exprt::unary_minus(const constant_inte return a.unary_minus(); } +constant_interval_exprt constant_interval_exprt::typecast(const typet &type) const +{ + exprt lower = get_lower(); + lower.type() = type; + + exprt upper = get_upper(); + upper.type() = type; + + return constant_interval_exprt(lower, upper, type); +} + /* Binary */ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &a, const constant_interval_exprt &b) diff --git a/src/util/interval.h b/src/util/interval.h index 8423c63b5c1..8106e0cc09a 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -114,6 +114,8 @@ class constant_interval_exprt : public binary_exprt constant_interval_exprt unary_plus() const; constant_interval_exprt unary_minus() const; + constant_interval_exprt typecast(const typet &type) const; + /* Logical */ tvt is_definitely_true() const; tvt is_definitely_false() const; From 3ac8c901edc5a1f352f437754eaa526f1937a072 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 8 Dec 2019 11:30:05 +0000 Subject: [PATCH 24/35] (INT) Typecast from ID_bool to integer types --- src/util/interval.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index cb670e45282..1fbe902c4c9 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1127,7 +1127,7 @@ bool constant_interval_exprt::is_float(const constant_interval_exprt &interval) bool constant_interval_exprt::is_bitvector(const typet &t) { return t.id() == ID_bv || t.id() == ID_signedbv || t.id() == ID_unsignedbv - || t.id() == ID_pointer || t.id() == ID_bool; + || t.id() == ID_c_bool; } bool constant_interval_exprt::is_signed(const typet &t) @@ -1137,8 +1137,7 @@ bool constant_interval_exprt::is_signed(const typet &t) bool constant_interval_exprt::is_unsigned(const typet &t) { - return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_pointer - || t.id() == ID_bool; + return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_c_bool; } bool constant_interval_exprt::is_signed(const constant_interval_exprt &interval) @@ -1587,13 +1586,28 @@ constant_interval_exprt constant_interval_exprt::unary_minus(const constant_inte constant_interval_exprt constant_interval_exprt::typecast(const typet &type) const { - exprt lower = get_lower(); - lower.type() = type; + if(this->type().id() == ID_bool && is_int(type)) + { + unsigned lower_num = !has_no_lower_bound() && get_lower().is_true(); + unsigned upper_num = has_no_upper_bound() || get_upper().is_true(); + + INVARIANT(lower_num <= upper_num, ""); + + constant_exprt lower = from_integer(lower_num, type); + constant_exprt upper = from_integer(upper_num, type); + + return constant_interval_exprt(lower, upper, type); + } + else + { + exprt lower = get_lower(); + lower.type() = type; - exprt upper = get_upper(); - upper.type() = type; + exprt upper = get_upper(); + upper.type() = type; - return constant_interval_exprt(lower, upper, type); + return constant_interval_exprt(lower, upper, type); + } } /* Binary */ From 90ffba14d5c622e04ceb7ca82a6de2c7824faafd Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 8 Dec 2019 11:31:01 +0000 Subject: [PATCH 25/35] (INT) Addressing review comments --- src/util/interval.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 1fbe902c4c9..1f2fe95e68b 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1588,15 +1588,15 @@ constant_interval_exprt constant_interval_exprt::typecast(const typet &type) con { if(this->type().id() == ID_bool && is_int(type)) { - unsigned lower_num = !has_no_lower_bound() && get_lower().is_true(); - unsigned upper_num = has_no_upper_bound() || get_upper().is_true(); + bool lower = !has_no_lower_bound() && get_lower().is_true(); + bool upper = has_no_upper_bound() || get_upper().is_true(); - INVARIANT(lower_num <= upper_num, ""); + INVARIANT(!lower || upper, ""); - constant_exprt lower = from_integer(lower_num, type); - constant_exprt upper = from_integer(upper_num, type); + constant_exprt lower_num = from_integer(lower, type); + constant_exprt upper_num = from_integer(upper, type); - return constant_interval_exprt(lower, upper, type); + return constant_interval_exprt(lower_num, upper_num, type); } else { From 47424c0f62c62a45792d4490a40becfeeb26323b Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Wed, 30 May 2018 16:47:17 +0100 Subject: [PATCH 26/35] (INT) Add well-formedness checks for constant_interval_exprt --- src/util/interval.h | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/util/interval.h b/src/util/interval.h index 8106e0cc09a..03a6d934c97 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -62,12 +62,11 @@ class constant_interval_exprt : public binary_exprt constant_interval_exprt(const exprt &lower, const exprt &upper, typet type) : binary_exprt(lower, ID_constant_interval, upper, type) { - PRECONDITION(type == upper.type()); - PRECONDITION(type == lower.type()); + PRECONDITION(is_well_formed()); } - constant_interval_exprt(): - constant_interval_exprt(min_exprt(nil_typet()), max_exprt(nil_typet()), nil_typet()) + constant_interval_exprt() + : constant_interval_exprt(min_exprt(nil_typet()), max_exprt(nil_typet()), nil_typet()) { } @@ -89,6 +88,43 @@ class constant_interval_exprt : public binary_exprt } + bool is_well_formed() const + { + bool b = true; + + const typet &type = this->type(); + const exprt &lower = get_lower(); + const exprt &upper = get_upper(); + + b &= is_numeric() || type.id() == ID_bool || type.is_nil(); + + b &= type == lower.type(); + b &= type == upper.type(); + + b &= is_valid_bound(lower); + b &= is_valid_bound(upper); + + b &= !is_numeric() || less_than_or_equal(lower, upper); + + return b; + } + + bool is_valid_bound(const exprt &expr) const + { + const irep_idt &id = expr.id(); + + bool b = true; + + b &= id == ID_constant || id == ID_min || id == ID_max; + + if(type().id() == ID_bool && id == ID_constant) + { + b &= expr == true_exprt() || expr == false_exprt(); + } + + return b; + } + static constant_interval_exprt tvt_to_interval(const tvt &val); /* Naming scheme From bdc2b088830b0d0d5f4d411d9d4ff81266ed70bb Mon Sep 17 00:00:00 2001 From: Petr Bauch Date: Thu, 13 Sep 2018 15:06:16 +0100 Subject: [PATCH 27/35] (INT) Extend interval multiplication for extremes --- src/util/interval.cpp | 185 +++++++++++++------------------- src/util/interval.h | 21 +++- unit/util/interval/multiply.cpp | 4 +- 3 files changed, 92 insertions(+), 118 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 1f2fe95e68b..a5db3c97f4d 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -455,15 +455,10 @@ constant_interval_exprt constant_interval_exprt::get_extremes( std::vector results; - results.push_back( - generate_expression(a.get_lower(), b.get_lower(), operation)); - results.push_back( - generate_expression(a.get_lower(), b.get_upper(), operation)); - results.push_back( - generate_expression(a.get_upper(), b.get_lower(), operation)); - results.push_back( - generate_expression(a.get_upper(), b.get_upper(), operation)); - + generate_expression(a.get_lower(), b.get_lower(), operation, results); + generate_expression(a.get_lower(), b.get_upper(), operation, results); + generate_expression(a.get_upper(), b.get_lower(), operation, results); + generate_expression(a.get_upper(), b.get_upper(), operation, results); for(auto result: results) { @@ -550,150 +545,118 @@ exprt constant_interval_exprt::get_extreme(std::vector values, bool min_v UNREACHABLE; } - - -exprt constant_interval_exprt::generate_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation) +void constant_interval_exprt::generate_expression( + const exprt &lhs, + const exprt &rhs, + const irep_idt &operation, + std::vector &collection) { if(operation == ID_mult) { - return generate_multiply_expression(lhs, rhs); + append_multiply_expression(lhs, rhs, collection); } - - if(operation == ID_div) + else if(operation == ID_div) { - return generate_division_expression(lhs, rhs); + collection.push_back(generate_division_expression(lhs, rhs)); } - - if(operation == ID_mod) + else if(operation == ID_mod) { - return generate_modulo_expression(lhs, rhs); + collection.push_back(generate_modulo_expression(lhs, rhs)); } - - if(operation == ID_shl || operation == ID_ashr) + else if(operation == ID_shl || operation == ID_ashr) { - return generate_shift_expression(lhs, rhs, operation); + collection.push_back(generate_shift_expression(lhs, rhs, operation)); } - - UNREACHABLE; } -exprt constant_interval_exprt::generate_multiply_expression(const exprt &lower, const exprt &upper) +/// Adds all possible values that may arise from multiplication (more than one, +/// in case of past the type boundary results). +/// \param lower lhs of multiplication +/// \param upper rhs of multiplication +/// \param collection vector of possible values +void constant_interval_exprt::append_multiply_expression( + const exprt &lower, + const exprt &upper, + std::vector &collection) { PRECONDITION(lower.type().is_not_nil() && is_numeric(lower.type())); if(is_max(lower)) { - return generate_multiply_expression_max(upper); + append_multiply_expression_max(upper, collection); } - - if(is_max(upper)) + else if(is_max(upper)) { - return generate_multiply_expression_max(lower); + append_multiply_expression_max(lower, collection); } - - if(is_min(lower)) + else if(is_min(lower)) { - return generate_multiply_expression_min(lower, upper); + append_multiply_expression_min(lower, upper, collection); } - - if(is_min(upper)) - { - return generate_multiply_expression_min(upper, lower); - } - - INVARIANT(!is_extreme(lower) && !is_extreme(upper), - "We ruled out extreme cases beforehand"); - - auto result = mult_exprt(lower, upper); - return simplified_expr(result); -} - - -exprt constant_interval_exprt::generate_multiply_expression_max(const exprt &expr) -{ - if(is_max (expr)) + else if(is_min(upper)) { - return max_exprt(expr); + append_multiply_expression_min(upper, lower, collection); } - - if(is_min (expr)) + else { - if(is_negative(expr)) - { - return min_exprt(expr); - } - else - { - INVARIANT(!is_positive(expr), "Min value cannot be >0."); - INVARIANT(is_zero(expr), "Non-negative MIN must be zero."); + INVARIANT( + !is_extreme(lower) && !is_extreme(upper), + "We ruled out extreme cases beforehand"); - return expr; - } + auto result = mult_exprt(lower, upper); + collection.push_back(simplified_expr(result)); } +} - INVARIANT(!is_extreme(expr), - "We ruled out extreme cases"); - - if(is_negative (expr)) +/// Appends interval bounds that could arise from MAX * expr. Accommodates for +/// overflows by over-approximating. +/// \param expr the unknown side of multiplication +/// \param collection vector of collected bounds +void constant_interval_exprt::append_multiply_expression_max( + const exprt &expr, + std::vector &collection) +{ + if(is_min(expr)) { - return min_exprt(expr); + INVARIANT(!is_positive(expr), "Min value cannot be >0."); + INVARIANT( + is_negative(expr) || is_zero(expr), "Non-negative MIN must be zero."); } - if(is_zero (expr)) + if(is_zero(expr)) + collection.push_back(expr); + else { - return expr; + collection.push_back(max_exprt(expr)); + collection.push_back(min_exprt(expr)); } - - if(is_positive (expr)) - { - return max_exprt(expr); - } - - UNREACHABLE; - return nil_exprt(); } -exprt constant_interval_exprt::generate_multiply_expression_min(const exprt &min, const exprt &other) +/// Appends interval bounds that could arise from MIN * other. Accommodates for +/// overflows by over-approximating. +/// \param min the side known to be MIN for a given type +/// \param other the side of unknown value +/// \param collection reference to the vector of collected boundaries +void constant_interval_exprt::append_multiply_expression_min( + const exprt &min, + const exprt &other, + std::vector &collection) { PRECONDITION(is_min(min)); + INVARIANT(!is_positive(min), "Min value cannot be >0."); + INVARIANT(is_negative(min) || is_zero(min), "Non-negative MIN must be zero."); - if(is_max(other)) - { - if(is_negative(min)) - { - return min_exprt(min); - } - else - { - INVARIANT(!is_positive(min), "Min value cannot be >0."); - INVARIANT(is_zero(min), "Non-negative MIN must be zero."); - - return min; - } - } - - if(is_min(other)) + if(is_zero(min)) + collection.push_back(min); + else if(is_zero(other)) + collection.push_back(other); + else { - INVARIANT(!is_positive(min) && !is_positive(other), "Min value cannot be >0."); - INVARIANT(is_negative(other) || is_zero(other), - "Other was established to be min value, which must be <= 0"); - - if(is_negative(min) && is_negative(other)) - { - return max_exprt(min); - } - - INVARIANT(is_zero(min) || is_zero(other), - "Min value must be <= 0"); - return (is_zero(min) ? min : other); + collection.push_back(min_exprt(min)); + collection.push_back(max_exprt(min)); } - - UNREACHABLE; - return nil_exprt(); } - - exprt constant_interval_exprt::generate_division_expression(const exprt &lhs, const exprt &rhs) { PRECONDITION(lhs.type().is_not_nil() && is_numeric(lhs.type())); diff --git a/src/util/interval.h b/src/util/interval.h index 03a6d934c97..4908b113690 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -374,11 +374,22 @@ class constant_interval_exprt : public binary_exprt static exprt abs(const exprt &expr); private: - - static exprt generate_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation); - static exprt generate_multiply_expression(const exprt &lower, const exprt &upper); - static exprt generate_multiply_expression_max(const exprt &expr); - static exprt generate_multiply_expression_min(const exprt &min, const exprt &other); + static void generate_expression( + const exprt &lhs, + const exprt &rhs, + const irep_idt &operation, + std::vector &collection); + static void append_multiply_expression( + const exprt &lower, + const exprt &upper, + std::vector &collection); + static void append_multiply_expression_max( + const exprt &expr, + std::vector &collection); + static void append_multiply_expression_min( + const exprt &min, + const exprt &other, + std::vector &collection); static exprt generate_division_expression(const exprt &lhs, const exprt &rhs); static exprt generate_modulo_expression(const exprt &lhs, const exprt &rhs); static exprt generate_shift_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation); diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index b1c1b1136bd..753ec9525f7 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -147,12 +147,12 @@ SCENARIO("multiply interval domain", CHECK(b.has_no_upper_bound()); } - THEN("The result is [14, INF]") + THEN("The result is [-INF, INF]") { CAPTURE(result); CHECK(result.has_no_upper_bound()); - CHECK(V(result.get_lower()) == 14); + CHECK(result.has_no_lower_bound()); } } } From c42cac7b089f256967284942208a84b775897246 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 8 Dec 2019 11:42:33 +0000 Subject: [PATCH 28/35] (INT) Add support for bit field and enums intervals.cpp --- src/util/interval.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index a5db3c97f4d..e56a68d28bb 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1090,17 +1090,20 @@ bool constant_interval_exprt::is_float(const constant_interval_exprt &interval) bool constant_interval_exprt::is_bitvector(const typet &t) { return t.id() == ID_bv || t.id() == ID_signedbv || t.id() == ID_unsignedbv - || t.id() == ID_c_bool; + || t.id() == ID_c_bool + || (t.id() == ID_c_bit_field && is_bitvector(t.subtype())); } bool constant_interval_exprt::is_signed(const typet &t) { - return t.id() == ID_signedbv; + return t.id() == ID_signedbv + || (t.id() == ID_c_bit_field && is_signed(t.subtype())); } bool constant_interval_exprt::is_unsigned(const typet &t) { - return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_c_bool; + return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_c_bool + || t.id() == ID_c_enum || (t.id() == ID_c_bit_field && is_unsigned(t.subtype())); } bool constant_interval_exprt::is_signed(const constant_interval_exprt &interval) From 6cd795f5d144519bba1e43cc2b6751821ded9951 Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Wed, 18 Jul 2018 15:12:00 +0100 Subject: [PATCH 29/35] (INT) Fix broken interval unit tests --- unit/util/interval/multiply.cpp | 6 +++--- unit/util/interval/subtract.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index 753ec9525f7..25fb0aa371a 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -59,15 +59,15 @@ SCENARIO("multiply interval domain", WHEN("One is entirely negative [-2,-5]*[7,11]") { - constant_interval_exprt a(values[-2], values[-5]); + constant_interval_exprt a(values[-5], values[-2]); constant_interval_exprt b(values[7], values[11]); constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") { - CHECK(V(a.get_lower()) == -2); - CHECK(V(a.get_upper()) == -5); + CHECK(V(a.get_lower()) == -5); + CHECK(V(a.get_upper()) == -2); CHECK(V(b.get_lower()) == 7); CHECK(V(b.get_upper()) == 11); } diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index 22832e078ab..65d778d20a7 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -107,9 +107,13 @@ SCENARIO("subtract interval domain", SCENARIO("Subtracting unsigned integers") { + auto get_value = [](int x) { + return from_integer(x, signedbv_typet(32)); + }; + WHEN("Subtracting two constant intervals") { - auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); - auto rhs = constant_interval_exprt(constant_exprt("0011", unsignedbv_typet(32))); + auto lhs = constant_interval_exprt(get_value(10)); + auto rhs = constant_interval_exprt(get_value(3)); THEN("it should work") { auto result = lhs.minus(rhs); REQUIRE(result.is_single_value_interval()); @@ -121,8 +125,8 @@ SCENARIO("Subtracting unsigned integers") WHEN("Subtracting zero from something") { - auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); - auto rhs = constant_interval_exprt(constant_exprt("0", unsignedbv_typet(32))); + auto lhs = constant_interval_exprt(get_value(10)); + auto rhs = constant_interval_exprt(get_value(0)); THEN("it should not give a completely crazy result") { @@ -136,9 +140,8 @@ SCENARIO("Subtracting unsigned integers") WHEN("Subtracting an non-constant interval containing zero") { - auto lhs = constant_interval_exprt(constant_exprt("1010", unsignedbv_typet(32))); - auto rhs = constant_interval_exprt(constant_exprt("0", unsignedbv_typet(32)), - constant_exprt("1", unsignedbv_typet(32))); + auto lhs = constant_interval_exprt(get_value(10)); + auto rhs = constant_interval_exprt(get_value(0), get_value(1)); THEN("it should not give a completely crazy result") { auto result = lhs.minus(rhs); From efe43280e54942e8e0ac820a3b8f15b9ce839bab Mon Sep 17 00:00:00 2001 From: Hannes Steffenhagen Date: Mon, 23 Jul 2018 16:10:25 +0100 Subject: [PATCH 30/35] (INT) Fix bug with interval typecasts Previously the typecast operator for interval_exprt simply set the type on the bounds; This yielded incorrect results for widening or narrowing casts. This delegates the typecast handling to simplify_expr instead. --- src/util/interval.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index e56a68d28bb..1d0db8fa2e6 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -1566,11 +1566,21 @@ constant_interval_exprt constant_interval_exprt::typecast(const typet &type) con } else { - exprt lower = get_lower(); - lower.type() = type; + auto do_typecast = [&type](exprt e) { + if(e.id() == ID_min || e.id() == ID_max) + { + e.type() = type; + } else { + e = simplified_expr(typecast_exprt(e, type)); + } + return e; + }; + + exprt lower = do_typecast(get_lower()); + POSTCONDITION(lower.id() == get_lower().id()); - exprt upper = get_upper(); - upper.type() = type; + exprt upper = do_typecast(get_upper()); + POSTCONDITION(upper.id() == get_upper().id()); return constant_interval_exprt(lower, upper, type); } From 8d8ed40bffc6173e20dab76692318c2b35d688f2 Mon Sep 17 00:00:00 2001 From: Petr Bauch Date: Mon, 10 Sep 2018 12:37:53 +0100 Subject: [PATCH 31/35] (INT) Assume relation between two int vars (issue #179) --- src/analyses/interval_domain.cpp | 8 +++---- src/util/interval_template.h | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/analyses/interval_domain.cpp b/src/analyses/interval_domain.cpp index b857a74dd8f..06222ec5afa 100644 --- a/src/analyses/interval_domain.cpp +++ b/src/analyses/interval_domain.cpp @@ -329,10 +329,10 @@ void interval_domaint::assume_rec( { integer_intervalt &lhs_i=int_map[lhs_identifier]; integer_intervalt &rhs_i=int_map[rhs_identifier]; - lhs_i.meet(rhs_i); - rhs_i=lhs_i; - if(rhs_i.is_bottom()) - make_bottom(); + if(id == ID_lt && !lhs_i.is_less_than(rhs_i)) + lhs_i.make_less_than(rhs_i); + if(id == ID_le && !lhs_i.is_less_than_eq(rhs_i)) + lhs_i.make_less_than_eq(rhs_i); } else if(is_float(lhs.type()) && is_float(rhs.type())) { diff --git a/src/util/interval_template.h b/src/util/interval_template.h index 43349080529..d002db72424 100644 --- a/src/util/interval_template.h +++ b/src/util/interval_template.h @@ -143,6 +143,47 @@ template class interval_templatet } } + void make_bottom() + { + lower_set = upper_set = true; + upper = T(); + lower = upper + 1; + } + + void make_less_than_eq(interval_templatet &i) + { + if(upper_set && i.upper_set) + upper = std::min(upper, i.upper); + if(lower_set && i.lower_set) + i.lower = std::max(lower, i.lower); + } + + void make_less_than(interval_templatet &i) + { + make_less_than_eq(i); + if(singleton() && i.singleton() && lower == i.lower) + { + make_bottom(); + i.make_bottom(); + } + } + + bool is_less_than_eq(const interval_templatet &i) + { + if(i.lower_set && upper_set && upper <= i.lower) + return true; + else + return false; + } + + bool is_less_than(const interval_templatet &i) + { + if(i.lower_set && upper_set && upper < i.lower) + return true; + else + return false; + } + void approx_union_with(const interval_templatet &i) { if(i.lower_set && lower_set) From 1867091913152e549b973e6ab2928adc683b2d5a Mon Sep 17 00:00:00 2001 From: Chris Ryder Date: Fri, 11 Oct 2019 16:02:45 +0100 Subject: [PATCH 32/35] (INT) Fixup for nil_typet being removed --- src/util/interval.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/interval.h b/src/util/interval.h index 4908b113690..25b946bfc29 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -66,7 +66,7 @@ class constant_interval_exprt : public binary_exprt } constant_interval_exprt() - : constant_interval_exprt(min_exprt(nil_typet()), max_exprt(nil_typet()), nil_typet()) + : constant_interval_exprt(min_exprt(typet()), max_exprt(typet()), typet()) { } From 4f76dbf74d9992afa3d9627bc075a3cbb51c7c17 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 8 Dec 2019 11:06:54 +0000 Subject: [PATCH 33/35] (INT) Fixups post-rebase --- src/util/interval.cpp | 2 - src/util/interval.h | 10 +-- unit/util/interval/add.cpp | 29 +++--- unit/util/interval/bitwise.cpp | 4 +- unit/util/interval/comparisons.cpp | 139 +++++++++++++---------------- unit/util/interval/eval.cpp | 2 +- unit/util/interval/get_extreme.cpp | 37 ++++---- unit/util/interval/modulo.cpp | 35 +++----- unit/util/interval/multiply.cpp | 38 +++----- unit/util/interval/shift.cpp | 19 ++-- unit/util/interval/subtract.cpp | 31 +++---- 11 files changed, 141 insertions(+), 205 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 1d0db8fa2e6..690f5858412 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -451,8 +451,6 @@ constant_interval_exprt constant_interval_exprt::get_extremes( const constant_interval_exprt &b, const irep_idt &operation) { - constant_interval_exprt result; - std::vector results; generate_expression(a.get_lower(), b.get_lower(), operation, results); diff --git a/src/util/interval.h b/src/util/interval.h index 25b946bfc29..f63a88acbc6 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -59,19 +59,19 @@ class min_exprt:public exprt class constant_interval_exprt : public binary_exprt { public: - constant_interval_exprt(const exprt &lower, const exprt &upper, typet type) + constant_interval_exprt(const exprt &lower, const exprt &upper, const typet type) : binary_exprt(lower, ID_constant_interval, upper, type) { PRECONDITION(is_well_formed()); } - constant_interval_exprt() - : constant_interval_exprt(min_exprt(typet()), max_exprt(typet()), typet()) + constant_interval_exprt (const constant_interval_exprt &x) + : constant_interval_exprt(x.get_lower(), x.get_upper(), x.type()) { } - explicit constant_interval_exprt(const exprt &x) + constant_interval_exprt(const exprt &x) : constant_interval_exprt(x, x, x.type()) { @@ -104,7 +104,7 @@ class constant_interval_exprt : public binary_exprt b &= is_valid_bound(lower); b &= is_valid_bound(upper); - b &= !is_numeric() || less_than_or_equal(lower, upper); + b &= !is_numeric() || is_bottom() || less_than_or_equal(lower, upper); return b; } diff --git a/unit/util/interval/add.cpp b/unit/util/interval/add.cpp index d9c9ad23670..a5ff447e365 100644 --- a/unit/util/interval/add.cpp +++ b/unit/util/interval/add.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,8 +11,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("add interval domain", @@ -20,23 +21,13 @@ SCENARIO("add interval domain", { GIVEN("Two simple signed intervals") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - source_locationt source_location; - - std::map values; - - for(int i = -100; i <= 100; i++) - { - values[i] = from_integer(mp_integer(i), type); - } - WHEN("Both are positive [2,4]+[6,8]") { - constant_interval_exprt left(values[2], values[4]); - constant_interval_exprt right(values[6], values[8]); + constant_interval_exprt left(CEV(2), CEV(4)); + constant_interval_exprt right(CEV(6), CEV(8)); constant_interval_exprt result = left.plus(right); @@ -58,8 +49,8 @@ SCENARIO("add interval domain", WHEN("One contains infinite [2,4]+[6,INF]") { - constant_interval_exprt left(values[2], values[4]); - constant_interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(CEV(2), CEV(4)); + constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.plus(right); @@ -82,8 +73,8 @@ SCENARIO("add interval domain", WHEN("Both contain infinite [2,INF]+[6,INF]") { - constant_interval_exprt left(values[2], max_exprt(type)); - constant_interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); + constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.plus(right); diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp index 85b7b3f23e5..3ce24674b69 100644 --- a/unit/util/interval/bitwise.cpp +++ b/unit/util/interval/bitwise.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -62,4 +62,4 @@ SCENARIO("bitwise interval domain", constant_interval_exprt(from_integer(2, unsigned_int))); } } -} \ No newline at end of file +} diff --git a/unit/util/interval/comparisons.cpp b/unit/util/interval/comparisons.cpp index afe4342e242..f59a7dd95ae 100644 --- a/unit/util/interval/comparisons.cpp +++ b/unit/util/interval/comparisons.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,8 +11,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("comparison interval domain", @@ -20,77 +21,65 @@ SCENARIO("comparison interval domain", { GIVEN("Two simple signed intervals") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - const typet t=type; - - source_locationt source_location; - - std::map v; - - for(int i = -100; i <= 100; i++) - { - v[i] = from_integer(mp_integer(i), type); - } - WHEN("<, >, <=, >=, ==, != are tested on expressions") { THEN("Require correctness") { - REQUIRE(constant_interval_exprt::less_than(v[0], v[1])); - REQUIRE(constant_interval_exprt::less_than(v[1], v[2])); - REQUIRE(constant_interval_exprt::less_than(v[1], v[100])); - - REQUIRE(constant_interval_exprt::less_than(v[-10], v[1])); - REQUIRE_FALSE(constant_interval_exprt::less_than(v[-10], v[-100])); - REQUIRE(constant_interval_exprt::less_than(v[-10], v[-5])); - REQUIRE(constant_interval_exprt::less_than(v[-10], max_exprt(t))); - REQUIRE(constant_interval_exprt::less_than(v[10], max_exprt(t))); - REQUIRE(constant_interval_exprt::less_than(v[0], max_exprt(t))); - - REQUIRE_FALSE(constant_interval_exprt::less_than(v[-10], min_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::less_than(v[10], min_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::less_than(v[0], min_exprt(t))); - - REQUIRE_FALSE(constant_interval_exprt::less_than(min_exprt(t), min_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(t), min_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(t), max_exprt(t))); - REQUIRE(constant_interval_exprt::less_than(min_exprt(t), max_exprt(t))); - - REQUIRE(constant_interval_exprt::equal(min_exprt(t), min_exprt(t))); - REQUIRE(constant_interval_exprt::not_equal(max_exprt(t), min_exprt(t))); - REQUIRE(constant_interval_exprt::equal(max_exprt(t), max_exprt(t))); - REQUIRE(constant_interval_exprt::not_equal(min_exprt(t), max_exprt(t))); + REQUIRE(constant_interval_exprt::less_than(CEV(0), CEV(1))); + REQUIRE(constant_interval_exprt::less_than(CEV(1), CEV(2))); + REQUIRE(constant_interval_exprt::less_than(CEV(1), CEV(100))); + + REQUIRE(constant_interval_exprt::less_than(CEV(-10), CEV(1))); + REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(-10), CEV(-100))); + REQUIRE(constant_interval_exprt::less_than(CEV(-10), CEV(-5))); + REQUIRE(constant_interval_exprt::less_than(CEV(-10), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than(CEV(10), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than(CEV(0), max_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(-10), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(10), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(0), min_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::less_than(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + + REQUIRE(constant_interval_exprt::equal(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::not_equal(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::equal(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::not_equal(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); } THEN("") { - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[0], v[1])); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[1], v[2])); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[1], v[100])); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(0), CEV(1))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(1), CEV(2))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(1), CEV(100))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], v[1])); - REQUIRE(constant_interval_exprt::greater_than(v[-10], v[-100])); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], v[-5])); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[-10], max_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[10], max_exprt(t))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(v[0], max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), CEV(1))); + REQUIRE(constant_interval_exprt::greater_than(CEV(-10), CEV(-100))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), CEV(-5))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), max_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(10), max_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(0), max_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than(v[-10], min_exprt(t))); - REQUIRE(constant_interval_exprt::greater_than(v[10], min_exprt(t))); - REQUIRE(constant_interval_exprt::greater_than(v[0], min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(CEV(-10), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than(CEV(10), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than(CEV(0), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(t), min_exprt(t))); - REQUIRE(constant_interval_exprt::greater_than_or_equal(min_exprt(t), min_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than_or_equal(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than(max_exprt(t), min_exprt(t))); - REQUIRE(constant_interval_exprt::greater_than_or_equal(max_exprt(t), min_exprt(t))); + REQUIRE(constant_interval_exprt::greater_than(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than_or_equal(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(max_exprt(t), max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(t), max_exprt(t))); + REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); } } @@ -98,45 +87,45 @@ SCENARIO("comparison interval domain", { THEN("Require correctness") { - CHECK(constant_interval_exprt(v[10], v[20]) < constant_interval_exprt(v[30], v[40])); - REQUIRE_FALSE(constant_interval_exprt(v[10], v[30]) < constant_interval_exprt(v[30], v[40])); - REQUIRE_FALSE(constant_interval_exprt(v[10], v[20]) > constant_interval_exprt(v[30], v[40])); + CHECK(constant_interval_exprt(CEV(10), CEV(20)) < constant_interval_exprt(CEV(30), CEV(40))); + REQUIRE_FALSE(constant_interval_exprt(CEV(10), CEV(30)) < constant_interval_exprt(CEV(30), CEV(40))); + REQUIRE_FALSE(constant_interval_exprt(CEV(10), CEV(20)) > constant_interval_exprt(CEV(30), CEV(40))); } THEN("[10, 29] < [30, 40] == true, [10, 30] < [30, 40] == unknown, [10, 31] < [30, 40] == unknown") { - CHECK(constant_interval_exprt(v[10], v[29]).less_than(constant_interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(constant_interval_exprt(v[10], v[30]).less_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(constant_interval_exprt(v[10], v[31]).less_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(29)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); + CHECK(constant_interval_exprt(CEV(10), CEV(30)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(31)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); - CHECK(constant_interval_exprt(v[30], v[40]).less_than(constant_interval_exprt(v[10], v[29])) == tvt(false)); + CHECK(constant_interval_exprt(CEV(30), CEV(40)).less_than(constant_interval_exprt(CEV(10), CEV(29))) == tvt(false)); } THEN("[10, 29] > [30, 40] == false, [10, 30] > [30, 40] == unknown, [10, 31] > [30, 40] == unknown") { - CHECK(constant_interval_exprt(v[10], v[29]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt(false)); - CHECK(constant_interval_exprt(v[10], v[29]).greater_than(constant_interval_exprt(v[30], v[40])) == - constant_interval_exprt(v[30], v[40]).less_than(constant_interval_exprt(v[10], v[29]))); + CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt(false)); + CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == + constant_interval_exprt(CEV(30), CEV(40)).less_than(constant_interval_exprt(CEV(10), CEV(29)))); - CHECK(constant_interval_exprt(v[10], v[30]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(constant_interval_exprt(v[10], v[31]).greater_than(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(30)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(31)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); } THEN("[10, 29] <= [30, 40] == true, [10, 30] <= [30, 40] == true, [10, 31] <- [30, 40] == unknown") { - CHECK(constant_interval_exprt(v[10], v[29]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(constant_interval_exprt(v[10], v[30]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(true)); - CHECK(constant_interval_exprt(v[10], v[31]).less_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(29)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); + CHECK(constant_interval_exprt(CEV(10), CEV(30)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); + CHECK(constant_interval_exprt(CEV(10), CEV(31)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); } THEN("[10, 29] >= [30, 40] == false, [10, 30] >= [30, 40] == unknown, [10, 31] >= [30, 40] == unknown") { - CHECK(constant_interval_exprt(v[10], v[29]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt(false)); - CHECK(constant_interval_exprt(v[10], v[30]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); - CHECK(constant_interval_exprt(v[10], v[31]).greater_than_or_equal(constant_interval_exprt(v[30], v[40])) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(false)); + CHECK(constant_interval_exprt(CEV(10), CEV(30)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK(constant_interval_exprt(CEV(10), CEV(31)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); } } } diff --git a/unit/util/interval/eval.cpp b/unit/util/interval/eval.cpp index 2490c9c19ee..d39b6894945 100644 --- a/unit/util/interval/eval.cpp +++ b/unit/util/interval/eval.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include diff --git a/unit/util/interval/get_extreme.cpp b/unit/util/interval/get_extreme.cpp index b2fdb921f11..fcb6cec3ab0 100644 --- a/unit/util/interval/get_extreme.cpp +++ b/unit/util/interval/get_extreme.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -12,8 +12,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("get extreme exprt value", @@ -21,25 +22,19 @@ SCENARIO("get extreme exprt value", { GIVEN("A selection of constant_exprts in a std::vector and map") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - std::map values; std::vector ve; for(int i = -100; i <= 100; i++) { - values[i]=from_integer(mp_integer(i), type); - ve.push_back(from_integer(mp_integer(i), type)); -// values[i] = constant_exprt(std::to_string(i), integer_typet());; -// ve.push_back(exprt(constant_exprt(std::to_string(i), integer_typet()))); + ve.push_back(from_integer(mp_integer(i), signedbv_typet(32))); } - WHEN("-20 <= 20 is tested") { - binary_predicate_exprt op1(values[-20], ID_le, values[20]); - bool interval_eval = constant_interval_exprt::less_than_or_equal(values[-20], values[20]); + binary_predicate_exprt op1(CEV(-20), ID_le, CEV(20)); + bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(20)); simplify(op1, ns); THEN("Require it is TRUE") @@ -52,8 +47,8 @@ SCENARIO("get extreme exprt value", WHEN("20 <= -20 is tested") { - binary_predicate_exprt op1(values[20], ID_le, values[-20]); - bool interval_eval = constant_interval_exprt::less_than_or_equal(values[20], values[-20]); + binary_predicate_exprt op1(CEV(20), ID_le, CEV(-20)); + bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(20), CEV(-20)); simplify(op1, ns); THEN("Require it is FALSE") @@ -65,8 +60,8 @@ SCENARIO("get extreme exprt value", WHEN("-20 <= -20 is tested") { - binary_predicate_exprt op1(values[-20], ID_le, values[-20]); - bool interval_eval = constant_interval_exprt::less_than_or_equal(values[-20], values[-20]); + binary_predicate_exprt op1(CEV(-20), ID_le, CEV(-20)); + bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(-20)); simplify(op1, ns); @@ -74,13 +69,13 @@ SCENARIO("get extreme exprt value", { REQUIRE(op1.is_true()); REQUIRE(interval_eval); - REQUIRE(constant_interval_exprt::equal(values[1], values[1])); + REQUIRE(constant_interval_exprt::equal(CEV(1), CEV(1))); } } WHEN("Two are selected and min found [20, -20]") { - std::vector selected = { values[20], values[-20] }; + std::vector selected = { CEV(20), CEV(-20) }; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); @@ -96,7 +91,7 @@ SCENARIO("get extreme exprt value", WHEN("Four are selected and min found [-20, 0, 20, 50]") { - std::vector selected = { values[-20], values[0], values[50], values[20] }; + std::vector selected = { CEV(-20), CEV(0), CEV(50), CEV(20) }; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); @@ -111,7 +106,7 @@ SCENARIO("get extreme exprt value", WHEN("One is selected [-100]") { - std::vector selected = { values[-100] }; + std::vector selected = { CEV(-100) }; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); @@ -125,7 +120,7 @@ SCENARIO("get extreme exprt value", WHEN("Five are selected [20, 30, 15, 0, -100]") { - std::vector selected = { values[20], values[30], values[15], values[0], values[-100] }; + std::vector selected = { CEV(20), CEV(30), CEV(15), CEV(0), CEV(-100) }; exprt min = constant_interval_exprt::get_extreme(selected, true); diff --git a/unit/util/interval/modulo.cpp b/unit/util/interval/modulo.cpp index e17ed390e80..bac8f5226d8 100644 --- a/unit/util/interval/modulo.cpp +++ b/unit/util/interval/modulo.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,8 +11,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("modulo interval domain", @@ -20,38 +21,28 @@ SCENARIO("modulo interval domain", { GIVEN("Two simple signed intervals") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - source_locationt source_location; - - std::map v; - - for(int i = -100; i <= 100; i++) - { - v[i] = from_integer(mp_integer(i), type); - } - WHEN("Positive RHS") { THEN("Ensure result is consistent.") { - REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[5], v[5])) == constant_interval_exprt(v[0], v[4])); - REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[4], v[5])) == constant_interval_exprt(v[0], v[4])); - REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); - REQUIRE(constant_interval_exprt(v[10], v[20]).modulo(constant_interval_exprt(v[-5], v[5])) == constant_interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(5), CEV(5))) == constant_interval_exprt(CEV(0), CEV(4))); + REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(4), CEV(5))) == constant_interval_exprt(CEV(0), CEV(4))); + REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(-5), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(v[-10], v[20]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); - REQUIRE(constant_interval_exprt(v[-20], v[-10]).modulo(constant_interval_exprt(v[0], v[5])) == constant_interval_exprt::top(type)); + REQUIRE(constant_interval_exprt(CEV(-10), CEV(20)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE(constant_interval_exprt(CEV(-20), CEV(-10)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(v[-20], v[-10]).modulo(constant_interval_exprt(v[1], v[1])) == constant_interval_exprt(v[0])); + REQUIRE(constant_interval_exprt(CEV(-20), CEV(-10)).modulo(constant_interval_exprt(CEV(1), CEV(1))) == constant_interval_exprt(CEV(0))); - REQUIRE(constant_interval_exprt(v[30], v[50]).modulo(constant_interval_exprt(v[2], v[2])) == constant_interval_exprt(v[0], v[1])); + REQUIRE(constant_interval_exprt(CEV(30), CEV(50)).modulo(constant_interval_exprt(CEV(2), CEV(2))) == constant_interval_exprt(CEV(0), CEV(1))); // Problems - REQUIRE(constant_interval_exprt(v[30], max_exprt(type)).modulo(constant_interval_exprt(v[2], v[2])) == constant_interval_exprt(v[0], v[1])); + REQUIRE(constant_interval_exprt(CEV(30), max_exprt(signedbv_typet(32))).modulo(constant_interval_exprt(CEV(2), CEV(2))) == constant_interval_exprt(CEV(0), CEV(1))); } } diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index 25fb0aa371a..2839b96dd81 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,32 +11,22 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("multiply interval domain", "[core][analyses][interval][multiply]") { GIVEN("A selection of constant_exprts in a std::vector and map") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - std::map values; - std::vector ve; - - for(int i = -100; i <= 100; i++) - { - values[i] = from_integer(mp_integer(i), type); - ve.push_back(exprt(from_integer(mp_integer(i), type))); - } - - WHEN("Both are positive [2,5]*[7,11]") { - constant_interval_exprt a(values[2], values[5]); - constant_interval_exprt b(values[7], values[11]); + constant_interval_exprt a(CEV(2), CEV(5)); + constant_interval_exprt b(CEV(7), CEV(11)); constant_interval_exprt result = a.multiply(b); @@ -59,8 +49,8 @@ SCENARIO("multiply interval domain", WHEN("One is entirely negative [-2,-5]*[7,11]") { - constant_interval_exprt a(values[-5], values[-2]); - constant_interval_exprt b(values[7], values[11]); + constant_interval_exprt a(CEV(-5), CEV(-2)); + constant_interval_exprt b(CEV(7), CEV(11)); constant_interval_exprt result = a.multiply(b); @@ -84,8 +74,8 @@ SCENARIO("multiply interval domain", WHEN("Range contains and extends from zero [-2,5]*[7,11]") { - constant_interval_exprt a(values[-2], values[5]); - constant_interval_exprt b(values[7], values[11]); + constant_interval_exprt a(CEV(-2), CEV(5)); + constant_interval_exprt b(CEV(7), CEV(11)); constant_interval_exprt result = a.multiply(b); @@ -110,8 +100,8 @@ SCENARIO("multiply interval domain", WHEN("One domain is infinite and other crosses zero [-2,5]*[7,INF]") { - constant_interval_exprt a(values[-2], values[5]); - constant_interval_exprt b(values[7], max_exprt(type)); + constant_interval_exprt a(CEV(-2), CEV(5)); + constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); constant_interval_exprt result = a.multiply(b); @@ -135,8 +125,8 @@ SCENARIO("multiply interval domain", WHEN("One domain is infinite and other is positive [2,5]*[7,INF]") { - constant_interval_exprt a(values[2], values[5]); - constant_interval_exprt b(values[7], max_exprt(type)); + constant_interval_exprt a(CEV(2), CEV(5)); + constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); constant_interval_exprt result = a.multiply(b); THEN("Domain is consistent") diff --git a/unit/util/interval/shift.cpp b/unit/util/interval/shift.cpp index a9238f37ae5..72a2b341493 100644 --- a/unit/util/interval/shift.cpp +++ b/unit/util/interval/shift.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,8 +11,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("shift interval domain", @@ -20,24 +21,14 @@ SCENARIO("shift interval domain", { GIVEN("Two simple signed intervals") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - source_locationt source_location; - - std::map v; - - for(int i = -100; i <= 100; i++) - { - v[i] = from_integer(mp_integer(i), type); - } - WHEN("Something") { THEN("Something else") { - REQUIRE(constant_interval_exprt(v[4], v[8]).left_shift(constant_interval_exprt(v[1])) == constant_interval_exprt(v[8], v[16])); + REQUIRE(constant_interval_exprt(CEV(4), CEV(8)).left_shift(constant_interval_exprt(CEV(1))) == constant_interval_exprt(CEV(8), CEV(16))); } } } diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index 65d778d20a7..52d28cc69b3 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -3,7 +3,7 @@ Author: DiffBlue Limited \*******************************************************************/ -#include +#include #include #include @@ -11,8 +11,9 @@ #include #include -#define V(X) (binary2integer(X.get(ID_value).c_str(), 2)) -#define V_(X) (binary2integer(X.c_str(), 2)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) SCENARIO("subtract interval domain", @@ -20,23 +21,13 @@ SCENARIO("subtract interval domain", { GIVEN("Two simple signed intervals") { - const typet type=signedbv_typet(32); symbol_tablet symbol_table; namespacet ns(symbol_table); - source_locationt source_location; - - std::map values; - - for(int i = -100; i <= 100; i++) - { - values[i] = from_integer(mp_integer(i), type); - } - WHEN("The result is positive [6,8]-[2,4]") { - constant_interval_exprt left(values[6], values[8]); - constant_interval_exprt right(values[2], values[4]); + constant_interval_exprt left(CEV(6), CEV(8)); + constant_interval_exprt right(CEV(2), CEV(4)); constant_interval_exprt result = left.minus(right); @@ -57,8 +48,8 @@ SCENARIO("subtract interval domain", WHEN("One contains infinite [2,4]-[6,INF]") { - constant_interval_exprt left(values[2], values[4]); - constant_interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(CEV(2), CEV(4)); + constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.minus(right); @@ -81,8 +72,8 @@ SCENARIO("subtract interval domain", WHEN("Both contain infinite [2,INF]-[6,INF]") { - constant_interval_exprt left(values[2], max_exprt(type)); - constant_interval_exprt right(values[6], max_exprt(type)); + constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); + constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.minus(right); @@ -153,4 +144,4 @@ SCENARIO("Subtracting unsigned integers") REQUIRE(maybe_upper.value() == 10); } } -} \ No newline at end of file +} From d62ce16d088769912ebd93111617dac771358fba Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 9 Dec 2019 22:22:11 +0000 Subject: [PATCH 34/35] clang-format changes to the interval code and unit tests --- src/util/interval.cpp | 482 ++++++++++++++++++----------- src/util/interval.h | 207 ++++++++----- unit/util/interval/add.cpp | 15 +- unit/util/interval/bitwise.cpp | 7 +- unit/util/interval/comparisons.cpp | 212 +++++++++---- unit/util/interval/get_extreme.cpp | 109 ++++--- unit/util/interval/modulo.cpp | 59 ++-- unit/util/interval/multiply.cpp | 165 +++++----- unit/util/interval/shift.cpp | 17 +- unit/util/interval/subtract.cpp | 24 +- 10 files changed, 781 insertions(+), 516 deletions(-) diff --git a/src/util/interval.cpp b/src/util/interval.cpp index 690f5858412..34161de013c 100644 --- a/src/util/interval.cpp +++ b/src/util/interval.cpp @@ -16,19 +16,19 @@ #include "interval.h" -#include -#include -#include -#include #include #include +#include +#include +#include +#include -const exprt& constant_interval_exprt::get_lower() const +const exprt &constant_interval_exprt::get_lower() const { return op0(); } -const exprt& constant_interval_exprt::get_upper() const +const exprt &constant_interval_exprt::get_upper() const { return op1(); } @@ -50,7 +50,7 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const if(has_no_upper_bound()) { - lower=min(); + lower = min(); } else { @@ -59,7 +59,7 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const if(has_no_lower_bound()) { - upper=max(); + upper = max(); } else { @@ -69,7 +69,8 @@ constant_interval_exprt constant_interval_exprt::unary_minus() const return constant_interval_exprt(lower, upper); } -constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::plus(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -85,7 +86,8 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex } else { - INVARIANT(!is_max(get_upper()) && !is_max(o.get_upper()), + INVARIANT( + !is_max(get_upper()) && !is_max(o.get_upper()), "We just excluded this case"); upper = simplified_expr(plus_exprt(get_upper(), o.get_upper())); } @@ -96,7 +98,8 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex } else { - INVARIANT(!is_min(get_lower()) && !is_min(o.get_lower()), + INVARIANT( + !is_min(get_lower()) && !is_min(o.get_lower()), "We just excluded that case"); lower = simplified_expr(plus_exprt(get_lower(), o.get_lower())); } @@ -104,7 +107,8 @@ constant_interval_exprt constant_interval_exprt::plus(const constant_interval_ex return simplified_interval(lower, upper); } -constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &other) const +constant_interval_exprt +constant_interval_exprt::minus(const constant_interval_exprt &other) const { if(other.is_single_value_interval() && is_single_value_interval()) { @@ -115,7 +119,8 @@ constant_interval_exprt constant_interval_exprt::minus(const constant_interval_e return plus(other.unary_minus()); } -constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::multiply(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -125,7 +130,8 @@ constant_interval_exprt constant_interval_exprt::multiply(const constant_interva return get_extremes(*this, o, ID_mult); } -constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::divide(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -141,7 +147,8 @@ constant_interval_exprt constant_interval_exprt::divide(const constant_interval_ return get_extremes(*this, o, ID_div); } -constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::modulo(const constant_interval_exprt &o) const { // SEE https://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers @@ -156,8 +163,9 @@ constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_ } // If the RHS is 1, or -1 (signed only), then return zero. - if(o == constant_interval_exprt(from_integer(1, o.type())) || - (o.is_signed() && o == constant_interval_exprt(from_integer(-1, o.type())))) + if( + o == constant_interval_exprt(from_integer(1, o.type())) || + (o.is_signed() && o == constant_interval_exprt(from_integer(-1, o.type())))) { return constant_interval_exprt(zero()); } @@ -173,31 +181,32 @@ constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_ return constant_interval_exprt(zero()); } - exprt lower=min(); - exprt upper=max(); + exprt lower = min(); + exprt upper = max(); // Positive case (cannot have zero on RHS). // 10 % 5 = [0, 4], 3 % 5 = [0, 3] if(!is_negative() && o.is_positive()) { - lower=zero(); - upper=get_min(get_upper(), o.decrement().get_upper()); + lower = zero(); + upper = get_min(get_upper(), o.decrement().get_upper()); } // [-5, 5] % [3] if(is_negative(get_lower()) && is_positive(get_upper())) { - INVARIANT(contains_zero(), + INVARIANT( + contains_zero(), "Zero should be between a negative and a positive value"); // This can be done more accurately. - lower=get_min(o.get_lower(), get_lower()); - upper=get_max(o.get_upper(), get_upper()); + lower = get_min(o.get_lower(), get_lower()); + upper = get_max(o.get_upper(), get_upper()); } if(is_negative() && o.is_negative()) { - lower=get_min(o.get_lower(), o.get_lower()); - upper=zero(); + lower = get_min(o.get_lower(), o.get_lower()); + upper = zero(); } return constant_interval_exprt(lower, upper); @@ -230,7 +239,8 @@ tvt constant_interval_exprt::is_definitely_false() const if(contains(constant_interval_exprt(zero()))) { - INVARIANT(is_positive(get_upper()) || is_negative(get_lower()), + INVARIANT( + is_positive(get_upper()) || is_negative(get_lower()), "If an interval contains zero its lower bound can't be positive" " and its upper bound can't be negative"); return tvt::unknown(); @@ -285,8 +295,8 @@ tvt constant_interval_exprt::logical_not() const return tvt::unknown(); } - -constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::left_shift(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -302,7 +312,8 @@ constant_interval_exprt constant_interval_exprt::left_shift(const constant_inter } // Arithmetic -constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::right_shift(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -317,7 +328,8 @@ constant_interval_exprt constant_interval_exprt::right_shift(const constant_inte return get_extremes(*this, o, ID_ashr); } -constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::bitwise_xor(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -327,7 +339,8 @@ constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_inte return top(); } -constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::bitwise_or(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -337,7 +350,8 @@ constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_inter return top(); } -constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &o) const +constant_interval_exprt +constant_interval_exprt::bitwise_and(const constant_interval_exprt &o) const { if(o.is_single_value_interval() && is_single_value_interval()) { @@ -378,12 +392,14 @@ tvt constant_interval_exprt::less_than(const constant_interval_exprt &o) const return tvt::unknown(); } -tvt constant_interval_exprt::greater_than(const constant_interval_exprt& o) const +tvt constant_interval_exprt::greater_than( + const constant_interval_exprt &o) const { return o.less_than(*this); } -tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt& o) const +tvt constant_interval_exprt::less_than_or_equal( + const constant_interval_exprt &o) const { if(is_single_value_interval() && o.is_single_value_interval()) { @@ -404,12 +420,13 @@ tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt& o return tvt::unknown(); } -tvt constant_interval_exprt::greater_than_or_equal(const constant_interval_exprt& o) const +tvt constant_interval_exprt::greater_than_or_equal( + const constant_interval_exprt &o) const { return o.less_than_or_equal(*this); } -tvt constant_interval_exprt::equal(const constant_interval_exprt& o) const +tvt constant_interval_exprt::equal(const constant_interval_exprt &o) const { if(is_single_value_interval() && o.is_single_value_interval()) { @@ -421,7 +438,9 @@ tvt constant_interval_exprt::equal(const constant_interval_exprt& o) const return tvt(true); } - if(less_than(o).is_true() || greater_than(o).is_true() || o.less_than(*this).is_true() || o.greater_than(*this).is_true()) + if( + less_than(o).is_true() || greater_than(o).is_true() || + o.less_than(*this).is_true() || o.greater_than(*this).is_true()) { return tvt(false); } @@ -430,7 +449,7 @@ tvt constant_interval_exprt::equal(const constant_interval_exprt& o) const return tvt::unknown(); } -tvt constant_interval_exprt::not_equal(const constant_interval_exprt& o) const +tvt constant_interval_exprt::not_equal(const constant_interval_exprt &o) const { return !equal(o); } @@ -438,7 +457,6 @@ tvt constant_interval_exprt::not_equal(const constant_interval_exprt& o) const constant_interval_exprt constant_interval_exprt::increment() const { return plus(constant_interval_exprt(from_integer(mp_integer(1), type()))); - } constant_interval_exprt constant_interval_exprt::decrement() const @@ -458,7 +476,7 @@ constant_interval_exprt constant_interval_exprt::get_extremes( generate_expression(a.get_upper(), b.get_lower(), operation, results); generate_expression(a.get_upper(), b.get_upper(), operation, results); - for(auto result: results) + for(auto result : results) { if(!is_extreme(result) && contains_extreme(result)) { @@ -466,13 +484,15 @@ constant_interval_exprt constant_interval_exprt::get_extremes( } } - exprt min=get_min(results); - exprt max=get_max(results); + exprt min = get_min(results); + exprt max = get_max(results); return simplified_interval(min, max); } -exprt constant_interval_exprt::get_extreme(std::vector values, bool min_value) +exprt constant_interval_exprt::get_extreme( + std::vector values, + bool min_value) { symbol_tablet symbol_table; namespacet ns(symbol_table); // Empty @@ -499,9 +519,9 @@ exprt constant_interval_exprt::get_extreme(std::vector values, bool min_v } } - typet type=values.begin()->type(); + typet type = values.begin()->type(); - for(auto v: values) + for(auto v : values) { if((min_value && is_min(v)) || (!min_value && is_max(v))) { @@ -509,13 +529,15 @@ exprt constant_interval_exprt::get_extreme(std::vector values, bool min_v } } - for(auto left: values) + for(auto left : values) { bool all_left_OP_right = true; - for(auto right: values) + for(auto right : values) { - if((min_value && less_than_or_equal(left, right)) || (!min_value && greater_than_or_equal(left, right))) + if( + (min_value && less_than_or_equal(left, right)) || + (!min_value && greater_than_or_equal(left, right))) { continue; } @@ -655,7 +677,9 @@ void constant_interval_exprt::append_multiply_expression_min( } } -exprt constant_interval_exprt::generate_division_expression(const exprt &lhs, const exprt &rhs) +exprt constant_interval_exprt::generate_division_expression( + const exprt &lhs, + const exprt &rhs) { PRECONDITION(lhs.type().is_not_nil() && is_numeric(lhs.type())); @@ -686,8 +710,7 @@ exprt constant_interval_exprt::generate_division_expression(const exprt &lhs, co return lhs; } - INVARIANT(!is_extreme(lhs), - "We ruled out extreme cases beforehand"); + INVARIANT(!is_extreme(lhs), "We ruled out extreme cases beforehand"); if(is_max(rhs)) { @@ -696,19 +719,22 @@ exprt constant_interval_exprt::generate_division_expression(const exprt &lhs, co if(is_min(rhs)) { - INVARIANT(is_signed(rhs), - "We think this is a signed integer for some reason?"); + INVARIANT( + is_signed(rhs), "We think this is a signed integer for some reason?"); return zero(rhs); } - INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + INVARIANT( + !is_extreme(lhs) && !is_extreme(rhs), "We ruled out extreme cases beforehand"); auto div_expr = div_exprt(lhs, rhs); return simplified_expr(div_expr); } -exprt constant_interval_exprt::generate_modulo_expression(const exprt &lhs, const exprt &rhs) +exprt constant_interval_exprt::generate_modulo_expression( + const exprt &lhs, + const exprt &rhs) { PRECONDITION(lhs.type().is_not_nil() && is_numeric(lhs.type())); @@ -739,8 +765,7 @@ exprt constant_interval_exprt::generate_modulo_expression(const exprt &lhs, cons return lhs; } - INVARIANT(!is_extreme(lhs), - "We rule out this case beforehand"); + INVARIANT(!is_extreme(lhs), "We rule out this case beforehand"); if(is_max(rhs)) { @@ -749,15 +774,15 @@ exprt constant_interval_exprt::generate_modulo_expression(const exprt &lhs, cons if(is_min(rhs)) { - INVARIANT(is_signed(rhs), - "We assume this is signed for some reason?"); + INVARIANT(is_signed(rhs), "We assume this is signed for some reason?"); return zero(rhs); } - INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + INVARIANT( + !is_extreme(lhs) && !is_extreme(rhs), "We ruled out extreme values beforehand"); - auto modulo_expr = mod_exprt(lhs,rhs); + auto modulo_expr = mod_exprt(lhs, rhs); return simplified_expr(modulo_expr); } @@ -867,8 +892,10 @@ constant_interval_exprt constant_interval_exprt::eval( return top(); } -exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const exprt &rhs, - const irep_idt &operation) +exprt constant_interval_exprt::generate_shift_expression( + const exprt &lhs, + const exprt &rhs, + const irep_idt &operation) { PRECONDITION(operation == ID_shl || operation == ID_ashr); @@ -879,8 +906,7 @@ exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const return lhs; } - INVARIANT(!is_negative(rhs), - "Should be caught at an earlier stage."); + INVARIANT(!is_negative(rhs), "Should be caught at an earlier stage."); if(is_max(lhs)) { @@ -897,14 +923,17 @@ exprt constant_interval_exprt::generate_shift_expression(const exprt &lhs, const return min_exprt(rhs); } - INVARIANT(!is_extreme(lhs) && !is_extreme(rhs), + INVARIANT( + !is_extreme(lhs) && !is_extreme(rhs), "We ruled out extreme cases beforehand"); auto shift_expr = shift_exprt(lhs, operation, rhs); return simplified_expr(shift_expr); } -constant_interval_exprt constant_interval_exprt::handle_constant_unary_expression(const irep_idt &op) const +constant_interval_exprt +constant_interval_exprt::handle_constant_unary_expression( + const irep_idt &op) const { if(is_single_value_interval()) { @@ -914,8 +943,10 @@ constant_interval_exprt constant_interval_exprt::handle_constant_unary_expressio return top(); } -constant_interval_exprt constant_interval_exprt::handle_constant_binary_expression(const constant_interval_exprt &other, - const irep_idt &op) const +constant_interval_exprt +constant_interval_exprt::handle_constant_binary_expression( + const constant_interval_exprt &other, + const irep_idt &op) const { PRECONDITION(is_single_value_interval() && other.is_single_value_interval()); auto expr = binary_exprt(get_lower(), op, other.get_lower()); @@ -943,7 +974,8 @@ exprt constant_interval_exprt::get_max(std::vector &values) } /* we don't simplify in the constructor otherwise */ -constant_interval_exprt constant_interval_exprt::simplified_interval(exprt &l, exprt &r) +constant_interval_exprt +constant_interval_exprt::simplified_interval(exprt &l, exprt &r) { return constant_interval_exprt(simplified_expr(l), simplified_expr(r)); } @@ -958,20 +990,22 @@ exprt constant_interval_exprt::simplified_expr(exprt expr) return simplify_expr(expr, ns); } -constant_exprt constant_interval_exprt::zero(const typet& type) +constant_exprt constant_interval_exprt::zero(const typet &type) { constant_exprt zero = from_integer(mp_integer(0), type); - INVARIANT(zero.is_zero() || (type.id() == ID_bool && zero.is_false()), + INVARIANT( + zero.is_zero() || (type.id() == ID_bool && zero.is_false()), "The value created from 0 should be zero or false"); return zero; } -constant_exprt constant_interval_exprt::zero(const exprt& expr) +constant_exprt constant_interval_exprt::zero(const exprt &expr) { return zero(expr.type()); } -constant_exprt constant_interval_exprt::zero(const constant_interval_exprt &interval) +constant_exprt +constant_interval_exprt::zero(const constant_interval_exprt &interval) { return zero(interval.type()); } @@ -1049,7 +1083,8 @@ bool constant_interval_exprt::is_numeric(const exprt &expr) return is_numeric(expr.type()); } -bool constant_interval_exprt::is_numeric(const constant_interval_exprt &interval) +bool constant_interval_exprt::is_numeric( + const constant_interval_exprt &interval) { return interval.is_numeric(); } @@ -1084,24 +1119,24 @@ bool constant_interval_exprt::is_float(const constant_interval_exprt &interval) return interval.is_float(); } - bool constant_interval_exprt::is_bitvector(const typet &t) { - return t.id() == ID_bv || t.id() == ID_signedbv || t.id() == ID_unsignedbv - || t.id() == ID_c_bool - || (t.id() == ID_c_bit_field && is_bitvector(t.subtype())); + return t.id() == ID_bv || t.id() == ID_signedbv || t.id() == ID_unsignedbv || + t.id() == ID_c_bool || + (t.id() == ID_c_bit_field && is_bitvector(t.subtype())); } bool constant_interval_exprt::is_signed(const typet &t) { - return t.id() == ID_signedbv - || (t.id() == ID_c_bit_field && is_signed(t.subtype())); + return t.id() == ID_signedbv || + (t.id() == ID_c_bit_field && is_signed(t.subtype())); } bool constant_interval_exprt::is_unsigned(const typet &t) { - return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_c_bool - || t.id() == ID_c_enum || (t.id() == ID_c_bit_field && is_unsigned(t.subtype())); + return t.id() == ID_bv || t.id() == ID_unsignedbv || t.id() == ID_c_bool || + t.id() == ID_c_enum || + (t.id() == ID_c_bit_field && is_unsigned(t.subtype())); } bool constant_interval_exprt::is_signed(const constant_interval_exprt &interval) @@ -1109,12 +1144,14 @@ bool constant_interval_exprt::is_signed(const constant_interval_exprt &interval) return is_signed(interval.type()); } -bool constant_interval_exprt::is_unsigned(const constant_interval_exprt &interval) +bool constant_interval_exprt::is_unsigned( + const constant_interval_exprt &interval) { return is_unsigned(interval.type()); } -bool constant_interval_exprt::is_bitvector(const constant_interval_exprt &interval) +bool constant_interval_exprt::is_bitvector( + const constant_interval_exprt &interval) { return is_bitvector(interval.type()); } @@ -1181,7 +1218,7 @@ bool constant_interval_exprt::is_min(const exprt &expr) bool constant_interval_exprt::is_positive(const exprt &expr) { - exprt simplified=simplified_expr(expr); + exprt simplified = simplified_expr(expr); if(expr.is_nil() || !simplified.is_constant() || expr.get(ID_value) == "") { @@ -1193,8 +1230,7 @@ bool constant_interval_exprt::is_positive(const exprt &expr) return true; } - INVARIANT(is_signed(expr), - "Not implemented for floats"); + INVARIANT(is_signed(expr), "Not implemented for floats"); // Floats later if(is_min(expr)) @@ -1224,8 +1260,7 @@ bool constant_interval_exprt::is_zero(const exprt &expr) return false; } - INVARIANT(!is_max(expr) && !is_min(expr), - "We excluded those cases"); + INVARIANT(!is_max(expr) && !is_min(expr), "We excluded those cases"); if(expr.is_zero()) { @@ -1242,16 +1277,15 @@ bool constant_interval_exprt::is_negative(const exprt &expr) return false; } - INVARIANT(is_signed(expr), - "We don't support anything other than integers yet"); + INVARIANT( + is_signed(expr), "We don't support anything other than integers yet"); if(is_min(expr)) { return true; } - INVARIANT(!is_extreme(expr), - "We excluded these cases before"); + INVARIANT(!is_extreme(expr), "We excluded these cases before"); return less_than(expr, zero(expr)); } @@ -1271,8 +1305,7 @@ exprt constant_interval_exprt::abs(const exprt &expr) return simplified_expr(unary_minus_exprt(expr)); } - -bool constant_interval_exprt::equal(const exprt& a, const exprt& b) +bool constant_interval_exprt::equal(const exprt &a, const exprt &b) { if(a == b) { @@ -1281,8 +1314,10 @@ bool constant_interval_exprt::equal(const exprt& a, const exprt& b) if(!is_numeric(a) || !is_numeric(b)) { - INVARIANT(!(a == b), - "Best we can do now is a==b?, but this is covered by the above, so always false"); + INVARIANT( + !(a == b), + "Best we can do now is a==b?, but this is covered by the above, so " + "always false"); return false; } @@ -1291,8 +1326,8 @@ bool constant_interval_exprt::equal(const exprt& a, const exprt& b) return true; } - exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; - exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; + exprt l = (is_min(a) && is_unsigned(a)) ? zero(a) : a; + exprt r = (is_min(b) && is_unsigned(b)) ? zero(b) : b; // CANNOT use is_zero(X) but can use X.is_zero(); if((is_min(l) && is_min(r))) @@ -1300,36 +1335,35 @@ bool constant_interval_exprt::equal(const exprt& a, const exprt& b) return true; } - if((is_max(l) && !is_max(r)) || (is_min(l) && !is_min(r)) || - (is_max(r) && !is_max(l)) || (is_min(r) && !is_min(l))) + if( + (is_max(l) && !is_max(r)) || (is_min(l) && !is_min(r)) || + (is_max(r) && !is_max(l)) || (is_min(r) && !is_min(l))) { return false; } - INVARIANT(!is_extreme(l, r), - "We've excluded this before"); + INVARIANT(!is_extreme(l, r), "We've excluded this before"); return simplified_expr(equal_exprt(l, r)).is_true(); } // TODO: Signed/unsigned comparisons. -bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) +bool constant_interval_exprt::less_than(const exprt &a, const exprt &b) { if(!is_numeric(a) || !is_numeric(b)) { return false; } - exprt l=(is_min(a) && is_unsigned(a)) ? zero(a) : a; - exprt r=(is_min(b) && is_unsigned(b)) ? zero(b) : b; + exprt l = (is_min(a) && is_unsigned(a)) ? zero(a) : a; + exprt r = (is_min(b) && is_unsigned(b)) ? zero(b) : b; if(is_max(l)) { return false; } - INVARIANT(!is_max(l), - "We've just excluded this case"); + INVARIANT(!is_max(l), "We've just excluded this case"); if(is_min(r)) { @@ -1337,15 +1371,15 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) return false; } - INVARIANT(!is_max(l) && !is_min(r), - "We've excluded these cases"); + INVARIANT(!is_max(l) && !is_min(r), "We've excluded these cases"); if(is_min(l)) { return true; } - INVARIANT(!is_max(l) && !is_min(r) && !is_min(l), + INVARIANT( + !is_max(l) && !is_min(r) && !is_min(l), "These cases should have all been handled before this point"); if(is_max(r)) @@ -1354,7 +1388,8 @@ bool constant_interval_exprt::less_than(const exprt& a, const exprt& b) return !is_max(l); } - INVARIANT(!is_extreme(l) && !is_extreme(r), + INVARIANT( + !is_extreme(l) && !is_extreme(r), "We have excluded all of these cases in the code above"); return simplified_expr(binary_relation_exprt(l, ID_lt, r)).is_true(); @@ -1365,12 +1400,14 @@ bool constant_interval_exprt::greater_than(const exprt &a, const exprt &b) return less_than(b, a); } -bool constant_interval_exprt::less_than_or_equal(const exprt& a, const exprt& b) +bool constant_interval_exprt::less_than_or_equal(const exprt &a, const exprt &b) { return less_than(a, b) || equal(a, b); } -bool constant_interval_exprt::greater_than_or_equal(const exprt& a, const exprt& b) +bool constant_interval_exprt::greater_than_or_equal( + const exprt &a, + const exprt &b) { return greater_than(a, b) || equal(a, b); } @@ -1380,17 +1417,15 @@ bool constant_interval_exprt::not_equal(const exprt &a, const exprt &b) return !equal(a, b); } -bool constant_interval_exprt::contains(const constant_interval_exprt& interval) const +bool constant_interval_exprt::contains( + const constant_interval_exprt &interval) const { // [a, b] Contains [c, d] If c >= a and d <= b. - return( - less_than_or_equal(interval.get_upper(), get_upper()) - && - greater_than_or_equal(interval.get_lower(), get_lower()) - ); + return ( + less_than_or_equal(interval.get_upper(), get_upper()) && + greater_than_or_equal(interval.get_lower(), get_lower())); } - std::string constant_interval_exprt::to_string() const { std::stringstream out; @@ -1398,8 +1433,7 @@ std::string constant_interval_exprt::to_string() const return out.str(); } -std::ostream& operator <<(std::ostream& out, - const constant_interval_exprt& i) +std::ostream &operator<<(std::ostream &out, const constant_interval_exprt &i) { out << "["; @@ -1408,7 +1442,8 @@ std::ostream& operator <<(std::ostream& out, // FIXME Not everything that's a bitvector is also an integer if(i.is_bitvector(i.get_lower())) { - out << binary2integer(id2string(i.get_lower().get(ID_value)), i.is_signed()); + out << binary2integer( + id2string(i.get_lower().get(ID_value)), i.is_signed()); } else { @@ -1438,7 +1473,8 @@ std::ostream& operator <<(std::ostream& out, { if(i.is_bitvector(i.get_upper())) { - out << binary2integer(id2string(i.get_upper().get(ID_value)), i.is_signed()); + out << binary2integer( + id2string(i.get_upper().get(ID_value)), i.is_signed()); } else { @@ -1453,72 +1489,100 @@ std::ostream& operator <<(std::ostream& out, return out; } -bool operator< (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator<( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.less_than(rhs).is_true(); } -bool operator> (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator>( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.greater_than(rhs).is_true(); } -bool operator<=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator<=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.less_than_or_equal(rhs).is_true(); } -bool operator>=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator>=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.greater_than(rhs).is_true(); } -bool operator==(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator==( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.equal(rhs).is_true(); } -bool operator!=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +bool operator!=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.not_equal(rhs).is_true(); } -const constant_interval_exprt operator+(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator+( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.unary_plus(rhs); } -const constant_interval_exprt operator-(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator-( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.minus(rhs); } -const constant_interval_exprt operator/(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator/( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.divide(rhs); } -const constant_interval_exprt operator*(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator*( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.multiply(rhs); } -const constant_interval_exprt operator%(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator%( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.modulo(rhs); } -const constant_interval_exprt operator&(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator&( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.bitwise_and(rhs); } -const constant_interval_exprt operator|(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator|( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.bitwise_or(rhs); } -const constant_interval_exprt operator^(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator^( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.bitwise_xor(rhs); } @@ -1528,27 +1592,34 @@ const constant_interval_exprt operator!(const constant_interval_exprt &lhs) return lhs.bitwise_not(); } -const constant_interval_exprt operator<<(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator<<( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.left_shift(rhs); } -const constant_interval_exprt operator>>(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs) +const constant_interval_exprt operator>>( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs) { return lhs.right_shift(rhs); } -constant_interval_exprt constant_interval_exprt::unary_plus(const constant_interval_exprt &a) +constant_interval_exprt +constant_interval_exprt::unary_plus(const constant_interval_exprt &a) { return a.unary_plus(); } -constant_interval_exprt constant_interval_exprt::unary_minus(const constant_interval_exprt &a) +constant_interval_exprt +constant_interval_exprt::unary_minus(const constant_interval_exprt &a) { return a.unary_minus(); } -constant_interval_exprt constant_interval_exprt::typecast(const typet &type) const +constant_interval_exprt +constant_interval_exprt::typecast(const typet &type) const { if(this->type().id() == ID_bool && is_int(type)) { @@ -1568,7 +1639,9 @@ constant_interval_exprt constant_interval_exprt::typecast(const typet &type) con if(e.id() == ID_min || e.id() == ID_max) { e.type() = type; - } else { + } + else + { e = simplified_expr(typecast_exprt(e, type)); } return e; @@ -1585,110 +1658,135 @@ constant_interval_exprt constant_interval_exprt::typecast(const typet &type) con } /* Binary */ -constant_interval_exprt constant_interval_exprt::plus(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::plus( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.plus(b); } -constant_interval_exprt constant_interval_exprt::minus(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::minus( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.minus(b); } -constant_interval_exprt constant_interval_exprt::multiply(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::multiply( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.multiply(b); } -constant_interval_exprt constant_interval_exprt::divide(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::divide( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.divide(b); } -constant_interval_exprt constant_interval_exprt::modulo(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::modulo( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.modulo(b); } /* Binary shifts */ -constant_interval_exprt constant_interval_exprt::left_shift(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::left_shift( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.left_shift(b); } -constant_interval_exprt constant_interval_exprt::right_shift(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::right_shift( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.right_shift(b); } /* Unary bitwise */ -constant_interval_exprt constant_interval_exprt::bitwise_not(const constant_interval_exprt &a) +constant_interval_exprt +constant_interval_exprt::bitwise_not(const constant_interval_exprt &a) { return a.bitwise_not(); } /* Binary bitwise */ -constant_interval_exprt constant_interval_exprt::bitwise_xor(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_xor( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_xor(b); } -constant_interval_exprt constant_interval_exprt::bitwise_or(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_or( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_or(b); } -constant_interval_exprt constant_interval_exprt::bitwise_and(const constant_interval_exprt &a, - const constant_interval_exprt &b) +constant_interval_exprt constant_interval_exprt::bitwise_and( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.bitwise_and(b); } -tvt constant_interval_exprt::less_than(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::less_than( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.less_than(b); } -tvt constant_interval_exprt::greater_than(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::greater_than( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.greater_than(b); } -tvt constant_interval_exprt::less_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::less_than_or_equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.less_than_or_equal(b); } -tvt constant_interval_exprt::greater_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::greater_than_or_equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.greater_than_or_equal(b); } -tvt constant_interval_exprt::equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.equal(b); } -tvt constant_interval_exprt::not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::not_equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.equal(b); } -constant_interval_exprt constant_interval_exprt::increment(const constant_interval_exprt &a) +constant_interval_exprt +constant_interval_exprt::increment(const constant_interval_exprt &a) { return a.increment(); } -constant_interval_exprt constant_interval_exprt::decrement(const constant_interval_exprt &a) +constant_interval_exprt +constant_interval_exprt::decrement(const constant_interval_exprt &a) { return a.decrement(); } @@ -1742,7 +1840,9 @@ bool constant_interval_exprt::contains_extreme(const exprt expr) return false; } -bool constant_interval_exprt::contains_extreme(const exprt expr1, const exprt expr2) +bool constant_interval_exprt::contains_extreme( + const exprt expr1, + const exprt expr2) { return contains_extreme(expr1) || contains_extreme(expr2); } @@ -1759,7 +1859,8 @@ bool constant_interval_exprt::is_empty() const bool constant_interval_exprt::is_single_value_interval() const { - return !is_extreme(get_lower()) && !is_extreme(get_upper()) && equal(get_lower(), get_upper()); + return !is_extreme(get_lower()) && !is_extreme(get_upper()) && + equal(get_lower(), get_upper()); } bool constant_interval_exprt::contains_zero() const @@ -1779,7 +1880,9 @@ bool constant_interval_exprt::contains_zero() const return true; } - if(less_than_or_equal(get_lower(), zero()) && greater_than_or_equal(get_upper(), zero())) + if( + less_than_or_equal(get_lower(), zero()) && + greater_than_or_equal(get_upper(), zero())) { return true; } @@ -1787,18 +1890,19 @@ bool constant_interval_exprt::contains_zero() const return false; } - -bool constant_interval_exprt::is_positive(const constant_interval_exprt& interval) +bool constant_interval_exprt::is_positive( + const constant_interval_exprt &interval) { return interval.is_positive(); } -bool constant_interval_exprt::is_zero(const constant_interval_exprt& interval) +bool constant_interval_exprt::is_zero(const constant_interval_exprt &interval) { return interval.is_zero(); } -bool constant_interval_exprt::is_negative(const constant_interval_exprt& interval) +bool constant_interval_exprt::is_negative( + const constant_interval_exprt &interval) { return interval.is_negative(); } @@ -1828,17 +1932,23 @@ tvt constant_interval_exprt::is_false(const constant_interval_exprt &a) return a.is_definitely_false(); } -tvt constant_interval_exprt::logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::logical_and( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.logical_and(b); } -tvt constant_interval_exprt::logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::logical_or( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.logical_or(b); } -tvt constant_interval_exprt::logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b) +tvt constant_interval_exprt::logical_xor( + const constant_interval_exprt &a, + const constant_interval_exprt &b) { return a.logical_xor(b); } diff --git a/src/util/interval.h b/src/util/interval.h index f63a88acbc6..bd154967044 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -8,45 +8,41 @@ #ifndef SRC_ANALYSES_INTERVAL_H_ #define SRC_ANALYSES_INTERVAL_H_ +#include #include +#include #include -#include #include +#include #include -#include -#include #include +#include #include #include -#include /// +∞ upper bound for intervals -class max_exprt:public exprt +class max_exprt : public exprt { public: - explicit max_exprt(const typet &_type): - exprt(ID_max, _type) + explicit max_exprt(const typet &_type) : exprt(ID_max, _type) { } - explicit max_exprt(const exprt &_expr): - exprt(ID_max, _expr.type()) + explicit max_exprt(const exprt &_expr) : exprt(ID_max, _expr.type()) { } }; /// -∞ upper bound for intervals -class min_exprt:public exprt +class min_exprt : public exprt { public: - explicit min_exprt(const typet &_type): - exprt(ID_min, _type) + explicit min_exprt(const typet &_type) : exprt(ID_min, _type) { } - explicit min_exprt(const exprt &_expr): - exprt(ID_min, _expr.type()) + explicit min_exprt(const exprt &_expr) : exprt(ID_min, _expr.type()) { } }; @@ -59,22 +55,23 @@ class min_exprt:public exprt class constant_interval_exprt : public binary_exprt { public: - constant_interval_exprt(const exprt &lower, const exprt &upper, const typet type) + constant_interval_exprt( + const exprt &lower, + const exprt &upper, + const typet type) : binary_exprt(lower, ID_constant_interval, upper, type) { PRECONDITION(is_well_formed()); } - constant_interval_exprt (const constant_interval_exprt &x) + constant_interval_exprt(const constant_interval_exprt &x) : constant_interval_exprt(x.get_lower(), x.get_upper(), x.type()) { - } constant_interval_exprt(const exprt &x) : constant_interval_exprt(x, x, x.type()) { - } explicit constant_interval_exprt(const typet &type) @@ -82,10 +79,9 @@ class constant_interval_exprt : public binary_exprt { } - constant_interval_exprt(const exprt &lower, const exprt &upper): - constant_interval_exprt(lower, upper, lower.type()) + constant_interval_exprt(const exprt &lower, const exprt &upper) + : constant_interval_exprt(lower, upper, lower.type()) { - } bool is_well_formed() const @@ -139,8 +135,11 @@ class constant_interval_exprt : public binary_exprt const exprt &get_upper() const; /** SET OF ARITHMETIC OPERATORS */ - constant_interval_exprt handle_constant_unary_expression(const irep_idt &op) const; - constant_interval_exprt handle_constant_binary_expression(const constant_interval_exprt &other, const irep_idt &) const; + constant_interval_exprt + handle_constant_unary_expression(const irep_idt &op) const; + constant_interval_exprt handle_constant_binary_expression( + const constant_interval_exprt &other, + const irep_idt &) const; constant_interval_exprt eval(const irep_idt &unary_operator) const; constant_interval_exprt @@ -194,7 +193,7 @@ class constant_interval_exprt : public binary_exprt bool is_single_value_interval() const; /** END SET OF ARITHMETIC OPERATORS */ -// tvt contains(constant_interval_exprt &o) const; + // tvt contains(constant_interval_exprt &o) const; /* SET OF EXPR COMPARATORS */ static bool equal(const exprt &a, const exprt &b); @@ -208,67 +207,130 @@ class constant_interval_exprt : public binary_exprt /* INTERVAL COMPARISONS, returns tvt.is_true(). False cannot be trusted * (could be false or unknown, either use less_than, etc method or use the correct * operator)! */ - friend bool operator< (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend bool operator> (const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend bool operator<=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend bool operator>=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend bool operator==(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend bool operator!=(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); + friend bool operator<( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend bool operator>( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend bool operator<=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend bool operator>=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend bool operator==( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend bool operator!=( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); /* Operator override for intervals */ - friend const constant_interval_exprt operator+(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator-(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator/(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator*(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator%(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator!(const constant_interval_exprt &lhs); - friend const constant_interval_exprt operator&(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator|(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator^(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator<<(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - friend const constant_interval_exprt operator>>(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs); - - friend std::ostream& operator<< (std::ostream& out, const constant_interval_exprt &i); + friend const constant_interval_exprt operator+( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator-( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator/( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator*( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator%( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator!( + const constant_interval_exprt &lhs); + friend const constant_interval_exprt operator&( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator|( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator^( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator<<( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + friend const constant_interval_exprt operator>>( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs); + + friend std::ostream & + operator<<(std::ostream &out, const constant_interval_exprt &i); std::string to_string() const; - /* Now static equivalents! */ static tvt is_true(const constant_interval_exprt &a); static tvt is_false(const constant_interval_exprt &a); - static tvt logical_and(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt logical_or(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt logical_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt logical_and( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static tvt logical_or( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static tvt logical_xor( + const constant_interval_exprt &a, + const constant_interval_exprt &b); static tvt logical_not(const constant_interval_exprt &a); static constant_interval_exprt unary_plus(const constant_interval_exprt &a); static constant_interval_exprt unary_minus(const constant_interval_exprt &a); /* Binary */ - static constant_interval_exprt plus(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt minus(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt multiply(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt divide(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt modulo(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt + plus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt + minus(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt + multiply(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt + divide(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt + modulo(const constant_interval_exprt &a, const constant_interval_exprt &b); /* Binary shifts */ - static constant_interval_exprt left_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt right_shift(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt left_shift( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static constant_interval_exprt right_shift( + const constant_interval_exprt &a, + const constant_interval_exprt &b); /* Unary bitwise */ static constant_interval_exprt bitwise_not(const constant_interval_exprt &a); /* Binary bitwise */ - static constant_interval_exprt bitwise_xor(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt bitwise_or(const constant_interval_exprt &a, const constant_interval_exprt &b); - static constant_interval_exprt bitwise_and(const constant_interval_exprt &a, const constant_interval_exprt &b); - - static tvt less_than(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt greater_than(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt less_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt greater_than_or_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt equal(const constant_interval_exprt &a, const constant_interval_exprt &b); - static tvt not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + static constant_interval_exprt bitwise_xor( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static constant_interval_exprt bitwise_or( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static constant_interval_exprt bitwise_and( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + + static tvt + less_than(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt greater_than( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static tvt less_than_or_equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static tvt greater_than_or_equal( + const constant_interval_exprt &a, + const constant_interval_exprt &b); + static tvt + equal(const constant_interval_exprt &a, const constant_interval_exprt &b); + static tvt + not_equal(const constant_interval_exprt &a, const constant_interval_exprt &b); static constant_interval_exprt increment(const constant_interval_exprt &a); static constant_interval_exprt decrement(const constant_interval_exprt &a); @@ -305,8 +367,10 @@ class constant_interval_exprt : public binary_exprt static constant_exprt zero(const constant_interval_exprt &interval); /* Private? */ - static constant_interval_exprt get_extremes(const constant_interval_exprt &lhs, const constant_interval_exprt &rhs, - const irep_idt &operation); + static constant_interval_exprt get_extremes( + const constant_interval_exprt &lhs, + const constant_interval_exprt &rhs, + const irep_idt &operation); static exprt get_extreme(std::vector values, bool min = true); static exprt get_max(const exprt &a, const exprt &b); static exprt get_min(const exprt &a, const exprt &b); @@ -392,12 +456,17 @@ class constant_interval_exprt : public binary_exprt std::vector &collection); static exprt generate_division_expression(const exprt &lhs, const exprt &rhs); static exprt generate_modulo_expression(const exprt &lhs, const exprt &rhs); - static exprt generate_shift_expression(const exprt &lhs, const exprt &rhs, const irep_idt &operation); + static exprt generate_shift_expression( + const exprt &lhs, + const exprt &rhs, + const irep_idt &operation); }; -inline const constant_interval_exprt& to_constant_interval_expr(const exprt& expr) { +inline const constant_interval_exprt & +to_constant_interval_expr(const exprt &expr) +{ PRECONDITION(expr.id() == ID_constant_interval); - return static_cast(expr); + return static_cast(expr); } #endif /* SRC_ANALYSES_INTERVAL_H_ */ diff --git a/unit/util/interval/add.cpp b/unit/util/interval/add.cpp index a5ff447e365..73aee75759f 100644 --- a/unit/util/interval/add.cpp +++ b/unit/util/interval/add.cpp @@ -5,19 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("add interval domain", - "[core][analyses][interval][add]") +SCENARIO("add interval domain", "[core][analyses][interval][add]") { GIVEN("Two simple signed intervals") { @@ -39,7 +37,6 @@ SCENARIO("add interval domain", REQUIRE(V(right.get_upper()) == 8); } - THEN("The result is [8, 12]") { REQUIRE(V(result.get_lower()) == 8); @@ -73,7 +70,7 @@ SCENARIO("add interval domain", WHEN("Both contain infinite [2,INF]+[6,INF]") { - constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); + constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.plus(right); diff --git a/unit/util/interval/bitwise.cpp b/unit/util/interval/bitwise.cpp index 3ce24674b69..8737956ff5e 100644 --- a/unit/util/interval/bitwise.cpp +++ b/unit/util/interval/bitwise.cpp @@ -5,14 +5,13 @@ #include +#include #include -#include #include +#include #include -#include -SCENARIO("bitwise interval domain", - "[core][analyses][interval][bitwise]") +SCENARIO("bitwise interval domain", "[core][analyses][interval][bitwise]") { WHEN("We have two unsigned single value intervals - 5 and 9") { diff --git a/unit/util/interval/comparisons.cpp b/unit/util/interval/comparisons.cpp index f59a7dd95ae..1a838bc0dd1 100644 --- a/unit/util/interval/comparisons.cpp +++ b/unit/util/interval/comparisons.cpp @@ -5,19 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("comparison interval domain", - "[core][analyses][interval][comparison]") +SCENARIO("comparison interval domain", "[core][analyses][interval][comparison]") { GIVEN("Two simple signed intervals") { @@ -35,23 +33,37 @@ SCENARIO("comparison interval domain", REQUIRE(constant_interval_exprt::less_than(CEV(-10), CEV(1))); REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(-10), CEV(-100))); REQUIRE(constant_interval_exprt::less_than(CEV(-10), CEV(-5))); - REQUIRE(constant_interval_exprt::less_than(CEV(-10), max_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::less_than(CEV(10), max_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::less_than(CEV(0), max_exprt(signedbv_typet(32)))); - - REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(-10), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(10), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::less_than(CEV(0), min_exprt(signedbv_typet(32)))); - - REQUIRE_FALSE(constant_interval_exprt::less_than(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::less_than(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::less_than(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); - - REQUIRE(constant_interval_exprt::equal(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::not_equal(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::equal(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::not_equal(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than( + CEV(-10), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than( + CEV(10), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than( + CEV(0), max_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::less_than( + CEV(-10), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than( + CEV(10), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than( + CEV(0), min_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::less_than( + min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than( + max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::less_than( + max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::less_than( + min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + + REQUIRE(constant_interval_exprt::equal( + min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::not_equal( + max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::equal( + max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::not_equal( + min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); } THEN("") @@ -63,23 +75,35 @@ SCENARIO("comparison interval domain", REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), CEV(1))); REQUIRE(constant_interval_exprt::greater_than(CEV(-10), CEV(-100))); REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), CEV(-5))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(-10), max_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(10), max_exprt(signedbv_typet(32)))); - REQUIRE_FALSE(constant_interval_exprt::greater_than(CEV(0), max_exprt(signedbv_typet(32)))); - - REQUIRE(constant_interval_exprt::greater_than(CEV(-10), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than(CEV(10), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than(CEV(0), min_exprt(signedbv_typet(32)))); - - REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than_or_equal(min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - - REQUIRE(constant_interval_exprt::greater_than(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - REQUIRE(constant_interval_exprt::greater_than_or_equal(max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); - - REQUIRE_FALSE(constant_interval_exprt::greater_than(max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); - - REQUIRE_FALSE(constant_interval_exprt::greater_than(min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::greater_than( + CEV(-10), max_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::greater_than( + CEV(10), max_exprt(signedbv_typet(32)))); + REQUIRE_FALSE(constant_interval_exprt::greater_than( + CEV(0), max_exprt(signedbv_typet(32)))); + + REQUIRE(constant_interval_exprt::greater_than( + CEV(-10), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than( + CEV(10), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than( + CEV(0), min_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::greater_than( + min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than_or_equal( + min_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + + REQUIRE(constant_interval_exprt::greater_than( + max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + REQUIRE(constant_interval_exprt::greater_than_or_equal( + max_exprt(signedbv_typet(32)), min_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::greater_than( + max_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); + + REQUIRE_FALSE(constant_interval_exprt::greater_than( + min_exprt(signedbv_typet(32)), max_exprt(signedbv_typet(32)))); } } @@ -87,45 +111,97 @@ SCENARIO("comparison interval domain", { THEN("Require correctness") { - CHECK(constant_interval_exprt(CEV(10), CEV(20)) < constant_interval_exprt(CEV(30), CEV(40))); - REQUIRE_FALSE(constant_interval_exprt(CEV(10), CEV(30)) < constant_interval_exprt(CEV(30), CEV(40))); - REQUIRE_FALSE(constant_interval_exprt(CEV(10), CEV(20)) > constant_interval_exprt(CEV(30), CEV(40))); + CHECK( + constant_interval_exprt(CEV(10), CEV(20)) < + constant_interval_exprt(CEV(30), CEV(40))); + REQUIRE_FALSE( + constant_interval_exprt(CEV(10), CEV(30)) < + constant_interval_exprt(CEV(30), CEV(40))); + REQUIRE_FALSE( + constant_interval_exprt(CEV(10), CEV(20)) > + constant_interval_exprt(CEV(30), CEV(40))); } - THEN("[10, 29] < [30, 40] == true, [10, 30] < [30, 40] == unknown, [10, 31] < [30, 40] == unknown") + THEN( + "[10, 29] < [30, 40] == true, [10, 30] < [30, 40] == unknown, [10, 31] " + "< [30, 40] == unknown") { - CHECK(constant_interval_exprt(CEV(10), CEV(29)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); - CHECK(constant_interval_exprt(CEV(10), CEV(30)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); - CHECK(constant_interval_exprt(CEV(10), CEV(31)).less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); - - CHECK(constant_interval_exprt(CEV(30), CEV(40)).less_than(constant_interval_exprt(CEV(10), CEV(29))) == tvt(false)); - + CHECK( + constant_interval_exprt(CEV(10), CEV(29)) + .less_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); + CHECK( + constant_interval_exprt(CEV(10), CEV(30)) + .less_than(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(31)) + .less_than(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); + + CHECK( + constant_interval_exprt(CEV(30), CEV(40)) + .less_than(constant_interval_exprt(CEV(10), CEV(29))) == + tvt(false)); } - - THEN("[10, 29] > [30, 40] == false, [10, 30] > [30, 40] == unknown, [10, 31] > [30, 40] == unknown") + THEN( + "[10, 29] > [30, 40] == false, [10, 30] > [30, 40] == unknown, [10, " + "31] > [30, 40] == unknown") { - CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt(false)); - CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == - constant_interval_exprt(CEV(30), CEV(40)).less_than(constant_interval_exprt(CEV(10), CEV(29)))); - - - CHECK(constant_interval_exprt(CEV(10), CEV(30)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); - CHECK(constant_interval_exprt(CEV(10), CEV(31)).greater_than(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(29)) + .greater_than(constant_interval_exprt(CEV(30), CEV(40))) == + tvt(false)); + CHECK( + constant_interval_exprt(CEV(10), CEV(29)) + .greater_than(constant_interval_exprt(CEV(30), CEV(40))) == + constant_interval_exprt(CEV(30), CEV(40)) + .less_than(constant_interval_exprt(CEV(10), CEV(29)))); + + CHECK( + constant_interval_exprt(CEV(10), CEV(30)) + .greater_than(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(31)) + .greater_than(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); } - THEN("[10, 29] <= [30, 40] == true, [10, 30] <= [30, 40] == true, [10, 31] <- [30, 40] == unknown") + THEN( + "[10, 29] <= [30, 40] == true, [10, 30] <= [30, 40] == true, [10, 31] " + "<- [30, 40] == unknown") { - CHECK(constant_interval_exprt(CEV(10), CEV(29)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); - CHECK(constant_interval_exprt(CEV(10), CEV(30)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(true)); - CHECK(constant_interval_exprt(CEV(10), CEV(31)).less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(29)) + .less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt(true)); + CHECK( + constant_interval_exprt(CEV(10), CEV(30)) + .less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt(true)); + CHECK( + constant_interval_exprt(CEV(10), CEV(31)) + .less_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); } - THEN("[10, 29] >= [30, 40] == false, [10, 30] >= [30, 40] == unknown, [10, 31] >= [30, 40] == unknown") + THEN( + "[10, 29] >= [30, 40] == false, [10, 30] >= [30, 40] == unknown, [10, " + "31] >= [30, 40] == unknown") { - CHECK(constant_interval_exprt(CEV(10), CEV(29)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt(false)); - CHECK(constant_interval_exprt(CEV(10), CEV(30)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); - CHECK(constant_interval_exprt(CEV(10), CEV(31)).greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(29)) + .greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt(false)); + CHECK( + constant_interval_exprt(CEV(10), CEV(30)) + .greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); + CHECK( + constant_interval_exprt(CEV(10), CEV(31)) + .greater_than_or_equal(constant_interval_exprt(CEV(30), CEV(40))) == + tvt::unknown()); } } } diff --git a/unit/util/interval/get_extreme.cpp b/unit/util/interval/get_extreme.cpp index fcb6cec3ab0..71ada31d94a 100644 --- a/unit/util/interval/get_extreme.cpp +++ b/unit/util/interval/get_extreme.cpp @@ -5,20 +5,18 @@ #include +#include #include -#include +#include #include +#include #include -#include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("get extreme exprt value", - "[core][analyses][interval][get_extreme]") +SCENARIO("get extreme exprt value", "[core][analyses][interval][get_extreme]") { GIVEN("A selection of constant_exprts in a std::vector and map") { @@ -31,72 +29,73 @@ SCENARIO("get extreme exprt value", { ve.push_back(from_integer(mp_integer(i), signedbv_typet(32))); } - WHEN("-20 <= 20 is tested") + WHEN("-20 <= 20 is tested") + { + binary_predicate_exprt op1(CEV(-20), ID_le, CEV(20)); + bool interval_eval = + constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(20)); + simplify(op1, ns); + + THEN("Require it is TRUE") { - binary_predicate_exprt op1(CEV(-20), ID_le, CEV(20)); - bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(20)); - simplify(op1, ns); - - THEN("Require it is TRUE") - { - REQUIRE(op1.is_true()); - REQUIRE(interval_eval); - } + REQUIRE(op1.is_true()); + REQUIRE(interval_eval); } + } + WHEN("20 <= -20 is tested") + { + binary_predicate_exprt op1(CEV(20), ID_le, CEV(-20)); + bool interval_eval = + constant_interval_exprt::less_than_or_equal(CEV(20), CEV(-20)); + simplify(op1, ns); - WHEN("20 <= -20 is tested") + THEN("Require it is FALSE") { - binary_predicate_exprt op1(CEV(20), ID_le, CEV(-20)); - bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(20), CEV(-20)); - simplify(op1, ns); - - THEN("Require it is FALSE") - { - REQUIRE(op1.is_false()); - REQUIRE_FALSE(interval_eval); - } + REQUIRE(op1.is_false()); + REQUIRE_FALSE(interval_eval); } + } - WHEN("-20 <= -20 is tested") - { - binary_predicate_exprt op1(CEV(-20), ID_le, CEV(-20)); - bool interval_eval = constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(-20)); + WHEN("-20 <= -20 is tested") + { + binary_predicate_exprt op1(CEV(-20), ID_le, CEV(-20)); + bool interval_eval = + constant_interval_exprt::less_than_or_equal(CEV(-20), CEV(-20)); - simplify(op1, ns); + simplify(op1, ns); - THEN("Require it is TRUE") - { - REQUIRE(op1.is_true()); - REQUIRE(interval_eval); - REQUIRE(constant_interval_exprt::equal(CEV(1), CEV(1))); - } + THEN("Require it is TRUE") + { + REQUIRE(op1.is_true()); + REQUIRE(interval_eval); + REQUIRE(constant_interval_exprt::equal(CEV(1), CEV(1))); } + } - WHEN("Two are selected and min found [20, -20]") - { - std::vector selected = { CEV(20), CEV(-20) }; + WHEN("Two are selected and min found [20, -20]") + { + std::vector selected = {CEV(20), CEV(-20)}; - exprt min = constant_interval_exprt::get_extreme(selected, true); - exprt max = constant_interval_exprt::get_extreme(selected, false); + exprt min = constant_interval_exprt::get_extreme(selected, true); + exprt max = constant_interval_exprt::get_extreme(selected, false); - THEN("Min (-20) and max (20) are verified") - { - CAPTURE(min.pretty()); + THEN("Min (-20) and max (20) are verified") + { + CAPTURE(min.pretty()); - REQUIRE(V(min) == -20); - REQUIRE(V(max) == 20); - } + REQUIRE(V(min) == -20); + REQUIRE(V(max) == 20); } + } WHEN("Four are selected and min found [-20, 0, 20, 50]") { - std::vector selected = { CEV(-20), CEV(0), CEV(50), CEV(20) }; + std::vector selected = {CEV(-20), CEV(0), CEV(50), CEV(20)}; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); - THEN("Min (-20) and max (50) are verified") { REQUIRE(V(min) == -20); @@ -106,7 +105,7 @@ SCENARIO("get extreme exprt value", WHEN("One is selected [-100]") { - std::vector selected = { CEV(-100) }; + std::vector selected = {CEV(-100)}; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); @@ -120,8 +119,8 @@ SCENARIO("get extreme exprt value", WHEN("Five are selected [20, 30, 15, 0, -100]") { - std::vector selected = { CEV(20), CEV(30), CEV(15), CEV(0), CEV(-100) }; - + std::vector selected = { + CEV(20), CEV(30), CEV(15), CEV(0), CEV(-100)}; exprt min = constant_interval_exprt::get_extreme(selected, true); exprt max = constant_interval_exprt::get_extreme(selected, false); diff --git a/unit/util/interval/modulo.cpp b/unit/util/interval/modulo.cpp index bac8f5226d8..0095e473c10 100644 --- a/unit/util/interval/modulo.cpp +++ b/unit/util/interval/modulo.cpp @@ -5,19 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("modulo interval domain", - "[core][analyses][interval][modulo]") +SCENARIO("modulo interval domain", "[core][analyses][interval][modulo]") { GIVEN("Two simple signed intervals") { @@ -26,24 +24,49 @@ SCENARIO("modulo interval domain", WHEN("Positive RHS") { - THEN("Ensure result is consistent.") { - REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(5), CEV(5))) == constant_interval_exprt(CEV(0), CEV(4))); - REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(4), CEV(5))) == constant_interval_exprt(CEV(0), CEV(4))); - REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(CEV(10), CEV(20)).modulo(constant_interval_exprt(CEV(-5), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE( + constant_interval_exprt(CEV(10), CEV(20)) + .modulo(constant_interval_exprt(CEV(5), CEV(5))) == + constant_interval_exprt(CEV(0), CEV(4))); + REQUIRE( + constant_interval_exprt(CEV(10), CEV(20)) + .modulo(constant_interval_exprt(CEV(4), CEV(5))) == + constant_interval_exprt(CEV(0), CEV(4))); + REQUIRE( + constant_interval_exprt(CEV(10), CEV(20)) + .modulo(constant_interval_exprt(CEV(0), CEV(5))) == + constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE( + constant_interval_exprt(CEV(10), CEV(20)) + .modulo(constant_interval_exprt(CEV(-5), CEV(5))) == + constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(CEV(-10), CEV(20)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(CEV(-20), CEV(-10)).modulo(constant_interval_exprt(CEV(0), CEV(5))) == constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE( + constant_interval_exprt(CEV(-10), CEV(20)) + .modulo(constant_interval_exprt(CEV(0), CEV(5))) == + constant_interval_exprt::top(signedbv_typet(32))); + REQUIRE( + constant_interval_exprt(CEV(-20), CEV(-10)) + .modulo(constant_interval_exprt(CEV(0), CEV(5))) == + constant_interval_exprt::top(signedbv_typet(32))); - REQUIRE(constant_interval_exprt(CEV(-20), CEV(-10)).modulo(constant_interval_exprt(CEV(1), CEV(1))) == constant_interval_exprt(CEV(0))); + REQUIRE( + constant_interval_exprt(CEV(-20), CEV(-10)) + .modulo(constant_interval_exprt(CEV(1), CEV(1))) == + constant_interval_exprt(CEV(0))); - REQUIRE(constant_interval_exprt(CEV(30), CEV(50)).modulo(constant_interval_exprt(CEV(2), CEV(2))) == constant_interval_exprt(CEV(0), CEV(1))); + REQUIRE( + constant_interval_exprt(CEV(30), CEV(50)) + .modulo(constant_interval_exprt(CEV(2), CEV(2))) == + constant_interval_exprt(CEV(0), CEV(1))); // Problems - REQUIRE(constant_interval_exprt(CEV(30), max_exprt(signedbv_typet(32))).modulo(constant_interval_exprt(CEV(2), CEV(2))) == constant_interval_exprt(CEV(0), CEV(1))); - + REQUIRE( + constant_interval_exprt(CEV(30), max_exprt(signedbv_typet(32))) + .modulo(constant_interval_exprt(CEV(2), CEV(2))) == + constant_interval_exprt(CEV(0), CEV(1))); } } } diff --git a/unit/util/interval/multiply.cpp b/unit/util/interval/multiply.cpp index 2839b96dd81..7214e1ccf38 100644 --- a/unit/util/interval/multiply.cpp +++ b/unit/util/interval/multiply.cpp @@ -5,18 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) -SCENARIO("multiply interval domain", - "[core][analyses][interval][multiply]") +SCENARIO("multiply interval domain", "[core][analyses][interval][multiply]") { GIVEN("A selection of constant_exprts in a std::vector and map") { @@ -48,104 +47,98 @@ SCENARIO("multiply interval domain", } WHEN("One is entirely negative [-2,-5]*[7,11]") - { - constant_interval_exprt a(CEV(-5), CEV(-2)); - constant_interval_exprt b(CEV(7), CEV(11)); - - constant_interval_exprt result = a.multiply(b); + { + constant_interval_exprt a(CEV(-5), CEV(-2)); + constant_interval_exprt b(CEV(7), CEV(11)); - THEN("Domain is consistent") - { - CHECK(V(a.get_lower()) == -5); - CHECK(V(a.get_upper()) == -2); - CHECK(V(b.get_lower()) == 7); - CHECK(V(b.get_upper()) == 11); - } + constant_interval_exprt result = a.multiply(b); - CAPTURE(result); + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -5); + CHECK(V(a.get_upper()) == -2); + CHECK(V(b.get_lower()) == 7); + CHECK(V(b.get_upper()) == 11); + } + CAPTURE(result); - THEN("The result is [-55, -14]") - { - CHECK(V(result.get_lower()) == mp_integer(-55)); - CHECK(V(result.get_upper()) == -14); - } - } + THEN("The result is [-55, -14]") + { + CHECK(V(result.get_lower()) == mp_integer(-55)); + CHECK(V(result.get_upper()) == -14); + } + } WHEN("Range contains and extends from zero [-2,5]*[7,11]") - { - constant_interval_exprt a(CEV(-2), CEV(5)); - constant_interval_exprt b(CEV(7), CEV(11)); - - constant_interval_exprt result = a.multiply(b); - - THEN("Domain is consistent") - { - CHECK(V(a.get_lower()) == -2); - CHECK(V(a.get_upper()) == 5); - CHECK(V(b.get_lower()) == 7); - CHECK(V(b.get_upper()) == 11); - } + { + constant_interval_exprt a(CEV(-2), CEV(5)); + constant_interval_exprt b(CEV(7), CEV(11)); - CAPTURE(result); + constant_interval_exprt result = a.multiply(b); + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(V(b.get_upper()) == 11); + } - THEN("The result is [-22, 55]") - { - CHECK(V(result.get_lower()) == mp_integer(-22)); - CHECK(V(result.get_upper()) == 55); - } - } + CAPTURE(result); + THEN("The result is [-22, 55]") + { + CHECK(V(result.get_lower()) == mp_integer(-22)); + CHECK(V(result.get_upper()) == 55); + } + } WHEN("One domain is infinite and other crosses zero [-2,5]*[7,INF]") - { - constant_interval_exprt a(CEV(-2), CEV(5)); - constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); - - constant_interval_exprt result = a.multiply(b); + { + constant_interval_exprt a(CEV(-2), CEV(5)); + constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); - THEN("Domain is consistent") - { - CHECK(V(a.get_lower()) == -2); - CHECK(V(a.get_upper()) == 5); - CHECK(V(b.get_lower()) == 7); - CHECK(constant_interval_exprt::is_max(b.get_upper())); - } + constant_interval_exprt result = a.multiply(b); - CAPTURE(result); + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == -2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(constant_interval_exprt::is_max(b.get_upper())); + } - THEN("The result is [-INF, INF]") - { - CHECK(constant_interval_exprt::is_max(result.get_upper())); - CHECK(constant_interval_exprt::is_min(result.get_lower())); - } - } + CAPTURE(result); + THEN("The result is [-INF, INF]") + { + CHECK(constant_interval_exprt::is_max(result.get_upper())); + CHECK(constant_interval_exprt::is_min(result.get_lower())); + } + } WHEN("One domain is infinite and other is positive [2,5]*[7,INF]") - { - constant_interval_exprt a(CEV(2), CEV(5)); - constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); - constant_interval_exprt result = a.multiply(b); - - THEN("Domain is consistent") - { - CHECK(V(a.get_lower()) == 2); - CHECK(V(a.get_upper()) == 5); - CHECK(V(b.get_lower()) == 7); - CHECK(b.has_no_upper_bound()); - } - - THEN("The result is [-INF, INF]") - { - CAPTURE(result); - - CHECK(result.has_no_upper_bound()); - CHECK(result.has_no_lower_bound()); - } - } - } + { + constant_interval_exprt a(CEV(2), CEV(5)); + constant_interval_exprt b(CEV(7), max_exprt(signedbv_typet(32))); + constant_interval_exprt result = a.multiply(b); + THEN("Domain is consistent") + { + CHECK(V(a.get_lower()) == 2); + CHECK(V(a.get_upper()) == 5); + CHECK(V(b.get_lower()) == 7); + CHECK(b.has_no_upper_bound()); + } + + THEN("The result is [-INF, INF]") + { + CAPTURE(result); + CHECK(result.has_no_upper_bound()); + CHECK(result.has_no_lower_bound()); + } + } + } } diff --git a/unit/util/interval/shift.cpp b/unit/util/interval/shift.cpp index 72a2b341493..3813bf97bbc 100644 --- a/unit/util/interval/shift.cpp +++ b/unit/util/interval/shift.cpp @@ -5,19 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("shift interval domain", - "[core][analyses][interval][shift]") +SCENARIO("shift interval domain", "[core][analyses][interval][shift]") { GIVEN("Two simple signed intervals") { @@ -28,7 +26,10 @@ SCENARIO("shift interval domain", { THEN("Something else") { - REQUIRE(constant_interval_exprt(CEV(4), CEV(8)).left_shift(constant_interval_exprt(CEV(1))) == constant_interval_exprt(CEV(8), CEV(16))); + REQUIRE( + constant_interval_exprt(CEV(4), CEV(8)) + .left_shift(constant_interval_exprt(CEV(1))) == + constant_interval_exprt(CEV(8), CEV(16))); } } } diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index 52d28cc69b3..e9857e0f47a 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -5,19 +5,17 @@ #include +#include #include -#include #include +#include #include -#include -#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) -#define V_(X) (bvrep2integer(X.c_str(), 32, true)) +#define V(X) (bvrep2integer(X.get(ID_value).c_str(), 32, true)) +#define V_(X) (bvrep2integer(X.c_str(), 32, true)) #define CEV(X) (from_integer(mp_integer(X), signedbv_typet(32))) - -SCENARIO("subtract interval domain", - "[core][analyses][interval][subtract]") +SCENARIO("subtract interval domain", "[core][analyses][interval][subtract]") { GIVEN("Two simple signed intervals") { @@ -72,7 +70,7 @@ SCENARIO("subtract interval domain", WHEN("Both contain infinite [2,INF]-[6,INF]") { - constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); + constant_interval_exprt left(CEV(2), max_exprt(signedbv_typet(32))); constant_interval_exprt right(CEV(6), max_exprt(signedbv_typet(32))); constant_interval_exprt result = left.minus(right); @@ -98,14 +96,14 @@ SCENARIO("subtract interval domain", SCENARIO("Subtracting unsigned integers") { - auto get_value = [](int x) { - return from_integer(x, signedbv_typet(32)); - }; + auto get_value = [](int x) { return from_integer(x, signedbv_typet(32)); }; - WHEN("Subtracting two constant intervals") { + WHEN("Subtracting two constant intervals") + { auto lhs = constant_interval_exprt(get_value(10)); auto rhs = constant_interval_exprt(get_value(3)); - THEN("it should work") { + THEN("it should work") + { auto result = lhs.minus(rhs); REQUIRE(result.is_single_value_interval()); auto maybe_lower = numeric_cast(result.get_lower()); From d92a7dba2f35ae522978c5a1af8061bf4b5c75aa Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 9 Dec 2019 22:28:47 +0000 Subject: [PATCH 35/35] Fixes for the linter. --- src/util/interval.h | 6 +++--- unit/util/interval/module_dependencies.txt | 3 +++ unit/util/interval/subtract.cpp | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 unit/util/interval/module_dependencies.txt diff --git a/src/util/interval.h b/src/util/interval.h index bd154967044..cadb323f19c 100644 --- a/src/util/interval.h +++ b/src/util/interval.h @@ -5,8 +5,8 @@ Author: Daniel Neville (2017) \*******************************************************************/ -#ifndef SRC_ANALYSES_INTERVAL_H_ -#define SRC_ANALYSES_INTERVAL_H_ +#ifndef CPROVER_UTIL_INTERVAL_H +#define CPROVER_UTIL_INTERVAL_H #include #include @@ -69,7 +69,7 @@ class constant_interval_exprt : public binary_exprt { } - constant_interval_exprt(const exprt &x) + explicit constant_interval_exprt(const exprt &x) : constant_interval_exprt(x, x, x.type()) { } diff --git a/unit/util/interval/module_dependencies.txt b/unit/util/interval/module_dependencies.txt new file mode 100644 index 00000000000..253b4a5d0f0 --- /dev/null +++ b/unit/util/interval/module_dependencies.txt @@ -0,0 +1,3 @@ +testing-utils +util + diff --git a/unit/util/interval/subtract.cpp b/unit/util/interval/subtract.cpp index e9857e0f47a..84f2386493d 100644 --- a/unit/util/interval/subtract.cpp +++ b/unit/util/interval/subtract.cpp @@ -94,7 +94,9 @@ SCENARIO("subtract interval domain", "[core][analyses][interval][subtract]") } } -SCENARIO("Subtracting unsigned integers") +SCENARIO( + "Subtracting unsigned integers", + "[core][analyses][interval][subtract]") { auto get_value = [](int x) { return from_integer(x, signedbv_typet(32)); };