@@ -32,6 +32,12 @@ class state_encodingt
32
32
const goto_functiont &,
33
33
encoding_targett &);
34
34
35
+ void encode (
36
+ const goto_functionst &,
37
+ const goto_functiont &,
38
+ const symbol_exprt &entry_state,
39
+ encoding_targett &);
40
+
35
41
protected:
36
42
using loct = goto_programt::const_targett;
37
43
@@ -63,6 +69,7 @@ class state_encodingt
63
69
encoding_targett &);
64
70
65
71
loct first_loc;
72
+ symbol_exprt entry_state = symbol_exprt(irep_idt(), typet());
66
73
using incomingt = std::map<loct, std::vector<loct>>;
67
74
incomingt incoming;
68
75
};
@@ -116,7 +123,7 @@ std::vector<irep_idt> state_encodingt::incoming_symbols(loct loc) const
116
123
symbol_exprt state_encodingt::in_state_expr (loct loc) const
117
124
{
118
125
if (loc == first_loc)
119
- return symbol_exprt ( " SInitial " , state_predicate_type ()) ;
126
+ return entry_state ;
120
127
121
128
auto incoming_symbols = this ->incoming_symbols (loc);
122
129
@@ -363,8 +370,9 @@ void state_encodingt::function_call_symbol(
363
370
goto_programt::const_targett loc,
364
371
encoding_targett &dest)
365
372
{
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 ();
368
376
369
377
// malloc is special-cased
370
378
if (identifier == " malloc" )
@@ -403,25 +411,31 @@ void state_encodingt::function_call_symbol(
403
411
}
404
412
405
413
// 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 ();
410
415
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
+ }
414
424
425
+ // Now assign them
415
426
auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
416
-
417
427
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);
420
434
421
435
// Function return state (suffix PostReturn).
422
436
// This is the state after exiting the function but prior to
423
437
// 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");
425
439
426
440
/*
427
441
constraints.push_back(
@@ -434,7 +448,7 @@ void state_encodingt::function_call_symbol(
434
448
// assign the return value, if any
435
449
if (loc->call_lhs ().is_not_nil ())
436
450
{
437
- exprt equality_rhs = return_state;
451
+ // exprt equality_rhs = return_state;
438
452
439
453
/*
440
454
auto &return_type = loc->call_lhs().type();
@@ -498,16 +512,27 @@ void state_encodingt::operator()(
498
512
if (goto_function.body .instructions .empty ())
499
513
return ;
500
514
501
- first_loc = goto_function.body .instructions .begin ();
502
-
503
- setup_incoming (goto_function);
504
-
505
515
// initial state
516
+ auto in_state = symbol_exprt (" SInitial" , state_predicate_type ());
517
+
506
518
dest << forall_exprt (
507
519
{state_expr ()},
508
520
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);
511
536
512
537
// constraints for each instruction
513
538
forall_goto_program_instructions (loc, goto_function.body )
0 commit comments