Linear Functions and Constraints - Numerical Optimization

Skip to content
Back to top
View this page
Edit this page

# Linear Functions and Constraints

This module implements linear functions (see `LinearFunction`) in formal variables and chained (in)equalities between them (see `LinearConstraint`). By convention, these are always written as either equalities or less-or-equal. For example:

Sage

    sage: p = MixedIntegerLinearProgram()
    sage: x = p.new_variable()
    sage: f = 1 + x[1] + 2*x[2];  f     #  a linear function
    1 + x_0 + 2*x_1
    sage: type(f)
    <class 'sage.numerical.linear_functions.LinearFunction'>

    sage: c = (0 <= f);  c    # a constraint
    0 <= 1 + x_0 + 2*x_1
    sage: type(c)
    <class 'sage.numerical.linear_functions.LinearConstraint'>

Python

    >>> from sage.all import *
    >>> p = MixedIntegerLinearProgram()
    >>> x = p.new_variable()
    >>> f = Integer(1) + x[Integer(1)] + Integer(2)*x[Integer(2)];  f     #  a linear function
    1 + x_0 + 2*x_1
    >>> type(f)
    <class 'sage.numerical.linear_functions.LinearFunction'>

    >>> c = (Integer(0) <= f);  c    # a constraint
    0 <= 1 + x_0 + 2*x_1
    >>> type(c)
    <class 'sage.numerical.linear_functions.LinearConstraint'>

Note that you can use this module without any reference to linear programming, it only implements linear functions over a base ring and constraints. However, for ease of demonstration we will always construct them out of linear programs (see `mip`).

Constraints can be equations or (non-strict) inequalities. They can be chained:

Sage

    sage: p = MixedIntegerLinearProgram()
    sage: x = p.new_variable()
    sage: x[0] == x[1] == x[2] == x[3]
    x_0 == x_1 == x_2 == x_3

    sage: ieq_01234 = x[0] <= x[1] <= x[2] <= x[3] <= x[4]
    sage: ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4

[Python]

    >>> from sage.all import *
    >>> p = MixedIntegerLinearProgram()
    >>> x = p.new_variable()
    >>> x[Integer(0)] == x[Integer(1)] == x[Integer(2)] == x[Integer(3)]
    x_0 == x_1 == x_2 == x_3

    >>> ieq_01234 = x[Integer(0)] <= x[Integer(1)] <= x[Integer(2)] <= x[Integer(3)] <= x[Integer(4)]
    >>> ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4

If necessary, the direction of inequality is flipped to always write inequalities as less or equal:

Sage

    sage: x[5] >= ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4 <= x_5

    sage: (x[5] <= x[6]) >= ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4 <= x_5 <= x_6
    sage: (x[5] <= x[6]) <= ieq_01234
    x_5 <= x_6 <= x_0 <= x_1 <= x_2 <= x_3 <= x_4

Python

    >>> from sage.all import *
    >>> x[Integer(5)] >= ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4 <= x_5

    >>> (x[Integer(5)] <= x[Integer(6)]) >= ieq_01234
    x_0 <= x_1 <= x_2 <= x_3 <= x_4 <= x_5 <= x_6
    >>> (x[Integer(5)] <= x[Integer(6)]) <= ieq_01234
    x_5 <= x_6 <= x_0 <= x_1 <= x_2 <= x_3 <= x_4

Warning

The implementation of chained inequalities uses a Python hack to make it work, so it is not completely robust. In particular, while constants are allowed, no two constants can appear next to each other. The following does not work for example:

Sage

    sage: x[0] <= 3 <= 4
    True

Python

    >>> from sage.all import *
    >>> x[Integer(0)] <= Integer(3) <= Integer(4)
    True

If you really need this for some reason, you can explicitly convert the constants to a `LinearFunction`:

Sage

    sage: from sage.numerical.linear_functions import LinearFunctionsParent
    sage: LF = LinearFunctionsParent(QQ)
    sage: x[1] <= LF(3) <= LF(4)
    x_1 <= 3 <= 4

[Python]

    >>> from sage.all import *
    >>> from sage.numerical.linear_functions import LinearFunctionsParent
    >>> LF = LinearFunctionsParent(QQ)
    >>> x[Integer(1)] <= LF(Integer(3)) <= LF(Integer(4))
    x_1 <= 3 <= 4

