@@ -17,10 +17,12 @@ def _xy_dataset(dataset, *, x_path=0, y_path=1):
1717
1818
1919def as_supervised (dataset , inputs , targets = None , * , input_as_target : bool = False ):
20- """Return a persisted Dataset graph yielding canonical ``(inputs, targets)`` pairs.
20+ """Return a Dataset graph yielding canonical ``(inputs, targets)`` pairs.
2121
2222 Args:
23- dataset: Source Dataset with a declared element specification.
23+ dataset: Source Dataset with a declared element specification, or a soft
24+ Definition, ConcreteDefinition, ObjectRef, StateRef, or explicit
25+ ``Ref(...)``/``Mat(...)`` assertion expected to identify one.
2426 inputs: One scalar path, :class:`Select`, or nonempty tree of explicit
2527 ``Select`` leaves describing model inputs.
2628 targets: Matching target selection. It is required unless
@@ -29,56 +31,83 @@ def as_supervised(dataset, inputs, targets=None, *, input_as_target: bool = Fals
2931 autoencoder-style Dataset without copying or backend conversion.
3032
3133 Returns:
32- An ordinary :class:`~dryml.data.dataset.Map` Dataset whose values are
33- ``(inputs, targets)`` and whose Method tree is persisted with the graph.
34+ An ordinary :class:`~dryml.data.dataset.Map` Dataset for a live source,
35+ or an inert Map Definition for a symbolic source. Its values are
36+ ``(inputs, targets)`` and its Method tree is persisted with the graph.
3437
3538 Raises:
36- TypeError: If ``dataset`` is not a Dataset or a selection tree is malformed.
39+ TypeError: If ``dataset`` is not a Dataset or supported Dataset authority,
40+ or a selection tree is malformed. A symbolic source that does not
41+ materialize a Dataset fails at its normal Definition
42+ binding/materialization boundary.
3743 ValueError: If a selection tree is empty or targets conflict with
3844 ``input_as_target``.
3945
4046 Side Effects:
41- None. This helper does not open the Dataset, copy values, select a backend ,
42- or add batching.
47+ None. This helper does not open or materialize the Dataset, copy values,
48+ select a backend, or add batching.
4349 """
4450
51+ from dryml .core import ConcreteDefinition , DefLink , Definition , ObjectRef , StateRef
4552 from dryml .data .dataset import Dataset , Map
4653
47- if not isinstance (dataset , Dataset ):
48- raise TypeError ("as_supervised requires a Dataset." )
54+ symbolic_types = (Definition , ConcreteDefinition , ObjectRef , StateRef )
55+ symbolic = isinstance (dataset , (* symbolic_types , DefLink ))
56+ if not isinstance (dataset , Dataset ) and not symbolic :
57+ raise TypeError ("as_supervised requires a Dataset or Dataset reference." )
58+ if isinstance (dataset , DefLink ):
59+ dataset = dataset .target
60+ if not isinstance (dataset , (Dataset , * symbolic_types )):
61+ raise TypeError ("as_supervised received an unsupported Ref/Mat target." )
4962 if type (input_as_target ) is not bool :
5063 raise TypeError ("input_as_target must be an exact bool." )
51- input_method = _selection_method (inputs )
64+ input_method = _selection_method (inputs , symbolic = symbolic )
5265 if input_as_target :
5366 if targets is not None :
5467 raise ValueError ("input_as_target does not accept an explicit target selection." )
5568 target_method = input_method
5669 else :
5770 if targets is None :
5871 raise ValueError ("as_supervised requires targets unless input_as_target is true." )
59- target_method = _selection_method (targets )
60- return Map (dataset , Project (input_method , target_method ), preserves_examples = True )
61-
62-
63- def _selection_method (selection , * , tree_leaf : bool = False ):
72+ target_method = _selection_method (targets , symbolic = symbolic )
73+ project = (
74+ Project .defn (input_method , target_method )
75+ if symbolic else Project (input_method , target_method )
76+ )
77+ if symbolic :
78+ return Map .defn (dataset , project , preserves_examples = True )
79+ return Map (dataset , project , preserves_examples = True )
80+
81+
82+ def _selection_method (
83+ selection , * , tree_leaf : bool = False , symbolic : bool = False ,
84+ ):
6485 """Build one Project-compatible Method tree while rejecting tuple/list ambiguity."""
6586
6687 if isinstance (selection , Select ):
67- return selection
88+ return Select . defn ( selection . idxs ) if symbolic else selection
6889 if isinstance (selection , (str , int )):
6990 if tree_leaf :
7091 raise TypeError ("Selection trees require Select.from_path leaves." )
71- return Select .from_path ((selection ,))
92+ return Select .defn ( selection ) if symbolic else Select . from_path ((selection ,))
7293 if isinstance (selection , dict ):
7394 if not selection :
7495 raise ValueError ("Selection trees must not be empty." )
75- return Project ({key : _selection_method (branch , tree_leaf = True ) for key , branch in selection .items ()})
96+ branches = {
97+ key : _selection_method (branch , tree_leaf = True , symbolic = symbolic )
98+ for key , branch in selection .items ()
99+ }
100+ return Project .defn (branches ) if symbolic else Project (branches )
76101 if isinstance (selection , (tuple , list )):
77102 if not selection :
78103 raise ValueError ("Selection trees must not be empty." )
79104 if any (not isinstance (branch , Select ) for branch in selection ):
80105 raise TypeError ("Ambiguous tuple/list selections require Select.from_path leaves." )
81- return Project (type (selection )(_selection_method (branch , tree_leaf = True ) for branch in selection ))
106+ branches = type (selection )(
107+ _selection_method (branch , tree_leaf = True , symbolic = symbolic )
108+ for branch in selection
109+ )
110+ return Project .defn (branches ) if symbolic else Project (branches )
82111 raise TypeError ("Selections must be a scalar path, Select, or tree of Select leaves." )
83112
84113
0 commit comments