How to create a 100% declarative model? - alloy

I am creating a simple model of a network. The network contains nodes. Nodes send and receive data.
Here's one way to model the network: Each node has a "data" field representing the data possessed by the node at time t. Each node also has a "send" field recording the data sent to other nodes at time t.
sig Node {
data: Data -> Time,
send: Data -> Node -> Time
}
In the spectrum between 100% declarative and 100% imperative, I don't think that that signature is at the 100% declarative side. In my first paragraph I said nothing about nodes having data stores, nothing about keeping a record of sent data.
Also, isn't "send" a verb? Isn't that a sign that the model is not as declarative as it could be? Shouldn't declarative models exclusively use nouns?
I want my model to be at the 100% declarative end of the spectrum. To achieve that, I must simply state what "is". Let's do it!
What is is there are nodes:
sig Node {}
What is is that at any time t, a node has data.
sig Node {
data: Data -> Time
}
What is is that the network has wires between nodes.
sig Network {
wire: Node -> Node
}
What is is that data d is on a wire between time t and t' ...
Let me stop there. Is the second approach that I sketched out more declarative? Is there an approach that is even more declarative?
How to model a network in a 100% declarative manner?

I think you need to separate the semantic content of the model, which is one issue, from the names used in it. To me, the essence of a declarative model is that it records observations -- which may be about state, or about dynamic things like transitions -- expressed in logic. The alternative, an operational model, is to describe behavior and states by building up sequences of primitive actions. A simple example: modeling an action that picks an element non-deterministically from a set. An operational spec might treat the set as ordered, and then use a loop to walk through the set, at each step tossing a coin, and returning the given element when the toss first comes up heads. This models the intuitive operational description: "go through the elements of the set one at a time, and pick one to return". A declarative spec would simply say that the returned value is an element of the set -- nothing else needs to be said.
Regarding the use of names in your particular model, it seems that a larger issue to me is whether the names convey directly what they mean. So send to me is not a very helpful name; a better one would be sentAt.

Related

Activity Diagram: Reusing Activity/Action With different inherited type of object flow as output

