I am trying to model a vending machine program using alloy . I wish to create a model in which I could insert some money and provide the machine a selection option for an item and it would provide me the same and in case the money supplied is less then nothing would be provided .
Here I am trying to input a coin along with a button as input and it should return the desired item from the vending machine provided the value ie. amount assigned to each item is provided as input. So here button a should require ten Rs, button b requires 5 rs, c requires 1 and d requires 2 . The op instance is the item returned once the money required is inserted. opc is the balance amount of coins to be returned. ip is input button and x is money input . How can I provide an instance such that it intakes multiple coins as input and also if the amount is greater than the item cost then it should return a no of coins back. If I could get some help it'll be greatly appreciated.
If I were you, I'd proceed by asking myself what kinds of entities I care about; you've done that (signatures for coins and items -- do you also need some notion of a customer?).
Next, I'd ask myself what constitutes a legal state for the system -- sometimes it helps to think about it backwards by asking what would constitute an illegal or unacceptable state.
Then I'd try to define operations -- you've already mentioned insertion of money and selection of an item -- as transitions from one legal state of the system to the next.
At each stage I'd use the Analyzer to examine instances of the model and see whether what I'd done so far makes sense. One example of this pattern of defining entities, states, and state transitions in that order is given in the Whirlwind Tour chapter of Daniel Jackson's Software Abstractions -- if you have access to that book, you will find it helpful to review that chapter.
Good luck!
module vending_machines
open util /ordering[Event]
fun fst:Event{ordering/first}
fun nxt:Event->Event{ordering/next}
fun upto[e:Event]:set Event{prevs[e]+e}
abstract sig Event{}
sig Coin extends Event{}
pred no_vendor_loss[product:set (Event-Coin)]
{
all e:Event | let pfx=upto[e] | #(product&pfx)<=#(Coin&pfx)
Related
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.
I am trying to implement the Jass card game in Haskell and would like to make the game state as explicit as possible or avoiding impossible states with types.
The standard variant involves four players. The players opposite each other form a team.
In a game rounds are played until one team reaches the target score.
At the start of each round each player is dealt with 9 cards one player gets to choose the trump, and lead the first trick.
In a trick every player has to play one card. The cards are compared with respect to the leading suit and trump and the player with the highest card wins the trick. The points of the tricks are added to the score of the winner's team. The winner also is lead on the next trick. In a round tricks are played until each player has no cards left.
There is a more detailed explanation on wikipedia and a german explanation on jassa.at.
My data model for the player looks something like this
data Player = Player
{ playerID :: PlayerID
, name :: String
, cards :: Set Card
, sendMessage :: Message -> IO ()
, receiveAction :: IO Action
}
this way I can just use different send and receive functions for like command line or network players.
I would like the represent the game as a state machine with a pure update function, however in most states there is only one action from only one player that is valid and so i think that in the update function a big part is just handling invalid inputs.
I don't know what would be the best way to represent these parts of the game state.
The Players.
My first idea was to use a simple list and rotate this list every time so the current player is always the head. This is easy to do, but i also think it's easy for something to go wrong, like what if the list is empty, or there is only one player and so on...
Use an Array for the players and use the index for the current player. This has the advantage that to get to the next player I just have to increase the index. Somewhere i have to use mod to cycle the array but that's not really a problem. I also tried this with XDataKinds to have the size of the array on the type level and so the nextPlayer function can handel the mod. This also has the advantage that for the teams I can just use the even and odd player indices. But with this i have to store a extra Map from playerID or index to the cards of the players. So now the array and map can get out of sync.
Trick
I am not sure if i should store a list of played cards and who played them or just a record with the lead, highest card, winner and the value of the played cards and keep track of all played cards in a writer monad.
Rounds and Tricks
This is kinda the same for both, should i store a list with all played rounds and tricks or only the current round and trick and save the sum of the points from the previous rounds/tricks
There is temptation to have the type checker prove your program is perfect. However, that will become an endless pursuit. There really are not the hours in the day to spend teaching a computer how to be sure what you're sure is sure is for sure for every surety.
What I do is start with some way of solving the problem and then learn as I go what the pain points are. Which mistakes am I actually prone to making? In your case, I would implement the game (or part of) in some way I can figure out, and then from that experience I will know how to do it better.
cycle :: [a] -> [a] takes a list and repeats it forever. You can do this for your players and take the head of the list forever.
For non-empty lists there is Data.List.NonEmpty.
A way to only construct valid game states is to define an abstract data type. Rather than exporting the data constructors for a type, you only export functions of your own definition which can construct the type. That way, you can do whatever (runtime) checking or fixing you want.
Another tool is unit testing. Encoding propositions as types is difficult, especially in Haskell, and so the vast majority will not be. Instead, you can use property-based unit testing to recover a modicum of assurance.
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.
Let's say you have a basic elevator system defined in Alloy...
You have a set of floors and a set of people waiting on the elevator on each floor.
You work with State to show the progress the elevator makes.
How can you send the elevator in the initial state to a random floor to pick up his first person? (aka; how can you randomise the element alloy takes?)
I think what you want to do here is to leave the initial state unspecified. That is, describe its existence, clarify that there is exactly one, but leave it unspecified which of the possible states is the initial state.
The Alloy Analyzer will then check your assertions and predicates for all possible initial states, and will (eventually) generate instances of the model for all possible initial states. This resembles the behavior of a good random number generator, in that the likelihood of any given state being chosen as the initial state is equal to the likelihood of any other given state being chosen -- it's just that the likelihood here becomes 1.0, not 1/n for n possible states.
And better to say an arbitrary floor, rather than a random floor.
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