Skip to content

Commit 3831765

Browse files
committed
Updated nondet solution injection in CEGIS control.
1 parent bcc964a commit 3831765

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

src/cegis/control/learn/nondet_solution.cpp

+75-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <deque>
12
#include <algorithm>
23

34
#include <cegis/control/value/control_vars.h>
@@ -23,17 +24,87 @@ void remove_solution_assignment_from_cprover_init(goto_functionst &gf)
2324
assert(end != pos);
2425
i.erase(pos);
2526
}
27+
28+
const exprt &get_comp(const namespacet &ns, const struct_exprt &value,
29+
const char * const comp)
30+
{
31+
const struct_typet &type=to_struct_type(ns.follow(value.type()));
32+
const struct_typet::componentst &comps=type.components();
33+
for (size_t i=0; i < comps.size(); ++i)
34+
if (id2string(comps[i].get_name()) == comp) return value.operands()[i];
35+
assert(!"Solution component not found.");
36+
}
37+
38+
const exprt &get_a_size(const namespacet &ns, const struct_exprt &value)
39+
{
40+
return get_comp(ns, value, CEGIS_CONTROL_A_SIZE_MEMBER_NAME);
41+
}
42+
43+
const exprt &get_b_size(const namespacet &ns, const struct_exprt &value)
44+
{
45+
return get_comp(ns, value, CEGIS_CONTROL_B_SIZE_MEMBER_NAME);
46+
}
47+
48+
class replace_sizes_visitort: public expr_visitort
49+
{
50+
std::deque<exprt *> a_sizes, b_sizes;
51+
const exprt &a_size;
52+
const exprt &b_size;
53+
public:
54+
replace_sizes_visitort(const exprt &a_size, const exprt &b_size) :
55+
a_size(a_size), b_size(b_size)
56+
{
57+
}
58+
59+
virtual ~replace_sizes_visitort()
60+
{
61+
for (exprt * const expr : a_sizes)
62+
*expr=a_size;
63+
for (exprt * const expr : b_sizes)
64+
*expr=b_size;
65+
}
66+
67+
virtual void operator()(exprt &expr)
68+
{
69+
if (ID_member != expr.id()) return;
70+
const member_exprt &member=to_member_expr(expr);
71+
const exprt &struct_op=member.struct_op();
72+
if (ID_symbol != struct_op.id()) return;
73+
const symbol_exprt &symbol=to_symbol_expr(struct_op);
74+
const std::string &var=id2string(symbol.get_identifier());
75+
if (CEGIS_CONTROL_SOLUTION_VAR_NAME != var) return;
76+
const std::string &comp=id2string(member.get_component_name());
77+
if (CEGIS_CONTROL_A_SIZE_MEMBER_NAME == comp) a_sizes.push_back(&expr);
78+
else if (CEGIS_CONTROL_B_SIZE_MEMBER_NAME == comp) b_sizes.push_back(&expr);
79+
}
80+
};
81+
82+
void replace_controller_sizes(const symbol_tablet &st, goto_functionst &gf)
83+
{
84+
const symbolt &symbol=st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME);
85+
const struct_exprt &controller_value=to_struct_expr(symbol.value);
86+
const namespacet ns(st);
87+
const exprt &a_size=get_a_size(ns, controller_value);
88+
const exprt &b_size=get_b_size(ns, controller_value);
89+
replace_sizes_visitort visitor(a_size, b_size);
90+
goto_programt &body=get_entry_body(gf);
91+
for (goto_programt::instructiont &instr : body.instructions)
92+
{
93+
instr.code.visit(visitor);
94+
instr.guard.visit(visitor);
95+
}
96+
}
2697
}
2798

2899
void nondet_control_solution(const symbol_tablet &st, goto_functionst &gf)
29100
{
30-
const irep_idt name(CEGIS_CONTROL_SOLUTION_VAR_NAME);
101+
const std::string name(CEGIS_CONTROL_SOLUTION_VAR_NAME);
31102
const symbolt &symbol=st.lookup(name);
103+
replace_controller_sizes(st, gf);
32104
const side_effect_expr_nondett value(symbol.type);
33105
const symbol_exprt solution_var(symbol.symbol_expr());
34106
goto_programt &body=get_entry_body(gf);
35-
const goto_programt::targett pos(find_cprover_initialize(body));
36-
cegis_assign_user_variable(st, gf, std::prev(pos), name, value);
37-
// TODO: Extract a_size, b_size and assign
107+
goto_programt::targett pos(find_cprover_initialize(body));
108+
pos=cegis_assign_user_variable(st, gf, std::prev(pos), name, value);
38109
remove_solution_assignment_from_cprover_init(gf);
39110
}

src/cegis/control/value/control_vars.h

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
#define CEGIS_CONTROL_SOLUTION_VAR_NAME "controller"
1414
#define CEGIS_CONTROL_A_MEMBER_NAME "a"
1515
#define CEGIS_CONTROL_A_SIZE_MEMBER_NAME "a_size"
16+
#define CEGIS_CONTROL_B_SIZE_MEMBER_NAME "b_size"
1617

1718
#endif /* CEGIS_CONTROL_VARS_H_ */

0 commit comments

Comments
 (0)