cottax.core.driven¶
How a problem is answered, before anything runs it: drivers, driven nodes, their ops.
Dependency:
- driver (the contract: DriverContract, Role / PerUnknown / PerProblem, arity;
entry_for, a table’s entry for a contract’s most specific class)
||——— / /
- nodes roles (nodes: DrivenNode, the level; Driven, its final; condition_of;
|| role_slots, where each problem takes or reports a role, by unknown; || roles: Start / Steps, the places the shipped contracts take) ||——— / /
- ops proof (ops: Assign / Undrive; AssignByRule, an Assign at the places
a rule gives; proof: DrivenGraph, every problem driven – what an export reads)
- class DriverContract[V: Place][source]¶
Bases:
Frozen,Generic[V]Algorithm answering a ConditionalNode’s problem.
takes (input roles) is not exhaustive: certain choices can not be made from the graph such as a Linear Solver type for a Newton driver.
- accepts: AbstractVar[Callable[[ConditionalNode[V]], bool]]¶
Whether it accepts that ConditionalNode
- takes: AbstractVar[tuple[type[Role], ...]]¶
Input roles
- reports: AbstractVar[tuple[type[Role], ...]]¶
Output roles.
- class PerProblem[source]¶
Bases:
RoleRole about solve (e.g. global tolerance)
- classmethod arity(node: ConditionalNode)[source]¶
How many places the role takes on node.
- Return type:
int
- class PerUnknown[source]¶
Bases:
RoleRole per unknown (e.g. initial guesses)
- classmethod arity(node: ConditionalNode)[source]¶
How many places the role takes on node.
- Return type:
int
- class Role[source]¶
Bases:
ABCWhat a place is to a driver: a class, never a value. Free to extend.
- abstractmethod classmethod arity(node: ConditionalNode)[source]¶
How many places the role takes on node.
- Return type:
int
- entry_for[T, D](table: Mapping[type[DriverContract], T], contract: DriverContract, default: D = None)[source]¶
The entry of table for contract’s most specific class along its ancestry, whatever order the table is written in; default if none covers it.
- Return type:
Union[T,D]
- class DrivenNode[V: Place][source]¶
Bases:
ConditionalNode[V],Generic[V]A conditional node with a driver answering it. Abstract like FunctionalNode & ConditionalNode; so an implementation or no implementation is possible.
- condition: AbstractVar[ConditionalNode[V]]¶
The node answered, without the driver.
- contract: AbstractVar[DriverContract[V]]¶
abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.
- Type:
What the level binds in place of the annotation
- data: AbstractVar[tuple[tuple[V, ...], ...]]¶
One slot per role in driver.takes, each as many places as its role’s arity.
- reports: AbstractVar[tuple[tuple[V, ...], ...]]¶
One slot per role in driver.reports, the same way.
- abstractmethod undriven()[source]¶
The condition node with the driver taken off: what Undrive edits. A final that cannot have it taken off refuses here.
- Return type:
- class Driven[V: Place](condition: ConditionalNode[V], contract: DriverContract[V], data: tuple[tuple[V, ...], ...], reports: tuple[tuple[V, ...], ...])[source]¶
Bases:
DrivenNode[V],Generic[V]Final of DrivenNode that has no implementation.
- condition: ConditionalNode[V]¶
The node answered, without the driver.
- contract: DriverContract[V]¶
- data: tuple[tuple[V, ...], ...]¶
One slot per role in driver.takes, each as many places as its role’s arity.
- reports: tuple[tuple[V, ...], ...]¶
One slot per role in driver.reports, the same way.
- checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_pairing>, <function check_slots>)¶
Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).
- property unknowns: tuple[V, ...]¶
abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.
- Type:
What the level binds in place of the annotation
- property conditions: tuple[V, ...]¶
abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.
- Type:
What the level binds in place of the annotation
- property reads: tuple[V, ...]¶
abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.
- Type:
What the level binds in place of the annotation
- property owns: tuple[V, ...]¶
abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.
- Type:
What the level binds in place of the annotation
- determined(unknowns: tuple[V, ...])[source]¶
Refused: an algorithm was chosen for the node as it stands, and its per-unknown slots are laid out against the unknowns it had.
- Return type:
Driven[V]
- is_driven(d: object)[source]¶
A node carrying a driver, bare or under what runs it.
- Return type:
bool
- role_slots[N: Label, V: Place](graph: NestingGraph[N, V], role: type[Role])[source]¶
Each place a driven problem takes or reports role at, in binding order: the place, its problem, and for a per-unknown role the unknown it pairs with (None for a per-problem one). A place two problems take is there twice.
- Return type:
tuple[tuple[V,N,Optional[V]],...]
- class Assign[N: Label, V: Place](problem: N, contract: DriverContract[V], data: tuple[tuple[V, ...], ...], reports: tuple[tuple[V, ...], ...])[source]¶
Bases:
Redefine[N,V],Generic[N,V]Attach a driver to a condition node, and say where each of its roles sits: the algorithm choice and its places, recorded in the plan and carried by the node. Where a place sits is a decision, so the op records it: a surface supplies the obvious ones.
- problem: N¶
- contract: DriverContract[V]¶
- data: tuple[tuple[V, ...], ...]¶
- reports: tuple[tuple[V, ...], ...]¶
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_drivable>,)¶
(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 AssignByRule[N: Label, V: Place](problem: N, contract: DriverContract[V], places: Callable[..., tuple[tuple[tuple[V, ...], ...], tuple[tuple[V, ...], ...]]])[source]¶
Bases:
ComposedOp[N,V],Generic[N,V]Assign at the places places(problem, unknowns, contract) gives, the problem’s unknowns read when it is applied: the rule is recorded, so a changed model has its places derived again.
- problem: N¶
- contract: DriverContract[V]¶
- places: Callable[..., tuple[tuple[tuple[V, ...], ...], tuple[tuple[V, ...], ...]]]¶
- class Undrive[N: Label, V: Place](problem: N)[source]¶
Bases:
Redefine[N,V],Generic[N,V]The inverse of Assign: the condition node alone again, and the driver’s places gone with it – undriven, asked of the node, so a wrapper refuses for itself.
- problem: N¶
- checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_undrives_a_driven_node>,)¶
(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 DrivenGraph[N: Label, V: Place](graph: NestingGraph[N, V])[source]¶
Bases:
SteppedExecutableGraph[N,V],Generic[N,V]Executable graph with additionally all problems driven.
- checks_node: PerLevel[tuple[Callable[[N, NodeDefinition[V]], Iterator[Violation]], ...]] = (<function check_driven>,)¶
the one thing a level below adds.
- Type:
(name, node) -> violations
- class Start[source]¶
Bases:
PerUnknownWhere each unknown starts.
- class Steps[source]¶
Bases:
PerProblemReported: how many iterations the solve took.