class sage.numerical.linear_functions.LinearConstraint

  Bases: `LinearFunctionOrConstraint`

  A class to represent formal Linear Constraints.

  A Linear Constraint being an inequality between two linear functions, this class lets the user write `LinearFunction1 <= LinearFunction2` to define the corresponding constraint, which can potentially involve several layers of such inequalities (`A <= B <= C`), or even equalities like `A == B == C`.

  Trivial constraints (meaning that they have only one term and no relation) are also allowed. They are required for the coercion system to work.

  Warning

  This class has no reason to be instantiated by the user, and is meant to be used by instances of `MixedIntegerLinearProgram`.

  INPUT:

  - `parent` – the parent; a `LinearConstraintsParent_class`

  - `terms` – list/tuple/iterable of two or more linear functions (or things that can be converted into linear functions)

  - `equality` – boolean (default: `False`); whether the terms are the entries of a chained less-or-equal (`<=`) inequality or a chained equality

  EXAMPLES:

  Sage

      sage: p = MixedIntegerLinearProgram()
      sage: b = p.new_variable()
      sage: b[2]+2*b[3] <= b[8]-5
      x_0 + 2*x_1 <= -5 + x_2

  Python

      >>> from sage.all import *
      >>> p = MixedIntegerLinearProgram()
      >>> b = p.new_variable()
      >>> b[Integer(2)]+Integer(2)*b[Integer(3)] <= b[Integer(8)]-Integer(5)
      x_0 + 2*x_1 <= -5 + x_2

  equals(left, right)

    Compare `left` and `right`.

    OUTPUT:

    boolean; whether all terms of `left` and `right` are equal. Note that this is stronger than mathematical equivalence of the relations.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable()
        sage: (x[1] + 1 >= 2).equals(3/3 + 1*x[1] + 0*x[2] >= 8/4)
        True
        sage: (x[1] + 1 >= 2).equals(x[1] + 1-1 >= 1-1)
        False

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> x = p.new_variable()
        >>> (x[Integer(1)] + Integer(1) >= Integer(2)).equals(Integer(3)/Integer(3) + Integer(1)*x[Integer(1)] + Integer(0)*x[Integer(2)] >= Integer(8)/Integer(4))
        True
        >>> (x[Integer(1)] + Integer(1) >= Integer(2)).equals(x[Integer(1)] + Integer(1)-Integer(1) >= Integer(1)-Integer(1))
        False

  equations()

    Iterate over the unchained(!) equations.

    OUTPUT:

    An iterator over pairs `(lhs, rhs)` such that the individual equations are `lhs == rhs`.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable()
        sage: eqns = 1 == b[0] == b[2] == 3 == b[3];  eqns
        1 == x_0 == x_1 == 3 == x_2
        sage: for lhs, rhs in eqns.equations():
        ....:     print(str(lhs) + ' == ' + str(rhs))
        1 == x_0
        x_0 == x_1
        x_1 == 3
        3 == x_2

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> b = p.new_variable()
        >>> eqns = Integer(1) == b[Integer(0)] == b[Integer(2)] == Integer(3) == b[Integer(3)];  eqns
        1 == x_0 == x_1 == 3 == x_2
        >>> for lhs, rhs in eqns.equations():
        ...     print(str(lhs) + ' == ' + str(rhs))
        1 == x_0
        x_0 == x_1
        x_1 == 3
        3 == x_2

  inequalities()

    Iterate over the unchained(!) inequalities.

    OUTPUT:

    An iterator over pairs `(lhs, rhs)` such that the individual equations are `lhs <= rhs`.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable()
        sage: ieq = 1 <= b[0] <= b[2] <= 3 <= b[3]; ieq
        1 <= x_0 <= x_1 <= 3 <= x_2

        sage: for lhs, rhs in ieq.inequalities():
        ....:     print(str(lhs) + ' <= ' + str(rhs))
        1 <= x_0
        x_0 <= x_1
        x_1 <= 3
        3 <= x_2

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> b = p.new_variable()
        >>> ieq = Integer(1) <= b[Integer(0)] <= b[Integer(2)] <= Integer(3) <= b[Integer(3)]; ieq
        1 <= x_0 <= x_1 <= 3 <= x_2

        >>> for lhs, rhs in ieq.inequalities():
        ...     print(str(lhs) + ' <= ' + str(rhs))
        1 <= x_0
        x_0 <= x_1
        x_1 <= 3
        3 <= x_2

  is_equation()

    Whether the constraint is a chained equation.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable()
        sage: (b[0] == b[1]).is_equation()
        True
        sage: (b[0] <= b[1]).is_equation()
        False

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> b = p.new_variable()
        >>> (b[Integer(0)] == b[Integer(1)]).is_equation()
        True
        >>> (b[Integer(0)] <= b[Integer(1)]).is_equation()
        False

  is_less_or_equal()

    Whether the constraint is a chained less-or_equal inequality.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable()
        sage: (b[0] == b[1]).is_less_or_equal()
        False
        sage: (b[0] <= b[1]).is_less_or_equal()
        True

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> b = p.new_variable()
        >>> (b[Integer(0)] == b[Integer(1)]).is_less_or_equal()
        False
        >>> (b[Integer(0)] <= b[Integer(1)]).is_less_or_equal()
        True

  is_trivial()

    Test whether the constraint is trivial.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: LC = p.linear_constraints_parent()
        sage: ieq = LC(1,2);  ieq
        1 <= 2
        sage: ieq.is_trivial()
        False

        sage: ieq = LC(1);  ieq
        trivial constraint starting with 1
        sage: ieq.is_trivial()
        True

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> LC = p.linear_constraints_parent()
        >>> ieq = LC(Integer(1),Integer(2));  ieq
        1 <= 2
        >>> ieq.is_trivial()
        False

        >>> ieq = LC(Integer(1));  ieq
        trivial constraint starting with 1
        >>> ieq.is_trivial()
        True

