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);