| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Circuit.Poly
Description
Polynomial objects are syntactic expressions, promoted to a kind:
p, q ::= Y the identity polynomial | Const A a constant set | Exp A y^A | Sum p q coproduct | Prod p q cartesian product | Tensor p q Dirichlet/parallel product | Comp p q composition (substitution)
The kind Poly is promoted, so polynomial expressions live at the type
level. Eval is a GADT that witnesses the value shape of p(x). We use
a GADT rather than a type family because Eval is not injective in x;
the GADT lets GHC keep track of the evaluation variable without ambiguity.
Morphisms are natural transformations between the induced polynomial functors, equivalently bundle maps (positions forward, directions backward).
Two extra constructors make dependent lenses expressible:
Konstintroduces a global element (a constant position).Dependis the copower universal property: aConst a-indexed family of morphismsp -> q.
With them, the general point-dependent lens (get :: a -> b, put :: a -> db -> da)
is a two-line Morphism.
The Tensor constructor adds the Dirichlet (parallel) product. It requires
Pos and Dir type families because a value of (p ⊗ q)(x) is a pair of
positions together with a single function out of the product of direction
sets — not derivable from a pair of ordinary Eval values.
Worked examples: $netlist-view, $netlist-roundtrip, $dirichlet-tensor,
Synopsis
- data Poly
- data Eval (p :: Poly) x where
- EY :: forall x. x -> Eval 'Y x
- EK :: forall c x. c -> Eval ('Const c) x
- EE :: forall a x. (a -> x) -> Eval ('Exp a) x
- ES :: forall (p1 :: Poly) x (q :: Poly). Either (Eval p1 x) (Eval q x) -> Eval ('Sum p1 q) x
- EP :: forall (p1 :: Poly) x (q :: Poly). (Eval p1 x, Eval q x) -> Eval ('Prod p1 q) x
- ET :: forall (p1 :: Poly) (q :: Poly) x. (Pos p1, Pos q) -> ((Dir p1, Dir q) -> x) -> Eval ('Tensor p1 q) x
- EC :: forall (p1 :: Poly) (q :: Poly) x. (Pos p1, Dir p1 -> Pos q) -> ((Dir p1, Dir q) -> x) -> Eval ('Comp p1 q) x
- type family Pos (p :: Poly) where ...
- type family Dir (p :: Poly) where ...
- class Netlist (p :: Poly) where
- netRoundTrip :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval p x
- tensorUnitorL :: forall (p :: Poly) x. Netlist p => Eval ('Tensor 'Y p) x -> Eval p x
- tensorUnitorL' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Tensor 'Y p) x
- tensorUnitorR :: forall (p :: Poly) x. Netlist p => Eval ('Tensor p 'Y) x -> Eval p x
- tensorUnitorR' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Tensor p 'Y) x
- morphAt :: forall (p :: Poly) (p' :: Poly). (Netlist p, Netlist p') => Morphism p p' -> Pos p -> (Pos p', Dir p' -> Dir p)
- parT :: forall (p :: Poly) (q :: Poly) (p' :: Poly) (q' :: Poly) x. (Netlist p, Netlist q, Netlist p', Netlist q') => Morphism p p' -> Morphism q q' -> Eval ('Tensor p q) x -> Eval ('Tensor p' q') x
- nestedToComp :: forall (p :: Poly) (q :: Poly) x. (Netlist p, Netlist q) => Eval p (Eval q x) -> Eval ('Comp p q) x
- compToNested :: forall (p :: Poly) (q :: Poly) x. (Netlist p, Netlist q) => Eval ('Comp p q) x -> Eval p (Eval q x)
- compUnitorL :: forall (p :: Poly) x. Netlist p => Eval ('Comp 'Y p) x -> Eval p x
- compUnitorL' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Comp 'Y p) x
- compUnitorR :: forall (p :: Poly) x. Netlist p => Eval ('Comp p 'Y) x -> Eval p x
- compUnitorR' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Comp p 'Y) x
- compAssocL :: forall (p :: Poly) (q :: Poly) (r :: Poly) x. Eval ('Comp ('Comp p q) r) x -> Eval ('Comp p ('Comp q r)) x
- compAssocR :: forall (p :: Poly) (q :: Poly) (r :: Poly) x. Eval ('Comp p ('Comp q r)) x -> Eval ('Comp ('Comp p q) r) x
- tensorEval :: forall (p :: Poly) (q :: Poly) a b. (Netlist p, Netlist q) => Eval p a -> Eval q b -> Eval ('Tensor p q) (a, b)
- data Morphism (p :: Poly) (q :: Poly) where
- Id :: forall (p :: Poly). Morphism p p
- Point :: forall (q :: Poly). Eval q () -> Morphism 'Y q
- ConstMap :: forall a b. (a -> b) -> Morphism ('Const a) ('Const b)
- ExpMap :: forall a b. (a -> b) -> Morphism ('Exp b) ('Exp a)
- Compose :: forall (q1 :: Poly) (q :: Poly) (p :: Poly). Morphism q1 q -> Morphism p q1 -> Morphism p q
- Par :: forall (p1 :: Poly) (p' :: Poly) (q1 :: Poly) (q' :: Poly). Morphism p1 p' -> Morphism q1 q' -> Morphism ('Prod p1 q1) ('Prod p' q')
- Inl :: forall (p :: Poly) (q1 :: Poly). Morphism p ('Sum p q1)
- Inr :: forall (p :: Poly) (p1 :: Poly). Morphism p ('Sum p1 p)
- Case :: forall (p1 :: Poly) (q :: Poly) (q1 :: Poly). Morphism p1 q -> Morphism q1 q -> Morphism ('Sum p1 q1) q
- Fst :: forall (q :: Poly) (q1 :: Poly). Morphism ('Prod q q1) q
- Snd :: forall (p1 :: Poly) (q :: Poly). Morphism ('Prod p1 q) q
- Pair :: forall (p :: Poly) (p1 :: Poly) (q1 :: Poly). Morphism p p1 -> Morphism p q1 -> Morphism p ('Prod p1 q1)
- Konst :: forall b (p :: Poly). b -> Morphism p ('Const b)
- Depend :: forall a (p1 :: Poly) (q :: Poly). (a -> Morphism p1 q) -> Morphism ('Prod ('Const a) p1) q
- TensorAssocL :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Tensor ('Tensor p1 q1) r) ('Tensor p1 ('Tensor q1 r))
- TensorAssocR :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Tensor p1 ('Tensor q1 r)) ('Tensor ('Tensor p1 q1) r)
- TensorBraid :: forall (p1 :: Poly) (q1 :: Poly). Morphism ('Tensor p1 q1) ('Tensor q1 p1)
- ParT :: forall da a db b dc c dd d. Morphism (Mono da a) (Mono db b) -> Morphism (Mono dc c) (Mono dd d) -> Morphism ('Tensor (Mono da a) (Mono dc c)) ('Tensor (Mono db b) (Mono dd d))
- CompUnitL :: forall (q :: Poly). Netlist q => Morphism ('Comp 'Y q) q
- CompUnitL' :: forall (p :: Poly). Netlist p => Morphism p ('Comp 'Y p)
- CompUnitR :: forall (q :: Poly). Netlist q => Morphism ('Comp q 'Y) q
- CompUnitR' :: forall (p :: Poly). Netlist p => Morphism p ('Comp p 'Y)
- CompAssocL :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Comp ('Comp p1 q1) r) ('Comp p1 ('Comp q1 r))
- CompAssocR :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Comp p1 ('Comp q1 r)) ('Comp ('Comp p1 q1) r)
- CompT :: forall da a db b dc c dd d. Morphism (Mono da a) (Mono db b) -> Morphism (Mono dc c) (Mono dd d) -> Morphism ('Comp (Mono da a) (Mono dc c)) ('Comp (Mono db b) (Mono dd d))
- Prism :: forall s a. (s -> Either a s) -> (a -> s) -> Morphism ('Prod ('Const s) ('Exp s)) ('Sum (Mono a a) (Mono s s))
- runMorphism :: forall (p :: Poly) (q :: Poly). Morphism p q -> forall x. Eval p x -> Eval q x
- type Mono i o = 'Prod ('Const o) ('Exp i)
- lens :: (a -> b) -> (a -> db -> da) -> Morphism (Mono da a) (Mono db b)
- dagger :: (a -> b) -> (db -> da) -> Morphism (Mono da a) (Mono db b)
- applyLens :: Morphism (Mono da a) (Mono db b) -> a -> (b, db -> da)
- prism :: (s -> Either a s) -> (a -> s) -> Morphism (Mono s s) ('Sum (Mono a a) (Mono s s))
- prismMatch :: Morphism (Mono s s) ('Sum (Mono a a) (Mono s s)) -> s -> Either a s
Polynomial expressions
Syntactic polynomial objects, promoted to a kind.
data Eval (p :: Poly) x where Source #
Values of a polynomial functor p evaluated at x.
The constructors mirror the polynomial grammar. EP and ES wrap the
standard product and coproduct of Haskell ((,) and Either); they are
not reimplemented, only tagged so that the polynomial shape remains
inspectable.
ET is the Dirichlet tensor: a pair of positions with one function out of
the product of direction sets. This cannot be built from a pair of ordinary
Eval values, which is why Pos and Dir are needed.
EC is the composition product: a p-position with a q-component hung on
each p-pin, and a path (dp, dq) into x.
Constructors
| EY :: forall x. x -> Eval 'Y x | |
| EK :: forall c x. c -> Eval ('Const c) x | |
| EE :: forall a x. (a -> x) -> Eval ('Exp a) x | |
| ES :: forall (p1 :: Poly) x (q :: Poly). Either (Eval p1 x) (Eval q x) -> Eval ('Sum p1 q) x | |
| EP :: forall (p1 :: Poly) x (q :: Poly). (Eval p1 x, Eval q x) -> Eval ('Prod p1 q) x | |
| ET :: forall (p1 :: Poly) (q :: Poly) x. (Pos p1, Pos q) -> ((Dir p1, Dir q) -> x) -> Eval ('Tensor p1 q) x | |
| EC :: forall (p1 :: Poly) (q :: Poly) x. (Pos p1, Dir p1 -> Pos q) -> ((Dir p1, Dir q) -> x) -> Eval ('Comp p1 q) x |
Positions and directions
type family Pos (p :: Poly) where ... Source #
Position set of a polynomial.
For a value of p(x), 'Pos p' is the index type of positions.
type family Dir (p :: Poly) where ... Source #
Direction set of a polynomial.
For a value of p(x) at a given position, 'Dir p' is the domain of the
function into x.
Sum gets a flat direction space . This
is an over-approximation: only the branch selected by the position is
in-fibre. It is nonetheless the right shape for dynamics, where the
input direction is supplied after the position is observed: a wrong-branch
direction is simply off-fibre. The netlist view (Either (Dir p) (Dir q)Netlist) remains
position-dependent and still does not admit a Sum instance.
For Comp, is the same flat
approximation: the Dir ('Comp p q) = ('Dir p, 'Dir q)q-position (hence its honest pin set) depends on which
p-direction was taken. Exact for Sum-free factors with uniform
directions — the monomial fragment.
Netlist view
class Netlist (p :: Poly) where Source #
Methods
toNet :: Eval p x -> (Pos p, Dir p -> x) Source #
Extract the position and pin assignment from a polynomial value.
fromNet :: Pos p -> (Dir p -> x) -> Eval p x Source #
Build a polynomial value from a position and pin assignment.
tensorUnitorL :: forall (p :: Poly) x. Netlist p => Eval ('Tensor 'Y p) x -> Eval p x Source #
Left unitor for the Dirichlet tensor: Y ⊗ p ≅ p.
The Y factor is degenerate; collapse via fromNet on the other factor.
tensorUnitorL' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Tensor 'Y p) x Source #
Inverse left unitor: p -> Y ⊗ p.
tensorUnitorR :: forall (p :: Poly) x. Netlist p => Eval ('Tensor p 'Y) x -> Eval p x Source #
Right unitor for the Dirichlet tensor: p ⊗ Y ≅ p.
tensorUnitorR' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Tensor p 'Y) x Source #
Inverse right unitor: p -> p ⊗ Y.
Tensor functoriality
morphAt :: forall (p :: Poly) (p' :: Poly). (Netlist p, Netlist p') => Morphism p p' -> Pos p -> (Pos p', Dir p' -> Dir p) Source #
parT :: forall (p :: Poly) (q :: Poly) (p' :: Poly) (q' :: Poly) x. (Netlist p, Netlist q, Netlist p', Netlist q') => Morphism p p' -> Morphism q q' -> Eval ('Tensor p q) x -> Eval ('Tensor p' q') x Source #
Functorial action of the Dirichlet tensor on Netlist factors.
Map each tensor factor through its morphism independently; backward directions thread through both pullback maps.
Composition product
nestedToComp :: forall (p :: Poly) (q :: Poly) x. (Netlist p, Netlist q) => Eval p (Eval q x) -> Eval ('Comp p q) x Source #
compToNested :: forall (p :: Poly) (q :: Poly) x. (Netlist p, Netlist q) => Eval ('Comp p q) x -> Eval p (Eval q x) Source #
Nested evaluation from a composition-product value.
Correctness iso (left): inverse of nestedToComp.
compUnitorL :: forall (p :: Poly) x. Netlist p => Eval ('Comp 'Y p) x -> Eval p x Source #
Left unitor for the composition product: Y ◁ p -> p.
compUnitorL' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Comp 'Y p) x Source #
Inverse left unitor for the composition product: p -> Y ◁ p.
compUnitorR :: forall (p :: Poly) x. Netlist p => Eval ('Comp p 'Y) x -> Eval p x Source #
Right unitor for the composition product: p ◁ Y -> p.
compUnitorR' :: forall (p :: Poly) x. Netlist p => Eval p x -> Eval ('Comp p 'Y) x Source #
Inverse right unitor for the composition product: p -> p ◁ Y.
compAssocL :: forall (p :: Poly) (q :: Poly) (r :: Poly) x. Eval ('Comp ('Comp p q) r) x -> Eval ('Comp p ('Comp q r)) x Source #
Left associator for the composition product:
((p ◁ q) ◁ r) -> (p ◁ (q ◁ r)).
compAssocR :: forall (p :: Poly) (q :: Poly) (r :: Poly) x. Eval ('Comp p ('Comp q r)) x -> Eval ('Comp ('Comp p q) r) x Source #
Right associator for the composition product.
Tensor wiring
tensorEval :: forall (p :: Poly) (q :: Poly) a b. (Netlist p, Netlist q) => Eval p a -> Eval q b -> Eval ('Tensor p q) (a, b) Source #
Pair two polynomial values into a Dirichlet tensor (p ⊗ q).
Each factor contributes its position and pin assignment; the result is one joint assignment over the product of direction sets.
Morphisms
data Morphism (p :: Poly) (q :: Poly) where Source #
A morphism p -> q in Poly, encoded as a natural transformation
between the evaluated functors.
By the Yoneda / sigma universal property, this is equivalent to a bundle map: a function on positions together with a contravariant family of functions on directions.
Konst and Depend extend the original Poly sketch so that backward
maps can depend on the current position, giving point-dependent lenses.
Constructors
| Id :: forall (p :: Poly). Morphism p p | Identity morphism. |
| Point :: forall (q :: Poly). Eval q () -> Morphism 'Y q | Global element: a point of By the Yoneda lemma, |
| ConstMap :: forall a b. (a -> b) -> Morphism ('Const a) ('Const b) | Covariant embedding of a plain function into constants. |
| ExpMap :: forall a b. (a -> b) -> Morphism ('Exp b) ('Exp a) | Contravariant embedding of a plain function into exponentials. |
| Compose :: forall (q1 :: Poly) (q :: Poly) (p :: Poly). Morphism q1 q -> Morphism p q1 -> Morphism p q | Sequential composition. |
| Par :: forall (p1 :: Poly) (p' :: Poly) (q1 :: Poly) (q' :: Poly). Morphism p1 p' -> Morphism q1 q' -> Morphism ('Prod p1 q1) ('Prod p' q') | Parallel composition (cartesian product of morphisms). |
| Inl :: forall (p :: Poly) (q1 :: Poly). Morphism p ('Sum p q1) | Coproduct injections. |
| Inr :: forall (p :: Poly) (p1 :: Poly). Morphism p ('Sum p1 p) | |
| Case :: forall (p1 :: Poly) (q :: Poly) (q1 :: Poly). Morphism p1 q -> Morphism q1 q -> Morphism ('Sum p1 q1) q | Coproduct case analysis. |
| Fst :: forall (q :: Poly) (q1 :: Poly). Morphism ('Prod q q1) q | Product projections. |
| Snd :: forall (p1 :: Poly) (q :: Poly). Morphism ('Prod p1 q) q | |
| Pair :: forall (p :: Poly) (p1 :: Poly) (q1 :: Poly). Morphism p p1 -> Morphism p q1 -> Morphism p ('Prod p1 q1) | Product pairing. |
| Konst :: forall b (p :: Poly). b -> Morphism p ('Const b) | Global element (constant introduction). |
| Depend :: forall a (p1 :: Poly) (q :: Poly). (a -> Morphism p1 q) -> Morphism ('Prod ('Const a) p1) q | Copower universal property: a |
| TensorAssocL :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Tensor ('Tensor p1 q1) r) ('Tensor p1 ('Tensor q1 r)) | Left associator for the Dirichlet tensor:
|
| TensorAssocR :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Tensor p1 ('Tensor q1 r)) ('Tensor ('Tensor p1 q1) r) | Right associator for the Dirichlet tensor. |
| TensorBraid :: forall (p1 :: Poly) (q1 :: Poly). Morphism ('Tensor p1 q1) ('Tensor q1 p1) | Symmetry/braiding for the Dirichlet tensor: |
| ParT :: forall da a db b dc c dd d. Morphism (Mono da a) (Mono db b) -> Morphism (Mono dc c) (Mono dd d) -> Morphism ('Tensor (Mono da a) (Mono dc c)) ('Tensor (Mono db b) (Mono dd d)) | Functorial action of the Dirichlet tensor on monomial morphisms:
Restricted to monomials because the current |
| CompUnitL :: forall (q :: Poly). Netlist q => Morphism ('Comp 'Y q) q | Left unitor for the composition product: |
| CompUnitL' :: forall (p :: Poly). Netlist p => Morphism p ('Comp 'Y p) | Inverse left unitor for the composition product. |
| CompUnitR :: forall (q :: Poly). Netlist q => Morphism ('Comp q 'Y) q | Right unitor for the composition product: |
| CompUnitR' :: forall (p :: Poly). Netlist p => Morphism p ('Comp p 'Y) | Inverse right unitor for the composition product. |
| CompAssocL :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Comp ('Comp p1 q1) r) ('Comp p1 ('Comp q1 r)) | Left associator for the composition product:
|
| CompAssocR :: forall (p1 :: Poly) (q1 :: Poly) (r :: Poly). Morphism ('Comp p1 ('Comp q1 r)) ('Comp ('Comp p1 q1) r) | Right associator for the composition product. |
| CompT :: forall da a db b dc c dd d. Morphism (Mono da a) (Mono db b) -> Morphism (Mono dc c) (Mono dd d) -> Morphism ('Comp (Mono da a) (Mono dc c)) ('Comp (Mono db b) (Mono dd d)) | Functorial action of the composition product on monomial morphisms:
Restricted to monomials for the same reason as |
| Prism :: forall s a. (s -> Either a s) -> (a -> s) -> Morphism ('Prod ('Const s) ('Exp s)) ('Sum (Mono a a) (Mono s s)) | Prism: a co-lens that matches on a sum-like position. Forward pass |
runMorphism :: forall (p :: Poly) (q :: Poly). Morphism p q -> forall x. Eval p x -> Eval q x Source #
Interpret a Morphism as a natural transformation.
Lenses
type Mono i o = 'Prod ('Const o) ('Exp i) Source #
The monomial interface: i directions (input), o positions (output).
lens :: (a -> b) -> (a -> db -> da) -> Morphism (Mono da a) (Mono db b) Source #
The general point-dependent lens.
Forward pass get :: a -> b; backward pass put :: a -> db -> da
depends on the current position.
>>>let l = lens show (\n d -> n + d) :: Morphism (Mono Int Int) (Mono Int String)>>>let (v, put) = applyLens l 40 in (v, put 2)("40",42)
applyLens :: Morphism (Mono da a) (Mono db b) -> a -> (b, db -> da) Source #
Apply a monomial morphism as a lens: (get, put).
Prisms
prism :: (s -> Either a s) -> (a -> s) -> Morphism (Mono s s) ('Sum (Mono a a) (Mono s s)) Source #
Prism: match on a sum-like source, build from the focused branch.
>>>let p = prism (\case Left n -> Left n; Right s -> Right (Right s)) Left :: Morphism (Mono (Either Int String) (Either Int String)) ('Sum (Mono Int Int) (Mono (Either Int String) (Either Int String)))>>>case runMorphism p (EP (EK (Left 7), EE id)) of ES (Left (EP (EK n, EE k))) -> (n, k 1)(7,Left 1)