cottax.core.maths.plan.ops module¶
Ops on Redefine: what a node reads and owns renamed (Rewire, Rename, Cut), a definition replaced (Replace), and what it determines (Determine, Undetermine).
- type Relabel[N: Label, V: Place] = Mapping[N, Renaming]¶
Per node, old place -> new. Keyed by place, so fn(x, x) renames both.
- check_renames_places_the_node_has(op: Rewire, graph: NestingGraph)[source]¶
Cannot rename a place the node does not read or own.
- Return type:
Iterator[Violation]
- class Rewire[N: Label, V: Place][source]¶
Bases:
Redefine[N,V],Generic[N,V]Rename the places a definition reads and owns only.
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_renames_places_the_node_has>,)¶
(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.
- Type:
What the op needs of the graph before it can compute anything
- abstractmethod renaming(graph: NestingGraph[N, V])[source]¶
Per node, old place -> new. One map: a node reads a place or owns it, never both, so nothing has to say which field a renaming lands in.
- Return type:
Relabel[N,V]
- redefined(graph: NestingGraph[N, V])[source]¶
The new definition for each node this touches. Names not here are untouched.
- Return type:
Mapping[N,NodeDefinition[V]]
- class Replace[N: Label, V: Place](node: N, definition: NodeDefinition[V])[source]¶
Bases:
Redefine[N,V],Generic[N,V]One binding given a definition the caller already holds.
- node: N¶
- definition: NodeDefinition[V]¶
- redefined(graph: NestingGraph[N, V])[source]¶
The new definition for each node this touches. Names not here are untouched.
- Return type:
Mapping[N,NodeDefinition[V]]
- class Rename[N: Label, V: Place](node: N, onto: tuple[tuple[V, V], ...])[source]¶
Bases:
Rewire[N,V],Generic[N,V]One node’s places renamed by a mapping the caller already holds.
- node: N¶
- onto: tuple[tuple[V, V], ...]¶
Old place -> the place to use instead. Pairs, since an op is a record and hashes.
- check_readers(op: Cut)[source]¶
A cut has readers: with none, the copy is a name nothing reads.
- Return type:
Iterator[Violation]
- check_cuts_a_produced_place(op: Cut, graph: NestingGraph)[source]¶
A boundary input renamed leaves nothing to close the cut against, and a second cut of one variable would put more readers on the first copy.
- Return type:
Iterator[Violation]
- check_readers_read_var(op: Cut, graph: NestingGraph)[source]¶
Every reader reads var. The producer owns it, so renaming there would move the output and leave var a boundary input.
- Return type:
Iterator[Violation]
- class Cut[N: Label, V: Place](var: V, readers: tuple[N, ...], copy_of: PlaceToPlace[V])[source]¶
Bases:
Rewire[N,V],Generic[N,V]Rewire the reads of readers onto a copy of var. The producer and var are untouched, so a reader outside readers still gets the computed value.
- var: V¶
- readers: tuple[N, ...]¶
- copy_of: PlaceToPlace[V]¶
Derives the copy’s place from var.
- checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_readers>,)¶
Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_cuts_a_produced_place>, <function check_readers_read_var>)¶
(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.
- Type:
What the op needs of the graph before it can compute anything
- property copy: V¶
The boundary variable readers end up reading.
- check_unknowns(op: Determine)[source]¶
Something is determined, and nothing twice.
- Return type:
Iterator[Violation]
- check_determines_nothing_yet(op: Determine, graph: NestingGraph)[source]¶
What a condition node determines is replaced, never added to.
- Return type:
Iterator[Violation]
- check_determines_something(op: Undetermine, graph: NestingGraph)[source]¶
The inverse: there is something to drop.
- Return type:
Iterator[Violation]
- class Determine[N: Label, V: Place](requirement: N, unknowns: tuple[V, ...])[source]¶
Bases:
Redefine[N,V],Generic[N,V]A requirement, with the unknowns it determines named: determined, asked of the node, so what makes an answer right stays the condition node’s own business.
- requirement: N¶
- unknowns: tuple[V, ...]¶
- checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_unknowns>,)¶
Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_determines_nothing_yet>,)¶
(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.
- Type:
What the op needs of the graph before it can compute anything
- redefined(graph: NestingGraph[N, V])[source]¶
The new definition for each node this touches. Names not here are untouched.
- Return type:
Mapping[N,NodeDefinition[V]]
- class Undetermine[N: Label, V: Place](problem: N)[source]¶
Bases:
Redefine[N,V],Generic[N,V]The inverse of Determine: the unknowns dropped, the condition node kept.
- problem: N¶
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_determines_something>,)¶
(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.
- Type:
What the op needs of the graph before it can compute anything
- redefined(graph: NestingGraph[N, V])[source]¶
The new definition for each node this touches. Names not here are untouched.
- Return type:
Mapping[N,NodeDefinition[V]]
- class NoReaders(var: Place, copy: Place)[source]¶
Bases:
Violation- template: AbstractClassVar[str] = 'cut({var}): no readers, so {copy!r} would be a name nothing reads'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class NoUnknowns[source]¶
Bases:
Violation- template: AbstractClassVar[str] = 'determine(): no unknowns -- a condition node that determines nothing is what it already is'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class UnknownTwice(unknowns: tuple[Place, ...])[source]¶
Bases:
Violation- template: AbstractClassVar[str] = 'determine(): {unknowns!r} names an unknown twice'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class AlreadyDetermined(requirement: Label, unknowns: tuple[Place, ...])[source]¶
Bases:
Violation- template: AbstractClassVar[str] = '{requirement!r} already determines {unknowns!r} -- `Undetermine` it first, so the earlier choice is dropped deliberately rather than silently replaced'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class AlreadyUndetermined(problem: Label)[source]¶
Bases:
Violation- template: AbstractClassVar[str] = '{problem!r} already determines nothing, so there is nothing to take off'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class NotRenamed(node: Label, places: tuple[Place, ...])[source]¶
Bases:
Violation- template: AbstractClassVar[str] = '{node!r} neither reads nor owns {places!r}'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class NotProduced(var: Place)[source]¶
Bases:
Violation- template: AbstractClassVar[str] = '{var!r} is not computed here, so there is nothing to cut'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class DoesNotRead(var: Place, nodes: tuple[Label, ...])[source]¶
Bases:
Violation- template: AbstractClassVar[str] = "cut({var}): {nodes} do not read {var!r}, so there is no read to move onto the copy -- a cut's readers read the variable, and its producer stays as it is"¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording
- class AlreadyCut(var: Place, copy: Place)[source]¶
Bases:
Violation- template: AbstractClassVar[str] = '{var!r} is already cut: its copy {copy} exists. A variable is cut at most once -- two cuts would assume two values for one place. Cut with more readers at once to share a copy'¶
e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’
- Type:
Wording