What you could do is use Tup's LUA support (you can write tupfiles and tuprules in LUA, and you can define and use LUA functions in them): have each rule handle just one step of your process, generate the whole necessary DAG of rules, encapsulate all of that in a LUA function defined in tuprules.lua and call that function in tupfile.lua for every diagram you want to generate. One thing that you lose is the ability to use `foreach` with your construction (other than by creating a variant of your constructions that embeds foreachness, or by using tup.glob and iterating).