cottax.consumers.visualization.sequencing module

How a graph is read for a drawing: each component as what it is (entries), the blocks a drawing rings (walk), and an order for its diagonal (sequence, problems_first). A graph that cannot be scheduled still has entries, so it is still drawn.

graph_drawn(handed: NestingGraph | ExecutableGraph | Plan)[source]

The graph a drawing draws of what it is handed: a Plan’s graph, a proof’s graph, or the graph itself.

Return type:

NestingGraph

class Entry(subgraph: NestingGraph)[source]

Bases: Frozen

One component of a graph, its kind the final (Run, Cycle, Solve, Unresolved). Built by entries.

subgraph: NestingGraph
property nodes: tuple[Label, ...]

The component, in the graph’s binding order.

class Run(subgraph: NestingGraph)[source]

Bases: Entry

One node, no problem: it runs.

class Cycle(subgraph: NestingGraph)[source]

Bases: Entry

A cycle with no problem on it: nothing iterates it.

class Solve(subgraph: NestingGraph, problem: Label, interior: NestingGraph)[source]

Bases: Entry

One outermost problem, answered at this component’s level, and its interior (the component without it, NestingGraph.interior), whose own entries are the next depth.

problem: Label
interior: NestingGraph
class Unresolved(subgraph: NestingGraph, problems: tuple[Label, ...])[source]

Bases: Entry

Several outermost problems with nothing nested: none is answered at this level.

problems: tuple[Label, ...]
entries(g: NestingGraph)[source]

Each component of g as an Entry, in dependency order, the members of each in binding order.

Return type:

tuple[Entry, ...]

class Block(entry: Entry, within: tuple[Label, ...], held: NestingGraph | None)[source]

Bases: Frozen

One entry as a drawing rings it: the entry, the problems it sits inside (within, outermost first; its length the depth), and held, the interior rung inside it: a Solve’s interior when that holds a problem, else None.

entry: Entry
within: tuple[Label, ...]
held: NestingGraph | None
property depth: int
property nodes: tuple[Label, ...]
property problem: Label | None

The problem answered at this block’s level, or None.

property solved: bool

a solve ring, else a run.

Type:

Whether it contains a cycle

walk(graph: NestingGraph)[source]

Every block a drawing rings, at every depth: the graph’s entries, each followed by its held interior’s, so an inner ring comes after (paints over) the ring around it. problems_first relies on this order.

Return type:

tuple[Block, ...]

draws_feedback(order: Sequence[Label], subgraph: NestingGraph)[source]

Whether some node in order reads a variable a later one owns: an edge drawn above the diagonal.

Return type:

bool

sequence(graph: NestingGraph)[source]

The graph’s nodes in an order for one diagonal: entry by entry in dependency order; a Solve its problem then its interior sequenced the same way; any other entry its problems in binding order, then its body as bound unless that draws feedback, else in components_order (defined on a cycle too). So the only edges left above the diagonal run through a problem, or are a cycle no problem closes.

Return type:

tuple[Label, ...]

ordered_graph(handed: NestingGraph | ExecutableGraph | Plan)[source]

The graph rebound in sequence order, no node merged and no edge changed: what a drawing puts on its diagonal.

Return type:

NestingGraph

problems_first(names: Sequence[Label], tree: Iterable[tuple[Sequence[Label], Label | None]], is_problem: Callable[[Label], bool])[source]

names permuted so each block’s problem leads it: the problem tree pairs with the block (walk’s blocks, outermost first, each with its Block.problem); where that is None, every problem in the block ahead of every other member. A block’s members are dealt back into the positions it already holds, so every block stays contiguous and no other step moves. is_problem says which names are problems. A caller with no rings pairs each component with None.

Return type:

list[Label]