1. Basics

The automaton object is the core of Awali. An automaton is a labelled directed graph; the vertices of this graph are states, the edges are transitions.

Each transition carries a label and a weight; the types of these labels and weights depend on the context of the automaton. There may exist several transitions with the same ends, but there can not exist distinct transitions with the same ends and the same label.

Initial and final status of states are internally represented by special states and transitions, that can be ignored at first glance. The automaton offers specific method to handle them.

Every state and transition has an identifier that is a nonnegative integer. Every operation on some state or transition must be operated through the automaton. The identifier of a given state never changes, but if a state is removed from the automaton, its identifier can be reused for a fresh state. The same holds for transitions. The identifiers are allocated sequentially by the automaton and they can not be chosen.

The weights on transitions belong to some semiring. No transition can exist with a weight equal to the zero of the semiring; setting the weight of a transition to zero amounts to remove it. Deleting a state causes the deletion of every incoming or outgoing transition.

The automata objects share the same API in the static library, the dynamic library and the python module, even if the syntax is slightly different. We describe here the main methods. To work with a specific library please consult the dedicated description.

2. Statistics

The four first methods are accessible as commands with Cora; they are the only "services" which are directly accessible with Cora; the edit command of Cora allows to visit and modify an automaton.

In the static library, these two last methods return internal iterators on the structure; in the dynamic lybrary and the python module, it returns a list of state (resp. transition) identifiers.

3. State status

The iteration over initial or final states is the same in the dynamic library and in the python module:
In the static library, this iteration is made possible through internal iterators over initial and final transitions:
  • initial_transitions() allows to iterate over initial transitons;
  • final_transitions() allows to iterate over final transitons.
An initial state is the destination of an initial transition that carries the initial weight (as well as the initial label for particular types of automata); likewise a final state is the source of an final transition that carries the final weight (as well as the final label for particular types of automata). These informations can be retrieved with the method handling transitions described below. For weighted automata, the initial or final weight can be set:
  • set_initial(id, w) makes the state initial with weight w; if w is zero, the state is made non-initial;
  • add_initial(id, w) add w to the initial weight; if state id was already initial with weight h, its initial weight is now w+h otherwise it makes it initial with weight w; in case w+h is zero, the state is made non-initial;
  • get_initial_weight(id) returns the initial weight of the state (zero if the state is not initial);
  • set_final(id, w) makes the state final with weight w; if w is zero, the state is made non-final;
  • add_final(id, w) add w to the final weight; if state id was already final with weight h, its final weight is now w+h otherwise it makes it final with weight w; in case w+h is zero, the state is made non-final;
  • get_final_weight(id) returns the final weight of the state (zero if the state is not initial).

4. Transitions

On top of the transitions() method which allows to iterate over all the transitions, there exist several method to iterate transitions adjacent to a given state. In the static Library these methods return internal iterators, while in the dynamic libraryand the python module, they return lists of transition identifiers.
For weighted automata, the weight of transitions can be handled:
  • weight_of(id) returns the weight of the transition.
  • set_transition(src_id, dst_id, label, weight) creates a transition with these ends, label and weight and returns its id; if there was a transition with the same ends and label, it is replaced; it the weight is zero, it deletes any potential transition with the same ends and label.
  • add_transition(src_id, dst_id, label [,weight = unit]) add a transition with these ends, label and weight and returns its id; if there was a transition with the same ends and label and weight h, its weight is incremented by the given weight; if the sum is zero, the transition is deleted;
  • set_weight(id, w) fixes a new weight w for the transition; if w is zero, the transition is deleted;
  • add_weight(id, w) adds w to the weight of the transition; if the sum is zero, the transition is deleted;
  • lmul_weight(id, w) multiply the weight of the transition by w to the left if the product is zero, the transition is deleted;
  • rmul_weight(id, w) multiply the weight of the transition by w to the right if the product is zero, the transition is deleted.

5. History and state names

Each state has a name, which is a string. By default, the name is forged from the identifier and looks like s[n], where [n] is a number; beware that, except in the python module, the identifier of the state named s[n] may be different from [n]. This name can be changed by the user and several states may have the same name. Depending on the way it is created, the automaton may carry some "history"; in this case, the automaton may refer to other automata, and some of its states may also carry some historical information. There are different kinds of history: The history is handled differently in the different libraries.

6. Hidden states and transitions

As written above, initial and final status of states are indeed encoded as transitions. To this end, every automaton contains two hidden states named pre (for pre-initial state) and post (for post-final state). If a state p is initial with weight w, there is a hidden transition from pre to p with weight w; the label of this transition is usually a special label.

These hidden states and transitions are not counted in the return of num_states() and num_transitions(). Likewise, the iterators described above do not iterate over hidden states or hidden transitions. Nevertheless, in some algorithms, it is convenient to consider that the automaton has a unique initial state pre and a unique final state post, and several methods give access to these states and transitions:

  • num_all_states() returns the number of states, including hidden states;
  • all_states() allows to iterate over all states, including hidden states;
  • all_transitions() allows to iterate over all transitions, including hidden transitions;
  • all_out(src) allows to iterate over all transitions outgoing from a state, including hidden transitions;
  • all_in(src) allows to iterate over all transitions incoming to a state, including hidden transitions;