sage.numerical.linear_functions.LinearConstraintsParent()

  Return the parent for linear functions over `base_ring`.

  The output is cached, so only a single parent is ever constructed for a given base ring.

  INPUT:

  - `linear_functions_parent` – a

      `LinearFunctionsParent_class`; the type of linear functions that the constraints are made out of

  OUTPUT: the parent of the linear constraints with the given linear functions

  EXAMPLES:

  Sage

      sage: from sage.numerical.linear_functions import (
      ....:     LinearFunctionsParent, LinearConstraintsParent)
      sage: LF = LinearFunctionsParent(QQ)
      sage: LinearConstraintsParent(LF)
      Linear constraints over Rational Field

  Python

      >>> from sage.all import *
      >>> from sage.numerical.linear_functions import (
      ...     LinearFunctionsParent, LinearConstraintsParent)
      >>> LF = LinearFunctionsParent(QQ)
      >>> LinearConstraintsParent(LF)
      Linear constraints over Rational Field

class sage.numerical.linear_functions.LinearConstraintsParent_class

  Bases: `Parent`

  Parent for `LinearConstraint`.

  Warning

  This class has no reason to be instantiated by the user, and is meant to be used by instances of `MixedIntegerLinearProgram`. Also, use the `LinearConstraintsParent()` factory function.

  INPUT/OUTPUT: see `LinearFunctionsParent()`

  EXAMPLES:

  Sage

      sage: p = MixedIntegerLinearProgram()
      sage: LC = p.linear_constraints_parent();  LC
      Linear constraints over Real Double Field
      sage: from sage.numerical.linear_functions import LinearConstraintsParent
      sage: LinearConstraintsParent(p.linear_functions_parent()) is LC
      True

  Python

      >>> from sage.all import *
      >>> p = MixedIntegerLinearProgram()
      >>> LC = p.linear_constraints_parent();  LC
      Linear constraints over Real Double Field
      >>> from sage.numerical.linear_functions import LinearConstraintsParent
      >>> LinearConstraintsParent(p.linear_functions_parent()) is LC
      True

  linear_functions_parent()

    Return the parent for the linear functions.

    EXAMPLES:

    Sage

        sage: LC = MixedIntegerLinearProgram().linear_constraints_parent()
        sage: LC.linear_functions_parent()
        Linear functions over Real Double Field

    Python

        >>> from sage.all import *
        >>> LC = MixedIntegerLinearProgram().linear_constraints_parent()
        >>> LC.linear_functions_parent()
        Linear functions over Real Double Field

