I7: Bizarre situation involving four cheeses

This is a longish code chunk, for which I apologize. It is essentially a carbon copy of the Four Cheeses example, but with changes made to account for the fact that replacing the scenario throws a compiler error (I suspect conversation tables may have to be supplied for every character).

Anyway, the more serious problem is demonstrated by the following example. For conciseness’ sake, I’ve put it under a rant tag - the example consists of most of the Four Cheeses code, minus “A person has a table name called chatter.” and onward. The small scenario I added demonstrates the error.

[rant][code]“Four Cheeses”

Section 1 - Telephones and Connections

A telephone is a kind of thing. Understand “phone” as a telephone.

Understand “call [any telephone] on [something]” as calling it on. Understand “call [any telephone]” as calling it on. Understand the commands “dial” or “phone” or “telephone” as “call”.

Connection relates one thing to another (called the other party).

The verb to reach (it reaches, they reach, it reached) implies the connection relation.

Calling it on is an action applying to one visible thing and one thing.

Check calling it on:
if the second noun is not a telephone, say “[The second noun] is unlikely to be much use in that respect.” instead;
if the second noun is the noun, say “You get a busy signal.” instead.

Carry out calling it on:
if a person (called the listener) can see the noun, now the player reaches the listener.

[Because we’ve said that connection is a reciprocal, one-to-one relationship, Inform will do the rest of the bookkeeping: if (for instance) we telephone someone else, the first connection will be broken automatically.]

Report calling it on:
say “‘Hello?’ says [the other party of the player].”

