Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional State Transitions? #72

Closed
colemand77 opened this issue Jul 13, 2017 · 6 comments
Closed

Conditional State Transitions? #72

colemand77 opened this issue Jul 13, 2017 · 6 comments

Comments

@colemand77
Copy link

Fully recognize this question may reflect bad practice or might just run counter to the opinion of the framework (which is great!), but do you have any plan to implement conditional state transitions?

Borrowing from your example, if the coffee maker needs, say, '5 beans' in order to brew coffee, is there any way (within the framework) to check that condition is satisfied, or would something like the following be the 'automatic' way to implement that? (pythonic -> automat-ic? get it?)

def put_in_some_beans(self, beans):
    self._bean_counter += beans.count
    if self._bean_counter >= 5:
        self._put_in_enough_beans(beans)
    else:
        self._put_in_not_enough_beans(beans)

@_machine.input()
def _put_in_enough_beans(self, beans):
    "There are enough beans in the hopper"

@_machine.input()
def _put_in_not_enough_beans(beans):
    "There aren't enough beans"

@_machine.output()
def bean_error(self, beans):
   return f'Missing {5-self._bean_counter} beans'

dont_have_beans.upon(_put_in_enough_beans, enter=have_beans, outputs=[])
dont_have_beans.upon(_put_in_not_enough_beans, enter=dont_have_beans, outputs=[bean_error])

I don't have any ideas or thoughts about how an alternative method would be implemented, or whether it even belongs. The reason I'm asking is that I see what could end up being a lot of state-checking and perhaps a lot of branching logic outside of the automat framework -> and maybe thats ok? Just making sure I'm not missing something.

As an aside: I'm working through this document: and trying to learn automat by implementing the examples; which is helpful in terms of thinking about setting up more complicated machines from primitives (cascading, parallel, etc), but their implementation philosophy is so different... if I can grok it, it might make for some helpful documentation additions.

@colemand77 colemand77 changed the title Conditional State Changes? Conditional State Transitions? Jul 13, 2017
@glyph
Copy link
Owner

glyph commented Jul 15, 2017

Thanks @colemand77, that is a great reference document for us to look at!

@glyph
Copy link
Owner

glyph commented Jul 15, 2017

do you have any plan to implement conditional state transitions?

In a word: no. Conditional transitions would compromise the purity of the machine, and make it more difficult to reason about what it takes to reach a particular state, which would obviate much of the usefulness of being able to diagram the machine automatically et cetera. But, obviously we need some way to handle the case that you've brought up. This is, in my mind, yet another use-case for #41 .

@glyph
Copy link
Owner

glyph commented Jul 15, 2017

The way to implement this within the scope of Automat's design would be for the put_in_bean input to generate a count_beans output, which would += the counter, and then, conditionally, potentially itself produce an _enough_beans input, using the feedback mechanism described in #41 . I am using the "private method" notation here because while _enough_beans is an input to the state machine, it is an input only generated by this output, not something that external users of the state machine should be supplying.

Does this make sense to you as a solution?

@colemand77
Copy link
Author

Yep, totally. The "no inputs in the outputs=[]" field is a logical constraint I keep bumping my head on. Looks like this is something that (may) get some work in the future, so I'll work around it and keep my eyes peeled.
If I can get something worked out from your use-case in twisted, I'll submit it, but pretty sure out of my depth.
Great job on the show by the way.

@lucaswiman
Copy link

Another use case for this kind of logic is a retry loop, where you want to retry something up to N times until you get a success. It is possible to represent both of these use cases as a state machine, but you need N copies of each of the states involved in processing a submission. This is similar to the (foo){1,50} syntax in regular expressions, where the state machine needed to recognize "between one and fifty copies of 'foo'" is much larger than the state machine for just foo. I don't know a good syntax for duplicating states and transitions, but that would be another way of addressing this fairly common use case that still gives the ability to diagram the output.

@glyph
Copy link
Owner

glyph commented Aug 19, 2024

The way to implement this sort of transition is now explicitly covered in the tutorial, under this exact heading: https://automat.readthedocs.io/en/latest/tutorial.html#conditional-state-transitions

Hope that this fixes the problem, sorry you had to wait 7 years :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants