2017 icon indicating copy to clipboard operation
2017 copied to clipboard

Prophet's Paradise

Open dougvalenta opened this issue 6 years ago • 7 comments

Inspired by "The Prophet's Paradise" from The King in Yellow. I'm interested in creating a machine that can output an enigmatic, repetitious prose poem in response to a prompt. At the end I'll compile 50k words of whatever it spits out.

dougvalenta avatar Oct 31 '17 02:10 dougvalenta

When humans craft prose (and especially poetry), they often use repetition to construct meaning. A classic example is the last two lines of Robert Frost's "Stopping By the Woods On a Snowy Evening." In "The Prophets' Paradise," the repetition (which almost always introduces some variation, either a reordering of phrases, dropping, adding, or changing an adjective or adverb, et cetera) is a lot of what adds a ritualistic and mystical quality to the writing.

On the other hand, repetition is a common undesirable artifact of machine-generated work. So for me, I think the central problem I'm trying to address is creating a repetitious machine that doesn't seem mechanically repetitive -- the repetition should seem meaningful, and invite the reader to play off the repeated (and varied) elements to try to construct additional meaning in their mind.

dougvalenta avatar Nov 01 '17 17:11 dougvalenta

Last night I wrote a replacement grammar engine for Java (similar to Tracery), and a little L-System processor. I'm seeing that the biggest impact on this project is going to be developing and tuning good, large grammars and corpora, so I'm trying to build as much tooling around this as early as possible.

The syntax for the replacement grammar is very natural (at least to me). It's basically a properties file (newline-delimited key-value pairs in the form key=value), where the key is a symbol, and the value is the replacement rule. Inside the rule, additional symbols can be inserted by name wrapped in square brackets. Any text or symbols inside parens are optional (50-50 chance of appearing). Segments inside parens divided by bars ("|") will be selected from (even chance for each option). In this sense, parens with no bar is really shorthand for "(optional text|)"

Here's a sample grammar:

root = Hello, [place](, how are you?)
place = (world|NaNoGenMo)

Piggybacking of the Java properties file format gets me proper trimming of leading and trailing whitespace (incl. whitespace around the first equal sign) and comments (demarcated with a "#") for free.

The L-system processor is what I'm planning on using to define the form of my stanzas. It's syntax is much similar, also based on properties file.

+ = ++|++-|+++--
- = +-|++--|+++---

Again, the bars are dividing different potential selections (so this is a stochastic system). It doesn't really have a concept of terminal vs. non-terminal symbols (I don't really need that for my purposes), you just feed it an iteration count. If a symbol in the input doesn't have a rule in the grammar, it just gets copied to the output. So with a properly designed grammar and sufficient iterations, you could end up with all terminal symbols, but the engine won't detect that for you.

dougvalenta avatar Nov 02 '17 16:11 dougvalenta

Things are beginning to come together. I combined together a grammar and an L-system to compose a stanza generator. Right now I have it generating boring little prose poems about nature. Here's an example:

"Ode to a Pond"

O, twisting boughs. Worried reeds tangling wildly. Softly, needles. Worried reeds tangling wildly. O, twisting boughs. Eerily, green boughs bobbing.

The title and each line are generated by a replacement grammar, and the order of the lines and their repetition is generated by an L-system.

The end goal is to produce output like this where when each line repeats it mutates in some way (reorganization of clauses, changing a word, lobbing off a clause, et cetera). This will require retaining some of the structural information about how the line is created, not just the string, so that individual elements can be tweaked.

Yesterday I also wrote an algorithm for selecting from corpora without replacement, and a system for inflecting terms (e.g. for case, tense, number, et cetera). Need to combine that together with a big to-do item which is a reference system (for symbolism, imagery, character, time and place, et cetera).

dougvalenta avatar Nov 03 '17 16:11 dougvalenta

I really like that output! Is that example representative?

On Fri, Nov 3, 2017 at 12:36 PM dougvalenta [email protected] wrote:

Things are beginning to come together. I combined together a grammar and an L-system to compose a stanza generator. Right now I have it generating boring little prose poems about nature. Here's an example:

"Ode to a Pond"

O, twisting boughs. Worried reeds tangling wildly. Softly, needles. Worried reeds tangling wildly. O, twisting boughs. Eerily, green boughs bobbing.

The title and each line are generated by a replacement grammar, and the order of the lines and their repetition is generated by an L-system.

The end goal is to produce output like this where when each line repeats it mutates in some way (reorganization of clauses, changing a word, lobbing off a clause, et cetera). This will require retaining some of the structural information about how the line is created, not just the string, so that individual elements can be tweaked.

Yesterday I also wrote an algorithm for selecting from corpora without replacement, and a system for inflecting terms (e.g. for case, tense, number, et cetera). Need to combine that together with a big to-do item which is a reference system (for symbolism, imagery, character, time and place, et cetera).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/NaNoGenMo/2017/issues/37#issuecomment-341758038, or mute the thread https://github.com/notifications/unsubscribe-auth/AAd6GUNKzqHr28UYGvJ_KKJOMY3fd-L0ks5sy0DzgaJpZM4QMHRB .

enkiv2 avatar Nov 03 '17 16:11 enkiv2

It's a fairly representative example of what I'm outputting right now, but not at all of what my end goal is. (Not sure which you meant.) Here's the grammar I'm working with (syntax explained above):

title = (On |Ode to |The Mysteries of )(Nature|a Pond|Wilderness)
first_line = O, [gerund] [plant_part].
line = ([line_adverb]|[line_adjective])
line_adverb = [adverb], ([adjective] )[plant_part]( [gerund]).
line_adjective = [adjective] [plant_part]( [gerund]( [adverb])).
adjective = (ruffled|salty|rickety|green|fresh|withered|wilted|worried|golden)
plant_part = (reeds|leaves|twigs|boughs|needles|berries|cobs)
gerund = (blowing|twisting|tangling|bobbing|whistling|drooping|breaking)
adverb = (lustily|brightly|wildly|eerily|softly|in the (summer |winter |autumn |spring |)(wind|breeze|water|rain|mist|haze|moonlight|sunlight|shade))

Some of the poems generated by this grammar are a little boring, but this isn't the grammar (or even the full line generation method, just one of the technologies) I'll be using for my final product, so I'm ready to move on.

dougvalenta avatar Nov 03 '17 16:11 dougvalenta

Okay, getting somewhere. Now on each appearance, each repeated line chooses a new "template," which determines phrase order and inclusion and punctuation, but the phrases themselves are retained from appearance to appearance.

Still not where I want to be, but a functioning technique:

"Fall"

Swaying softly in the tattered dusk, pale reeds rustle. And crackling, red reeds snap in the glistening afternoon. Then pale reeds rustle softly, swaying. And crackling, red reeds snap softly. Then in the tattered dusk, pale reeds rustle softly, swaying.

The pattern of lines is ABABA, but each time a line repeats it is rephrased.

dougvalenta avatar Nov 03 '17 18:11 dougvalenta

Took the day off, but was getting some interesting output last night, now aping the symbolist mood of Chambers:

Death stares in the shade. He says, "If it is untrue, then go alone." Beneath the willow, Death laughs, forgotten.

dougvalenta avatar Nov 06 '17 05:11 dougvalenta