Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
julianpeeters committed Feb 4, 2024
1 parent f94f0d6 commit 8ca617b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 30 deletions.
30 changes: 21 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ There are several aspects to the composition of state systems with wiring diagra
import cats.implicits.given
import dynamical.fsm.{Mealy, Moore, Wiring}
import polynomial.`object`.Monomial
import polynomial.`object`.Monomial.Store
import polynomial.morphism.~>
import polynomial.product.

Expand All @@ -100,19 +101,30 @@ type Controller[Y] = Monomial.Interface[Char, Byte => Char, Y]
type System[Y] = Monomial.Interface[Byte, Byte => Char, Y]
type ω[Y] = ((PlantController) ~> System)[Y]

val w: Wiring[ω] = Wiring(b => a => b._2(a), (b, a) => ((a, b._2), b._2(a)))
// w: Wiring[ω] = dynamical.fsm.Wiring$$anon$5@6a6ac8c2
val w: Wiring[ω] = Wiring(
b => a => b._2(a),
(b, a) => ((a, b._2), b._2(a))
)
// w: Wiring[ω] = dynamical.fsm.methods.polymap.asWiring$$anon$6@5d58a18a

val m: Moore[(Monomial.Store[Char, _] ⊗ Monomial.Store[Byte => Char, _]) ~> (PlantController)] =
val m: Moore[(Store[Char, _] ⊗ Store[Byte => Char, _]) ~> (PlantController)] =
(Moore[Char, (Byte, Byte => Char), Char, Nothing](" ".charAt(0), identity, (s, i) => i._2(i._1))
Moore[Byte => Char, Char, Byte => Char, Nothing](b => b.toChar, identity, (f, i) => if i != ' ' then f else b => b.toChar.toUpper))
// m: Moore[~>[⊗[[_$5 >: Nothing <: Any] => Store[Char, _$5], [_$6 >: Nothing <: Any] => Store[Function1[Byte, Char], _$6]], ⊗[Plant, Controller]]] = dynamical.fsm.methods.moore.product.tensor$$anon$1@4b2a3393
// m: Moore[~>[⊗[[_$5 >: Nothing <: Any] => Store[Char, _$5], [_$6 >: Nothing <: Any] => Store[Function1[Byte, Char], _$6]], ⊗[Plant, Controller]]] = dynamical.fsm.methods.moore.product.tensor$$anon$1@469083ba

val fsm: Mealy[((Monomial.Store[Char, _] ⊗ Monomial.Store[Byte => Char, _]) ~> (PlantController) ~> System)] = m.andThen(w).asMealy
// fsm: Mealy[~>[~>[⊗[[_$7 >: Nothing <: Any] => Store[Char, _$7], [_$8 >: Nothing <: Any] => Store[Function1[Byte, Char], _$8]], ⊗[Plant, Controller]], System]] = dynamical.fsm.Moore$$anon$3@5b02d761
val fsm: Mealy[((Store[Char, _] ⊗ Store[Byte => Char, _]) ~> (PlantController) ~> System)] =
m.andThen(w).asMealy
// fsm: Mealy[~>[~>[⊗[[_$7 >: Nothing <: Any] => Store[Char, _$7], [_$8 >: Nothing <: Any] => Store[Function1[Byte, Char], _$8]], ⊗[Plant, Controller]], System]] = dynamical.fsm.methods.moore.conversions.asMealy$$anon$3@15b1ee9d

val s: String = "hello world".getBytes().toList.mapAccumulate(fsm.init)(fsm.run)._2.mkString
// s: String = "hello WORLD"
val input = "hello world".getBytes().toList
// input: List[Byte] = List(
// 104,
// 101,
// 108,
// ...

val result: String = input.mapAccumulate(fsm.init)(fsm.run)._2.mkString
// result: String = "hello WORLD"
```

(Note: example adapted from [Niu and Spivak](https://topos.site/poly-book.pdf))
Expand All @@ -136,7 +148,7 @@ import polynomial.morphism.~>
import polynomial.`object`.Monomial

val m: Mealy[Monomial.Store[Boolean, _] ~> Monomial.Interface[Int, Int => Int, _]] = Mealy(false, s => i => i + i, (s, i) => s)
// m: Mealy[~>[[_$9 >: Nothing <: Any] => Store[Boolean, _$9], [_$10 >: Nothing <: Any] => Interface[Int, Function1[Int, Int], _$10]]] = dynamical.fsm.methods.polymap.asMealy$$anon$1@73114d06
// m: Mealy[~>[[_$9 >: Nothing <: Any] => Store[Boolean, _$9], [_$10 >: Nothing <: Any] => Interface[Int, Function1[Int, Int], _$10]]] = dynamical.fsm.methods.polymap.asMealy$$anon$1@3b4b6f8f

val l: List[Int] = Stream(1, 2, 3).through(m.transducer).compile.toList
// l: List[Int] = List(2, 4, 6)
Expand Down
17 changes: 12 additions & 5 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ There are several aspects to the composition of state systems with wiring diagra
- after composition, `System` is then said to "wrap" such a state system, as a "wrapper interface"
- composition introduces no delay into the machine, since we defined the controller to emit a runnable function

```scala mdoc:reset
```scala mdoc:reset:height=5
import cats.implicits.given
import dynamical.fsm.{Mealy, Moore, Wiring}
import polynomial.`object`.Monomial
import polynomial.`object`.Monomial.Store
import polynomial.morphism.~>
import polynomial.product.

Expand All @@ -99,15 +100,21 @@ type Controller[Y] = Monomial.Interface[Char, Byte => Char, Y]
type System[Y] = Monomial.Interface[Byte, Byte => Char, Y]
type ω[Y] = ((PlantController) ~> System)[Y]

val w: Wiring[ω] = Wiring(b => a => b._2(a), (b, a) => ((a, b._2), b._2(a)))
val w: Wiring[ω] = Wiring(
b => a => b._2(a),
(b, a) => ((a, b._2), b._2(a))
)

val m: Moore[(Monomial.Store[Char, _] ⊗ Monomial.Store[Byte => Char, _]) ~> (PlantController)] =
val m: Moore[(Store[Char, _] ⊗ Store[Byte => Char, _]) ~> (PlantController)] =
(Moore[Char, (Byte, Byte => Char), Char, Nothing](" ".charAt(0), identity, (s, i) => i._2(i._1))
Moore[Byte => Char, Char, Byte => Char, Nothing](b => b.toChar, identity, (f, i) => if i != ' ' then f else b => b.toChar.toUpper))

val fsm: Mealy[((Monomial.Store[Char, _] ⊗ Monomial.Store[Byte => Char, _]) ~> (PlantController) ~> System)] = m.andThen(w).asMealy
val fsm: Mealy[((Store[Char, _] ⊗ Store[Byte => Char, _]) ~> (PlantController) ~> System)] =
m.andThen(w).asMealy

val input = "hello world".getBytes().toList

val s: String = "hello world".getBytes().toList.mapAccumulate(fsm.init)(fsm.run)._2.mkString
val result: String = input.mapAccumulate(fsm.init)(fsm.run)._2.mkString
```

