Skip to content

Add LazyExpresssions #888

Description

@brynpickering

Spinning out the Lazy part of the now closed issue on an expressions container (#881). Copying some text from that issue verbatim

Would be interesting to add some lazy equivalent (LazyExpressions?) of expressions which doesn't evaluate the expression but rather takes a callable and only promotes them to an Expression member on request. This would work well with the text math (#561) as you could define any number of expressions and have only those which will be used by downstream constraints or objectives actually evaluated; the rest only need evaluating on-the-fly when requesting their solutions (they could be statistics of your model runs that you just want to calculate in postprocessing).

I had a few thoughts on the LazyExpressions that I haven't fully resolved in my head:

  • Should they always be promoted on first evaluation or not? I'm leaning towards having a separate promote method which explicitly promotes them, otherwise they can spit out the evaluated expression on calling evaluate but the linopy model still stores them as a LazyExpression.
  • Should it be possible for them to store an explicit AST or is a callable OK? From the perspective of having a consistent Python API that allows these to be created interactively in Python or (in future) via the text math, I was thinking of keeping it as a callable. But if we limited it to just working with the text math, it could also hold the AST, knowing that it is a pyparsing object and having explicit functionality to deal with that.
  • How to handle arithmetic operations? I guess easiest is to always evaluate them if any kind of arithmetic is applied, but then you can't have lazy + lazy -> lazy. One could also defer the operations by storing the callables and their connecting arithmetic, then you could get a LazyExpression out of combining two lazy expressions (you probably wouldn't want to support lazy + variable -> lazy).
  • should providing a mask be possible, and how to handle cases where this should also be a callable / AST? The use-case is where you mask based on a value in the solution (e.g. mask to only evaluate when p_nom > 0), so it is only viable to evaluate the mask also when calling LazyExpression.solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions