Skip to content

Commit 38a3362

Browse files
author
Pascal Kesseli
committed
First full CEGIS control symex synthesis.
1 parent 55d2c91 commit 38a3362

18 files changed

+7053
-1325
lines changed

regression/cegis/cegis_control_benchmark_01/example-a_SCHEMA1_IMPL1.c

Lines changed: 653 additions & 615 deletions
Large diffs are not rendered by default.

regression/cegis/cegis_control_benchmark_01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
example-a_SCHEMA1_IMPL1.c
3-
--gcc --cegis-control --cegis-statistics --cegis-genetic
3+
--gcc --cegis-control --cegis-statistics --cegis-genetic --cegis-max-size 1
44
^EXIT=0$
55
^SIGNAL=0$
66
--

regression/cegis/cegis_control_benchmark_02/example-a_SCHEMA2_IMPL1.c

Lines changed: 613 additions & 581 deletions
Large diffs are not rendered by default.

regression/cegis/cegis_control_benchmark_03/example-a_PLANT2_SCHEMA4_IMPL3.c

Lines changed: 5279 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
example-a_PLANT2_SCHEMA4_IMPL3.c
3+
--gcc --cegis-control --cegis-statistics --cegis-genetic --cegis-max-size 1
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring

src/cegis/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ SRC = danger/meta/meta_variable_names.cpp danger/facade/danger_runner.cpp danger
4646
jsa/genetic/jsa_source_provider.cpp jsa/genetic/dynamic_jsa_test_runner.cpp jsa/genetic/random_jsa_mutate.cpp \
4747
jsa/genetic/random_jsa_cross.cpp jsa/genetic/jsa_genetic_convert.cpp jsa/genetic/jsa_random.cpp \
4848
jsa/genetic/solution_helper.cpp jsa/genetic/jsa_serialiser.cpp jsa/genetic/jsa_paragon_wrapper.cpp \
49-
control/facade/control_runner.cpp control/preprocessing/control_preprocessing.cpp \
49+
control/facade/control_runner.cpp \
50+
control/preprocessing/control_preprocessing.cpp control/preprocessing/propagate_controller_sizes.cpp \
5051
control/options/control_program.cpp \
5152
control/learn/control_symex_learn.cpp control/learn/nondet_solution.cpp \
53+
control/simplify/remove_unused_elements.cpp \
5254
control/verify/control_symex_verify.cpp control/verify/insert_solution.cpp \
53-
control/value/control_types.cpp \
55+
control/value/float_helper.cpp control/value/control_types.cpp \
5456
wordsize/restrict_bv_size.cpp value/program_individual_serialisation.cpp value/assignments_printer.cpp \
5557
seed/literals_seed.cpp \
5658
genetic/instruction_set_info_factory.cpp genetic/random_mutate.cpp genetic/random_cross.cpp \

src/cegis/control/learn/control_symex_learn.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
#include <goto-programs/goto_trace.h>
2+
3+
#include <cegis/cegis-util/program_helper.h>
14
#include <cegis/learn/constraint_helper.h>
25
#include <cegis/learn/insert_counterexample.h>
6+
#include <cegis/control/value/control_vars.h>
7+
#include <cegis/control/value/float_helper.h>
8+
#include <cegis/control/preprocessing/propagate_controller_sizes.h>
39
#include <cegis/control/learn/nondet_solution.h>
410
#include <cegis/control/learn/control_symex_learn.h>
511

@@ -37,11 +43,50 @@ void control_symex_learnt::set_word_width(const size_t word_width_in_bits) const
3743
{
3844
}
3945

46+
namespace
47+
{
48+
const struct_exprt &find_solution(const goto_tracet &trace)
49+
{
50+
for (const goto_trace_stept &step : trace.steps)
51+
{
52+
const exprt &lhs=step.full_lhs;
53+
if (ID_symbol != lhs.id()) continue;
54+
const std::string &id=id2string(to_symbol_expr(lhs).get_identifier());
55+
if (CEGIS_CONTROL_SOLUTION_VAR_NAME != id) continue;
56+
return to_struct_expr(step.full_lhs_value);
57+
}
58+
assert(!"Control solution not found in trace.");
59+
}
60+
61+
const array_exprt &get_a(const namespacet &ns, const struct_exprt &solution)
62+
{
63+
return to_array_expr(
64+
get_controller_comp(ns, solution, CEGIS_CONTROL_A_MEMBER_NAME));
65+
}
66+
67+
const array_exprt &get_b(const namespacet &ns, const struct_exprt &solution)
68+
{
69+
return to_array_expr(
70+
get_controller_comp(ns, solution, CEGIS_CONTROL_B_MEMBER_NAME));
71+
}
72+
73+
void extract(std::vector<double> &data, const array_exprt &array)
74+
{
75+
const exprt::operandst &ops=array.operands();
76+
const size_t size=ops.size();
77+
data.resize(size);
78+
for (size_t i=0; i < size; ++i)
79+
data[i]=to_control_float(to_constant_expr(ops[i]));
80+
}
81+
}
82+
4083
void control_symex_learnt::convert(candidatet &current_candidate,
4184
const goto_tracet &trace, const size_t max_solution_size) const
4285
{
43-
// TODO: Implement
44-
assert(false);
86+
const struct_exprt &solution=find_solution(trace);
87+
const namespacet ns(current_program.st);
88+
extract(current_candidate.a, get_a(ns, solution));
89+
extract(current_candidate.b, get_b(ns, solution));
4590
}
4691