class sage.numerical.linear_functions.LinearFunction

  Bases: `LinearFunctionOrConstraint`

  An elementary algebra to represent symbolic linear functions.

  Warning

  You should never instantiate `LinearFunction` manually. Use the element constructor in the parent instead.

  EXAMPLES:

  For example, do this:

  Sage

      sage: p = MixedIntegerLinearProgram()
      sage: parent = p.linear_functions_parent()
      sage: parent({0 : 1, 3 : -8})
      x_0 - 8*x_3

  Python

      >>> from sage.all import *
      >>> p = MixedIntegerLinearProgram()
      >>> parent = p.linear_functions_parent()
      >>> parent({Integer(0) : Integer(1), Integer(3) : -Integer(8)})
      x_0 - 8*x_3

  instead of this:

  Sage

      sage: from sage.numerical.linear_functions import LinearFunction
      sage: LinearFunction(p.linear_functions_parent(), {0 : 1, 3 : -8})
      x_0 - 8*x_3

  [Python]

      >>> from sage.all import *
      >>> from sage.numerical.linear_functions import LinearFunction
      >>> LinearFunction(p.linear_functions_parent(), {Integer(0) : Integer(1), Integer(3) : -Integer(8)})
      x_0 - 8*x_3

  coefficient(x)

    Return one of the coefficients.

    INPUT:

    - `x` – a linear variable or an integer; if an integer \(i\) is passed, then \(x_i\) is used as linear variable

    OUTPUT:

    A base ring element. The coefficient of `x` in the linear function. Pass `-1` for the constant term.

    EXAMPLES:

    Sage

        sage: mip.<b> = MixedIntegerLinearProgram()
        sage: lf = -8 * b[3] + b[0] - 5;  lf
        -5 - 8*x_0 + x_1
        sage: lf.coefficient(b[3])
        -8.0
        sage: lf.coefficient(0)      # x_0 is b[3]
        -8.0
        sage: lf.coefficient(4)
        0.0
        sage: lf.coefficient(-1)
        -5.0

    Python

        >>> from sage.all import *
        >>> mip = MixedIntegerLinearProgram(names=('b',)); (b,) = mip._first_ngens(1)
        >>> lf = -Integer(8) * b[Integer(3)] + b[Integer(0)] - Integer(5);  lf
        -5 - 8*x_0 + x_1
        >>> lf.coefficient(b[Integer(3)])
        -8.0
        >>> lf.coefficient(Integer(0))      # x_0 is b[3]
        -8.0
        >>> lf.coefficient(Integer(4))
        0.0
        >>> lf.coefficient(-Integer(1))
        -5.0

  dict()

    Return the dictionary corresponding to the Linear Function.

    OUTPUT:

    The linear function is represented as a dictionary. The value are the coefficient of the variable represented by the keys ( which are integers ). The key `-1` corresponds to the constant term.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: LF = p.linear_functions_parent()
        sage: lf = LF({0 : 1, 3 : -8})
        sage: lf.dict()
        {0: 1.0, 3: -8.0}

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> LF = p.linear_functions_parent()
        >>> lf = LF({Integer(0) : Integer(1), Integer(3) : -Integer(8)})
        >>> lf.dict()
        {0: 1.0, 3: -8.0}

  equals(left, right)

    Logically compare `left` and `right`.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable()
        sage: (x[1] + 1).equals(3/3 + 1*x[1] + 0*x[2])
        True

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> x = p.new_variable()
        >>> (x[Integer(1)] + Integer(1)).equals(Integer(3)/Integer(3) + Integer(1)*x[Integer(1)] + Integer(0)*x[Integer(2)])
        True

  is_zero()

    Test whether `self` is zero.

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable()
        sage: (x[1] - x[1] + 0*x[2]).is_zero()
        True

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> x = p.new_variable()
        >>> (x[Integer(1)] - x[Integer(1)] + Integer(0)*x[Integer(2)]).is_zero()
        True

  items()

    Iterate over the index, coefficient pairs.

    OUTPUT:

    An iterator over the `(key, coefficient)` pairs. The keys are integers indexing the variables. The key `-1` corresponds to the constant term.

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram(solver = 'ppl')
        sage: x = p.new_variable()
        sage: f = 0.5 + 3/2*x[1] + 0.6*x[3]
        sage: for id, coeff in sorted(f.items()):
        ....:     print(f'id = {id}   coeff = {coeff}')
        id = -1   coeff = 1/2
        id = 0   coeff = 3/2
        id = 1   coeff = 3/5

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram(solver = 'ppl')
        >>> x = p.new_variable()
        >>> f = RealNumber('0.5') + Integer(3)/Integer(2)*x[Integer(1)] + RealNumber('0.6')*x[Integer(3)]
        >>> for id, coeff in sorted(f.items()):
        ...     print(f'id = {id}   coeff = {coeff}')
        id = -1   coeff = 1/2
        id = 0   coeff = 3/2
        id = 1   coeff = 3/5

  iteritems(*args, **kwds)

    Deprecated: Use `items()` instead. See Issue #40996 for details.

