@@ -27,25 +27,31 @@ Module: State Encoding
27
27
class state_encodingt
28
28
{
29
29
public:
30
+ state_encodingt (const goto_functionst &__goto_functions)
31
+ : goto_functions(__goto_functions)
32
+ {
33
+ }
34
+
30
35
void operator ()(
31
- const goto_functionst &,
32
36
const goto_functiont &,
33
37
encoding_targett &);
34
38
35
39
void encode (
36
- const goto_functionst &,
37
40
const goto_functiont &,
41
+ const std::string &state_prefix,
38
42
const symbol_exprt &entry_state,
43
+ const exprt &return_lhs,
39
44
encoding_targett &);
40
45
41
46
protected:
42
47
using loct = goto_programt::const_targett;
48
+ const goto_functionst &goto_functions;
43
49
44
50
symbol_exprt out_state_expr (loct) const ;
45
51
symbol_exprt state_expr_with_suffix (loct, const std::string &suffix) const ;
46
52
symbol_exprt out_state_expr (loct, bool taken) const ;
47
53
symbol_exprt in_state_expr (loct) const ;
48
- std::vector<irep_idt > incoming_symbols (loct) const ;
54
+ std::vector<symbol_exprt > incoming_symbols (loct) const ;
49
55
exprt evaluate_expr (loct, const exprt &, const exprt &) const ;
50
56
exprt evaluate_expr_rec (
51
57
loct,
@@ -60,16 +66,16 @@ class state_encodingt
60
66
void setup_incoming (const goto_functiont &);
61
67
exprt assignment_constraint (loct, exprt lhs, exprt rhs) const ;
62
68
void function_call (
63
- const goto_functionst &,
64
69
goto_programt::const_targett,
65
70
encoding_targett &);
66
71
void function_call_symbol (
67
- const goto_functionst &,
68
72
goto_programt::const_targett,
69
73
encoding_targett &);
70
74
75
+ std::string state_prefix;
71
76
loct first_loc;
72
77
symbol_exprt entry_state = symbol_exprt(irep_idt(), typet());
78
+ exprt return_lhs = nil_exprt();
73
79
using incomingt = std::map<loct, std::vector<loct>>;
74
80
incomingt incoming;
75
81
};
@@ -84,7 +90,7 @@ symbol_exprt state_encodingt::state_expr_with_suffix(
84
90
const std::string &suffix) const
85
91
{
86
92
irep_idt identifier =
87
- std::string ( " S " ) + std::to_string (loc->location_number ) + suffix;
93
+ state_prefix + std::to_string (loc->location_number ) + suffix;
88
94
return symbol_exprt (identifier, state_predicate_type ());
89
95
}
90
96
@@ -93,13 +99,13 @@ symbol_exprt state_encodingt::out_state_expr(loct loc, bool taken) const
93
99
return state_expr_with_suffix (loc, taken ? " T" : " " );
94
100
}
95
101
96
- std::vector<irep_idt > state_encodingt::incoming_symbols (loct loc) const
102
+ std::vector<symbol_exprt > state_encodingt::incoming_symbols (loct loc) const
97
103
{
98
104
auto incoming_it = incoming.find (loc);
99
105
100
106
DATA_INVARIANT (incoming_it != incoming.end (), " incoming is complete" );
101
107
102
- std::vector<irep_idt > symbols;
108
+ std::vector<symbol_exprt > symbols;
103
109
symbols.reserve (incoming_it->second .size ());
104
110
105
111
for (auto &loc_in : incoming_it->second )
@@ -114,7 +120,7 @@ std::vector<irep_idt> state_encodingt::incoming_symbols(loct loc) const
114
120
suffix = " T" ;
115
121
}
116
122
117
- symbols.push_back (" S " + std::to_string (loc_in-> location_number ) + suffix);
123
+ symbols.push_back (state_expr_with_suffix (loc_in, suffix) );
118
124
}
119
125
120
126
return symbols;
@@ -128,10 +134,9 @@ symbol_exprt state_encodingt::in_state_expr(loct loc) const
128
134
auto incoming_symbols = this ->incoming_symbols (loc);
129
135
130
136
if (incoming_symbols.size () == 1 )
131
- return symbol_exprt (incoming_symbols.front (), state_predicate_type ());
132
-
133
- return symbol_exprt (
134
- " S" + std::to_string (loc->location_number ) + " in" , state_predicate_type ());
137
+ return incoming_symbols.front ();
138
+ else
139
+ return state_expr_with_suffix (loc, " in" );
135
140
}
136
141
137
142
exprt state_encodingt::evaluate_expr (
@@ -366,7 +371,6 @@ static exprt simplifying_not(exprt src)
366
371
}
367
372
368
373
void state_encodingt::function_call_symbol (
369
- const goto_functionst &goto_functions,
370
374
goto_programt::const_targett loc,
371
375
encoding_targett &dest)
372
376
{
@@ -428,9 +432,11 @@ void state_encodingt::function_call_symbol(
428
432
loc, function_application_exprt (function_entry_state, {arguments_state}));
429
433
430
434
// now do the body, recursively
431
- state_encodingt body_state_encoding;
435
+ state_encodingt body_state_encoding (goto_functions);
436
+ auto new_state_prefix =
437
+ state_prefix + std::to_string (loc->location_number ) + " ." ;
432
438
body_state_encoding.encode (
433
- goto_functions, f->second , function_entry_state, dest);
439
+ f->second , new_state_prefix, function_entry_state, nil_exprt () , dest);
434
440
435
441
// Function return state (suffix PostReturn).
436
442
// This is the state after exiting the function but prior to
@@ -481,7 +487,6 @@ void state_encodingt::function_call_symbol(
481
487
}
482
488
483
489
void state_encodingt::function_call (
484
- const goto_functionst &goto_functions,
485
490
goto_programt::const_targett loc,
486
491
encoding_targett &dest)
487
492
{
@@ -495,7 +500,7 @@ void state_encodingt::function_call(
495
500
}
496
501
else if (function.id () == ID_symbol)
497
502
{
498
- function_call_symbol (goto_functions, loc, dest);
503
+ function_call_symbol (loc, dest);
499
504
}
500
505
else
501
506
{
@@ -505,7 +510,6 @@ void state_encodingt::function_call(
505
510
}
506
511
507
512
void state_encodingt::operator ()(
508
- const goto_functionst &goto_functions,
509
513
const goto_functiont &goto_function,
510
514
encoding_targett &dest)
511
515
{
@@ -520,17 +524,20 @@ void state_encodingt::operator()(
520
524
implies_exprt (
521
525
true_exprt (), function_application_exprt (in_state, {state_expr ()})));
522
526
523
- encode (goto_functions, goto_function , in_state, dest);
527
+ encode (goto_function, " S " , in_state, nil_exprt () , dest);
524
528
}
525
529
526
530
void state_encodingt::encode (
527
- const goto_functionst &goto_functions,
528
531
const goto_functiont &goto_function,
532
+ const std::string &state_prefix,
529
533
const symbol_exprt &entry_state,
534
+ const exprt &return_lhs,
530
535
encoding_targett &dest)
531
536
{
532
537
first_loc = goto_function.body .instructions .begin ();
538
+ this ->state_prefix = state_prefix;
533
539
this ->entry_state = entry_state;
540
+ this ->return_lhs = return_lhs;
534
541
535
542
setup_incoming (goto_function);
536
543
@@ -549,13 +556,10 @@ void state_encodingt::encode(
549
556
auto s = state_expr ();
550
557
for (auto incoming_symbol : incoming_symbols)
551
558
{
552
- auto incoming_state =
553
- symbol_exprt (incoming_symbol, state_predicate_type ());
554
-
555
559
dest << forall_exprt (
556
560
{s},
557
561
implies_exprt (
558
- function_application_exprt (std::move (incoming_state) , {s}),
562
+ function_application_exprt (incoming_symbol , {s}),
559
563
function_application_exprt (in_state_expr (loc), {s})));
560
564
}
561
565
}
@@ -645,14 +649,21 @@ void state_encodingt::encode(
645
649
}
646
650
else if (loc->is_function_call ())
647
651
{
648
- function_call (goto_functions, loc, dest);
652
+ function_call (loc, dest);
649
653
}
650
654
else if (loc->is_set_return_value ())
651
655
{
652
- // treat these as assignments to a special symbol named 'return_value'
653
- auto rhs = loc->return_value ();
654
- auto lhs = symbol_exprt (" return_value" , rhs.type ());
655
- dest << assignment_constraint (loc, std::move (lhs), std::move (rhs));
656
+ const auto &rhs = loc->return_value ();
657
+
658
+ if (return_lhs.is_nil ())
659
+ {
660
+ // treat these as assignments to a special symbol named 'return_value'
661
+ auto lhs = symbol_exprt (" return_value" , rhs.type ());
662
+ dest << assignment_constraint (loc, std::move (lhs), std::move (rhs));
663
+ }
664
+ else
665
+ {
666
+ }
656
667
}
657
668
}
658
669
}
@@ -670,7 +681,7 @@ void state_encoding(
670
681
if (f_entry == goto_model.goto_functions .function_map .end ())
671
682
throw incorrect_goto_program_exceptiont (" The program has no entry point" );
672
683
673
- state_encodingt{}( goto_model.goto_functions , f_entry->second , dest);
684
+ state_encodingt{goto_model.goto_functions }( f_entry->second , dest);
674
685
}
675
686
else
676
687
{
@@ -682,7 +693,7 @@ void state_encoding(
682
693
if (f->second .body_available ())
683
694
{
684
695
dest.annotation (" function " + id2string (f->first ));
685
- state_encodingt{}( goto_model.goto_functions , f->second , dest);
696
+ state_encodingt{goto_model.goto_functions }( f->second , dest);
686
697
}
687
698
}
688
699
}
0 commit comments