graph

[Class]
  `graph`

Generates elements by traversing a graph of nodes and returning the element at each node. The transition from one node to the next is accomplished by applying a user-specified selection function to the current node to return the identifier of the subsequent node. Each element in the pattern is specified as a graph node list:

> `(`element {keyword value}+`)`

where element is the value or sub-pattern in the node and is followed by one or more keyword value pairs:

> `:id` {integer | symbol}
>   Identifies the node with a unique name or number in the graph. If omitted the identifier defaults to the element, but since the element may be a sub-pattern or a list it is good practice to always provide explicit ids.
> `:to` {id | pattern}
>   Specifies the transition rule for the graph node. The value may be a node identifier or a pattern of identifiers. This keyword can also be specified as a "right-arrow" ->.

`graph` supports the following slot initializations:

`:of` list
  The list of graph nodes to traverse in the pattern. Each
`:selector` function
  Sets the node selection function of the graph. This function is passed three values, the pattern, the last node selected and the list of ids representing past selections. Defaults to the system's graph traversal function `#'default-graph-node-select`.
`:props` list
  A property list to associate with the graph. This list can be used to cache information for a specified `:selector` function.
`:starting-node-index` integer
  Sets the node at position index in the node list as the initial node for the pattern. The default value is 0, which means that first node in the node list will produce the first value in the pattern.
`:last` `(`{id}*`)`
  Initializes the graph to a specific list of ids representing past node choices. Can be used in conjunction with implementing Markov selection.

See generic pattern initializations for documentation on additional keyword initializations to the pattern.

#### Examples:

Example 1. An Alberti bass figure.

    (define pat1
      (new graph :notes `((c3 :id 1 :to 3)
                          (e  :id 2 :to 3)
                          (g  :id 3
                              :to ,(new cycle :of '(2 1))))))

    (next pat1 12)
    ⇒ (c3 g3 e3 g3 c3 g3 e3 g3 c3 g3 e3 g3)

Example 2. A quasi-Markov chant with periodic breath.

    (define pat1
      (new cycle
           :of `(,(new graph :for (new heap :of '(6 8 12))
                       :of `((c4 :id 1
                                 :to ,(new random :of '(2 5)))
                             (d4 :id 2
                                 :to ,(new random :of '(1 3)))
                             (ef4 :id 3
                                  :to ,(new random :of '(2 4)))
                             (f4 :id 4
                                 :to ,(new random :of '(3 5)))
                             (,(new heap :of '(g4 a4 bf4 c5))
                                 :id 5
                                 :to ,(new cycle :of '(1 2 3 4)))))
                 r)))

    (define (play-pat reps pat rate)
      (process repeat reps
               for k = (next pat)
               unless (rest? k)
               output (new midi :time (now)
                           :keynum k
                           :duration (* rate 1.5))
               wait rate))

    (events (play-pat 80 pat1 .2) "test.mid")
    ⇒ "test.mid"

#### See also:

- Pattern classes [Topic]