some error messages involving indexed text

I’m trying to write a rule to go through the player’s command word by word, comparing each word to some indexed texts, but I’m getting some error messages that confuse me – because they don’t really seem like they should be errors. Can someone explain what I’ve done wrong? My head is sort of spinning right now (you’ll be able to see why from my extraordinarily inelegant code), so any help would be appreciated.

Here are the messages:

(But if the uniquely matched block is a variable that holds a block, shouldn’t that work?)

(Again, what am I supposed to be passing to the phrase?)

(Number 1 is the one I want, but why don’t the instructions to work out indexed texts work there?)

I have a phrase beginning “To decide what indexed text is the apparent name of (cube - a block):” – is it that I shouldn’t use “To decide what indexed text is” phrases?

I’m hoping that the error messages themselves will give someone smarter an idea of what’s going on, but the whole convoluted code is below:

[spoiler][code]Use American dialect and the serial comma.

Section - Colors

[This is a bunch of stuff to make the color of a block vary dynamically depending on its real color and the color of the player’s glasses.]

A color is a kind of value. The colors are red, blue, and yellow.

A block is a kind of thing. A block has a color. A block has an indexed text called the known name. Understand “block” as a block.

Resetting the blocks is an activity.
For resetting the blocks:
repeat with cube running through blocks:
now the known name of the cube is the apparent name of the cube.

For printing the name of a block: say the known name of the item described.

When play begins:
carry out the resetting the blocks activity.

The player wears some glasses. The glasses have a color. The description of the glasses is “The glasses are currently colored [color of the glasses]. Push the button to change the color.” Understand “button” as the glasses.

Carry out pushing the glasses:
now the color of the glasses is the color after the color of the glasses;
carry out the resetting the blocks activity.
Report pushing the glasses:
say “The glasses are now colored [color of the glasses].”;
rule succeeds.

To decide what indexed text is the apparent name of (cube - a block):
if the player does not wear the glasses:
decide on “a [color of the cube] block”;
otherwise:
if the color of the glasses is red:
if the color of the cube is:
– red: decide on “a red block”;
– blue: decide on “a purple block”;
– yellow: decide on “an orange block”;
otherwise if the color of the glasses is blue:
if the color of the cube is:
– red: decide on “a purple block”;
– blue: decide on “a blue block”;
– yellow: decide on “a green block”;
otherwise: [the color of the glasses is yellow]
if the color of the cube is:
– red: decide on “an orange block”;
– blue: decide on “a green block”;
– yellow: decide on “a yellow block”.

Section - Replacing The Command With The Apparent Name

The uniquely matched block is a block that varies. [Just trying to see if this helps with the compiler error – it doesn’t.]

After reading a command:
let the hand-parsed command be indexed text;
now the hand-parsed command is the player’s command;
let the block matching list be a list of blocks;
let the first currently matched word number be a number; [we’re going to look for strings of words that all match a single block’s name]
repeat with n running from 1 to the number of punctuated words in the hand-parsed command: [punctuated words so we don’t get mixed up by commas and periods. Don’t use “yellow-green” as a color name.]
now the uniquely matched block is entry 1 in the block matching list;
if the number of entries in the block matching list is one:
if the apparent name of uniquely matched block does not match the text “[punctuated word number n in the hand-parsed command]”:
repeat with k running from the first currently matched word number to n minus one: [it’s the end of a string of words all matching one block, so replace it with its True Name, which I think had better be one word for this not to get fubar]
replace unpunctuated word number k in the hand-parsed command with “[the uniquely matched block]”;
now the block matching list is {}; [reset the list, but we have to see if this starts a new string]
repeat with tested block running through visible blocks:
if unpunctuated word number n in the hand-parsed command matches the text “[the apparent name of the tested block]”:
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
if the number of entries in the block matching list is greater than one: [and thus has more than one entry]
repeat with tested block running through the block matching list:
if the apparent name of the tested block does not match the unpunctuated word number n in the hand-parsed command:
remove the tested block from the block matching list;
if the block matching list is empty: [uh-oh! that string of words is ambiguous]
repeat with k running from the first currently matched word number to n minus one:
replace unpunctuated word number k in the hand-parsed command with “block”; [replace everything in the string with “block”, which will be ambiguous]
now the block matching list is {}; [reset the list, but we have to see if this starts a new string]
repeat with tested block running through visible blocks:
if the apparent name of the tested block in the hand-parsed command matches the text the unpunctuated word number n in the hand-parsed command:
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
if the block matching list is empty: [we need to start a new string]
repeat with tested block running through visible blocks:
if the apparent name of the tested block matches the text “[unpunctuated word number n in the hand-parsed command]”:
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
say “Parsed command: [hand-parsed command].”; [debugging]
change the text of the player’s command to the hand-parsed command.