(Note: example adapted from [Niu and Spivak](https://topos.site/poly-book.pdf))
Expand Down
60 changes: 44 additions & 16 deletions modules/fsm/shared/src/main/scala/dynamical/fsm/Wiring.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,61 @@ object Wiring:
def apply[A1, B1, A2, B2, A3, B3, I, O, Y](
r: (((B1, B2), B3)) => I => O,
u: (((B1, B2), B3), I) => ((A1, A2), A3)
): Wiring[(Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]) ~> Monomial.Interface[I, I => O, _]] =
PolyMap[(Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]), Monomial.Interface[I, I => O, _], Y](r, u).asWiring
): Wiring[
(Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]) ~>
Monomial.Interface[I, I => O, _]
] =
PolyMap[
(Monomial.Interface[A1, B1, _] ⊗ Monomial.Interface[A2, B2, _] ⊗ Monomial.Interface[A3, B3, _]),
Monomial.Interface[I, I => O, _],
Y
](r, u).asWiring

@scala.annotation.targetName("appTensored3")
def apply[A, B, C, Y](
r: ((C, B)) => A => C,
u: ((C, B), A) => ((A, B), C)
): Wiring[(Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]) ~> Monomial.Interface[A, A => C, _]] =
PolyMap[(Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]), Monomial.Interface[A, A => C, _], Y](r, u).asWiring
): Wiring[
(Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]) ~>
Monomial.Interface[A, A => C, _]
] =
PolyMap[
(Monomial.Interface[(A, B), C, _] ⊗ Monomial.Interface[C, B, _]),
Monomial.Interface[A, A => C, _],
Y
](r, u).asWiring

@scala.annotation.targetName("appBiTensored1")
def apply[A1, B1, A2, B2, A3, B3, A4, B4, Y](
r1: ((B1, B3)) => A1 => B3,
r2: ((B2, B4)) => A2 => B4,
u1: ((B1, B3), A1) => (A1, A3),
u2: ((B2, B4), A2) => (A2, A4)
): Wiring[(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]) ~> Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _]] =
PolyMap[(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]), Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _], Y]((r1, r2), (u1, u2)).asWiring
): Wiring[
(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]) ~>
Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _]
] =
PolyMap[
(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[A3, B3, A4, B4, _]),
Binomial.Interface[A1, A1 => B3, A2, A2 => B4, _],
Y
]((r1, r2), (u1, u2)).asWiring

@scala.annotation.targetName("appTensored4")
def serially[A1, B1, A2, B2, B3, Y]: Wiring[(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[B1, B1, B2, B3, _]) ~> Binomial.Interface[A1, A1 => B1, A2, A2 => B3, _]] =
PolyMap[(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[B1, B1, B2, B3, _]), Binomial.Interface[A1, A1 => B1, A2, A2 => B3, _], Y](
(
(_, b1) => a1 => b1,
(_, b3) => a2 => b3
),(
(b, a1) => (a1, b._2),
(b, a2) => (a2, b._1)
)
).asWiring
def serially[A1, B1, A2, B2, B3, Y]: Wiring[
(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[B1, B1, B2, B3, _]) ~>
Binomial.Interface[A1, A1 => B1, A2, A2 => B3, _]
] =
PolyMap[
(Binomial.Interface[A1, B1, A2, B2, _] ⊗ Binomial.Interface[B1, B1, B2, B3, _]),
Binomial.Interface[A1, A1 => B1, A2, A2 => B3, _],
Y
](
(
(_, b1) => a1 => b1,
(_, b3) => a2 => b3
),(
(b, a1) => (a1, b._2),
(b, a2) => (a2, b._1)
)
).asWiring

0 comments on commit 8ca617b

Please sign in to comment.