5#ifndef IDOL_GENERATIONPATTERN_H
6#define IDOL_GENERATIONPATTERN_H
8#include "idol/mixed-integer/modeling/expressions/AffExpr.h"
10#include "idol/mixed-integer/modeling/expressions/operations/operators.h"
13 template<
class,
class>
class GenerationPattern;
16template<
class GeneratedT,
21 using KeyT = std::conditional_t<std::is_same_v<GeneratedT, Var>,
Ctr,
Var>;
26 : m_constant(std::move(t_constant)), m_linear(std::move(t_linear)) {}
28 auto& constant() {
return m_constant; }
30 [[nodiscard]]
const auto& constant()
const {
return m_constant; }
32 auto& linear() {
return m_linear; }
34 [[nodiscard]]
const auto& linear()
const {
return m_linear; }
37 return evaluate(m_constant, t_values);
43 for (
const auto& [key, value] : m_linear) {
44 result += key * evaluate(value, t_values);
52 result.constant() = generate_constant(t_values);
57 m_constant += t_other.constant();
58 for (
const auto& [var, coeff] : t_other.linear()) {
59 m_linear.set(var, m_linear.get(var) + coeff);
65 m_constant -= t_other;
66 for (
const auto& [var, coeff] : t_other.linear()) {
67 m_linear.set(var, m_linear.get(var) - coeff);
73 m_constant += t_other.m_constant;
74 m_linear += t_other.m_linear;
79 m_constant += t_scalar;
84 m_constant -= t_other.m_constant;
85 m_linear -= t_other.m_linear;
90 m_constant *= t_scalar;
96 m_constant /= t_scalar;
102 if (!m_linear.empty()) {
103 throw Exception(
"Trying to build a quadratic generation pattern.");
108 m_linear.set(t_key, m_constant);
120 template<
class GeneratedT,
class CoefficientT>
124 t_os << t_constant.constant();
126 for (
const auto& [key, value] : t_constant.linear()) {
127 t_os <<
" + " << value <<
" !" << key;
132 print_constant(t_gen.constant());
133 for (
const auto& [key, value] : t_gen.linear()) {
135 if (value.linear().empty()) {
136 print_constant(value);
139 print_constant(value);
148 template<
class GeneratedT,
class CoefficientT>
151 auto result = t_other;
156 template<
class GeneratedT,
class CoefficientT>
159 auto result = t_other;
164 template<
class GeneratedT,
class CoefficientT>
167 auto result = t_other;
172 template<
class GeneratedT,
class CoefficientT>
175 auto result = t_other;
180 template<
class GeneratedT,
class CoefficientT>
183 auto result = t_other;
188 template<
class GeneratedT,
class CoefficientT>
191 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
196 template<
class GeneratedT,
class CoefficientT>
199 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
204 template<
class GeneratedT,
class CoefficientT>
207 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
212 template<
class GeneratedT,
class CoefficientT>
215 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
220 template<
class GeneratedT,
class CoefficientT>
223 auto result = t_other;
228 template<
class GeneratedT,
class CoefficientT>
231 const typename idol::GenerationPattern<GeneratedT, CoefficientT>::KeyT &t_key) {
237 template<
class GeneratedT,
class CoefficientT>
239 operator*(
const typename idol::GenerationPattern<GeneratedT, CoefficientT>::KeyT &t_key,
246 template<
class GeneratedT,
class CoefficientT>
250 auto result = t_gen1;
255 template<
class GeneratedT,
class CoefficientT>
259 auto result = t_gen1;
264 template<
class GeneratedT,
class CoefficientT>
266 operator-(
const CoefficientT& t_gen1,
268 GenerationPattern<GeneratedT, CoefficientT> result;
269 result.linear().set(t_gen1, 1);
274 template<
class GeneratedT,
class CoefficientT>
277 const CoefficientT& t_gen2) {
278 GenerationPattern<GeneratedT, CoefficientT> result = t_gen1;
283 template<
class GeneratedT,
class CoefficientT>
291 template<
class GeneratedT,
class CoefficientT>
299 template<
class GeneratedT,
class CoefficientT>
307 template<
class GeneratedT,
class CoefficientT>
315 template<
class GeneratedT,
class CoefficientT>
323 template<
class GeneratedT,
class CoefficientT>
331 template<
class GeneratedT,
class CoefficientT>
341 cut.constant().linear().set(t_var, 1);
345 template<
class GeneratedT,
class CoefficientT>
349 result.constant().constant() = t_gen.constant().constant();
350 for (
const auto &[key, value]: t_gen.constant().linear()) {
351 result.linear().set(key, result.linear().get(key) + value);
353 for (
const auto &[key, coefficient]: t_gen.linear()) {
354 result.constant().linear().set(key, result.constant().linear().get(key) + coefficient.constant());
355 for (
const auto &[key2, value]: coefficient.linear()) {
356 result.linear().set(key2, result.linear().get(key2) + value * key);