Package tulip :: Package transys :: Module machines :: Class Transducer
[frames] | no frames]

Class Transducer


Sequential Transducer, i.e., a letter-to-letter function.

Inputs

P = {p1, p2,...} is the set of input ports. An input port p takes values in a set Vp. Set Vp is called the "type" of input port p. A "valuation" is an assignment of values to the input ports in P.

We call "inputs" the set of pairs:

 {(p_i, Vp_i),...}

of input ports p_i and their corresponding types Vp_i.

A guard is a predicate (bool-valued) used as sub-label for a transition. A guard is defined by a set and evaluated using set membership. So given an input port value p=x, then if:

 x \in guard_set

then the guard is True, otherwise it is False.

The "inputs" are defined by an OrderedDict:

 {'p1':explicit, 'p2':check, 'p3':None, ...}

where:

Guards annotate transitions:

 Guards: States x States ---> Input_Predicates

Outputs

Similarly defined to inputs, but:

State Variables

Similarly defined to inputs, they annotate states, for both Mealy and Moore machines:

 States ---> State_Variables

Update Function

The transition relation:

Note

A transducer may operate on either finite or infinite words, i.e., it is not equipped with interpretation semantics on the words, so it does not "care" about word length. It continues as long as its input is fed with letters.

For Machines, each state label consists of (possibly multiple) sublabels, each of which is either a variable, or, only for Moore machines, may be an output.

See Also

FSM, MealyMachine, MooreMachine

Instance Methods
 
__init__(self)
Initialize the types of labelings on states and edges.
 
add_inputs(self, new_inputs, masks=None)
Create new inputs.
 
add_state_vars(self, new_state_vars)

Inherited from labeled_graphs.LabeledDiGraph: add_edge, add_edges_from, add_node, add_nodes_from, dot_str, has_deadends, is_consistent, plot, remove_deadends, remove_labeled_edge, remove_labeled_edges_from, save

Inherited from networkx.classes.multidigraph.MultiDiGraph: degree_iter, edges_iter, in_degree_iter, in_edges, in_edges_iter, is_directed, is_multigraph, out_degree_iter, out_edges, out_edges_iter, remove_edge, reverse, subgraph, to_directed, to_undirected

Inherited from networkx.classes.multigraph.MultiGraph: edges, get_edge_data, has_edge, number_of_edges, remove_edges_from, selfloop_edges

Inherited from networkx.classes.digraph.DiGraph: clear, has_predecessor, has_successor, in_degree, neighbors, neighbors_iter, out_degree, predecessors, predecessors_iter, remove_node, remove_nodes_from, successors, successors_iter

Inherited from networkx.classes.graph.Graph: __contains__, __getitem__, __iter__, __len__, __str__, add_cycle, add_path, add_star, add_weighted_edges_from, adjacency_iter, adjacency_list, copy, degree, has_node, nbunch_iter, nodes, nodes_iter, nodes_with_selfloops, number_of_nodes, number_of_selfloops, order, size

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __subclasshook__

Properties

Inherited from networkx.classes.graph.Graph: name

Inherited from object: __class__

Method Details

__init__(self)
(Constructor)

 

Initialize the types of labelings on states and edges.

Label types by example

Use a dict for each label type you want to define, like this:

>>> types = [
        {'name': 'drink',
         'values': {'tea', 'coffee'},
         'setter': True,
         'default': 'tea'},
    ]

This will create a label type named 'drink' that can take the values 'tea' and 'coffee'.

Assuming this label type applies to nodes, you can now label a new node as:

>>> g = LabeledDiGraph(types)
>>> g.add_node(1, drink='coffee')

If you omit the label when adding a new node, it gets the default value:

>>> g.add_node(2)
>>> g.node[2]
{'drink': 'tea'}

The main difference with vanilla networkx is that the dict above includes type checking:

>>> type(g.node[2])
tulip.transys.mathset.TypedDict

The 'setter' key with value True creates also a field g.drink. Be careful to avoid name conflicts with existing networkx MultiDiGraph attributes.

This allows us to add more values after creating the graph:

>>> g.drink
{'coffee', 'tea'}
>>> g.drink.add('water')
{'coffee', 'tea', 'water'}

Finally, the graph will prevent us from accidentally using an untyped label name, by raising an AttributeError:

>>> g.add_node(3, day='Jan')
AttributeError: ...

To add untyped labels, do so explicitly:

>>> g.add_node(3, day='Jan', check=False)
>>> g.node[3]
{'day': 'Jan', 'drink': 'tea'}

Details on label types

Each label type is defined by a dict that must have the keys 'name' and 'values':

  • 'name': with str value
  • 'values' : B implements __contains__ used to check label validity.

    If you want the codomain B to be extensible even after initialization, it must implement method add.

and optionally the keys:

  • 'setter': C with 3 possibilities:
    • if absent, then no setter attribute is created
    • otherwise an attribute self.A is created, pointing at:
      • the given co-domain B if C is True
      • C, otherwise.
  • 'default': d is a value in B to be returned for node and edge labels not yet explicitly specified by the user.
Parameters:
  • node_label_types - applies to nodes, as described above.
  • edge_label_types - applies to edges, as described above.
  • deterministic - if True, then edge-label-deterministic
Overrides: object.__init__
(inherited documentation)

add_inputs(self, new_inputs, masks=None)

 

Create new inputs.

Parameters:
  • new_inputs (dict) - dict of pairs {port_name : port_type} where:
    • port_name: str
    • port_type: Iterable | check class
  • masks (dict of functions {port_name : mask_function} each mask_function returns bool) - custom mask functions, for each sublabel based on its current value each such function returns:
    • True, if the sublabel should be shown
    • False, otherwise (to hide it)