/*----------------------------------------------------------------------------- | Copyright (c) 2013-2017, Nucleic Development Team. | | Distributed under the terms of the Modified BSD License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ #pragma once #include #include "constraint.h" #include "expression.h" #include "term.h" #include "variable.h" namespace kiwi { // Variable multiply, divide, and unary invert inline Term operator*( const Variable& variable, double coefficient ) { return Term( variable, coefficient ); } inline Term operator/( const Variable& variable, double denominator ) { return variable * ( 1.0 / denominator ); } inline Term operator-( const Variable& variable ) { return variable * -1.0; } // Term multiply, divide, and unary invert inline Term operator*( const Term& term, double coefficient ) { return Term( term.variable(), term.coefficient() * coefficient ); } inline Term operator/( const Term& term, double denominator ) { return term * ( 1.0 / denominator ); } inline Term operator-( const Term& term ) { return term * -1.0; } // Expression multiply, divide, and unary invert inline Expression operator*( const Expression& expression, double coefficient ) { std::vector terms; terms.reserve( expression.terms().size() ); for (const Term &term : expression.terms()) terms.push_back(term * coefficient); return Expression( std::move(terms), expression.constant() * coefficient ); } inline Expression operator/( const Expression& expression, double denominator ) { return expression * ( 1.0 / denominator ); } inline Expression operator-( const Expression& expression ) { return expression * -1.0; } // Double multiply inline Expression operator*( double coefficient, const Expression& expression ) { return expression * coefficient; } inline Term operator*( double coefficient, const Term& term ) { return term * coefficient; } inline Term operator*( double coefficient, const Variable& variable ) { return variable * coefficient; } // Expression add and subtract inline Expression operator+( const Expression& first, const Expression& second ) { std::vector terms; terms.reserve( first.terms().size() + second.terms().size() ); terms.insert( terms.begin(), first.terms().begin(), first.terms().end() ); terms.insert( terms.end(), second.terms().begin(), second.terms().end() ); return Expression( std::move(terms), first.constant() + second.constant() ); } inline Expression operator+( const Expression& first, const Term& second ) { std::vector terms; terms.reserve( first.terms().size() + 1 ); terms.insert( terms.begin(), first.terms().begin(), first.terms().end() ); terms.push_back( second ); return Expression( std::move(terms), first.constant() ); } inline Expression operator+( const Expression& expression, const Variable& variable ) { return expression + Term( variable ); } inline Expression operator+( const Expression& expression, double constant ) { return Expression( expression.terms(), expression.constant() + constant ); } inline Expression operator-( const Expression& first, const Expression& second ) { return first + -second; } inline Expression operator-( const Expression& expression, const Term& term ) { return expression + -term; } inline Expression operator-( const Expression& expression, const Variable& variable ) { return expression + -variable; } inline Expression operator-( const Expression& expression, double constant ) { return expression + -constant; } // Term add and subtract inline Expression operator+( const Term& term, const Expression& expression ) { return expression + term; } inline Expression operator+( const Term& first, const Term& second ) { return Expression( { first, second } ); } inline Expression operator+( const Term& term, const Variable& variable ) { return term + Term( variable ); } inline Expression operator+( const Term& term, double constant ) { return Expression( term, constant ); } inline Expression operator-( const Term& term, const Expression& expression ) { return -expression + term; } inline Expression operator-( const Term& first, const Term& second ) { return first + -second; } inline Expression operator-( const Term& term, const Variable& variable ) { return term + -variable; } inline Expression operator-( const Term& term, double constant ) { return term + -constant; } // Variable add and subtract inline Expression operator+( const Variable& variable, const Expression& expression ) { return expression + variable; } inline Expression operator+( const Variable& variable, const Term& term ) { return term + variable; } inline Expression operator+( const Variable& first, const Variable& second ) { return Term( first ) + second; } inline Expression operator+( const Variable& variable, double constant ) { return Term( variable ) + constant; } inline Expression operator-( const Variable& variable, const Expression& expression ) { return variable + -expression; } inline Expression operator-( const Variable& variable, const Term& term ) { return variable + -term; } inline Expression operator-( const Variable& first, const Variable& second ) { return first + -second; } inline Expression operator-( const Variable& variable, double constant ) { return variable + -constant; } // Double add and subtract inline Expression operator+( double constant, const Expression& expression ) { return expression + constant; } inline Expression operator+( double constant, const Term& term ) { return term + constant; } inline Expression operator+( double constant, const Variable& variable ) { return variable + constant; } inline Expression operator-( double constant, const Expression& expression ) { return -expression + constant; } inline Expression operator-( double constant, const Term& term ) { return -term + constant; } inline Expression operator-( double constant, const Variable& variable ) { return -variable + constant; } // Expression relations inline Constraint operator==( const Expression& first, const Expression& second ) { return Constraint( first - second, OP_EQ ); } inline Constraint operator==( const Expression& expression, const Term& term ) { return expression == Expression( term ); } inline Constraint operator==( const Expression& expression, const Variable& variable ) { return expression == Term( variable ); } inline Constraint operator==( const Expression& expression, double constant ) { return expression == Expression( constant ); } inline Constraint operator<=( const Expression& first, const Expression& second ) { return Constraint( first - second, OP_LE ); } inline Constraint operator<=( const Expression& expression, const Term& term ) { return expression <= Expression( term ); } inline Constraint operator<=( const Expression& expression, const Variable& variable ) { return expression <= Term( variable ); } inline Constraint operator<=( const Expression& expression, double constant ) { return expression <= Expression( constant ); } inline Constraint operator>=( const Expression& first, const Expression& second ) { return Constraint( first - second, OP_GE ); } inline Constraint operator>=( const Expression& expression, const Term& term ) { return expression >= Expression( term ); } inline Constraint operator>=( const Expression& expression, const Variable& variable ) { return expression >= Term( variable ); } inline Constraint operator>=( const Expression& expression, double constant ) { return expression >= Expression( constant ); } // Term relations inline Constraint operator==( const Term& term, const Expression& expression ) { return expression == term; } inline Constraint operator==( const Term& first, const Term& second ) { return Expression( first ) == second; } inline Constraint operator==( const Term& term, const Variable& variable ) { return Expression( term ) == variable; } inline Constraint operator==( const Term& term, double constant ) { return Expression( term ) == constant; } inline Constraint operator<=( const Term& term, const Expression& expression ) { return expression >= term; } inline Constraint operator<=( const Term& first, const Term& second ) { return Expression( first ) <= second; } inline Constraint operator<=( const Term& term, const Variable& variable ) { return Expression( term ) <= variable; } inline Constraint operator<=( const Term& term, double constant ) { return Expression( term ) <= constant; } inline Constraint operator>=( const Term& term, const Expression& expression ) { return expression <= term; } inline Constraint operator>=( const Term& first, const Term& second ) { return Expression( first ) >= second; } inline Constraint operator>=( const Term& term, const Variable& variable ) { return Expression( term ) >= variable; } inline Constraint operator>=( const Term& term, double constant ) { return Expression( term ) >= constant; } // Variable relations inline Constraint operator==( const Variable& variable, const Expression& expression ) { return expression == variable; } inline Constraint operator==( const Variable& variable, const Term& term ) { return term == variable; } inline Constraint operator==( const Variable& first, const Variable& second ) { return Term( first ) == second; } inline Constraint operator==( const Variable& variable, double constant ) { return Term( variable ) == constant; } inline Constraint operator<=( const Variable& variable, const Expression& expression ) { return expression >= variable; } inline Constraint operator<=( const Variable& variable, const Term& term ) { return term >= variable; } inline Constraint operator<=( const Variable& first, const Variable& second ) { return Term( first ) <= second; } inline Constraint operator<=( const Variable& variable, double constant ) { return Term( variable ) <= constant; } inline Constraint operator>=( const Variable& variable, const Expression& expression ) { return expression <= variable; } inline Constraint operator>=( const Variable& variable, const Term& term ) { return term <= variable; } inline Constraint operator>=( const Variable& first, const Variable& second ) { return Term( first ) >= second; } inline Constraint operator>=( const Variable& variable, double constant ) { return Term( variable ) >= constant; } // Double relations inline Constraint operator==( double constant, const Expression& expression ) { return expression == constant; } inline Constraint operator==( double constant, const Term& term ) { return term == constant; } inline Constraint operator==( double constant, const Variable& variable ) { return variable == constant; } inline Constraint operator<=( double constant, const Expression& expression ) { return expression >= constant; } inline Constraint operator<=( double constant, const Term& term ) { return term >= constant; } inline Constraint operator<=( double constant, const Variable& variable ) { return variable >= constant; } inline Constraint operator>=( double constant, const Expression& expression ) { return expression <= constant; } inline Constraint operator>=( double constant, const Term& term ) { return term <= constant; } inline Constraint operator>=( double constant, const Variable& variable ) { return variable <= constant; } // Constraint strength modifier inline Constraint operator|( const Constraint& constraint, double strength ) { return Constraint( constraint, strength ); } inline Constraint operator|( double strength, const Constraint& constraint ) { return constraint | strength; } } // namespace kiwi