Skip to content

Commit 773188c

Browse files
committed
SAT-based neural ranking engine
This adds a variant of neural ranking that uses a SAT solver to compute the weights and biases in the neural network.
1 parent d5d9151 commit 773188c

File tree

12 files changed

+782
-1
lines changed

12 files changed

+782
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
counter1.sv
3+
--traces 1 --solver-neural-liveness
4+
^weight: nn::fc1\.n0\.w0 = 1$
5+
^bias: nn::fc1\.n0\.b = 0$
6+
^\[main\.property\.p0\] always s_eventually main\.counter == 0: PROVED$
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// count down from 10 to 0
2+
3+
module main(input clk);
4+
5+
reg [7:0] counter;
6+
7+
initial counter = 10;
8+
9+
always @(posedge clk)
10+
if(counter != 0)
11+
counter = counter - 1;
12+
13+
// expected to pass
14+
p0: assert property (s_eventually counter == 0);
15+
16+
endmodule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
wrap_around1.sv
3+
--traces 1 --solver-neural-liveness
4+
^weight: nn::fc1\.n0\.w0 = -1$
5+
^bias: nn::fc1\.n0\.b = 9$
6+
^\[main\.property\.p0\] always s_eventually main\.counter == 10: PROVED$
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// count up from 0 to 10
2+
3+
module main(input clk);
4+
5+
reg [7:0] counter;
6+
7+
initial counter = 0;
8+
9+
always @(posedge clk)
10+
if(counter == 10)
11+
counter = 0;
12+
else
13+
counter = counter + 1;
14+
15+
// expected to pass
16+
p0: assert property (s_eventually counter == 10);
17+
18+
endmodule

src/ebmc/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ SRC = \
2323
output_verilog.cpp \
2424
random_traces.cpp \
2525
ranking_function.cpp \
26+
ranking_net.cpp \
2627
report_results.cpp \
2728
show_formula_solver.cpp \
2829
show_properties.cpp \
2930
show_trans.cpp \
31+
solver_neural_liveness.cpp \
3032
transition_system.cpp \
3133
waveform.cpp \
3234
#empty line

src/ebmc/ebmc_parse_options.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Author: Daniel Kroening, [email protected]
2525
#include "random_traces.h"
2626
#include "ranking_function.h"
2727
#include "show_trans.h"
28+
#include "solver_neural_liveness.h"
2829

2930
#include <iostream>
3031

@@ -162,6 +163,9 @@ int ebmc_parse_optionst::doit()
162163
if(cmdline.isset("neural-liveness"))
163164
return do_neural_liveness(cmdline, ui_message_handler);
164165

166+
if(cmdline.isset("solver-neural-liveness"))
167+
return do_solver_neural_liveness(cmdline, ui_message_handler);
168+
165169
if(cmdline.isset("ranking-function"))
166170
return do_ranking_function(cmdline, ui_message_handler);
167171

src/ebmc/ebmc_parse_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ebmc_parse_optionst:public parse_options_baset
3434
"(po)(cegar)(k-induction)(2pi)(bound2):"
3535
"(outfile):(xml-ui)(verbosity):(gui)(json-result):"
3636
"(neural-liveness)(neural-engine):"
37+
"(solver-neural-liveness)"
3738
"(reset):"
3839
"(version)(verilog-rtl)(verilog-netlist)"
3940
"(compute-interpolant)(interpolation)(interpolation-vmcai)"

src/ebmc/ebmc_solver_factory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Author: Daniel Kroening, [email protected]
1616
#include <solvers/decision_procedure.h>
1717
#include <solvers/prop/prop.h>
1818

19-
#include <iosfwd>
19+
#include <fstream>
2020
#include <memory>
2121

2222
class ebmc_solvert final

