Scope inspection¶
scope
¶
Scope-path resolution for compiled QVR modules.
Every meta-command in the REPL that takes a binding name (:info,
:type, :doc, :browse, :where, ...) routes through
the resolver in this module. The grammar of a scope path is::
path ::= name ('::' name)*
name ::= a valid Python-style identifier
The leftmost segment is looked up against the module's top-level
declarations (objects / spaces / morphisms / rules / programs /
deductions / signatures / encoders / decoders / losses / bundles /
contractions / categories / compositions). Each subsequent segment
is looked up against the previous binding's scope view, a
Mapping[str, ScopedRef] derived from its AST shape:
- A
program lda(α, β) : ...exposes its typed parameters and every step (sample/observe/let/marginalize/score/return) by the names they bind. - A
marginalize z : T <- F [over=G]exposes its inner body steps the same way, solda::z::wworks the same aslda::wwould at top level. - A
deduction CCGexposesrulesandatomsas sub-bindings; each rule underrulesexposespremisesandconclusionfor further drill-down. - A
signature LFexposessorts/constructors/binders/vertex_kinds/edge_kindsas sub-maps. encoder/decoder/bundle/ inline-bodiedcompositiondeclarations expose the named entries from their bodies (op_rules, member rule names,tensor_op/join/unit/zero).
Container kinds that do not introduce names (rule premise
patterns, let value expressions, leaf morphisms) return an
empty scope; the resolver stops walking at them.
The resolver is purely structural. It does not recompile the
program; it reads the already-elaborated AST nodes from the
Compiler instance the REPL hands it. Consumers that need
runtime values (a sample site's actual tensor, a deduction rule's
weight) should look those up via the runtime accessors after
locating the binding.
ScopeKind
module-attribute
¶
ScopeKind = Literal['object', 'space', 'morphism', 'rule', 'program', 'deduction', 'signature', 'encoder', 'decoder', 'loss', 'bundle', 'contraction', 'composition', 'category', 'param', 'sample-site', 'observe-site', 'let-site', 'marginalize-site', 'score-site', 'return-site', 'atom', 'deduction-rule', 'lexicon-entry', 'sort', 'constructor', 'binder', 'vertex-kind', 'edge-kind', 'op-rule', 'init-rule', 'message-rule', 'update-rule', 'var-init', 'decoder-head', 'composition-entry', 'bundle-member']
The kind tag carried by every ScopedRef, used for pretty-printing,
click-target classification, and the :browse section grouping.
TOP_LEVEL_KINDS
module-attribute
¶
TOP_LEVEL_KINDS: tuple[ScopeKind, ...] = ('object', 'space', 'morphism', 'rule', 'program', 'deduction', 'signature', 'encoder', 'decoder', 'loss', 'bundle', 'contraction', 'composition', 'category')
The top-level container kinds, those reachable directly from the
compiler's public accessors, in the order ReplSession.browse()
walks them for output.
SCOPE_SEPARATOR
module-attribute
¶
The separator between the segments of a scoped path such as
"prog::x".
ScopedRef
didactic-model
¶
ScopedRef(*, name: str, kind: ScopeKind, path: str, parent_kind: ScopeKind | None = None, node: object = field(opaque=True))
Bases: Model
One resolved binding.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Last path segment.
TYPE:
|
kind |
Categorical tag indicating which declaration / step kind this ref points at.
TYPE:
|
path |
The full
TYPE:
|
parent_kind |
TYPE:
|
scope_children
¶
Return the named children of ref's scope, or an empty
mapping if ref.kind introduces no further bindings.
Idempotent + pure; callers can cache. Reads only the AST
fields exposed on each declaration shape, so adding a new
declaration kind requires registering one entry in
_SCOPE_DISPATCH.
| PARAMETER | DESCRIPTION |
|---|---|
ref
|
The binding whose scope is listed.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Mapping[str, ScopedRef]
|
The child bindings, keyed by name. |
Source code in src/quivers/analysis/scope.py
split_path
¶
Split "a::b::c" into ["a", "b", "c"]. Leading or
trailing separators yield empty segments, which the resolver
rejects.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
A
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
The path's segments, in order. |
Source code in src/quivers/analysis/scope.py
resolve_scoped_path
¶
resolve_scoped_path(compiler, path: str) -> ScopedRef | None
Resolve a ::-separated path against compiler's
elaborated module. Returns None if any segment fails to
resolve.
| PARAMETER | DESCRIPTION |
|---|---|
compiler
|
A
|
path
|
A non-empty
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ScopedRef | None
|
The terminal binding, or |
Source code in src/quivers/analysis/scope.py
find_all_references
¶
find_all_references(compiler, name: str) -> list[ScopedRef]
Find every binding in compiler's module whose final
path segment equals name.
Returns refs sorted by depth (top-level first) then by path
lexicographic order. Used by :where NAME to surface every
scope a bare name appears in.
| PARAMETER | DESCRIPTION |
|---|---|
compiler
|
A
TYPE:
|
name
|
The bare name to search for.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ScopedRef]
|
Every binding whose final path segment is |