[To avoid annoyance, we should also let the player use CALL #### as well as CALL #### ON TELEPHONE. A rule from Chapter 16 comes in handy here:]

Rule for supplying a missing second noun while calling something on:
assign a phone.

To assign a phone:
if the player can touch a telephone (called the current phone):
say “(on [the current phone])[line break]”;
now the second noun is the current phone;
otherwise:
say “You don’t have a phone handy.”

[Things might be a little more complicated if we had cell phones that could be moved around, but for right now the player can only touch a maximum of one phone at a time.]

[Suppose we further want to allow the player to call people up by name, but only if they’ve already been encountered or are familiar to the player for some reason.]

A person can be known or unknown.

Understand “call [any known person] on [something]” as calling it by name on.

Rule for supplying a missing second noun while calling something by name on:
assign a phone.

Calling it by name on is an action applying to one visible thing and one thing.

Check calling it by name on:
if the noun is in the location, say “[The noun] is right here.” instead.

Carry out calling it by name on:
if the noun can touch a telephone (called the link), try calling the link on the second noun;
otherwise say “You can’t reach [the noun].” instead.

Before calling something on something when the player reaches someone:
say “(first ending your conversation with [the other party of the player])[command clarification break]”;
end current conversation.

Understand “hang up [something]” as hanging up.

Hanging up is an action applying to one thing.

Check hanging up:
if the noun is not a telephone, say “You can’t hang up [the noun].” instead;
if the player does not reach someone, say “You’re not on the line with anyone.” instead.

Carry out hanging up:
now the player does not reach anyone.

Report hanging up:
say “You put down [the noun], cutting the connection.”

Before going somewhere when the player reaches someone:
say “(first hanging up on [the other party of the player])[command clarification break]”;
end current conversation.

[And finally we want to make sure that calling random other numbers produces a sensible result:]

Understand “call [text]” as misdialling. Misdialling is an action applying to one topic. Carry out misdialling: say “The phone rings and rings but no one answers.”

Understand “call 911” or “call 999” or “call police” or “call fire department” as a mistake (“After strict warnings, you’ve given up making prank calls to emergency services.”).

Before misdialling when the player reaches someone:
say “(first ending your conversation with [the other party of the player])[command clarification break]”;
end current conversation.

To end current conversation:
let the current phone be a random telephone which can be touched by the player;
silently try hanging up the current phone.

After deciding the scope of the player while the player reaches someone:
place the other party of the player in scope, but not its contents.

[A note about this scope addition: the player can refer to the other party whenever he has the other person on the phone. He can’t, however, see or refer to anything that person might be holding or wearing, thanks to the “but not its contents” option.]

[Furthermore, the player can’t actually do anything to that person that requires touching. That’s because of the reaching inside rules, which govern whether the player can reach through intervening barriers such as rooms. (See the Advanced Actions chapter for more about changing reachability.) There are two things we might want to be careful about, though.]

[First, we should specifically disallow the player from looking at the person on the other end of the line. Since sight doesn’t require touching, the reaching inside rules will not be consulted about a command such as EXAMINE BOSS or LOOK UNDER BOSS. We can, however, intervene in such cases using the visibility rules, which are consulted for any actions that “require light” (including EXAMINE and LOOK UNDER). Here again we borrow some options from the Advanced Actions chapter:]

To decide whether acting through the line:
if the noun is something and the location of the noun is not the location of the player:
yes;
if the second noun is something and the location of the second noun is not the location of the player:
yes;
no.

Visibility rule when acting through the line:
there is insufficient light.

Rule for printing a refusal to act in the dark when acting through the line:
say “You’re not on a video phone, so you can only hear.” instead.

[Second, though the existing reaching inside rules are adequate to stop us from touching the person on the other end of the line, the response that’s currently printed is a bit generic: it just says “You can’t reach into [the room containing the person].” Let’s add our own custom reply, instead:]

A rule for reaching inside a room (called destination):
if the other party of the player is enclosed by the destination:
say “Though you’re on the line with [the other party of the player], you can’t physically reach to [the destination].”;
deny access.

Section 2 - Conversation over the Phone, In General

[This portion supplies a simple method of conversation; but we could substitute some completely different conversation system if appropriate. The effect of the telephones is that we are allowed to talk to characters in distant locations under certain circumstances, after which the usual conversation rules apply.]

Instead of listening to a telephone when the player reaches someone:
say “You can hear [the other party of the player] breathing.”

Before listening to someone when the player cannot touch the noun:
say “[The noun] is waiting for you to carry on the conversation.” instead.

The Oblong Office is a room. The desk is a scenery supporter in the Office. The red phone is a telephone. It is on the desk.

The Line of Fire is a room. General Kilgore is a known man in the line of fire. The black phone is a telephone in the line of fire.

Test me with “Call kilgore”.[/code][/rant]

To me, this looks like a problem with the underlying logic structures. I hope I’m mistaken. Any thoughts and/or thumps to the back of me head?

Well, the problem arises whenever the phone is on the desk; take the phone and it doesn’t arise. I suppose you know that.

Adding this line seems to make it work:

Understand "call [any known person]" as calling it by name on.

And section 16.22 suggests that you need something like that:

But I wonder why it works when the phone isn’t on the desk. That doesn’t seem like it should make a difference, since the phone is touchable; it seems as though the built-in rules for supplying a missing second noun should either interrupt the rules we’ve written whether or not the phone is on the desk, or shouldn’t interrupt them at all.

Without the line Understand "call [any known person]" as calling it by name on. the code Rule for supplying a missing second noun while calling something by name on: assign a phone. isn’t run in either situation (which matches the behavior described in WI 17.30). It’s just that the parser thinks the desk a slightly more likely candidate in the first case, but prefers the phone otherwise.

Also, this should be reported as a bug in the examples.

Thanks EmacsUser! I thought I had checked that “assign a phone” was running in that case (I added something to the disambiguation message it prints), but checking Four Cheeses again, it isn’t. I’ll report it at a bug.

When your code compiles successfully today you get a picture of a little chickie, presumably in honor of Easter weekend. And a compiler error gives you… a broken egg. That’s kind of sad, actually. :frowning:

Oh, and I guess it’s… an Easter egg.