4792
namespace
Lines changed: 7 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,19 @@
1-
#include <deque>
2-
#include <algorithm>
3-
4-
#include <cegis/control/value/control_vars.h>
51
#include <cegis/cegis-util/program_helper.h>
62
#include <cegis/instrument/literals.h>
73
#include <cegis/instrument/find_cprover_initialize.h>
8-
#include <cegis/control/learn/nondet_solution.h>
9-
10-
namespace
11-
{
12-
bool is_sol_assign(const goto_programt::instructiont &instr)
13-
{
14-
if (goto_program_instruction_typet::ASSIGN != instr.type) return false;
15-
const std::string &var=id2string(get_affected_variable(instr));
16-
return CEGIS_CONTROL_SOLUTION_VAR_NAME == var;
17-
}
18-
19-
void remove_solution_assignment_from_cprover_init(goto_functionst &gf)
20-
{
21-
goto_programt::instructionst &i=get_body(gf, CPROVER_INIT).instructions;
22-
const goto_programt::targett end(i.end());
23-
const goto_programt::targett pos=std::find_if(i.begin(), end, is_sol_assign);
24-
assert(end != pos);
25-
i.erase(pos);
26-
}
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-
}
97-
}
4+
#include <cegis/control/value/control_vars.h>
5+
#include <cegis/control/preprocessing/propagate_controller_sizes.h>
986

997
void nondet_control_solution(const symbol_tablet &st, goto_functionst &gf)
1008
{
1019
const std::string name(CEGIS_CONTROL_SOLUTION_VAR_NAME);
10210
const symbolt &symbol=st.lookup(name);
103-
replace_controller_sizes(st, gf);
11+
propagate_controller_sizes(st, gf);
10412
const side_effect_expr_nondett value(symbol.type);
10513
const symbol_exprt solution_var(symbol.symbol_expr());
10614
goto_programt &body=get_entry_body(gf);
107-
goto_programt::targett pos(find_cprover_initialize(body));
108-
pos=cegis_assign_user_variable(st, gf, std::prev(pos), name, value);
109-
remove_solution_assignment_from_cprover_init(gf);
15+
const goto_programt::targett pos(find_cprover_initialize(body));
16+
cegis_assign_user_variable(st, gf, std::prev(pos), name, value);
17+
goto_programt &init=get_body(gf, CPROVER_INIT);
18+
remove_solution_assignment(init);
11019
}

src/cegis/control/preprocessing/control_preprocessing.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <cegis/cegis-util/inline_user_program.h>
33
#include <cegis/cegis-util/counterexample_vars.h>
44
#include <cegis/cegis-util/program_helper.h>
5+
#include <cegis/control/value/control_vars.h>
6+
#include <cegis/control/simplify/remove_unused_elements.h>
57
#include <cegis/control/preprocessing/control_preprocessing.h>
68

