Skip to content

Commit 8ce6943

Browse files
committed
CHC encoder: universally quantify nondeterministic choices
Nondeterministic choices must be universally quantified, as opposed to existentially, to yield the desired adversarial nondeterminism.
1 parent beb35ec commit 8ce6943

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

regression/goto-instrument-chc/basic/nondet1.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ nondet1.c
33
--horn
44
^EXIT=0$
55
^SIGNAL=0$
6-
^\(assert \(forall \( \(|__CPROVER_rounding_mode| \(_ BitVec 32\)\) \(|main::1::x| \(_ BitVec 32\)\) \(|main::1::y| \(_ BitVec 32\)\) \(|return_value| \(_ BitVec 32\)\) \) \(=> \(|S30Entry| |__CPROVER_rounding_mode| |main::1::x| |main::1::y| |return_value|\) \(|S30\.2| |__CPROVER_rounding_mode| |nondet::S30\.2| |main::1::y| |return_value|\)\)\)\)$
7-
^\(assert \(forall \( \(|__CPROVER_rounding_mode| \(_ BitVec 32\)\) \(|main::1::x| \(_ BitVec 32\)\) \(|main::1::y| \(_ BitVec 32\)\) \(|return_value| \(_ BitVec 32\)\) \) \(=> \(|S30\.2| |__CPROVER_rounding_mode| |main::1::x| |main::1::y| |return_value|\) \(= |main::1::x| \(_ bv20 32\)\)\)\)\)$
6+
^\(assert \(forall \( \(__CPROVER_rounding_mode \(_ BitVec 32\)\) \(|main::1::x| \(_ BitVec 32\)\) \(|main::1::y| \(_ BitVec 32\)\) \(return_value \(_ BitVec 32\)\) \(|nondet::S30\.2| \(_ BitVec 32\)\) \) \(=> \(S30Entry __CPROVER_rounding_mode |main::1::x| |main::1::y| return_value\) \(S30\.2 __CPROVER_rounding_mode |nondet::S30\.2| |main::1::y| return_value\)\)\)\)$
7+
^\(assert \(forall \( \(__CPROVER_rounding_mode \(_ BitVec 32\)\) \(|main::1::x| \(_ BitVec 32\)\) \(|main::1::y| \(_ BitVec 32\)\) \(return_value \(_ BitVec 32\)\) \) \(=> \(S30\.2 __CPROVER_rounding_mode |main::1::x| |main::1::y| return_value\) \(= |main::1::x| \(_ bv20 32\)\)\)\)\)$
88
--

src/goto-instrument/horn_encoding.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,14 @@ exprt state_encodingt::assignment_constraint(loct loc, exprt lhs, exprt rhs)
663663

664664
auto new_state = update_state_exprt(s, address, new_value);
665665

666-
return forall_states_expr(
667-
loc, function_application_exprt(out_state_expr(loc), {new_state}));
666+
forall_exprt::variablest binding = {state_expr()};
667+
binding.insert(binding.end(), nondet_symbols.begin(), nondet_symbols.end());
668+
669+
return forall_exprt(
670+
std::move(binding),
671+
implies_exprt(
672+
function_application_exprt(in_state_expr(loc), {state_expr()}),
673+
function_application_exprt(out_state_expr(loc), {new_state})));
668674
}
669675

670676
void state_encodingt::setup_incoming(const goto_functiont &goto_function)
@@ -1042,11 +1048,17 @@ exprt variable_encoding(exprt src, const binding_exprt::variablest &variables)
10421048
{
10431049
auto &forall_expr = to_forall_expr(src);
10441050
if(
1045-
forall_expr.variables().size() == 1 &&
1046-
forall_expr.symbol().type().id() == ID_state)
1051+
forall_expr.variables().size() >= 1 &&
1052+
forall_expr.variables().front().type().id() == ID_state)
10471053
{
1054+
// replace 'state' by the program variables
1055+
forall_exprt::variablest new_variables = variables;
1056+
new_variables.insert(
1057+
new_variables.end(),
1058+
forall_expr.variables().begin() + 1,
1059+
forall_expr.variables().end());
10481060
forall_expr
1049-
.variables() = variables;
1061+
.variables() = std::move(new_variables);
10501062
return std::move(forall_expr);
10511063
}
10521064
}

0 commit comments

Comments
 (0)