dlinear  0.0.1
Delta-complete SMT solver for linear programming
Loading...
Searching...
No Matches
symbolic.cpp
1
6#include "symbolic.h"
7
8#include <algorithm>
9#include <iterator>
10#include <map>
11#include <utility>
12
13#include "dlinear/libs/libgmp.h"
14#include "dlinear/util/exception.h"
15#include "dlinear/util/logging.h"
16
17namespace dlinear {
18
19FormulaKind operator-(const FormulaKind kind) {
20 switch (kind) {
21 case FormulaKind::Geq:
22 return FormulaKind::Leq;
23 case FormulaKind::Gt:
24 return FormulaKind::Lt;
25 case FormulaKind::Leq:
26 return FormulaKind::Geq;
27 case FormulaKind::Lt:
28 return FormulaKind::Gt;
29 default:
30 return kind;
31 }
32}
33
34Formula imply(const Formula &f1, const Formula &f2) { return !f1 || f2; }
35Formula imply(const Variable &v, const Formula &f) { return imply(Formula{v}, f); }
36Formula imply(const Formula &f, const Variable &v) { return imply(f, Formula{v}); }
37Formula imply(const Variable &v1, const Variable &v2) { return imply(Formula{v1}, Formula{v2}); }
38
39Formula iff(const Formula &f1, const Formula &f2) { return imply(f1, f2) && imply(f2, f1); }
40
41Formula iff(const Variable &v, const Formula &f) { return iff(Formula{v}, f); }
42
43Formula iff(const Formula &f, const Variable &v) { return iff(f, Formula{v}); }
44
45Formula iff(const Variable &v1, const Variable &v2) { return iff(Formula{v1}, Formula{v2}); }
46
47std::set<Formula> map(const std::set<Formula> &formulas, const std::function<Formula(const Formula &)> &func) {
48 std::set<Formula> result;
49 std::transform(formulas.cbegin(), formulas.cend(), std::inserter(result, result.begin()), func);
50 return result;
51}
52
53bool is_atomic(const Formula &f) {
54 switch (f.get_kind()) {
55 case FormulaKind::False:
56 case FormulaKind::True:
57 case FormulaKind::Var:
58 case FormulaKind::Eq:
59 case FormulaKind::Neq:
60 case FormulaKind::Gt:
61 case FormulaKind::Geq:
62 case FormulaKind::Lt:
63 case FormulaKind::Leq:
64 case FormulaKind::Forall:
65 return true;
66 case FormulaKind::And:
67 case FormulaKind::Or:
68 return false;
69 case FormulaKind::Not: {
70 const Formula &negated_formula{get_operand(f)};
71 return is_variable(negated_formula) || is_relational(negated_formula);
72 }
73 default:
74 DLINEAR_UNREACHABLE();
75 }
76}
77
78bool is_clause(const Formula &f) {
79 if (is_atomic(f)) {
80 return true;
81 }
82 if (is_negation(f)) {
83 return is_atomic(get_operand(f));
84 }
85 if (is_conjunction(f)) {
86 return false;
87 }
88 if (is_disjunction(f)) {
89 const auto &operands = get_operands(f);
90 // FIXME: should this also be checking for negated atomic formulas?
91 const bool result{
92 std::all_of(operands.cbegin(), operands.cend(), [](const Formula &formula) { return is_atomic(formula); })};
93 return result;
94 }
95 DLINEAR_UNREACHABLE();
96}
97
98std::set<Formula> get_clauses(const Formula &f) {
99 if (is_conjunction(f)) {
100 DLINEAR_ASSERT(std::all_of(get_operands(f).begin(), get_operands(f).end(),
101 [](const Formula &clause) { return is_clause(clause); }),
102 "All operands must be clauses");
103 return get_operands(f);
104 } else {
105 DLINEAR_ASSERT(is_clause(f), "Must be a clause");
106 return {f};
107 }
108}
109
110bool is_cnf(const Formula &f) {
111 if (is_atomic(f)) {
112 return true;
113 }
114 if (is_disjunction(f)) {
115 return is_clause(f);
116 }
117 if (is_conjunction(f)) {
118 const auto &operands = get_operands(f);
119 const bool result{
120 std::all_of(operands.cbegin(), operands.cend(), [](const Formula &formula) { return is_clause(formula); })};
121 return result;
122 }
123 DLINEAR_UNREACHABLE();
124}
125
126bool HaveIntersection(const Variables &variables1, const Variables &variables2) {
127 auto begin1 = variables1.begin();
128 auto begin2 = variables2.begin();
129 const auto end1 = variables1.end();
130 const auto end2 = variables2.end();
131 while (begin1 != end1 && begin2 != end2) {
132 if (begin1->less(*begin2)) {
133 ++begin1;
134 } else {
135 if (!begin2->less(*begin1)) {
136 return true;
137 }
138 ++begin2;
139 }
140 }
141 return false;
142}
143
144namespace {
146class DeltaStrengthenVisitor {
147 public:
148 DeltaStrengthenVisitor() = default;
149 [[nodiscard]] Formula Strengthen(const Formula &f, const double delta) const {
150 if (delta == 0) {
151 return f;
152 }
153 return Visit(f, delta);
154 }
155
156 private:
157 [[nodiscard]] Expression Visit(const Expression &e, const double delta) const {
158 return VisitExpression<Expression>(this, e, delta);
159 }
160 [[nodiscard]] Expression VisitVariable(const Expression &e, const double) const { return e; }
161 [[nodiscard]] Expression VisitConstant(const Expression &e, const double) const { return e; }
162 [[nodiscard]] Expression VisitAddition(const Expression &e, const double delta) const {
163 Expression ret{get_constant_in_addition(e)};
164 for (const auto &p : get_expr_to_coeff_map_in_addition(e)) {
165 const Expression &e_i{p.first};
166 const mpq_class &coeff{p.second};
167 ret += coeff * Visit(e_i, delta);
168 }
169 return ret;
170 }
171 [[nodiscard]] Expression VisitMultiplication(const Expression &e, const double delta) const {
172 Expression ret{get_constant_in_multiplication(e)};
173 for (const auto &p : get_base_to_exponent_map_in_multiplication(e)) {
174 const Expression &base{p.first};
175 const Expression &exponent{p.second};
176 ret *= pow(Visit(base, delta), Visit(exponent, delta));
177 }
178 return ret;
179 }
180 [[nodiscard]] Expression VisitDivision(const Expression &e, const double delta) const {
181 return Visit(get_first_argument(e), delta) / Visit(get_second_argument(e), delta);
182 }
183 [[nodiscard]] Expression VisitLog(const Expression &e, const double delta) const {
184 return log(Visit(get_argument(e), delta));
185 }
186 [[nodiscard]] Expression VisitAbs(const Expression &e, const double delta) const {
187 return abs(Visit(get_argument(e), delta));
188 }
189 [[nodiscard]] Expression VisitExp(const Expression &e, const double delta) const {
190 return exp(Visit(get_argument(e), delta));
191 }
192 [[nodiscard]] Expression VisitSqrt(const Expression &e, const double delta) const {
193 return sqrt(Visit(get_argument(e), delta));
194 }
195 [[nodiscard]] Expression VisitPow(const Expression &e, const double delta) const {
196 return pow(Visit(get_first_argument(e), delta), Visit(get_second_argument(e), delta));
197 }
198 [[nodiscard]] Expression VisitSin(const Expression &e, const double delta) const {
199 return sin(Visit(get_argument(e), delta));
200 }
201 [[nodiscard]] Expression VisitCos(const Expression &e, const double delta) const {
202 return cos(Visit(get_argument(e), delta));
203 }
204 [[nodiscard]] Expression VisitTan(const Expression &e, const double delta) const {
205 return tan(Visit(get_argument(e), delta));
206 }
207 [[nodiscard]] Expression VisitAsin(const Expression &e, const double delta) const {
208 return asin(Visit(get_argument(e), delta));
209 }
210 [[nodiscard]] Expression VisitAcos(const Expression &e, const double delta) const {
211 return acos(Visit(get_argument(e), delta));
212 }
213 [[nodiscard]] Expression VisitAtan(const Expression &e, const double delta) const {
214 return atan(Visit(get_argument(e), delta));
215 }
216 [[nodiscard]] Expression VisitAtan2(const Expression &e, const double delta) const {
217 return atan2(Visit(get_first_argument(e), delta), Visit(get_second_argument(e), delta));
218 }
219 [[nodiscard]] Expression VisitSinh(const Expression &e, const double delta) const {
220 return sinh(Visit(get_argument(e), delta));
221 }
222 [[nodiscard]] Expression VisitCosh(const Expression &e, const double delta) const {
223 return cosh(Visit(get_argument(e), delta));
224 }
225 [[nodiscard]] Expression VisitTanh(const Expression &e, const double delta) const {
226 return tanh(Visit(get_argument(e), delta));
227 }
228 [[nodiscard]] Expression VisitMin(const Expression &e, const double delta) const {
229 return min(Visit(get_first_argument(e), delta), Visit(get_second_argument(e), delta));
230 }
231 [[nodiscard]] Expression VisitMax(const Expression &e, const double delta) const {
232 return max(Visit(get_first_argument(e), delta), Visit(get_second_argument(e), delta));
233 }
234 [[nodiscard]] Expression VisitIfThenElse(const Expression &e, const double delta) const {
235 return if_then_else(Visit(get_conditional_formula(e), delta), Visit(get_then_expression(e), delta),
236 Visit(get_else_expression(e), delta));
237 }
238 [[nodiscard]] Expression VisitUninterpretedFunction(const Expression &e, const double) const { return e; }
239
240 [[nodiscard]] Formula Visit(const Formula &f, const double delta) const {
241 return VisitFormula<Formula>(this, f, delta);
242 }
243 [[nodiscard]] Formula VisitFalse(const Formula &f, const double) const { return f; }
244 [[nodiscard]] Formula VisitTrue(const Formula &f, const double) const { return f; }
245 [[nodiscard]] Formula VisitVariable(const Formula &f, const double) const { return f; }
246 [[nodiscard]] Formula VisitEqualTo(const Formula &f, const double delta) const {
247 if (delta > 0) {
248 DLINEAR_WARN_FMT("Strengthening {} with {} results in false. However, we return {}.", f, delta, f);
249 return f;
250 } else {
251 // lhs = rhs
252 // -> (lhs >= rhs) ∧ (lhs <= rhs)
253 const Expression lhs{Visit(get_lhs_expression(f), delta)};
254 const Expression rhs{Visit(get_rhs_expression(f), delta)};
255 return VisitGreaterThanOrEqualTo(lhs >= rhs, delta) && VisitLessThanOrEqualTo(lhs <= rhs, delta);
256 }
257 }
258 [[nodiscard]] Formula VisitNotEqualTo(const Formula &f, const double delta) const {
259 if (delta > 0) {
260 // lhs ≠ rhs
261 // -> (lhs > rhs) ∨ (lhs < rhs)
262 const Expression lhs{Visit(get_lhs_expression(f), delta)};
263 const Expression rhs{Visit(get_rhs_expression(f), delta)};
264 return VisitGreaterThan(lhs > rhs, delta) || VisitLessThan(lhs < rhs, delta);
265 } else {
266 return Formula::True();
267 }
268 }
269 [[nodiscard]] Formula VisitGreaterThan(const Formula &f, const double delta) const {
270 // lhs > rhs
271 //
272 // After strengthening, we have:
273 // (lhs > rhs + delta)
274 const Expression lhs{Visit(get_lhs_expression(f), delta)};
275 const Expression rhs{Visit(get_rhs_expression(f), delta)};
276 if (is_variable(rhs)) {
277 // We return the following so that possibly we can keep the
278 // bounded constraint form (c relop. v) where c is a constant.
279 // Keeping this syntactic form is useful because our
280 // FilterAssertion relies on that.
281 return (lhs - delta > rhs);
282 } else {
283 return (lhs > rhs + delta);
284 }
285 }
286 [[nodiscard]] Formula VisitGreaterThanOrEqualTo(const Formula &f, const double delta) const {
287 // lhs >= rhs
288 //
289 // After strengthening, we have:
290 // (lhs >= rhs + delta)
291 const Expression lhs{Visit(get_lhs_expression(f), delta)};
292 const Expression rhs{Visit(get_rhs_expression(f), delta)};
293 if (is_variable(rhs)) {
294 // We return the following so that possibly we can keep the
295 // bounded constraint form (c relop. v) where c is a constant.
296 // Keeping this syntactic form is useful because our
297 // FilterAssertion relies on that.
298 return (lhs - delta >= rhs);
299 } else {
300 return (lhs >= rhs + delta);
301 }
302 }
303 [[nodiscard]] Formula VisitLessThan(const Formula &f, const double delta) const {
304 // lhs < rhs
305 //
306 // After strengthening, we have:
307 // (lhs + delta < rhs)
308 const Expression lhs{Visit(get_lhs_expression(f), delta)};
309 const Expression rhs{Visit(get_rhs_expression(f), delta)};
310 if (is_variable(lhs)) {
311 // We return the following so that possibly we can keep the
312 // bounded constraint form (v relop. c) where c is a constant.
313 // Keeping this syntactic form is useful because our
314 // FilterAssertion relies on that.
315 return (lhs < rhs - delta);
316 } else {
317 return (lhs + delta < rhs);
318 }
319 }
320 [[nodiscard]] Formula VisitLessThanOrEqualTo(const Formula &f, const double delta) const {
321 // lhs <= rhs
322 //
323 // After strengthening, we have:
324 // (lhs + delta <= rhs)
325 const Expression lhs{Visit(get_lhs_expression(f), delta)};
326 const Expression rhs{Visit(get_rhs_expression(f), delta)};
327 if (is_variable(lhs)) {
328 // We return the following so that possibly we can keep the
329 // bounded constraint form (v relop. c) where c is a constant.
330 // Keeping this syntactic form is useful because our
331 // FilterAssertion relies on that.
332 return (lhs <= rhs - delta);
333 } else {
334 return (lhs + delta <= rhs);
335 }
336 }
337 [[nodiscard]] Formula VisitConjunction(const Formula &f, const double delta) const {
338 Formula ret{Formula::True()};
339 for (const auto &f_i : get_operands(f)) {
340 ret = std::move(ret) && this->Visit(f_i, delta);
341 }
342 return ret;
343 }
344 [[nodiscard]] Formula VisitDisjunction(const Formula &f, const double delta) const {
345 Formula ret{Formula::False()};
346 for (const auto &f_i : get_operands(f)) {
347 ret = std::move(ret) || this->Visit(f_i, delta);
348 }
349 return ret;
350 }
351 [[nodiscard]] Formula VisitNegation(const Formula &f, const double delta) const {
352 return !Visit(get_operand(f), -delta);
353 }
354 [[nodiscard]] Formula VisitForall(const Formula &, const double) const {
355 DLINEAR_RUNTIME_ERROR("DeltaStrengthenVisitor: forall formula is not supported.");
356 }
357
358 // Makes VisitExpression a friend of this class so that it can use private
359 // operator()s.
360 friend Expression drake::symbolic::VisitExpression<Expression>(const DeltaStrengthenVisitor *, const Expression &,
361 const double &);
362
363 // Makes VisitFormula a friend of this class so that it can use private
364 // operator()s.
365 friend Formula drake::symbolic::VisitFormula<Formula>(const DeltaStrengthenVisitor *, const Formula &,
366 const double &);
367};
368
370class IsDifferentiableVisitor {
371 public:
372 IsDifferentiableVisitor() = default;
373 [[nodiscard]] bool Visit(const Formula &f) const { return VisitFormula<bool>(this, f); }
374 [[nodiscard]] bool Visit(const Expression &e) const { return VisitExpression<bool>(this, e); }
375
376 private:
377 // Handle Formulas.
378 [[nodiscard]] bool VisitFalse(const Formula &) const { return true; }
379 [[nodiscard]] bool VisitTrue(const Formula &) const { return true; }
380 [[nodiscard]] bool VisitVariable(const Formula &) const { return true; }
381 [[nodiscard]] bool VisitEqualTo(const Formula &f) const {
382 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
383 }
384 [[nodiscard]] bool VisitNotEqualTo(const Formula &f) const {
385 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
386 }
387 [[nodiscard]] bool VisitGreaterThan(const Formula &f) const {
388 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
389 }
390 [[nodiscard]] bool VisitGreaterThanOrEqualTo(const Formula &f) const {
391 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
392 }
393 [[nodiscard]] bool VisitLessThan(const Formula &f) const {
394 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
395 }
396 [[nodiscard]] bool VisitLessThanOrEqualTo(const Formula &f) const {
397 return Visit(get_lhs_expression(f)) && Visit(get_rhs_expression(f));
398 }
399 [[nodiscard]] bool VisitConjunction(const Formula &f) const {
400 std::set<Formula> formulae = get_operands(f);
401 return std::all_of(formulae.begin(), formulae.end(), [this](const Formula &formula) { return Visit(formula); });
402 }
403 [[nodiscard]] bool VisitDisjunction(const Formula &f) const {
404 std::set<Formula> formulae = get_operands(f);
405 return std::all_of(formulae.begin(), formulae.end(), [this](const Formula &formula) { return Visit(formula); });
406 }
407 [[nodiscard]] bool VisitNegation(const Formula &f) const { return Visit(get_operand(f)); }
408 [[nodiscard]] bool VisitForall(const Formula &) const { return false; }
409
410 // Handle Expressions.
411 [[nodiscard]] bool VisitVariable(const Expression &) const { return true; }
412 [[nodiscard]] bool VisitConstant(const Expression &) const { return true; }
413 [[nodiscard]] bool VisitAddition(const Expression &e) const {
414 for (const auto &p : get_expr_to_coeff_map_in_addition(e)) {
415 const Expression &e_i{p.first};
416 if (!Visit(e_i)) {
417 return false;
418 }
419 }
420 return true;
421 }
422 [[nodiscard]] bool VisitMultiplication(const Expression &e) const {
423 for (const auto &p : get_base_to_exponent_map_in_multiplication(e)) {
424 const Expression &base{p.first};
425 const Expression &exponent{p.second};
426 if (!Visit(base) || !Visit(exponent)) {
427 return false;
428 }
429 }
430 return true;
431 }
432 [[nodiscard]] bool VisitDivision(const Expression &e) const {
433 return Visit(get_first_argument(e)) && Visit(get_second_argument(e));
434 }
435 [[nodiscard]] bool VisitLog(const Expression &e) const { return Visit(get_argument(e)); }
436 [[nodiscard]] bool VisitAbs(const Expression &) const { return false; }
437 [[nodiscard]] bool VisitExp(const Expression &e) const { return Visit(get_argument(e)); }
438 [[nodiscard]] bool VisitSqrt(const Expression &e) const { return Visit(get_argument(e)); }
439 [[nodiscard]] bool VisitPow(const Expression &e) const {
440 return Visit(get_first_argument(e)) && Visit(get_second_argument(e));
441 }
442 [[nodiscard]] bool VisitSin(const Expression &e) const { return Visit(get_argument(e)); }
443 [[nodiscard]] bool VisitCos(const Expression &e) const { return Visit(get_argument(e)); }
444 [[nodiscard]] bool VisitTan(const Expression &e) const { return Visit(get_argument(e)); }
445 [[nodiscard]] bool VisitAsin(const Expression &e) const { return Visit(get_argument(e)); }
446 [[nodiscard]] bool VisitAcos(const Expression &e) const { return Visit(get_argument(e)); }
447 [[nodiscard]] bool VisitAtan(const Expression &e) const { return Visit(get_argument(e)); }
448 [[nodiscard]] bool VisitAtan2(const Expression &e) const {
449 return Visit(get_first_argument(e)) && Visit(get_second_argument(e));
450 }
451 [[nodiscard]] bool VisitSinh(const Expression &e) const { return Visit(get_argument(e)); }
452 [[nodiscard]] bool VisitCosh(const Expression &e) const { return Visit(get_argument(e)); }
453 [[nodiscard]] bool VisitTanh(const Expression &e) const { return Visit(get_argument(e)); }
454 [[nodiscard]] bool VisitMin(const Expression &) const { return false; }
455 [[nodiscard]] bool VisitMax(const Expression &) const { return false; }
456 [[nodiscard]] bool VisitIfThenElse(const Expression &) const { return false; }
457 [[nodiscard]] bool VisitUninterpretedFunction(const Expression &) const { return false; }
458
459 // Makes VisitFormula a friend of this class so that it can use private
460 // operator()s.
461 friend bool drake::symbolic::VisitFormula<bool>(const IsDifferentiableVisitor *, const Formula &);
462 // Makes VisitExpression a friend of this class so that it can use private
463 // operator()s.
464 friend bool drake::symbolic::VisitExpression<bool>(const IsDifferentiableVisitor *, const Expression &);
465};
466
467} // namespace
468
470Formula DeltaStrengthen(const Formula &f, const double delta) {
471 DLINEAR_ASSERT(delta > 0, "delta must be positive.");
472 return DeltaStrengthenVisitor{}.Strengthen(f, delta);
473}
474
476Formula DeltaWeaken(const Formula &f, const double delta) {
477 DLINEAR_ASSERT(delta > 0, "delta must be positive.");
478 return DeltaStrengthenVisitor{}.Strengthen(f, -delta);
479}
480
481bool IsDifferentiable(const Formula &f) { return IsDifferentiableVisitor{}.Visit(f); }
482
483bool IsDifferentiable(const Expression &e) { return IsDifferentiableVisitor{}.Visit(e); }
484
485Formula make_conjunction(const std::vector<Formula> &formulas) {
486 Formula ret{Formula::True()};
487 for (const auto &f_i : formulas) {
488 ret = std::move(ret) && f_i;
489 }
490 return ret;
491}
492
493Formula make_disjunction(const std::vector<Formula> &formulas) {
494 Formula ret{Formula::False()};
495 for (const auto &f_i : formulas) {
496 ret = std::move(ret) || f_i;
497 }
498 return ret;
499}
500
501std::vector<Variable> CreateVector(const std::string &prefix, const int size, const Variable::Type type) {
502 DLINEAR_ASSERT(!prefix.empty(), "prefix must not be empty.");
503 DLINEAR_ASSERT(size >= 1, "size must be positive.");
504 std::vector<Variable> v;
505 v.reserve(size);
506 for (int i = 0; i < size; ++i) {
507 v.emplace_back(prefix + std::to_string(i), type);
508 }
509 return v;
510}
511
513 switch (op) {
526 default:
527 DLINEAR_UNREACHABLE();
528 }
529}
530
531std::ostream &operator<<(std::ostream &os, const RelationalOperator op) {
532 switch (op) {
534 return os << "=";
536 return os << "≠";
538 return os << ">";
540 return os << "≥";
542 return os << "<";
544 return os << "≤";
545 default:
546 DLINEAR_UNREACHABLE();
547 }
548}
549
550std::ostream &operator<<(std::ostream &os, const FormulaKind &kind) {
551 switch (kind) {
552 case FormulaKind::False:
553 return os << "False";
554 case FormulaKind::True:
555 return os << "True";
556 case FormulaKind::Var:
557 return os << "Var";
558 case FormulaKind::Eq:
559 return os << "Eq";
560 case FormulaKind::Neq:
561 return os << "Neq";
562 case FormulaKind::Gt:
563 return os << "Gt";
564 case FormulaKind::Geq:
565 return os << "Geq";
566 case FormulaKind::Lt:
567 return os << "Lt";
568 case FormulaKind::Leq:
569 return os << "Leq";
570 case FormulaKind::And:
571 return os << "And";
572 case FormulaKind::Or:
573 return os << "Or";
574 case FormulaKind::Not:
575 return os << "Not";
576 case FormulaKind::Forall:
577 return os << "Forall";
578 default:
579 DLINEAR_UNREACHABLE();
580 }
581}
582
583std::ostream &operator<<(std::ostream &os, const ExpressionKind &kind) {
584 switch (kind) {
585 case ExpressionKind::Var:
586 return os << "Var";
587 case ExpressionKind::Constant:
588 return os << "Constant";
589 case ExpressionKind::Infty:
590 return os << "Infty";
591 case ExpressionKind::NaN:
592 return os << "NaN";
593 case ExpressionKind::Add:
594 return os << "Addition";
595 case ExpressionKind::Mul:
596 return os << "Multiplication";
597 case ExpressionKind::Div:
598 return os << "Division";
599 case ExpressionKind::Log:
600 return os << "Log";
601 case ExpressionKind::Abs:
602 return os << "Abs";
603 case ExpressionKind::Exp:
604 return os << "Exp";
605 case ExpressionKind::Sqrt:
606 return os << "Sqrt";
607 case ExpressionKind::Pow:
608 return os << "Pow";
609 case ExpressionKind::Sin:
610 return os << "Sin";
611 case ExpressionKind::Cos:
612 return os << "Cos";
613 case ExpressionKind::Tan:
614 return os << "Tan";
615 case ExpressionKind::Asin:
616 return os << "Asin";
617 case ExpressionKind::Acos:
618 return os << "Acos";
619 case ExpressionKind::Atan:
620 return os << "Atan";
621 case ExpressionKind::Atan2:
622 return os << "Atan2";
623 case ExpressionKind::Sinh:
624 return os << "Sinh";
625 case ExpressionKind::Cosh:
626 return os << "Cosh";
627 case ExpressionKind::Tanh:
628 return os << "Tanh";
629 case ExpressionKind::Min:
630 return os << "Min";
631 case ExpressionKind::Max:
632 return os << "Max";
633 case ExpressionKind::IfThenElse:
634 return os << "IfThenElse";
635 case ExpressionKind::UninterpretedFunction:
636 return os << "UninterpretedFunction";
637 default:
638 DLINEAR_UNREACHABLE();
639 }
640}
641
642} // namespace dlinear
Represents a symbolic form of an expression.
Represents a symbolic form of a first-order logic formula.
Represents a symbolic variable.
Type
Supported types of symbolic variables.
Represents a set of variables.
iterator begin()
Returns an iterator to the beginning.
iterator end()
Returns an iterator to the end.
Global namespace for the dlinear library.
Formula make_conjunction(const std::vector< Formula > &formulas)
Make conjunction of formulas.
Definition symbolic.cpp:485
Formula DeltaWeaken(const Formula &f, const double delta)
Weaken the input formula $p f by delta.
Definition symbolic.cpp:476
std::set< Formula > map(const std::set< Formula > &formulas, const std::function< Formula(const Formula &)> &func)
Given formulas = {f₁, ..., fₙ} and a func : Formula → Formula, map(formulas, func) returns a set {fun...
Definition symbolic.cpp:47
std::set< Formula > get_clauses(const Formula &f)
Returns the set of clauses in f.
Definition symbolic.cpp:98
bool is_cnf(const Formula &f)
Check if f is in CNF form.
Definition symbolic.cpp:110
RelationalOperator
Relational operators are used in formulas.
Definition symbolic.h:191
bool IsDifferentiable(const Formula &f)
Check if the formula f is symbolic-differentiable.
Definition symbolic.cpp:481
LpColBound operator!(LpColBound bound)
Invert the bound with delta == 0.
Formula iff(const Formula &f1, const Formula &f2)
Return a formula f1 ⇔ f2.
Definition symbolic.cpp:39
Formula imply(const Formula &f1, const Formula &f2)
Return a formula f1 ⇒ f2.
Definition symbolic.cpp:34
Formula DeltaStrengthen(const Formula &f, const double delta)
Strengthen the input formula $p f by delta.
Definition symbolic.cpp:470
Formula make_disjunction(const std::vector< Formula > &formulas)
Make disjunction of formulas.
Definition symbolic.cpp:493
LpColBound operator-(LpColBound bound)
Invert the bound with delta > 0.
std::vector< Variable > CreateVector(const std::string &prefix, const int size, const Variable::Type type)
Creates a vector of variables of type whose size is size.
Definition symbolic.cpp:501
bool is_clause(const Formula &f)
Check if f is a clause.
Definition symbolic.cpp:78
bool HaveIntersection(const Variables &variables1, const Variables &variables2)
Check if the intersection of variables1 and variables2 is non-empty.
Definition symbolic.cpp:126
bool is_atomic(const Formula &f)
Check if f is atomic.
Definition symbolic.cpp:53