@@ -32,6 +32,12 @@ class state_encodingt
3232 const goto_functiont &,
3333 encoding_targett &);
3434
35+ void encode (
36+ const goto_functionst &,
37+ const goto_functiont &,
38+ const symbol_exprt &entry_state,
39+ encoding_targett &);
40+
3541protected:
3642 using loct = goto_programt::const_targett;
3743
@@ -63,6 +69,7 @@ class state_encodingt
6369 encoding_targett &);
6470
6571 loct first_loc;
72+ symbol_exprt entry_state = symbol_exprt(irep_idt(), typet());
6673 using incomingt = std::map<loct, std::vector<loct>>;
6774 incomingt incoming;
6875};
@@ -116,7 +123,7 @@ std::vector<irep_idt> state_encodingt::incoming_symbols(loct loc) const
116123symbol_exprt state_encodingt::in_state_expr (loct loc) const
117124{
118125 if (loc == first_loc)
119- return symbol_exprt ( " SInitial " , state_predicate_type ()) ;
126+ return entry_state ;
120127
121128 auto incoming_symbols = this ->incoming_symbols (loc);
122129
@@ -363,8 +370,9 @@ void state_encodingt::function_call_symbol(
363370 goto_programt::const_targett loc,
364371 encoding_targett &dest)
365372{
366- const auto &function = loc->call_function ();
367- auto identifier = to_symbol_expr (function).get_identifier ();
373+ const auto &function = to_symbol_expr (loc->call_function ());
374+ const auto &type = to_code_type (function.type ());
375+ auto identifier = function.get_identifier ();
368376
369377 // malloc is special-cased
370378 if (identifier == " malloc" )
@@ -403,25 +411,31 @@ void state_encodingt::function_call_symbol(
403411 }
404412
405413 // Evaluate the arguments of the call in the 'in state'
406- multi_ary_exprt arguments_evaluated (ID_tuple, {}, typet (ID_tuple));
407- arguments_evaluated.reserve_operands (loc->call_arguments ().size ());
408-
409- const auto in_state = in_state_expr (loc);
414+ exprt arguments_state = state_expr ();
410415
411- for (auto &argument : loc->call_arguments ())
412- arguments_evaluated.add_to_operands (
413- evaluate_expr (loc, in_state, argument));
416+ for (std::size_t i = 0 ; i < type.parameters ().size (); i++)
417+ {
418+ auto address = object_address_exprt (symbol_exprt (
419+ f->second .parameter_identifiers [i], type.parameters ()[i].type ()));
420+ auto argument = loc->call_arguments ()[i];
421+ auto value = evaluate_expr (loc, state_expr (), argument);
422+ arguments_state = update_state_exprt (arguments_state, address, value);
423+ }
414424
425+ // Now assign them
415426 auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
416-
417427 dest << forall_states_expr (
418- loc,
419- function_application_exprt (function_entry_state, {state_expr ()}));
428+ loc, function_application_exprt (function_entry_state, {arguments_state}));
429+
430+ // now do the body, recursively
431+ state_encodingt body_state_encoding;
432+ body_state_encoding.encode (
433+ goto_functions, f->second , function_entry_state, dest);
420434
421435 // Function return state (suffix PostReturn).
422436 // This is the state after exiting the function but prior to
423437 // assigning the LHS of the function call.
424- auto return_state = state_expr_with_suffix (loc, " PostReturn" );
438+ // auto return_state = state_expr_with_suffix(loc, "PostReturn");
425439
426440 /*
427441 constraints.push_back(
@@ -434,7 +448,7 @@ void state_encodingt::function_call_symbol(
434448 // assign the return value, if any
435449 if (loc->call_lhs ().is_not_nil ())
436450 {
437- exprt equality_rhs = return_state;
451+ // exprt equality_rhs = return_state;
438452
439453 /*
440454 auto &return_type = loc->call_lhs().type();
@@ -498,16 +512,27 @@ void state_encodingt::operator()(
498512 if (goto_function.body .instructions .empty ())
499513 return ;
500514
501- first_loc = goto_function.body .instructions .begin ();
502-
503- setup_incoming (goto_function);
504-
505515 // initial state
516+ auto in_state = symbol_exprt (" SInitial" , state_predicate_type ());
517+
506518 dest << forall_exprt (
507519 {state_expr ()},
508520 implies_exprt (
509- true_exprt (),
510- function_application_exprt (in_state_expr (first_loc), {state_expr ()})));
521+ true_exprt (), function_application_exprt (in_state, {state_expr ()})));
522+
523+ encode (goto_functions, goto_function, in_state, dest);
524+ }
525+
526+ void state_encodingt::encode (
527+ const goto_functionst &goto_functions,
528+ const goto_functiont &goto_function,
529+ const symbol_exprt &entry_state,
530+ encoding_targett &dest)
531+ {
532+ first_loc = goto_function.body .instructions .begin ();
533+ this ->entry_state = entry_state;
534+
535+ setup_incoming (goto_function);
511536
512537 // constraints for each instruction
513538 forall_goto_program_instructions (loc, goto_function.body )
0 commit comments