circuits-diagrams
Safe HaskellNone
LanguageGHC2024

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

Span descriptions

data Span Source #

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 PosC (c :: Span) where ... Source #

Position set of a span polynomial.

Equations

PosC 'CY = () 
PosC ('CConst a) = a 
PosC ('CExp a) = () 
PosC ('CSum p q) = Either (PosC p) (PosC q) 
PosC ('CProd p q) = (PosC p, PosC q) 
PosC ('CTensor p q) = (PosC p, PosC q) 
PosC ('CComp p q) = (PosC p, DirC p -> PosC q) 

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.

Equations

DirC 'CY = () 
DirC ('CConst a) = Void 
DirC ('CExp a) = a 
DirC ('CSum p q) = Either (DirC p) (DirC q) 
DirC ('CProd p q) = Either (DirC p, PosC q) (PosC p, DirC q) 
DirC ('CTensor p q) = (DirC p, DirC q) 
DirC ('CComp p q) = (DirC p, DirC q) 

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 

Instances

Instances details
Functor (EvalC c) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

fmap :: (a -> b) -> EvalC c a -> EvalC c b #

(<$) :: a -> EvalC c b -> EvalC c a #

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 DirC p -> PosC q, so there is no function DirC (CComp p q) -> PosC (CComp p q) to write. This is a mathematical impossibility, not a Haskell limitation; it is documented at the type level by the missing instance.

Methods

projC :: DirC c -> PosC c Source #

Instances

Instances details
SpanC 'CY Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC 'CY -> PosC 'CY Source #

SpanC ('CConst a) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC ('CConst a) -> PosC ('CConst a) Source #

SpanC ('CExp a) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC ('CExp a) -> PosC ('CExp a) Source #

(SpanC p, SpanC q) => SpanC ('CProd p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC ('CProd p q) -> PosC ('CProd p q) Source #

(SpanC p, SpanC q) => SpanC ('CSum p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC ('CSum p q) -> PosC ('CSum p q) Source #

(SpanC p, SpanC q) => SpanC ('CTensor p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

projC :: DirC ('CTensor p q) -> PosC ('CTensor p q) Source #

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 #

Instances

Instances details
NetlistC 'CY Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC 'CY x -> (PosC 'CY, DirC 'CY -> Maybe x) Source #

fromNetC :: PosC 'CY -> (DirC 'CY -> Maybe x) -> EvalC 'CY x Source #

NetlistC ('CConst a) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CConst a) x -> (PosC ('CConst a), DirC ('CConst a) -> Maybe x) Source #

fromNetC :: PosC ('CConst a) -> (DirC ('CConst a) -> Maybe x) -> EvalC ('CConst a) x Source #

NetlistC ('CExp a) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CExp a) x -> (PosC ('CExp a), DirC ('CExp a) -> Maybe x) Source #

fromNetC :: PosC ('CExp a) -> (DirC ('CExp a) -> Maybe x) -> EvalC ('CExp a) x Source #

NetlistC ('CComp p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CComp p q) x -> (PosC ('CComp p q), DirC ('CComp p q) -> Maybe x) Source #

fromNetC :: PosC ('CComp p q) -> (DirC ('CComp p q) -> Maybe x) -> EvalC ('CComp p q) x Source #

(NetlistC p, NetlistC q, Eq (PosC p), Eq (PosC q)) => NetlistC ('CProd p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CProd p q) x -> (PosC ('CProd p q), DirC ('CProd p q) -> Maybe x) Source #

fromNetC :: PosC ('CProd p q) -> (DirC ('CProd p q) -> Maybe x) -> EvalC ('CProd p q) x Source #

(NetlistC p, NetlistC q) => NetlistC ('CSum p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CSum p q) x -> (PosC ('CSum p q), DirC ('CSum p q) -> Maybe x) Source #

fromNetC :: PosC ('CSum p q) -> (DirC ('CSum p q) -> Maybe x) -> EvalC ('CSum p q) x Source #

NetlistC ('CTensor p q) Source # 
Instance details

Defined in Circuit.Poly.Span

Methods

toNetC :: EvalC ('CTensor p q) x -> (PosC ('CTensor p q), DirC ('CTensor p q) -> Maybe x) Source #

fromNetC :: PosC ('CTensor p q) -> (DirC ('CTensor p q) -> Maybe x) -> EvalC ('CTensor p q) x Source #

netRoundTripC :: forall (c :: Span) x. NetlistC c => EvalC c x -> EvalC c x Source #

Reassemble a value after taking it apart.

This is the executable form of the round-trip law fromNetC (toNetC v) ≡ v. It is exact for every constructor. The reverse direction toNetC (fromNetC i h) ≡ (i, h) holds exactly when h respects the fibre, and fails otherwise.

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 #

Left distributivity of CProd over CSum: CProd (CSum p q) r -> CSum (CProd p r) (CProd q r).

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 #

Right distributivity of CProd over CSum: CSum (CProd p r) ('CProd q r) -> CProd (CSum p q) r.

distrPosLC :: forall (p :: Span) (q :: Span) (r :: Span). PosC ('CProd ('CSum p q) r) -> PosC ('CSum ('CProd p r) ('CProd q r)) Source #

Position isomorphism for the left distributivity of CProd over CSum.

distrDirLC :: forall (p :: Span) (q :: Span) (r :: Span). DirC ('CProd ('CSum p q) r) -> DirC ('CSum ('CProd p r) ('CProd q r)) Source #

Direction isomorphism for the left distributivity of CProd over CSum.

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.

compAssocLC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CComp ('CComp p q) r) x -> EvalC ('CComp p ('CComp q r)) x Source #

Left associator for the composition product: ((p ◁ q) ◁ r) -> (p ◁ (q ◁ r)).

compAssocRC :: forall (p :: Span) (q :: Span) (r :: Span) x. EvalC ('CComp p ('CComp q r)) x -> EvalC ('CComp ('CComp p q) r) x Source #

Right associator for the composition product.