-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
opt_cmds.cpp
180 lines (142 loc) · 4.96 KB
/
opt_cmds.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
opt_cmds.cpp
Abstract:
Commands for optimization benchmarks
Author:
Anh-Dung Phan (t-anphan) 2013-10-14
Notes:
TODO:
- Add appropriate statistics tracking to opt::context
- Deal with push/pop (later)
--*/
#include "opt/opt_cmds.h"
#include "cmd_context/cmd_context.h"
#include "ast/ast_pp.h"
#include "opt/opt_context.h"
#include "util/cancel_eh.h"
#include "util/scoped_ctrl_c.h"
#include "util/scoped_timer.h"
#include "cmd_context/parametric_cmd.h"
#include "opt/opt_params.hpp"
#include "model/model_smt2_pp.h"
static opt::context& get_opt(cmd_context& cmd, opt::context* opt) {
if (opt) {
return *opt;
}
if (!cmd.get_opt()) {
cmd.set_opt(alloc(opt::context, cmd.m()));
}
return dynamic_cast<opt::context&>(*cmd.get_opt());
}
class assert_soft_cmd : public parametric_cmd {
unsigned m_idx;
expr* m_formula;
opt::context* m_opt;
public:
assert_soft_cmd(opt::context* opt):
parametric_cmd("assert-soft"),
m_idx(0),
m_formula(nullptr),
m_opt(opt)
{}
void reset(cmd_context & ctx) override {
m_idx = 0;
m_formula = nullptr;
}
char const * get_usage() const override { return "<formula> [:weight <rational-weight>] [:id <symbol>]"; }
char const * get_main_descr() const override { return "assert soft constraint with optional weight and identifier"; }
// command invocation
void prepare(cmd_context & ctx) override {
reset(ctx);
}
cmd_arg_kind next_arg_kind(cmd_context & ctx) const override {
if (m_idx == 0) return CPK_EXPR;
return parametric_cmd::next_arg_kind(ctx);
}
void init_pdescrs(cmd_context & ctx, param_descrs & p) override {
p.insert("weight", CPK_NUMERAL, "(default: 1) penalty of not satisfying constraint.");
p.insert("id", CPK_SYMBOL, "(default: null) partition identifier for soft constraints.");
}
void set_next_arg(cmd_context & ctx, expr * t) override {
SASSERT(m_idx == 0);
if (!ctx.m().is_bool(t)) {
throw cmd_exception("Invalid type for expression. Expected Boolean type.");
}
m_formula = t;
++m_idx;
}
void failure_cleanup(cmd_context & ctx) override {
reset(ctx);
}
void execute(cmd_context & ctx) override {
if (!m_formula) {
throw cmd_exception("assert-soft requires a formulas as argument.");
}
symbol w("weight");
rational weight = ps().get_rat(symbol("weight"), rational::one());
symbol id = ps().get_sym(symbol("id"), symbol::null);
get_opt(ctx, m_opt).add_soft_constraint(m_formula, weight, id);
ctx.print_success();
reset(ctx);
reset_params();
}
void finalize(cmd_context & ctx) override {
}
};
class min_maximize_cmd : public cmd {
bool m_is_max;
opt::context* m_opt;
public:
min_maximize_cmd(bool is_max, opt::context* opt):
cmd(is_max?"maximize":"minimize"),
m_is_max(is_max),
m_opt(opt)
{}
void reset(cmd_context & ctx) override { }
char const * get_usage() const override { return "<term>"; }
char const * get_descr(cmd_context & ctx) const override { return "check sat modulo objective function";}
unsigned get_arity() const override { return 1; }
void prepare(cmd_context & ctx) override {}
cmd_arg_kind next_arg_kind(cmd_context & ctx) const override { return CPK_EXPR; }
void set_next_arg(cmd_context & ctx, expr * t) override {
if (!is_app(t)) {
throw cmd_exception("malformed objective term: it cannot be a quantifier or bound variable");
}
get_opt(ctx, m_opt).add_objective(to_app(t), m_is_max);
ctx.print_success();
}
void failure_cleanup(cmd_context & ctx) override {
reset(ctx);
}
void execute(cmd_context & ctx) override {
}
};
class get_objectives_cmd : public cmd {
opt::context* m_opt;
public:
get_objectives_cmd(opt::context* opt):
cmd("get-objectives"),
m_opt(opt)
{}
void reset(cmd_context & ctx) override { }
char const * get_usage() const override { return "(get-objectives)"; }
char const * get_descr(cmd_context & ctx) const override { return "retrieve the objective values (after optimization)"; }
unsigned get_arity() const override { return 0; }
void prepare(cmd_context & ctx) override {}
void failure_cleanup(cmd_context & ctx) override {
reset(ctx);
}
void execute(cmd_context & ctx) override {
if (!ctx.ignore_check()) {
get_opt(ctx, m_opt).display_assignment(ctx.regular_stream());
}
}
};
void install_opt_cmds(cmd_context & ctx, opt::context* opt) {
ctx.insert(alloc(assert_soft_cmd, opt));
ctx.insert(alloc(min_maximize_cmd, true, opt));
ctx.insert(alloc(min_maximize_cmd, false, opt));
ctx.insert(alloc(get_objectives_cmd, opt));
}