charles-river-analytics / figaro

Figaro Programming Language and Core Libraries

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Top-down refinement is broken

wkretschmer opened this issue · comments

Recall that top-down refinement works as follows: start with a list of Atomic components, refine the ranges of these components by any desired ranging method, then update any dependent components so that all ranges are consistent.

Today I discovered 2 bugs in the implementation. The first is an extension of #647, which deals with avoiding subproblem reuse for recursive models. Our solution to mark subproblems as "open" during expansion does not apply here. Because elements are discovered in a top-down manner, it's possible to get to a Chain in a recursive subproblem without first expanding into that subproblem from the top-level. In this case, the subproblem will not be marked as "open". When the top-down strategy calls expand(), there will be a subproblem inside of itself. A solution might be to avoid calling expand() altogether, though I think factor creation assumes that subproblems are created for every parent value (even if they are just empty).

The second issue also has to do with Chains, but occurs even in non-recursive models. After finding the list of dependent components that need updates, the strategy visits components in any order. When visiting a component, it first checks to see if any of the args need updates. This fails when a Chain depends on an Atomic through a subproblem, in part because top-down strategies do not recurse on subproblems, and in part because args are treated differently than subproblems. One solution would be to topologically sort the components to visit them in the correct order.

Because both of these issues are related to recursion in top-down strategies, an appropriate solution probably also involves removing the shared inheritance with bottom-up strategies.

I've fixed the second issue and documented the first issue. These changes will be included in my next pull request.

I think the refining strategy code could use some additional improvements, though. Currently, refining consists of either ranging an atomic component, or expanding a Chain subproblem. The intention was to have top-down strategies for ranging, and bottom-up strategies for expanding. However, bottom-up strategies currently also do ranging: they simply visit components that aren't fully refined, which could be an atomic component. Perhaps we should have a pure expanding strategy that only expands subproblems. If we add such a strategy, we may need to reevaluate the polymorphism among the various refining strategy interfaces.