I have a question regarding modeling on an Activity Diagram that has been bothering me for some time and I was not able to find any answers / Convention anywhere.
Here is an example to better understand my question:
Let say that I have two class named "flat" and "house". both are a generalization of the class "housing".
housing contain an attribute "residents" for the person living in it.
flat contain an attributes "floor" that says at which floor the flat is.
Here is the class diagram:
In an activity diagram, I want to represent the action of giving persons a housing.
this action can take either house or flat as input (so the use of "housing" type for the input pin is correct I think) as well as an undefined number of people.
I want this action to give an updated house or flat as output (not an updated housing as this would mean that information specific to the house or flat would be lost.
I don't really know if I must create two actions (one for house and another for flats) or if there is a way to reuse the action for both class and have a correct output out of it.
Here is the activity Diagram:
My question is: how to represent in an activity diagram, an action that is the same for different type of Object flows as input, and that give the updated Object flow as output (that may be therefore of different type)?
nb:
all type of object flow are class and inherit from a same other class.
I'm representing this in modelio but first had this issue in Cameo.
I'm Trying to fit as best as I can within the rules of UML Language.
Cameo is right in rejecting this model. Give Flat Floor expects a Flat and will not work with a House, but Assign Resident to Housing could return a House. I know, in your context it can only return a Flat, but how should the tool know that?
The correct way to capture this fact would be to add a postcondition to Activity Assign Resident to Housing that states that the type of the input and output pin will be the same.
However, it would be really hard to define a complete set of compatibilty rules that takes into account all the global and local pre- and postconditions and the tools would also be hard pressed to validate a model according to these rules. Therefore the UML specification choose the easy road and simply doesn't allow to connect the pins.
The solution is to use the transformation property of the ObjectFlow. Just assign an OpaqueBehavior that casts the Type House to the Type Flat. Cameo will then accept the model. It is the modelers responsibility to ensure, that this cast will always work, since no exception handling can be defined here. Maybe this should be documented with a local postcondition.
In your specific example there is an even easier solution: simply fork the ObjectFlow of Type Flat and omit the OutputPin of Assign Resident to Housing.
As a side note: Due to a bug in Cameo, you can change the type of the OutputPin to a more specific Type than that of the ActivityParameter. This is correct for InputPins, but should be the opposite for OutputPins. You could use this to let the Parameter be of type House, but the OutputPin-Type would be Flat.
The two flows (top object and lower control) in the blue frame could stay as they are. Give flat floor would commence only when it receives a Flat object and the control token is sent. In order to make the right action sort of optional I would just use the object flow, thus only triggering when a Flat object is passed. That would just be enough and no additional control flow is needed.
To make things clear I would also add a guarded flow from the Assign action to an exit reading [ house was assigned ] or the like.

BLoC pattern best practice - is it legit to store data in the BLoC class?

I am new to Flutter and the BLoC design pattern. However, the concept of BLoC looks pretty straightforward and I think I understand it pretty well.
Occasionally, when reviewing my coworkers' code, I see that when implementing a BLoC, they tend to store data inside the BLoC class. I believe this is wrong, and that the data belongs in the state class. If it needs to be passed around or stored somewhere until the state can be created, it should be stored in the event instance that triggers the change, not the BLoC itself.
My understanding is that the BLoC class is a state machine whose sole purpose is to map events to states and have no other state besides the defined "state" class. This is separation of concerns - the event class(es) should store the data triggering the change, the state class(es) should store the data after the change, and the BLoC should handle the operations manipulating that data and mapping it from event to state.
If you store data inside the BLoC class, the state machine changes its functionality from (event, state0) => state1 to (event, state0, blocData) => state1. It's clear that if you want to unit-test your BLoC, the complexity of your tests increases, because you will need to test |event| X |state| X |blocData| cases instead of |event| X |state| cases (meaning cartesian multiplication of number of possible values for each type). One can claim that it doesn't really affect the number of possible values, because we would just move blocData to state. However, my claim is that if you encapsulate the data together, you will usually find that they are dependent and some combinations are irrelevant, but you can maintain this dependency only when encapsulating them together, or at least protect it from breaking only when encapsulating together.
Another reason is that your application code that sees a state and sends an event, may potentially produce indeterministic results. This is because the BLoC instance has a "dirty" state that has an effect on its functionality.
I'd like to hear opinions from developers that have some more experience in this design pattern. If you can post some references to articles on this issue, that'd be great too. I didn't find anything specific about this issue.

Can I repeatedly create & destroy random generator/distributor objects and destroy them (with a 'dice' class)?

I'm trying out the random number generation from the new library in C++11 for a simple dice class. I'm not really grasping what actually happens but the reference shows an easy example:
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1,6);
int dice_roll = distribution(generator);
I read somewhere that with the "old" way you should only seed once (e.g. in the main function) in your application ideally. However I'd like an easily reusable dice class. So would it be okay to use this code block in a dice::roll() method although multiple dice objects are instantiated and destroyed multiple times in an application?
Currently I made the generator as a class member and the last two lines are in the dice:roll() methods. It looks okay but before I compute statistics I thought I'd ask here...
Think of instantiating a pseudo-random number generator (PRNG) as digging a well - it's the overhead you have to go through to be able to get access to water. Generating instances of a pseudo-random number is like dipping into the well. Most people wouldn't dig a new well every time they want a drink of water, why invoke the unnecessary overhead of multiple instantiations to get additional pseudo-random numbers?
Beyond the unnecessary overhead, there's a statistical risk. The underlying implementations of PRNGs are deterministic functions that update some internally maintained state to generate the next value. The functions are very carefully crafted to give a sequence of uncorrelated (but not independent!) values. However, if the state of two or more PRNGs is initialized identically via seeding, they will produce the exact same sequences. If the seeding is based on the clock (a common default), PRNGs initialized within the same tick of the clock will produce identical results. If your statistical results have independence as a requirement then you're hosed.
Unless you really know what you're doing and are trying to use correlation induction strategies for variance reduction, best practice is to use a single instantiation of a PRNG and keep going back to it for additional values.