Section - Scenario

The Playroom is a room. Block1 is a red block in The Playroom. Block2 is a blue block in The Playroom. Block3 is a yellow block in The Playroom.
[/code][/spoiler]

You have a couple of problems here

The big one is that you’re trying to invoke a test “if (txb - indexed text) does not match the text (ftxb - indexed text)”. There is no such phrase defined in the standard rules; it only exists in the positive sense. You could define a negative one, or else say

unless the apparent name of uniquely matched block matches the text “[punctuated word number n in the hand-parsed command]”:

You need to fix this in three places. Then, the second occurence is missing the words “the text”. The third occurrence has an extra “in the hand-parsed command” in there.

When I fix all that, the code compiles. I’m not going to risk testing it. :slight_smile:

Thanks! Should’ve caught those, though the error message wasn’t helping. The extra “hand-parsed command” came from a cut-and-paste error, because in the original version of my code I forgot which way around indexed text matching goes.

…and running my now compiling code, it seems I have forgotten to write the part that changes the text when you hit the end of the command. Oops. And when I fix it, “x red” causes the compiler to hang, though “x block” doesn’t. Better sleep on it, and probably burn it in the morning.

UPDATE: Ah, I’m pretty sure that the problem is that I’m trying to edit a list while repeating through it, which is a big no-no.

I’ve been working on something similar, but without using indexed text. I like your term “the apparent name” - I have a hard time coming up with names for snippets, but I think that’s a good one.

Have a look at Disambiguation Override. It’s a work in progress but it might get you where you want to be. And if you have any suggestions of uses, features, or fixes (or a new name) for it, please let me know.

eyeballsun.org//i/Disambigua … erride.i7x

What it does: instead of using indexed text, it requires you to use a topic in the form of “[any (adjective) (kind)].” But then it gives you access to the match list so you can choose a single object or a group of objects that matched the topic.

What I’d like to add: I7 awareness of what object is being parsed now (the person asked, the noun, the second noun, etc), and maybe awareness of what has already been parsed and information about the operative grammar line. So we could do something like this:

Does the player mean doing something with a container when the apparent name of the noun includes "box":

Thanks capmikee. I’ll take a look at that (though I still don’t understand the I6) – the way I’ve got my code right now just completely punts on disambiguation, by replacing every matching word with “block” if there’s more than one block that matches. So the idea of taking the match list and doing stuff with it appeals to me. I might be able to do that by turning the block matching list from a local variable to a global. Even if I can’t drop Disambiguation Override in, I might be able to cannibalize some ideas.

FWIW, here’s the current stage of the code, which is surprisingly not only not crashing but doing most of what I want at the moment. (The biggest failure I know about, aside from the wonky handling of articles, is that if you type “take red. press button. drop purple” it doesn’t work, because it processes all the apparent names before doing any of the actions. I think the only way around that is to do something to interrupt the chained commands if the player does anything that changes a bunch of apparent names, assuming that’s desired behavior.)

[spoiler][code]“dynamic block parsing” by Matt Weiner

Use American dialect and the serial comma.

Section - Matching Wordwise

To decide whether (string1 - indexed text) matches wordwise (string2 - indexed text):
if string1 matches the regular expression “\b[string2]\b”, decide yes;
decide no.

Section - Colors

[This is a bunch of stuff to make the color of a block vary dynamically depending on its real color and the color of the player’s glasses.]

A color is a kind of value. The colors are red, blue, and yellow.

A block is a kind of thing. A block has a color. Understand “block” as a block. Understand “blocks” as the plural of a block.

For printing the name of a block: say the apparent name of the item described.

The player wears some glasses. The glasses have a color. The description of the glasses is “The glasses are currently colored [color of the glasses]. Push the button to change the color.” Understand “button” as the glasses.

Carry out pushing the glasses:
now the color of the glasses is the color after the color of the glasses.
Report pushing the glasses:
say “The glasses are now colored [color of the glasses].”;
rule succeeds.

