# taxonomy of poetry generators part 2: Lutz’s “Stochastische Texte”

Continuing my attempt to build a taxonomy of poetry generators, I will now look at Lutz’s Stochastiche Texte.

Recall that my approach is to define a General Algorithm, and then see how various poetry generators fit into that algorithm, for comparison. I initially used variables like i, d, and r, which I’m now renaming *initialize*, *editable*, and *replace*.

I talked about Lutz’s algorithm before.

Given:

Logical Operators= {A, AN, EVERY, NO, NOT EVERY}

Subjects= {COUNT, STRANGER, LOOK, CHURCH, CASTLE, PICTURE, EYE, VILLAGE, TOWER, FARMER, WAY, GUEST, DAY, HOUSE, TABLE, LABOURER}

Predicates= {OPEN, SILENT, STRONG, GOOD, NARROW, NEAR, NEW, QUIET, FAR, DEEP, LATE, DARK, FREE, LARGE, OLD, ANGRY}

Logical Constants= {AND, OR, THEREFORE, .}

stochastic select: a method of randomly choosing an element of a set.Print the following:

stochastic select fromLogical Operatorstochastic select fromSubjectthe string "IS" stochastic select fromPredicatestochastic select fromLogical Constantstochastic select fromLogical Operatorstochastic select fromSubjectthe string "IS" stochastic select fromPredicatethe string "."

Figure 2.1: Algorithm for Lutz’s “Stochastic Texts”, adapted from (Lutz, 1959) (transl. Helen MacCormack, 2005).

This is a bit of a simplification in three ways. First, Lutz’s algorithm actually selected from *Subject* first, then selected a *Logical Operator* that coordinated its gender with that of the *Subject*. English does not have gender in this fashion, but it does make a distinction between “A” and “AN” that would need to be tracked in a similar way. Second, Lutz’s algorithm selected from *Logical Constant* differently than it did from the other sets; specifically, it chose a “.” with a probability of 5/8 and the other elements with a 1/8 probability each. Finally, Lutz’s implementation on a ZUSE Z22 did not stop: “The machine continues to work until it is turned off.” The algorithm above describes the generation of a single line, which would be performed repeatedly.

Lutz’s algorithm can be expressed in terms of the General Algorithm in the following way.

Given

Logical Operators,Subjects,Predicates, andLogical Constantsas above,Let

Template Elementsbe a set of strings { logical_operator_slot, subject_slot, IS, predicate_slot, logical_constant_slot, . }Let

Words=Logical Operators∪Subjects∪Predicates∪Logical Constants∪Template ElementsLet the sequence

Poembe a function from {1, 2, …, 10} toWords

So a poem is going to be made up of ten parts, where each part will be one of the *Words*.

Let

initializebe the function fromPoemto the setTemplate Elementsthat defines the following sequence: (logical_operator_slot, subject_slot, IS, predicate_slot, logical_constant_slot, logical_operator_slot, subject_slot, IS, predicate_slot, .)Let

editablebe an indicator function onPoemwhere

I _{editable}(x) ={ 0 if x ∈ {IS, .} 1 for all other x Let

replacebe the following algorithm:Given

stochastic selectas above,Given the set

Wordsand aw∈Poem, replacewwith:casewof logical_operator_slot: stochastic select fromLogical Operatorssubject_slot: stochastic select fromSubjectspredicate_slot: stochastic select fromPredicateslogical_constant_slot: stochastic select fromLogical Constants

So a poem is going to be initialized into a sequence of slot symbols representing a template. Every slot except for the word “IS” and for the period will be editable. During generation, the slots will be replaced by an appropriate subset of *Words*: the first slot symbol will be replaced by a *Logical Operator*, the second by a *Subject*, etc.

Now we may trace through the General Algorithm.

initialize(Poem)

The *initialize* function defines *Poem* as: (logical_operator_slot, subject_slot, IS, predicate_slot, logical_constant_slot, logical_operator_slot, subject_slot, IS, predicate_slot, .).

for each revision for eachtextinPoem

There will only be one revision: replacing the template “slots” with the appropriate texts. The algorithm does this by iterating through the *text* elements of the poem.

ifeditable(text)replace(text)

The *editable* indicator function replaces every slot, and leaves unchanged the two IS elements and the period. The *replace* algorithm changes each slot in the sequence into a word, which it selects from the approriate subset of *Words*.

For example, when the algorithm begins to generate a poem:

- The
*editable*will determine that logical_operator_slot is editable, after which*replace*will determine that it should be replaced by an element of*Logical Operators*, and stochastically select an element of that set, such as “EVERY”. - In the next iteration through the
*Poem*sequence,*editable*will determine that subject_slot is editable, and*replace*will determine that subject_slot should be replaced by an element of*Subjects*, such as “VILLAGE”. - In the next iteration,
*editable*will determine that “IS” is not editable, and leave it unchanged. - In the next iteration,
*editable*will determine that predicate_slot is editable, and*replace*will determine that subject_slot should be replaced by an element of*Predicates*, such as “DARK”.

and so on.

What, you may ask, is the point? Well, ultimately I’ll want to make a table like this to classify poetry generators:

algorithm | initialize | editable | replace | replace parameter |
---|---|---|---|---|

Stochastische Texte | human authored | human authored | stochastic | (human selected) |

100,000,000,000,000 Poems | human authored | all | stochastic | (human authored) |

n+7 | human selected | algorithmic | algorithmic | (human selected) |

Erasures | human selected | all | human selected | none |

Dada | none | all | algorithmic | (human selected) |

Diastics | none | all | algorithmic | (human selected) |

Gnoetry | none | all | interactive algorithmic | (human selected) |

Dissociated Press | none | all | algorithmic | (human selected) |

MCGONAGALL | none | all | algorithmic | (human authored) |

Gaiku | none | all | algorithmic | (human authored) |

Still a lot of details to work out, naturally. I need to split up the replacement algorithms in a better way somehow.

Need to think this over a while.