| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Circuit.Poly.Span
Description
The span fragment of polynomial functors.
The standard Poly encoding uses type families Pos and Dir.
Sum has no Dir row because directions over a sum are position-dependent,
and GHC cannot match on the result of a type family inside a GADT or type
family equation.
This module experiments with the alternative: represent a polynomial as a
span Dir -> Pos. The position-dependency is carried by an explicit
projection function rather than by a dependent type family. Sum becomes
the coproduct of spans, so it does admit a netlist view in this encoding.
The cost is that correctness of the netlist view for Prod becomes a fibre
condition: a direction function supplied to fromNetC must return Nothing
outside the fibre of the chosen position. In the double-category picture
those fibre conditions are the lower-dimensional cells (companions,
conjoints, and the Beck–Chevalley cube).
The span fragment is the six constructors CY, CConst, CExp, CSum,
CProd and CTensor. CComp is included in the grammar but not in the
span fragment: it has a NetlistC view, but no SpanC projection. See
'loom/cube.md' for the research direction that CComp belongs to.
The ETC constructor is the netlist view inlined into the value; it is not
structural like ESC or EPC. This makes tensor round-trips exact in the
spike, but it is an asymmetry of the encoding, not a mathematical fact about
tensors.
Synopsis
- data Span
- type family PosC (c :: Span) where ...
- type family DirC (c :: Span) where ...
- data EvalC (c :: Span) x where
- EYC :: forall x. x -> EvalC 'CY x
- EKC :: forall c1 x. c1 -> EvalC ('CConst c1) x
- EEC :: forall a x. (a -> x) -> EvalC ('CExp a) x
- ESC :: forall (p :: Span) x (q :: Span). Either (EvalC p x) (EvalC q x) -> EvalC ('CSum p q) x
- EPC :: forall (p :: Span) x (q :: Span). (EvalC p x, EvalC q x) -> EvalC ('CProd p q) x
- ETC :: forall (p :: Span) (q :: Span) x. PosC p -> PosC q -> (DirC p -> DirC q -> x) -> EvalC ('CTensor p q) x
- ECC :: forall (p :: Span) (q :: Span) x. (PosC p, DirC p -> PosC q) -> ((DirC p, DirC q) -> x) -> EvalC ('CComp p q) x
- class SpanC (c :: Span) where
- onFibreC :: forall (c :: Span). (Eq (PosC c), SpanC c) => PosC c -> DirC c -> Bool
- class NetlistC (c :: Span) where
- netRoundTripC :: forall (c :: Span) x. NetlistC c => EvalC c x -> EvalC c x
- prodSumDistrLC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CProd ('CSum p q) r) x -> EvalC ('CSum ('CProd p r) ('CProd q r)) x
- prodSumDistrRC :: forall (p :: Span) (r :: Span) (q :: Span) x. EvalC ('CSum ('CProd p r) ('CProd q r)) x -> EvalC ('CProd ('CSum p q) r) x
- distrPosLC :: forall (p :: Span) (q :: Span) (r :: Span). PosC ('CProd ('CSum p q) r) -> PosC ('CSum ('CProd p r) ('CProd q r))
- distrDirLC :: forall (p :: Span) (q :: Span) (r :: Span). DirC ('CProd ('CSum p q) r) -> DirC ('CSum ('CProd p r) ('CProd q r))
- nestedToCompC :: forall (p :: Span) (q :: Span) x. (NetlistC p, NetlistC q) => EvalC p (EvalC q x) -> EvalC ('CComp p q) x
- compToNestedC :: forall (p :: Span) (q :: Span) x. (NetlistC p, NetlistC q) => EvalC ('CComp p q) x -> EvalC p (EvalC q x)
- compAssocLC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CComp ('CComp p q) r) x -> EvalC ('CComp p ('CComp q r)) x
- compAssocRC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CComp p ('CComp q r)) x -> EvalC ('CComp ('CComp p q) r) x
Span descriptions
Promoted description of a polynomial as a span Dir -> Pos.
Unlike Poly, this grammar does not need a position-indexed
Dir family; the projection is supplied by the SpanC class at the term
level.
CComp is in the grammar but outside the span fragment: it has a netlist
view, but no span projection. See SpanC and the module header.
type family DirC (c :: Span) where ... Source #
Total direction space of a span polynomial.
For CProd, the total direction space includes the other position so that
the projection to the product of positions is a pure function. In the
double-category picture this is the universal property of the product of
spans.
Values
data EvalC (c :: Span) x where Source #
Values of a span polynomial functor evaluated at x.
ETC stores the tensor netlist directly: a pair of positions and a curried
direction function. This is not structural like ESC or EPC, and it makes
the tensor round-trip exact in the spike. See the module header.
Constructors
| EYC :: forall x. x -> EvalC 'CY x | |
| EKC :: forall c1 x. c1 -> EvalC ('CConst c1) x | |
| EEC :: forall a x. (a -> x) -> EvalC ('CExp a) x | |
| ESC :: forall (p :: Span) x (q :: Span). Either (EvalC p x) (EvalC q x) -> EvalC ('CSum p q) x | |
| EPC :: forall (p :: Span) x (q :: Span). (EvalC p x, EvalC q x) -> EvalC ('CProd p q) x | |
| ETC :: forall (p :: Span) (q :: Span) x. PosC p -> PosC q -> (DirC p -> DirC q -> x) -> EvalC ('CTensor p q) x | |
| ECC :: forall (p :: Span) (q :: Span) x. (PosC p, DirC p -> PosC q) -> ((DirC p, DirC q) -> x) -> EvalC ('CComp p q) x |
Span projection (six span constructors)
class SpanC (c :: Span) where Source #
Span polynomials: those constructors that admit a projection Dir -> Pos.
CComp is deliberately not an instance. A single direction (dp, dq)
does not determine the hang map , so there is no
function DirC p -> PosC q to write. This is
a mathematical impossibility, not a Haskell limitation; it is documented at
the type level by the missing instance.DirC (CComp p q) -> PosC (CComp p q)
onFibreC :: forall (c :: Span). (Eq (PosC c), SpanC c) => PosC c -> DirC c -> Bool Source #
Test whether a direction lies in the fibre of a given position.
This is the lowest-dimensional fibre law, equivalent to the Beck–Chevalley condition for the identity cell.
Netlist view (all seven constructors)
class NetlistC (c :: Span) where Source #
Polynomials that admit a netlist view in the span encoding.
The netlist view is EvalC p x ≅ (PosC p, DirC p -> Maybe x), where
Nothing means "outside the fibre of the chosen position".
fromNetC assumes the supplied function respects the fibre. If it returns
Nothing on a direction that is inside the fibre, fromNetC raises an
internal error: that is the encoding's assertion of the Beck–Chevalley
condition, not user-facing junk.
Every constructor is an instance, including CComp, because a value of any
constructor can be stored together with its position and direction function.
CComp is not a SpanC, so its netlist view is not a span netlist view.
Methods
toNetC :: EvalC c x -> (PosC c, DirC c -> Maybe x) Source #
fromNetC :: PosC c -> (DirC c -> Maybe x) -> EvalC c x Source #
Sum / product distributivity
prodSumDistrLC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CProd ('CSum p q) r) x -> EvalC ('CSum ('CProd p r) ('CProd q r)) x Source #
prodSumDistrRC :: forall (p :: Span) (r :: Span) (q :: Span) x. EvalC ('CSum ('CProd p r) ('CProd q r)) x -> EvalC ('CProd ('CSum p q) r) x Source #
distrPosLC :: forall (p :: Span) (q :: Span) (r :: Span). PosC ('CProd ('CSum p q) r) -> PosC ('CSum ('CProd p r) ('CProd q r)) Source #
distrDirLC :: forall (p :: Span) (q :: Span) (r :: Span). DirC ('CProd ('CSum p q) r) -> DirC ('CSum ('CProd p r) ('CProd q r)) Source #
Composition product (outside the span fragment)
nestedToCompC :: forall (p :: Span) (q :: Span) x. (NetlistC p, NetlistC q) => EvalC p (EvalC q x) -> EvalC ('CComp p q) x Source #
Composition-product view of a nested span evaluation.
Correctness iso (right):
.EvalC p (EvalC q x) ≅ EvalC (CComp p q) x
This is the span analogue of nestedToComp, but it works
through the Maybe netlist view. Off-fibre directions in the outer
polynomial have no canonical q-position, so the hang map is only
defined on the fibre; this is the same cube boundary as the missing SpanC
instance for CComp.
compToNestedC :: forall (p :: Span) (q :: Span) x. (NetlistC p, NetlistC q) => EvalC ('CComp p q) x -> EvalC p (EvalC q x) Source #
Nested span evaluation from a composition-product value.
Correctness iso (left): inverse of nestedToCompC.