Procedural Constraints + Scheduling in Typescript #1122
Replies: 4 comments
-
@mattdailis There's no mention of profile streaming in procedural constraints because I dropped that feature from my prototype. It is still possible though. |
Beta Was this translation helpful? Give feedback.
-
I edited the main post to include goal delegation (enabling linkage) as part of the MVP. |
Beta Was this translation helpful? Give feedback.
-
I think the procedural scheduling proposal is parallel in nature to Clipper requests as they address different aspects. Procedural scheduling is a generic instrument to allow the users to do what vanilla Aerie cannot do, at least in an easy way. On the other hand, the different features discussed with Clipper team such as grouping, advanced anchoring and activity linkage, are fundamental capabilities (to any mission, not only for Clipper) that should be inherent to Aerie and easy to model (this point was emphasized a number of times by Clipper team). I would suggest to start designing/implementing these capabilities (Clipper highlighted them as high priority). That will benefit not only Clipper, but can also be used by procedural constraints/scheduling. |
Beta Was this translation helpful? Give feedback.
-
Very positive conversation with Joel. I recap below the main outcome:
|
Beta Was this translation helpful? Give feedback.
-
@adrienmaillard @jmdelfa @mattdailis @camargo I summon thee.
Intro
In the effort to address Aerie’s scheduler expressiveness problems, a year ago I proposed “spans-based scheduling”. Ultimately we threw it out for a couple reasons:
I think that might have been a bit premature though, because we misunderstood the limitations of spans-based scheduling. The idea was to allow you to place an activity anywhere you could create a span, and to chain steps of activity creation together to enable activity groups and anchors. The limitation that killed that proposal wasn’t inherent inexpressiveness in spans-based goals, but the inexpressiveness of the constraints package in our ability to create spans.
On the other hand, spans-based scheduling had one massive advantage over procedural scheduling: ease of implementation. It seemed like our two main options for procedural scheduling were both terrible:
But I present the following MathTM:
I’ll try to justify that in a bit. The point is that we can implement truly procedural scheduling - in typescript, to maintain integration with the eDSL - without re-implementing the scheduler itself. We need to re-implement “only” the constraints package in typescript, which is not a small task, but is orders of magnitude simpler.
Procedural Constraints
Procedural Constraints are actually a separate problem that we will need to solve at some point anyway. Constraints have the exact same expressiveness problem as the scheduler; we regularly get requests for help with constraints that are either impossible or ludicrously complicated to implement in the current system, and they have to wait for us to make the necessary updates every time.
It is also a requirement for every design we have for procedural scheduling. So to me it seems just as important as the scheduler; we just don’t focus on it because Clipper has much more complex and pressing needs for the scheduler. So let’s just focus on constraints for a minute.
It would be the easiest transition for the user if they could take their existing profiles and spans objects in the eDSL and just pull out the segments so they could do their own operations on them, and not have to change their constraints at all during the migration. Here’s what that would look like:
[profile].Resource(…)
functions actually query the profiles directly from the database. Same deal for activity instances..collect()
function on the profiles/spans objects which produces the segments or spans for the author to use. Expose the lower-level.map
,.map2
, and.filter
functions we already have to allow custom operations without even unwrapping the data.async
and add an import statement, which are pretty brainless changes. Everything else is drop-in.Long term, there are some operations that only exist because of the declarative context, and could slowly be deprecated and replaced with more idiomatic procedural operations (looking at you,
ForEachActivity
).Example
Let’s look at a simple operation that doesn’t exist in the eDSL: squaring a piece-wise constant real resource. Currently, the only way you can do that is by squaring it in the mission model and emitting a second resource just for your constraint. The constraint would look like this:
If we implemented procedural constraints in typescript, they would have two options for how to do this:
I exported the
square
function. That’s because all these constraints would be loaded and executed in the same workspace; if we add the ability to set file names, we could let other constraints import this function and use it. (This is already the case, but if they start implementing truly novel operators the demand for the feature will increase.) Theoretically they could even workaround the current lack of code-sharing by extending theReal
class prototype, but uhh….let’s not encourage that.Again, for constraints that work good enough in the current system and don’t have a use for procedural constraints, the only necessary changes are that the
import
statement and theasync
keyword, which are both brainless changes. The bounds argument in the function signature is optional; they don’t have to add it if they don’t need it.Spans-based scheduling is just procedural scheduling with a fake mustache
In my old proposal I came up with a callback-chaining design I called "spans-based scheduling". I've realized that it is actually equivalent to procedural scheduling, so I'm going to stop using that old name. It was intended to allow this pattern:
That looks a lot like procedural scheduling. It didn’t look very procedural at first, because the original proposal used a very declarative-looking syntax and relied on declarative constraints. But if we modernize that algorithm a little bit to have the goal operate on missing activity instance conflicts instead of spans, then I’d argue it actually is procedural scheduling. And if we modernize the interface to be defined by a generator, I think it’s undeniable. Here’s an example with a hypothetical syntax:
This solution would be tricky, but small:
ProceduralGoal
type in the scheduler backend would need to be able to cede control back and forth with node, provide multiple sets of conflicts to the solver, and request resimulations. From the user perspective, theyield new Schedule(...)
would look like an RPC.As an aside, I think it would be good to create a fourth goal type,
SimpleGoal
orBasicGoal
or something like that, which is just a container for conflicts to be passed to the scheduler. The user would create the conflicts themselves, and the scheduler would solve them. Even if we never implement the full procedural scheduling design above, this could be a big improvement in expressiveness when combined with procedural constraints.With
SimpleGoal
in mind, the exact role of the procedural goal driver becomes more clear: the yielding of concrete conflicts is just syntactic sugar for aggregation into aSimpleGoal
, and the driver only serves as an iteration tool that delegates to other goals. So lets define the driver's purpose as such:Application to current scheduler problems
Activity Groups:
Procedural goals don’t need to produce activities of all the same type, and by allowing the goal to resume after the schedule request and produce more activities, it can produce a structure of related activities.
Anchoring:
Anchoring is not fully addressed by this proposal, but it gets us halfway there: with access to the concrete activity instances in the plan, all we need to do is extend the conflicts to allow anchoring.
Advanced Linkage:
This is where goal delegation comes in. If the above example code essentially delegates to a
SimpleGoal
, why not delegate to a more complex goal? To take the linkage example from Juan's presentation, the procedure could look like this:Proposed implementation plan
SimpleGoal
.Pros of this approach
Cons of this approach
Beta Was this translation helpful? Give feedback.
All reactions