class sage.numerical.linear_functions.LinearFunctionOrConstraint

  Bases: `ModuleElement`

  Base class for `LinearFunction` and `LinearConstraint`.

  This class exists solely to implement chaining of inequalities in constraints.

sage.numerical.linear_functions.LinearFunctionsParent()

  Return the parent for linear functions over `base_ring`.

  The output is cached, so only a single parent is ever constructed for a given base ring.

  INPUT:

  - `base_ring` – a ring; the coefficient ring for the linear functions

  OUTPUT: the parent of the linear functions over `base_ring`

  EXAMPLES:

  Sage

      sage: from sage.numerical.linear_functions import LinearFunctionsParent
      sage: LinearFunctionsParent(QQ)
      Linear functions over Rational Field

  Python

      >>> from sage.all import *
      >>> from sage.numerical.linear_functions import LinearFunctionsParent
      >>> LinearFunctionsParent(QQ)
      Linear functions over Rational Field

class sage.numerical.linear_functions.LinearFunctionsParent_class

  Bases: `Parent`

  The parent for all linear functions over a fixed base ring.

  Warning

  You should use `LinearFunctionsParent()` to construct instances of this class.

  INPUT/OUTPUT: see `LinearFunctionsParent()`

  EXAMPLES:

  Sage

      sage: from sage.numerical.linear_functions import LinearFunctionsParent_class
      sage: LinearFunctionsParent_class
      <class 'sage.numerical.linear_functions.LinearFunctionsParent_class'>

  Python

      >>> from sage.all import *
      >>> from sage.numerical.linear_functions import LinearFunctionsParent_class
      >>> LinearFunctionsParent_class
      <class 'sage.numerical.linear_functions.LinearFunctionsParent_class'>

  gen(i)

    Return the linear variable \(x_i\).

    INPUT:

    - `i` – nonnegative integer

    OUTPUT: the linear function \(x_i\)

    EXAMPLES:

    Sage

        sage: LF = MixedIntegerLinearProgram().linear_functions_parent()
        sage: LF.gen(23)
        x_23

    Python

        >>> from sage.all import *
        >>> LF = MixedIntegerLinearProgram().linear_functions_parent()
        >>> LF.gen(Integer(23))
        x_23

  set_multiplication_symbol(symbol='*')

    Set the multiplication symbol when pretty-printing linear functions.

    INPUT:

    - `symbol` – string (default: `'*'`); the multiplication symbol to be used

    EXAMPLES:

    Sage

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable()
        sage: f = -1-2*x[0]-3*x[1]
        sage: LF = f.parent()
        sage: LF._get_multiplication_symbol()
        '*'
        sage: f
        -1 - 2*x_0 - 3*x_1
        sage: LF.set_multiplication_symbol(' ')
        sage: f
        -1 - 2 x_0 - 3 x_1
        sage: LF.set_multiplication_symbol()
        sage: f
        -1 - 2*x_0 - 3*x_1

    Python

        >>> from sage.all import *
        >>> p = MixedIntegerLinearProgram()
        >>> x = p.new_variable()
        >>> f = -Integer(1)-Integer(2)*x[Integer(0)]-Integer(3)*x[Integer(1)]
        >>> LF = f.parent()
        >>> LF._get_multiplication_symbol()
        '*'
        >>> f
        -1 - 2*x_0 - 3*x_1
        >>> LF.set_multiplication_symbol(' ')
        >>> f
        -1 - 2 x_0 - 3 x_1
        >>> LF.set_multiplication_symbol()
        >>> f
        -1 - 2*x_0 - 3*x_1

  tensor(free_module)

    Return the tensor product with `free_module`.

    INPUT:

    - `free_module` – vector space or matrix space over the same base ring

    OUTPUT:

    Instance of `sage.numerical.linear_tensor.LinearTensorParent_class`.

    EXAMPLES:

    Sage

        sage: LF = MixedIntegerLinearProgram().linear_functions_parent()
        sage: LF.tensor(RDF^3)
        Tensor product of Vector space of dimension 3 over Real Double Field
        and Linear functions over Real Double Field
        sage: LF.tensor(QQ^2)
        Traceback (most recent call last):
        ...
        ValueError: base rings must match

    Python

        >>> from sage.all import *
        >>> LF = MixedIntegerLinearProgram().linear_functions_parent()
        >>> LF.tensor(RDF**Integer(3))
        Tensor product of Vector space of dimension 3 over Real Double Field
        and Linear functions over Real Double Field
        >>> LF.tensor(QQ**Integer(2))
        Traceback (most recent call last):
        ...
        ValueError: base rings must match

