0

A mealy machine is just a stateful function. Hence, two mealy machines can be composed using simple function composition. A moore machine is a restricted mealy machine with an initial output value. Is there a way to compose two moore machines? This is what I tried in Haskell:

type Mealy a b = a -> b -- a stateful function, probably using unsafePerformIO

type Moore a b = (b, Mealy a b) -- output must be consistent with current state

composeMoore :: (c, b -> c) -> (b, a -> b) -> (c, a -> c)
composeMoore (x, f) (_, g) = (x,   f . g) --    is this correct?
composeMoore (_, f) (y, g) = (f y, f . g) -- or is this correct?

I believe that they are both wrong. In fact, I believe that it's not possible to compose two moore machines. However, I might be wrong. Is there a correct way of composing moore machines?

Defintion: The composition of moore machines is an operation of the type (.) :: Moore b c -> Moore a b -> Moore a c for which the law of associativity (i.e. h . (g . f) = (h . g) . f) holds true.

Note: This is just a theoretical question. I am not actually using Haskell to write stateful functions.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • 1
    Haskell functions aren't supposed to be stateful and circumventing this using `unsafePerformIO` will rarely have the desired effect. – sepp2k Aug 23 '15 at 17:24
  • I am not using Haskell for writing stateful functions. I am using Haskell to demonstrate the problem succinctly. This is just a theoretical question. In practice, I might use either JavaScript or OCaml. – Aadit M Shah Aug 23 '15 at 17:26
  • 1
    You have to define what you mean by "composing" machines. – Benjamin Gruenbaum Aug 23 '15 at 17:36
  • I really don't see how the type of a mealy machine is different from the one of a moore machine when you are using impure functions to represent them anyway. Please come up with a theoretically sound representation (i.e. not using `unsafePerformIO`) and we may be able to give an appropriate answer – Bergi Aug 23 '15 at 17:43
  • @AaditMShah is what you're _actually_ asking is how you can represent the _subtype_ relationship between moore and mealy machines using type constraints, encapsulating the fact you cannot use the transition function? – Benjamin Gruenbaum Aug 23 '15 at 17:43
  • In your impure function `a -> b`, are those types input and output (with impure state), or does the function represent a transition between states (with impure IO)? – Bergi Aug 23 '15 at 17:46
  • @Bergi A mealy machine doesn't produce an output unless given an input. A moore machine always has an output even if it is never given an input. Yes, the function `a -> b` is an impure function with input `a`, output `b` and some hidden state. The function can also mutate its own state. Hence, it's also a transition function. – Aadit M Shah Aug 23 '15 at 17:53
  • @BenjaminGruenbaum No. All I am asking is whether there's some logical way to connect the output of a moore machine to the input of some other moore machine such that it satisfies the law of associativity. – Aadit M Shah Aug 23 '15 at 17:55
  • Yes, there is. Just because something is a state machine doesn't mean it has to have uncontrolled state. When you `unsafePerformIO` you forsake all the information of the machine. Represent it as a 6 tuple like in the definition and composing it will become simple function composition (composing the transition function and "running both machines" together). – Benjamin Gruenbaum Aug 23 '15 at 17:57
  • Your model of a Moore machine in Haskell is wrong. A Moore machine has state. Its type isn't `input -> output`, it's `(input * state) -> (output * state)` or something isomorphic. – Gilles 'SO- stop being evil' Aug 23 '15 at 18:00
  • @Gilles The state is hidden. That's why I mentioned that it's a stateful function. It's `input -> output` with hidden mutable state. I don't know the convention of writing the type of functions with mutable state. – Aadit M Shah Aug 23 '15 at 18:18
  • @BenjaminGruenbaum I figured out why you can never have a correct composition operator for moore machines: http://stackoverflow.com/a/32171450/783743. The reason is because you can never create an identity moore machine which satisfies both the left and the right identity laws of categories. The reason why you can't create an identity moore machine is because the initial output of the moore machine would always be undefined. – Aadit M Shah Aug 23 '15 at 21:04

2 Answers2

1

I think your result machine has to have the start output of the first argument, but also needs to apply the transition of the first on the start output of the second machine.