src/ebmc/ranking_net.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*******************************************************************\
2+
3+
Module: Ranking Neural Net
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "ranking_net.h"
10+
11+
#include <util/arith_tools.h>
12+
#include <util/bitvector_types.h>
13+
#include <util/std_expr.h>
14+
15+
exprt wrap_around(exprt expr)
16+
{
17+
// map negative values to positive ones, wrap around:
18+
// -1 --> int_max-1, -2 --> int_max-2, etc.
19+
auto int_max = to_signedbv_type(expr.type()).largest_expr();
20+
return if_exprt{sign_exprt{expr}, plus_exprt{int_max, expr}, expr};
21+
}
22+
23+
tuple_exprt wrap_around_tuple(tuple_exprt expr)
24+
{
25+
// map negative values to positive ones, wrap around:
26+
// -1 --> int_max-1, -2 --> int_max-2, etc.
27+
for(auto &op : expr.operands())
28+
op = wrap_around(op);
29+
30+
return expr;
31+
}
32+
33+
tuple_exprt ranking_nett::forward(const tuple_exprt &inputs) const
34+
{
35+
auto fc1_out = fc1.forward(inputs);
36+
auto w_out = wrap_around_tuple(fc1_out);
37+
return w_out;
38+
}
39+
40+
ranking_nett::lineart::lineart(
41+
const irep_idt &__name,
42+
std::size_t in,
43+
std::size_t out,
44+
const typet &type)
45+
: name(__name)
46+
{
47+
neurons.reserve(out);
48+
49+
for(std::size_t i = 0; i < out; i++)
50+
{
51+
irep_idt identifier = id2string(__name) + ".n" + std::to_string(i);
52+
neurons.emplace_back(identifier, in, type);
53+
}
54+
}
55+
56+
ranking_nett::lineart::neuront::neuront(
57+
const irep_idt &__name,
58+
std::size_t in,
59+
const typet &type)
60+
: name(__name)
61+
{
62+
{
63+
irep_idt identifier = id2string(__name) + ".b";
64+
bias = symbol_exprt(identifier, type);
65+
}
66+
67+
weights.reserve(in);
68+
69+
for(std::size_t i = 0; i < in; i++)
70+
{
71+
irep_idt identifier = id2string(__name) + ".w" + std::to_string(i);
72+
weights.emplace_back(symbol_exprt{identifier, type});
73+
}
74+
}
75+
76+
exprt ranking_nett::lineart::neuront::forward(const tuple_exprt &input) const
77+
{
78+
exprt::operandst result;
79+
result.reserve(weights.size() + 1); // one more for bias
80+
81+
result.push_back(bias);
82+
83+
PRECONDITION(weights.size() == input.operands().size());
84+
85+
for(std::size_t i = 0; i < weights.size(); i++)
86+
result.push_back(mult_exprt{weights[i], input.operands()[i]});
87+
88+
return plus_exprt{std::move(result), bias.type()};
89+
}
90+
91+
exprt relu(exprt expr)
92+
{
93+
auto zero = from_integer(0, expr.type());
94+
return if_exprt{greater_than_or_equal_exprt{expr, zero}, expr, zero};
95+
}
96+
97+
tuple_exprt ranking_nett::lineart::forward(const tuple_exprt &input) const
98+
{
99+
tuple_exprt::operandst result;
100+
result.reserve(neurons.size());
101+
102+
for(auto &neuron : neurons)
103+
result.push_back(neuron.forward(input));
104+
105+
return tuple_exprt{std::move(result)};
106+
}

src/ebmc/ranking_net.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*******************************************************************\
2+
3+
Module: Ranking Neural Net
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef EBMC_RANKING_NET_H
10+
#define EBMC_RANKING_NET_H
11+
12+
#include <util/mathematical_expr.h>
13+
14+
exprt relu(exprt);
15+
exprt wrap_around(exprt);
16+
17+
class ranking_nett
18+
{
19+
public:
20+
explicit ranking_nett(
21+
std::size_t number_of_state_variables,
22+
const typet &__type)
23+
: fc1("nn::fc1", number_of_state_variables, 1, __type)
24+
{
25+
}
26+
27+
tuple_exprt forward(const tuple_exprt &inputs) const;
28+
29+
class lineart
30+
{
31+
public:
32+
lineart(
33+
const irep_idt &name,
34+
std::size_t in,
35+
std::size_t out,
36+
const typet &);
37+
38+
irep_idt name;
39+
40+
class neuront
41+
{
42+
public:
43+
std::vector<exprt> weights;
44+
exprt bias;
45+
irep_idt name;
46+
neuront(const irep_idt &name, std::size_t in, const typet &);
47+
exprt forward(const tuple_exprt &) const;
48+
};
49+
50+
std::vector<neuront> neurons;
51+
52+
tuple_exprt forward(const tuple_exprt &) const;
53+
};
54+
55+
lineart fc1;
56+
};
57+
58+
#endif // EBMC_RANKING_NET

0 commit comments

Comments
 (0)