sage.numerical.linear_functions.is_LinearConstraint(x)

  Test whether `x` is a linear constraint.

  INPUT:

  - `x` – anything

  OUTPUT: boolean

  EXAMPLES:

  Sage

      sage: p = MixedIntegerLinearProgram()
      sage: x = p.new_variable()
      sage: ieq = (x[0] <= x[1])
      sage: from sage.numerical.linear_functions import is_LinearConstraint
      sage: is_LinearConstraint(ieq)
      doctest:warning...
      DeprecationWarning: The function is_LinearConstraint is deprecated;
      use 'isinstance(..., LinearConstraint)' instead.
      See https://github.com/sagemath/sage/issues/38184 for details.
      True
      sage: is_LinearConstraint('a string')
      False

  Python

      >>> from sage.all import *
      >>> p = MixedIntegerLinearProgram()
      >>> x = p.new_variable()
      >>> ieq = (x[Integer(0)] <= x[Integer(1)])
      >>> from sage.numerical.linear_functions import is_LinearConstraint
      >>> is_LinearConstraint(ieq)
      doctest:warning...
      DeprecationWarning: The function is_LinearConstraint is deprecated;
      use 'isinstance(..., LinearConstraint)' instead.
      See https://github.com/sagemath/sage/issues/38184 for details.
      True
      >>> is_LinearConstraint('a string')
      False

sage.numerical.linear_functions.is_LinearFunction(x)

  Test whether `x` is a linear function.

  INPUT:

  - `x` – anything

  OUTPUT: boolean

  EXAMPLES:

  Sage

      sage: p = MixedIntegerLinearProgram()
      sage: x = p.new_variable()
      sage: from sage.numerical.linear_functions import is_LinearFunction
      sage: is_LinearFunction(x[0] - 2*x[2])
      doctest:warning...
      DeprecationWarning: The function is_LinearFunction is deprecated;
      use 'isinstance(..., LinearFunction)' instead.
      See https://github.com/sagemath/sage/issues/38184 for details.
      True
      sage: is_LinearFunction('a string')
      False

  Python

      >>> from sage.all import *
      >>> p = MixedIntegerLinearProgram()
      >>> x = p.new_variable()
      >>> from sage.numerical.linear_functions import is_LinearFunction
      >>> is_LinearFunction(x[Integer(0)] - Integer(2)*x[Integer(2)])
      doctest:warning...
      DeprecationWarning: The function is_LinearFunction is deprecated;
      use 'isinstance(..., LinearFunction)' instead.
      See https://github.com/sagemath/sage/issues/38184 for details.
      True
      >>> is_LinearFunction('a string')
      False