So your composition function would be neither of the two you've given, but rather a mix of them:

composeMoore :: (c, b -> c) -> (b, a -> b) -> (c, a -> c)
composeMoore (x, f) (y, g) = ((x; f y), f . g)

where ; is the impure computation sequencing operator (think , in JS).

I think your reasoning could benefit a lot from using a pure machine model :-)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I figured out why you can never have a correct composition operator for moore machines: http://stackoverflow.com/a/32171450/783743. I used pure mathematical reasoning to figure it out. – Aadit M Shah Aug 23 '15 at 20:59
-2

No, there's no correct way of composing two moore machines. Composition has no meaning without an identity element. This is because composition along with its identity element must together form a monoid in order to be meaningful. This is the mathematical definition of a category.

A category C consists of:

  1. A class, ob(C), of sets called objects.
  2. A class, hom(C), of morphisms between the objects. The hom-class, hom(a, b), is the collection of all the morphisms from a to b (each morphism f is denoted as f : a -> b).
  3. A binary operation hom(b, c) * hom(a, b) -> hom(a, c) called the composition of morphisms, for every three objects a, b and c.

In addition, they must satisfy the following laws:

  1. Associativity: For all f : a -> b, g : b -> c and h : c -> d, the relation h . (g . f) = (h . g) . f must hold true.
  2. Left identity: For all objects x there must be a morphism id_x : x -> x called the identity morphism for x such that for all f : a -> x the relation id_x . f = f holds true.
  3. Right identity: For all objects x there must be a morphism id_x : x -> x called the identity morphism for x such that for all g : x -> b the relation g . id_x = g holds true.

There's no way of composing two moore machines simply because there's no identity element for the composition of two moore machines. Hence, moore machines do not form a category. A moore machine is defined as a 6-tuple (s, s0, a, b, t, g) consisting of:

  1. A finite set of states s.
  2. A start state s0 which is an element s.
  3. A finite set a called the input alphabet.
  4. A finite set b called the output alphabet.
  5. A transition function t : s * a -> s.
  6. An output function g : s -> b.

The reason there's no identity element for moore machines is because the output of the moore machine doesn't depend upon its input. It only depends upon the current state. The initial state is s0. Hence, the initial output is g(s0). The initial output would be undefined for the identity element because it would have to match the type of the input which is yet unknown. Therefore, the "identity element" would be unable to satisfy the left and/or the right identity laws.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • I'm not sure what's wrong with an empty initial output for the identity element? – Bergi Aug 23 '15 at 21:12
  • @Bergi An empty initial value for the identity element wouldn't be able to satisfy the left and/or right identity laws of a category. – Aadit M Shah Aug 23 '15 at 21:20
  • @Bergi empty initial output isn't possible. The machine would have to be nondeterministic in order for it to work. AaditMShah the initial output is an artifact and not an important part of the model (representing initial sensor reading). I'm not sure why the fixation on it (or on categories :S). Truth be told moore and mealy machines are just not very interesting computation models, they're maybe half a lesson when instructors want to show students output but are still in DFA land :) – Benjamin Gruenbaum Aug 23 '15 at 21:24
  • Also, it's trivial that when composing two moore machines (which is entirely possible as I've demonstrated in chat) the initial output would be that of the _right_ machine. Just like if you take the function that always returns zero apply it to the result of any other function it will still only return zero. Your categorization is wrong. A moore automaton is not a function, the fact there is no identity moore automaton you can compose with both ways doesn't really prove much alone. – Benjamin Gruenbaum Aug 23 '15 at 21:28
  • In fact, it's trivial to show there is no identity function since the input and output are from different sets. The input of a word `n` is always a word of length `n+1` (in your choice of the model). You can still compose these machines just fine as I've said here: http://chat.stackoverflow.com/transcript/message/25260531#25260531. Saying you can't compose certain types of functions because there is no identity is silly, you can compose functions of the form ` + i` for a positive integer `i` just fine, composing `+1` with `+1` is perfectly legal and well defined. – Benjamin Gruenbaum Aug 23 '15 at 21:30