79
control_preprocessingt::control_preprocessingt(const symbol_tablet &st,
@@ -12,7 +14,7 @@ control_preprocessingt::control_preprocessingt(const symbol_tablet &st,
1214

1315
namespace
1416
{
15-
const char * const excluded_functions[]= {
17+
const char * const excluded_functions[]={
1618
"verify_stability_closedloop_using_dslib", "check_stability_closedloop",
1719
"fxp_double_to_fxp", "fxp_to_double", "ft_closedloop_series", "poly_mult",
1820
"poly_sum", "internal_pow" };
@@ -24,14 +26,20 @@ bool is_meta(const goto_programt::const_targett pos)
2426
const std::string &func=id2string(loc.get_function());
2527
for (const char * const excluded : excluded_functions)
2628
if (contains(func, excluded)) return true;
27-
return false;
29+
if (goto_program_instruction_typet::ASSIGN != pos->type) return false;
30+
const exprt &lhs=to_code_assign(pos->code).lhs();
31+
if (ID_symbol != lhs.id()) return false;
32+
const std::string &var=id2string(to_symbol_expr(lhs).get_identifier());
33+
return CEGIS_CONTROL_SOLUTION_VAR_NAME == var;
2834
}
2935
}
3036

3137
void control_preprocessingt::operator ()()
3238
{
39+
symbol_tablet &st=control_program.st;
3340
goto_functionst &gf=control_program.gf;
34-
inline_user_program(control_program.st, gf);
41+
remove_unused_elements(st, gf);
42+
inline_user_program(st, gf);
3543
goto_programt::targetst &locs=control_program.counterexample_locations;
3644
goto_programt &body=get_entry_body(gf);
3745
collect_counterexample_locations(locs, body, is_meta);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <deque>
2+
#include <algorithm>
3+
4+
#include <goto-programs/goto_functions.h>
5+
6+
#include <cegis/cegis-util/program_helper.h>
7+
#include <cegis/control/value/control_vars.h>
8+
9+
const exprt &get_controller_comp(const namespacet &ns,
10+
const struct_exprt &value, const char * const comp)
11+
{
12+
const struct_typet &type=to_struct_type(ns.follow(value.type()));
13+
const struct_typet::componentst &comps=type.components();
14+
for (size_t i=0; i < comps.size(); ++i)
15+
if (id2string(comps[i].get_name()) == comp) return value.operands()[i];
16+
assert(!"Solution component not found.");
17+
}
18+
19+
namespace
20+
{
21+
const exprt &get_a_size(const namespacet &ns, const struct_exprt &value)
22+
{
23+
return get_controller_comp(ns, value, CEGIS_CONTROL_A_SIZE_MEMBER_NAME);
24+
}
25+
26+
const exprt &get_b_size(const namespacet &ns, const struct_exprt &value)
27+
{
28+
return get_controller_comp(ns, value, CEGIS_CONTROL_B_SIZE_MEMBER_NAME);
29+
}
30+
31+
class replace_sizes_visitort: public expr_visitort
32+
{
33+
std::deque<exprt *> a_sizes, b_sizes;
34+
const exprt &a_size;
35+
const exprt &b_size;
36+
public:
37+
replace_sizes_visitort(const exprt &a_size, const exprt &b_size) :
38+
a_size(a_size), b_size(b_size)
39+
{
40+
}
41+
42+
virtual ~replace_sizes_visitort()
43+
{
44+
for (exprt * const expr : a_sizes)
45+
*expr=a_size;
46+
for (exprt * const expr : b_sizes)
47+
*expr=b_size;
48+
}
49+
50+
virtual void operator()(exprt &expr)
51+
{
52+
if (ID_member != expr.id()) return;
53+
const member_exprt &member=to_member_expr(expr);
54+
const exprt &struct_op=member.struct_op();
55+
if (ID_symbol != struct_op.id()) return;
56+
const symbol_exprt &symbol=to_symbol_expr(struct_op);
57+
const std::string &var=id2string(symbol.get_identifier());
58+
if (CEGIS_CONTROL_SOLUTION_VAR_NAME != var) return;
59+
const std::string &comp=id2string(member.get_component_name());
60+
if (CEGIS_CONTROL_A_SIZE_MEMBER_NAME == comp) a_sizes.push_back(&expr);
61+
else if (CEGIS_CONTROL_B_SIZE_MEMBER_NAME == comp) b_sizes.push_back(&expr);
62+
}
63+
};
64+
}
65+
66+
void propagate_controller_sizes(const symbol_tablet &st, goto_functionst &gf)
67+
{
68+
const symbolt &symbol=st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME);
69+
const struct_exprt &controller_value=to_struct_expr(symbol.value);
70+
const namespacet ns(st);
71+
const exprt &a_size=get_a_size(ns, controller_value);
72+
const exprt &b_size=get_b_size(ns, controller_value);
73+
replace_sizes_visitort visitor(a_size, b_size);
74+
goto_programt &body=get_entry_body(gf);
75+
for (goto_programt::instructiont &instr : body.instructions)
76+
{
77+
instr.code.visit(visitor);
78+
instr.guard.visit(visitor);
79+
}
80+
}
81+
82+
namespace
83+
{
84+
bool is_sol_assign(const goto_programt::instructiont &instr)
85+
{
86+
if (goto_program_instruction_typet::ASSIGN != instr.type) return false;
87+
const std::string &var=id2string(get_affected_variable(instr));
88+
return CEGIS_CONTROL_SOLUTION_VAR_NAME == var;
89+
}
90+
}
91+
92+
goto_programt::targett get_solution_assignment(goto_programt &body)
93+
{
94+
goto_programt::instructionst &i=body.instructions;
95+
const goto_programt::targett end(i.end());
96+
const goto_programt::targett pos=std::find_if(i.begin(), end, is_sol_assign);
97+
assert(end != pos);
98+
return pos;
99+
}
100+
101+
void remove_solution_assignment(goto_programt &body)
102+
{
103+
body.instructions.erase(get_solution_assignment(body));
104+
}

0 commit comments

Comments
 (0)