To decide what indexed text is the apparent name of (cube - a block):
if the player does not wear the glasses:
decide on “[color of the cube] block”;
otherwise:
if the color of the glasses is red:
if the color of the cube is:
– red: decide on “red block”;
– blue: decide on “purple block”;
– yellow: decide on “orange block”;
otherwise if the color of the glasses is blue:
if the color of the cube is:
– red: decide on “purple block”;
– blue: decide on “blue block”;
– yellow: decide on “green block”;
otherwise: [the color of the glasses is yellow]
if the color of the cube is:
– red: decide on “orange block”;
– blue: decide on “green block”;
– yellow: decide on “yellow block”.

Section - Replacing The Command With The Apparent Name

After reading a command:
let the hand-parsed command be indexed text;
now the hand-parsed command is the player’s command;
let the block matching list be a list of blocks;
now the block matching list is {};
let the first currently matched word number be a number; [we’re going to look for strings of words that all match a single block’s name]
repeat with n running from 1 to the number of punctuated words in the hand-parsed command: [punctuated words so we don’t get mixed up by commas and periods. Don’t use “yellow-green” as a color name.]
say “Checking word [n].”;
if the number of entries in the block matching list is one:
let the uniquely matched block be an object;
now the uniquely matched block is entry 1 in the block matching list;
unless the apparent name of uniquely matched block matches wordwise “[punctuated word number n in the hand-parsed command]”:
repeat with k running from the first currently matched word number to n minus one: [it’s the end of a string of words all matching one block, so replace it with its True Name, which I think had better be one word for this not to get fubar]
replace punctuated word number k in the hand-parsed command with “[printed name of the uniquely matched block]”;
now the block matching list is {}; [reset the list, but we have to see if this starts a new string]
repeat with tested block running through visible blocks:
if “[the apparent name of the tested block]” matches wordwise punctuated word number n in the hand-parsed command:
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
if the number of entries in the block matching list is greater than one: [and thus has more than one entry]
let the temporary block matching list be a list of blocks;
now the temporary block matching list is the block matching list; [store the block matching list in a temporary list so we can remove blocks from the temporary list while iterating through the original list]
repeat with tested block running through the block matching list:
unless the apparent name of the tested block matches wordwise the punctuated word number n in the hand-parsed command:
remove the tested block from the temporary block matching list;
now the block matching list is the temporary block matching list;
if the block matching list is empty: [uh-oh! that string of words is ambiguous]
repeat with k running from the first currently matched word number to n minus one:
replace punctuated word number k in the hand-parsed command with “block”; [replace everything in the string with “block”, which will be ambiguous]
now the block matching list is {}; [reset the list, but we have to see if this starts a new string]
repeat with tested block running through visible blocks:
if the apparent name of the tested block matches wordwise the punctuated word number n in the hand-parsed command:
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
if the block matching list is empty: [we need to start a new string]
repeat with tested block running through visible blocks:
say “Testing [tested block] against ‘[punctuated word number n in the hand-parsed command]’.”;
if the apparent name of the tested block matches wordwise “[punctuated word number n in the hand-parsed command]”:
say “Match!”;
add the tested block to the block matching list;
now the first currently matched word number is n; [since we’ve started a new string]
say “Starting to look at [first currently matched word number].”;
[and now we resolve everything at the end of the command]
if the number of entries in the block matching list is one:
let the uniquely matched block be an object;
now the uniquely matched block is entry 1 in the block matching list;
repeat with k running from the first currently matched word number to the number of punctuated words in the player’s command: [it has to be the player’s command, not the hand-parsed command, since we’re changing the hadn-parsed command as we go. This seems to cause an infinite loop even though we’re just replacing single words with single words, as long as the printed names of the blocks are one word. Probably to be really safe I should copy the hand-parsed command to a temporary text and change that, though if there were multiple word names this would get messed up anyway]
replace punctuated word number k in the hand-parsed command with “[printed name of the uniquely matched block]”;
otherwise if the number of entries in the block matching list is greater than one:
repeat with k running from the first currently matched word number to the number of punctuated words in the hand-parsed command:
replace punctuated word number k in the hand-parsed command with “block”;
say “Parsed command: [hand-parsed command]. First matched word number: [first currently matched word number].”; [debugging]
change the text of the player’s command to the hand-parsed command.

Section - Scenario

The Playroom is a room. Block1 is a red block in The Playroom. Block2 is a blue block in The Playroom. Block3 is a yellow block in The Playroom.

Weight is a kind of value. The weights are heavy and light.
A block has a weight. Block1 is heavy. Block2 is light. Block3 is heavy. Understand the weight property as describing a block. Before printing the name of the block: say "[weight of the item described] ".

Alice is a woman in The Playroom. Persuasion rule: Rule succeeds.[/code][/spoiler]