Automat
for stateful computation, such as parsing.Sometimes computation has to be stateful, such as in parsing files etc. The aim of the Automat
class is to abstract this away from the user.
# A <- Automat$new()
# a$addTransition(from,input,to,FUN)
# a$setState(state)
# a$setPredicate(state,PFUN)
# a$read(input)
# a$print(long=F)
# a$visualize()
A character object naming the state this transition starts from. Can be NA
to produce a 'from-any'-transition (e.g. for triggering a reset into a special state).
A character object naming the state this transition leads to.
The input triggering the state transition. Can be NA
to create a 'on-any'-transition.
A character object defining a state.
A function taking the current state, the read input and the next state as parameters. The function need not be deterministic and can have side effects.
A predicate function for the given stateThe funtion is invoked on the input before it is further processed. It is intended for more complex transitions conditions (e.g. input string has 3 "x"'s) or converting non-character inputs to character strings.
when TRUE
a detailed description of the state machine is printed, a short summary otherwise (default behaviour)
For new()
A new Automat object, nothing for setState()
. The return value of read()
depends on the function associated with the transition triggered.
An R6Class
generator object.
new()
Create a new instance of an Automat
.
addTransition(from,input,to,FUN)
Add a transition from
a named state upon input
to
named state. While any comparable type would do, these values are restricted to character types by the internal implementation. Use as.character()
if your states are simply numbered. The function FUN
is called upon a successful transition with the previous state, the current state and the original input as argument. It is used for generating side effects or producing output values.
setPredicate(state,PFUN)
Used to set a predicate function PFUN
for a given state. A predicate function is a function called on the input before it is processed. It must return a value of type character but can be used to extend the input domain to arbitrary objects and conveniently implement complex transitions (e.g. depending on prefixes).
setState(state)
Set the Automat
to a certain state (e.g. to the initial state).
read(input)
Tell the Automat
to read/consume the given input
and act upon it.
print(long=F)
Prints a summary of the Automat
. When long
is TRUE
, a full list of states and transitions is returned.
getGraph()
Produces a renderable representation of the state graph of the Automat
using the DiagrammeR
package.
visualize()
Displays the state graph of the Automat
using the DiagrammeR
package.
An Automat
is a finite state machine (or DFA[1]). For usage it is first set up with a set of transitions. Then it is fed with inputs, triggering internal transitions and returning outputs as determined by the current internal state and the input. Each transition can be augmented by a user-supplied function, that can compute return values or trigger side effects. Support for 'from-any' and 'by-any' transitions is also provided. Explicitly set transitions take precedence over these wildcard transitions, with by-any-transitions taking precedence over from-any-transitions. Finally each state can be augmented with a predicate function that transforms the actual input into a new input that is actually used for selecting the proper transition. Each transition can also be annotated with a function that may generate additional outputs or side effects like maintaining stacks or other memory to implement more powerful classes of automata.
Footnotes: [1]https://en.wikipedia.org/wiki/Deterministic_finite_automaton
# NOT RUN {
A <- Automat$new()
f <- function(s,i,t){paste0("You caught ",i,"!")}
g <- function(s,i,t){paste0("You caught the flu!")}
A$addTransition("ready",NA,FUN=f) # add a loop
A$setState("ready")
A$read("Pikachu")
A$read("Bulbasaur")
A$read("Squirtle")
A$addTransition("ready","Pikachu","ready",g) # Pikachu no more
A$read("Pikachu")
A$read("Bulbasaur")
# }
# NOT RUN {
A$visualize()
# }
Run the code above in your browser using DataLab