State Machine - What is the best way to define boolean for different states? - boolean

I have got the following question which is pondering me for some time. I'm new to state machine modeling so would really appreciate your help, ideas, and suggestions.
Let's say I have a "Valve" which can be in state "opened" or "closed". Now when I model the state machine.
Should I define two booleans for each state?
bool opened;
bool closed;
Hence, I should use both booleans for each state?
Example: State "opened" will have the booleans--> opened = 1 and closed = 0;
OR
Simply can I define only one boolean variable?
bool opened;
Example: State "opened" will have only one boolean-->opened = 1 and in the state "closed" it will have boolean opened = 0;
What is the best practice here? Any advantages of using two booleans over one boolean? I can imagine in this case too many variables have to been defined and reset every time state transitions into another state.
Thank you in advance

I think you could consider not using boolean at all to represent object state. Most objects will have more than two states, and if you use boolean flags you'll end up with qute a lot of them. This can make it quite hard to test and verify that the code works as expected all the time. I worked with someone who had 22 boolean flags in one class. This meant that the class has over 4 million possible states.
I usually use an enum to represent class state. The Valve could be Open or Closed, but what if it became defective, and impossible to operated? I can easily add more states to the enum increasing the number of states by 1, but if I use an boolean I will exponentially increase the number of possible states when adding more flags.
I'd also recommend using a state machine library, instead of manually handling state in your own code. There are many state machine libraries available, I use (and contribute to) the stateless state machine library on Github.

If the two states are mutually exclusive, there's no point in having a redundant state variable, which you'd need to maintain. A single boolean provides you with two possible states already.
Depending on the language, you might be able to introduce an alias such that you'd be able to refer to the same state under different names, purely for aesthetic purposes, and the compiler would remove the redundancy. But again, it may be more of a nuisance than something truly useful.
You want to have additional state variables when you need to deal with independent states or when you want to describe substates.

Related

What are the potential repercussions of a lazy property getting initialised more than once?

The Apple doc says that
If a property marked with the lazy modifier is accessed by multiple
threads simultaneously and the property has not yet been initialized,
there is no guarantee that the property will be initialized only once.
My question is what are the potential repercussions of a property getting initialized more than once?
And in case of a property getting initialized more than once, which one of it will be used? How Swift manages them?
I went through some of the answers.
Is it normal that lazy var property is initialized twice?
But they are just saying that lazy properties can get initialized more than once. I want to know what are the repercussions of this.
Thanks in advance.
(See my comment to rmaddy's answer regarding my concern about thread-safety on writing the pointer itself. My gut is that memory corruption is not possible, but that object duplication is. But I can't prove so far from the documentation that memory corruption isn't possible.)
Object duplication is a major concern IMO if the lazy var has reference semantics. Two racing threads can get different instances:
Thread 1 begins to initialize (object A)
Thread 2 begins to initialize (object B)
Thread 1 assigns A to var and returns A to caller
Thread 2 assigns B to var and returns B to caller
This means that thread 1 and thread 2 have different instances. That definitely could be a problem if they are expecting to have the same instance. If the type has value semantics, then this shouldn't matter (that being the point of value semantics). But if it has reference semantics, then this very likely be a problem.
IMO, lazy should always be avoided if multi-threaded callers are possible. It throws uncertainty into what thread the object construction will occur on, and the last thing you want in a thread-safe object is uncertainty about what thread code will run on.
Personally I've rarely seen good use cases for lazy except for where you need to pass self in the initializer of one of your own properties. (Even then, I typically use ! types rather than lazy.) In this way, lazy is really just a kludgy work-around a Swift init headache that I wish we could solve another way, and do away with lazy, which IMO has the same "doesn't quite deliver what it promises, and so you probably have to write your own version anyway" problem as #atomic in ObjC.
The concept of "lazy initialization" is only useful if the type in question is both very expensive to construct, and unlikely to ever be used. If the variable is actually used at some point, it's slower and has less deterministic performance to make it lazy, plus it forces you to make it var when it is most often readonly.
The answer completely depends on the code you have inside the implementation of the lazy property. The biggest problem would arise from any side effects you've put in the code since they might be called more than once.
If all you do is create a self-contained object, initialize it, and return it, then there won't be any issues.
But if also do things like add a view, update an array or other data structure, or modify other properties, then you have an issue if the lazy variable is created more than once since all of those side effects will happen more than once. You end up adding two views or adding two objects to the array, etc.
Ensure that the code in your lazy property only creates and initializes an object and does not perform any other operations. If you do that, then your code won't cause any issues if the lazy property gets created multiple times from multiple threads.

Track program change on WAGO PLC with CoDeSys

I need to increment an integer value each time the PLC program is updated to track changes.
There are system events like online_change and before_download, but I have no idea how to implement their functions.
Also I need to save value between updates. I think the tracking variable should be created as RETAIN but not sure.
The variable declaration type should be VAR RETAIN PERSISTENT in your case. Variables declared under RETAIN only will lose their values (intentionally) with a program change.
I believe the builtin Codesys library SysLibProjectInfo.lib has what you are looking for with the function SysGetProjectID. If you store SysGetProjectID as a RETAIN PERSISTENT and then compare against it, you can track changes (or, this unique value may be exactly what you wanted in the first place, without manually creating an ID).
Note: Depending on how you declare your variables, changing the I/O configuration can have unexpected changes even on VAR RETAIN PERSISTENT variables (as all dynamically allocated addresses are shifted and may not point where they used to).
If I understand you you only want to know like what version is running on the PLC and you want to track changes that you make? You can do it two ways:
Since it's a constant each time you make a change external to the PLC you roll the rev of a variable that is declared like SoftwareVersion :WORD := 100; and keep it in a Revision global list that you can add your notes to and change the version before downloading to PLC.
You can also use the PLC summary area that has fields to enter the values and then you can read them through CoDeSys without software upload.
And of course the suggestion above can work.

Implementing snapshot in FRP

I'm implementing an FRP framework in Scala and I seem to have run into a problem. Motivated by some thinking, this question I decided to restrict the public interface of my framework so Behaviours could only be evaluated in the 'present' i.e.:
behaviour.at(now)
This also falls in line with Conal's assumption in the Fran paper that Behaviours are only ever evaluated/sampled at increasing times. It does restrict transformations on Behaviours but otherwise we find ourselves in huge problems with Behaviours that represent some input:
val slider = Stepper(0, sliderChangeEvent)
With this Behaviour, evaluating future values would be incorrect and evaluating past values would require an unbounded amount of memory (all occurrences used in the 'slider' event would have to be stored).
I am having trouble with the specification for the 'snapshot' operation on Behaviours given this restriction. My problem is best explained with an example (using the slider mentioned above):
val event = mouseB // an event that occurs when the mouse is pressed
val sampler = slider.snapshot(event)
val stepper = Stepper(0, sampler)
My problem here is that if the 'mouseB' Event has occurred when this code is executed then the current value of 'stepper' will be the last 'sample' of 'slider' (the value at the time the last occurrence occurred). If the time of the last occurrence is in the past then we will consequently end up evaluating 'slider' using a past time which breaks the rule set above (and your original assumption). I can see a couple of ways to solve this:
We 'record' the past (keep hold of all past occurrences in an Event) allowing evaluation of Behaviours with past times (using an unbounded amount of memory)
We modify 'snapshot' to take a time argument ("sample after this time") and enforce that that time >= now
In a more wacky move, we could restrict creation of FRP objects to the initial setup of a program somehow and only start processing events/input after this setup is complete
I could also simply not implement 'sample' or remove 'stepper'/'switcher' (but I don't really want to do either of these things). Has anyone any thoughts on this? Have I misunderstood anything here?
Oh I see what you mean now.
Your "you can only sample at 'now'" restriction isn't tight enough, I think. It needs to be a bit stronger to avoid looking into the past. Since you are using an environmental conception of now, I would define the behavior construction functions in terms of it (so long as now cannot advance by the mere execution of definitions, which, per my last answer, would get messy). For example:
Stepper(i,e) is a behavior with the value i in the interval [now,e1] (where e1 is the
time of first occurrence of e after now), and the value of the most recent occurrence of e afterward.
With this semantics, your prediction about the value of stepper that got you into this conundrum is dismantled, and the stepper will now have the value 0. I don't know whether this semantics is desirable to you, but it seems natural enough to me.
From what I can tell, you are worried about a race condition: what happens if an event occurs while the code is executing.
Purely functional code does not like to have to know that it gets executed. Functional techniques are at their finest in the pure setting, such that it does not matter in what order code is executed. A way out of this dilemma is to pretend that every change happened in one sensitive (internal, probably) piece of imperative code; pretend that any functional declarations in the FRP framework happen in 0 time so it is impossible for something to change during their declaration.
Nobody should ever sleep, or really do anything time sensitive, in a section of code that is declaring behaviors and things. Essentially, code that works with FRP objects ought to be pure, then you don't have any problems.
This does not necessarily preclude running it on multiple threads, but to support that you might need to reorganize your internal representations. Welcome to the world of FRP library implementation -- I suspect your internal representation will fluctuate many times during this process. :-)
I'm confused about your confusion. The way I see is that Stepper will "set" the behavior to a new value whenever the event occurs. So, what happens is the following:
The instant in which the event mouseB occurs, the value of the slider behavior will be read (snapshot). This value will be "set" into the behavior stepper.
So, it is true that the Stepper will "remember" values from the past; the point is that it only remembers the latest value from the past, not everything.
Semantically, it is best to model Stepper as a function like luqui proposes.

Inconsistent behavior between local actor and remote actor

This is sort of a follow up to an earlier question at Scala variable binding when used with Actors
Against others' advice, I decided to make a message containing a closure and mutate the variable that closure is closed under between messages.. and explicitly wait for them.
The environment is akka 1.2 on scala 2.9
Consider the following
var minAge = 18
val isAdult = (age: Int) => age >= minAge
println((actor ? answer(19, isAdult)).get)
minAge = 20
println((actor ? answer(19, isAdult)).get)
The message handler for answer essentially applies isAdult to the first parameter (19).
When actor is local, I get the answers I expect.
true
false
But when it is remote, I get
false
false
I am simply curious why this would be the behavior? I would have expected consistent behavior between the two..
Thanks in advance!
Well, you have come across what may (or may not) be considered a problem for a system where the behaviour is specified by rules which are not enforced by the language. The same kind of thing happens in Java. Here:
Client: Data d = rmiServer.getSomeData();
Client: d.mutate()
Do you expect the mutation to happen on the server as well? A fundamental issue with any system which involves remote communication, especially when that communication is transparent to a client, is understanding where that communication is occurring and what, exactly, is going on.
The communication with the actor takes the form of message-passing
An effect can pass a boundary only by the mechanism of message-passing (that is, the effect must reside within the returned value)
The actor library may transparently handle the transmission of a message remotely
If your effect is not a message, it is not happening!
What you encounter here is what I would call “greediness” of Scala closures: they never close “by-value”, presumably because of the uniform access principle. This means that the closure contains an $outer reference which it uses to obtain the value of minAge. You did not give enough context to show what the $outer looks like in your test, hence I cannot be more precise in how it is serialized, from which would follow why it prints what you show.
One word, though: don’t send closures around like that, please. It is not a recipe for happiness, as you acknowledge yourself.

Design pattern import files alters behaviour

I am developing an application where the program can do a number of operations. It relies on a XML file being imported and DB connection established. However, some of the functions can work without an xml file imported, and some can work only if the XML is imported or only if the DB is connected.
So, my question is what design pattern I should use in order to model this ? I read about the state pattern where an object's behaviour changes relative to the current state. Is this a good way of doing it ? For example, I can have several states : XML_FILE_IMPORTED_ONLY, DB_CONNECTED_ONLY, XML_IMPORTRED_AND_DB_CONNECTED, NOTHING_IMPORTED and based on the current state of the object relevant functions will be available ?
Any help will be much appreciated.
Regards,
Petar
You have two state machines, each controlling a portion of your overall state. Each state machine will perform transitions independent of the other.
XML Imported Statemachine
Initial state: Not Imported
Not Imported. transitions: "import happens" -> Imported.
Imported. transitions: "unload" -> Not Imported.
DB Connection Statemachine
Initial State: Not Connected
Not Connected. transitions: "connect succeeded" -> Connected.
Connected. transitions: "disconnect" -> Not Connected.
Edit: State machines are overkill for this problem.
The state machines in question each have two states with one transition in each direction. A much better way to represent this situation would be to use a boolean variable.
boolean dbConnected;
boolean xmlImported;