Maintaining complex state in Haskell

Suppose you're building a fairly large simulation in Haskell. There are many different types of entities whose attributes update as the simulation progresses. Let's say, for the sake of example, that your entities are called Monkeys, Elephants, Bears, etc..
What is your preferred method for maintaining these entities' states?
The first and most obvious approach I thought of was this:
mainLoop :: [Monkey] -> [Elephant] -> [Bear] -> String
mainLoop monkeys elephants bears =
let monkeys' = updateMonkeys monkeys
elephants' = updateElephants elephants
bears' = updateBears bears
in
if shouldExit monkeys elephants bears then "Done" else
mainLoop monkeys' elephants' bears'
It's already ugly having each type of entity explicitly mentioned in the mainLoop function signature. You can imagine how it would get absolutely awful if you had, say, 20 types of entities. (20 is not unreasonable for complex simulations.) So I think this is an unacceptable approach. But its saving grace is that functions like updateMonkeys are very explicit in what they do: They take a list of Monkeys and return a new one.
So then the next thought would be to roll everything into one big data structure that holds all state, thus cleaning up the signature of mainLoop:
mainLoop :: GameState -> String
mainLoop gs0 =
let gs1 = updateMonkeys gs0
gs2 = updateElephants gs1
gs3 = updateBears gs2
in
if shouldExit gs0 then "Done" else
mainLoop gs3
Some would suggest that we wrap GameState up in a State Monad and call updateMonkeys etc. in a do. That's fine. Some would rather suggest we clean it up with function composition. Also fine, I think. (BTW, I'm a novice with Haskell, so maybe I'm wrong about some of this.)
But then the problem is, functions like updateMonkeys don't give you useful information from their type signature. You can't really be sure what they do. Sure, updateMonkeys is a descriptive name, but that's little consolation. When I pass in a god object and say "please update my global state," I feel like we're back in the imperative world. It feels like global variables by another name: You have a function that does something to the global state, you call it, and you hope for the best. (I suppose you still avoid some concurrency problems that would be present with global variables in an imperative program. But meh, concurrency isn't nearly the only thing wrong with global variables.)
A further problem is this: Suppose the objects need to interact. For example, we have a function like this:
stomp :: Elephant -> Monkey -> (Elephant, Monkey)
stomp elephant monkey =
(elongateEvilGrin elephant, decrementHealth monkey)
Say this gets called in updateElephants, because that's where we check to see if any of the elephants are in stomping range of any monkeys. How do you elegantly propagate the changes to both the monkeys and elephants in this scenario? In our second example, updateElephants takes and returns a god object, so it could effect both changes. But this just muddies the waters further and reinforces my point: With the god object, you're effectively just mutating global variables. And if you're not using the god object, I'm not sure how you'd propagate those types of changes.
What to do? Surely many programs need to manage complex state, so I'm guessing there are some well-known approaches to this problem.
Just for the sake of comparison, here's how I might solve the problem in the OOP world. There would be Monkey, Elephant, etc. objects. I'd probably have class methods to do lookups in the set of all live animals. Maybe you could lookup by location, by ID, whatever. Thanks to the data structures underlying the lookup functions, they'd stay allocated on the heap. (I'm assuming GC or reference counting.) Their member variables would get mutated all the time. Any method of any class would be able to mutate any live animal of any other class. E.g. an Elephant could have a stomp method that would decrement the health of a passed-in Monkey object, and there would be no need to pass that
Likewise, in an Erlang or other actor-oriented design, you could solve these problems fairly elegantly: Each actor maintains its own loop and thus its own state, so you never need a god object. And message passing allows one object's activities to trigger changes in other objects without passing a bunch of stuff all the way back up the call stack. Yet I have heard it said that actors in Haskell are frowned upon.
The answer is functional reactive programming (FRP). It it a hybrid of two coding styles: component state management and time-dependent values. Since FRP is actually a whole family of design patterns, I want to be more specific: I recommend Netwire.
The underlying idea is very simple: You write many small, self-contained components each with their own local state. This is practically equivalent to time-dependent values, because each time you query such a component you may get a different answer and cause a local state update. Then you combine those components to form your actual program.
While this sounds complicated and inefficient it's actually just a very thin layer around regular functions. The design pattern implemented by Netwire is inspired by AFRP (Arrowized Functional Reactive Programming). It's probably different enough to deserve its own name (WFRP?). You may want to read the tutorial.
In any case a small demo follows. Your building blocks are wires:
myWire :: WireP A B
Think of this as a component. It is a time-varying value of type B that depends on a time-varying value of type A, for example a particle in a simulator:
particle :: WireP [Particle] Particle
It depends on a list of particles (for example all currently existing particles) and is itself a particle. Let's use a predefined wire (with a simplified type):
time :: WireP a Time
This is a time-varying value of type Time (= Double). Well, it's time itself (starting at 0 counted from whenever the wire network was started). Since it doesn't depend on another time-varying value you can feed it whatever you want, hence the polymorphic input type. There are also constant wires (time-varying values that don't change over time):
pure 15 :: Wire a Integer
-- or even:
15 :: Wire a Integer
To connect two wires you simply use categorical composition:
integral_ 3 . 15
This gives you a clock at 15x real time speed (the integral of 15 over time) starting at 3 (the integration constant). Thanks to various class instances wires are very handy to combine. You can use your regular operators as well as applicative style or arrow style. Want a clock that starts at 10 and is twice the real time speed?
10 + 2*time
Want a particle that starts and (0, 0) with (0, 0) velocity and accelerates with (2, 1) per second per second?
integral_ (0, 0) . integral_ (0, 0) . pure (2, 1)
Want to display statistics while the user presses the spacebar?
stats . keyDown Spacebar <|> "stats currently disabled"
This is just a small fraction of what Netwire can do for you.
I know this is old topic. But I am facing the same problem right now while trying to implement Rail Fence cipher exercise from exercism.io. It is quite disappointing to see such a common problem having such poor attention in Haskell. I don't take it that to do some as simple as maintaining state I need to learn FRP. So, I continued googling and found solution looking more straightforward - State monad: https://en.wikibooks.org/wiki/Haskell/Understanding_monads/State

Managing a stateful computation system in Haskell

So, I have a system of stateful processors that are chained together. For example, a processor might output the average of its last 10 inputs. It requires state to calculate this average.
I would like to submit values to the system, and get the outputs. I also would like to jump back and restore the state at any time in the past. Ie. I run 1000 values through the system. Now I want to "move" the system back to exactly as it was after I had sent the 500th value through. Then I want to "replay" the system from that point again.
I also need to be able to persist the historical state to disk so I can restore the whole thing again some time in the future (and still have the move back and replay functions work). And of course, I need to do this with gigabytes of data, and have it be extremely fast :)
I had been approaching it using closures to hold state. But I'm wondering if it would make more sense to use a monad. I have only read through 3 or 4 analogies for monads so don't understand them well yet, so feel free to educate me.
If each processor modifies its state in the monad in such a way that its history is kept and it is tied to an id for each processing step. And then somehow the monad is able to switch its state to a past step id and run the system with the monad in that state. And the monad would have some mechanism for (de)serializing itself for storage.
(and given the size of the data... it really shouldn't even all be in memory, which would mean the monad would need to be mapped to disk, cached, etc...)
Is there an existing library/mechanism/approach/concept that has already been done to accomplish or assist in accomplishing what I'm trying to do?
So, I have a system of stateful processors that are chained together. For example, a processor might output the average of its last 10 inputs. It requires state to calculate this average.
First of all, it sounds like what you have are not just "stateful processors" but something like finite-state machines and/or transducers. This is probably a good place to start for research.
I would like to submit values to the system, and get the outputs. I also would like to jump back and restore the state at any time in the past. Ie. I run 1000 values through the system. Now I want to "move" the system back to exactly as it was after I had sent the 500th value through. Then I want to "replay" the system from that point again.
The simplest approach here, of course, is to simply keep a log of all prior states. But since it sounds like you have a great deal of data, the storage needed could easily become prohibitive. I would recommend thinking about how you might construct your processors in a way that could avoid this, e.g.:
If a processor's state can be reconstructed easily from the states of its neighbors a few steps prior, you can avoid logging it directly
If a processor is easily reversible in some situations, you don't need to log those immediately; rewinding can be calculated directly, and logging can be done as periodic snapshots
If you can nail a processor down to a very small number of states, make sure to do so.
If a processor behaves in very predictable ways on certain kinds of input, you can record that as such--e.g., if it idles on numeric input below some cutoff, rather than logging each value just log "idled for N steps".
I also need to be able to persist the historical state to disk so I can restore the whole thing again some time in the future (and still have the move back and replay functions work). And of course, I need to do this with gigabytes of data, and have it be extremely fast :)
Explicit state is your friend. Functions are a convenient way to represent active state machines, but they can't be serialized in any simple way. You want a clean separation of a (basically static) network of processors vs. a series of internal states used by each processor to calculate the next step.
Is there an existing library/mechanism/approach/concept that has already been done to accomplish what I'm trying to do? Does the monad approach make sense? Are there other better/special approaches that would help it do this efficiently especially given the enormous amount of data I have to manage?
If most of your processors resemble finite state transducers, and you need to have processors that take inputs of various types and produce different types of outputs, what you probably want is actually something with a structure based on Arrows, which gives you an abstraction for things that compose "like functions" in some sense, e.g., connecting the input of one processor to the output of another.
Furthermore, as long as you avoid the ArrowApply class and make sure that your state machine model only returns an output value and a new state, you'll be guaranteed to avoid implicit state because (unlike functions) Arrows aren't automatically higher-order.
Given the size of the data... it really shouldn't even all be in memory, which would mean the monad would need to be mapped to disk, cached, etc...
Given a static representation of your processor network, it shouldn't be too difficult to also provide an incremental input/output system that would read the data, serialize/deserialize the state, and write any output.
As a quick, rough starting point, here's an example of probably the simplest version of what I've outlined above, ignoring the logging issue for the moment:
data Transducer s a b = Transducer { curState :: s
, runStep :: s -> a -> (s, b)
}
runTransducer :: Transducer s a b -> [a] -> [b]
runTransducer t [] = (t, [])
runTransducer t (x:xs) = let (s, y) = runStep t (curState t) x
(t', ys) = runTransducer (t { curState = s }) xs
in (t', y:ys)
It's a simple, generic processor with explicit internal state of type s, input of type a, and output of type b. The runTransducer function shoves a list of inputs through, updating the state value manually, and collects a list of outputs.
P.S. -- since you were asking about monads, you might want to know if the example I gave is one. In fact, it's a combination of multiple common monads, though which ones depends on how you look at it. However, I've deliberately avoided treating it as a monad! The thing is, monads capture only abstractions that are in some sense very powerful, but that same power also makes them more resistant in some ways to optimization and static analysis. The main thing that needs to be ruled out is processors that take other processors as input and run them, which (as you can imagine) can create convoluted logic that's nearly impossible to analyze.
So, while the processors probably could be monads, and in some logical sense intrinsically are, it may be more useful to pretend that they aren't; imposing an artificial limitation in order to make static analysis simpler.

Resources