mysterious behavior of nested understanding by relations

Consider this source code:

[code]Blur is a room.
Loving relates various people to various people. The verb to love means the loving relation.
Liking relates various people to various people. The verb to like means the liking relation.

Understand “who/that loves [something related by loving]” as a person.
Understand “who/that likes [something related by liking]” as a person.
Understand “person” as a person.

Alice is a woman in Blur. Bob is a man in Blur. Charlie is a woman in Blur. Damon is a man in Blur.
Bob loves Alice. Damon loves Bob. Charlie loves Damon. Alice loves Charlie.
Alice likes Bob. Charlie likes Alice. Charlie likes Damon. Bob likes Charlie.
The player is Alice.[/code]

I wouldn’t really expect this to work when you pile relations on top of each other, but it works some of the time:

[quote]

x the person who loves charlie
You can’t see any such thing. [should be me]

x the person who likes charlie
You see nothing special about Bob.

x the person who loves me
You see nothing special about Bob.

x the person who loves damon
You see nothing special about Charlie.

x the person who likes the person who loves damon
Who do you mean, Bob or Charlie? [should just be Bob]

x the person who likes me
You see nothing special about Charlie.

x the person who likes the person who likes me
Who do you mean, Bob or Charlie?

x the person who likes bob
You can’t see any such thing. [should be me]

x the person who loves the person who likes me
You see nothing special about Charlie. [should be me]

x the person who loves the person who loves me
You see nothing special about Damon. [correct]

x the person who likes the person who loves bob
You see nothing special about Charlie. [correct]

[/url]

Anyone have any idea what’s actually happening?

Well, first off, the parser isn’t understanding the player as a person. If you add

Understand "person" as yourself. then your “should be me” problems will clear up.

Weird. Is that a bug? The player is a person (Alice), so it seems to me like “Understand… as a person” should catch the player.

This fixes the “you can’t see any such thing” errors though “x the person who loves the person who likes me” still gives Charlie rather than me.

I believe it’s intentional. Otherwise when you have something very common like “Understand “woman” as a woman” you’d always get a disambiguation prompt unless you remember to specifically exclude the player.

I don’t think either of the above answers are really correct. If you add:

When play begins: now the player is Alice; now yourself is off-stage.

you see different results to the test commands:

[code]>[1] x the person who loves charlie
You see nothing special about yourself.

[2] x the person who likes charlie
You see nothing special about Bob.

[3] x the person who loves me
You see nothing special about Bob.

[4] x the person who loves damon
You see nothing special about Charlie.

[5] x the person who loves damon
You see nothing special about Charlie.

[6] x the person who likes me
You see nothing special about Charlie.

[7] x the person who likes the person who likes me
Who do you mean, Bob or Charlie?

[8] x the person who likes bob
You see nothing special about yourself.

[9] x the person who loves the person who likes me
(Charlie)
You see nothing special about Charlie.

[10] x the person who loves the person who loves me
Who do you mean, Bob or Damon?

[11] x the person who likes the person who loves bob
You can’t see any such thing.[/code]

Also:

>x person Who do you mean, yourself, Bob, Charlie or Damon?

I think maybe the compiler is making some undocumented (if reasonable) assumptions about what you intend as the author when you specify the player as a specific person. It looks like maybe it is interpreting that as a cue to modify the default “yourself” person with some properties (such as description, gender) from the created person (Alice), but not all properties (e.g. name – “showme Alice” in your original code indicates there is no such object). This is a good assumption if there is no intent to change the player during play, as it prevents an extraneous “your former self” (i.e. yourself, the default player) being created and placed in the first room.

With respect to the unexpected disambiguation, my guess is that the parser does not see the second “person” as necessarily indicating the start of a new thing but as a continuation of the first, since there are two independent phrases for understanding a person (plain “person” and the one using the relation). It’s therefore seeing “person who loves the person” much as it would see “red ball red” as referring to a red ball thing. Changing the way it understands with:

Understand "person who/that loves [something related by loving]" as a person. Understand "person who/that likes [something related by liking]" as a person. [Understand "person" as a person.]

may be more to your liking, with these test results:

[code]>[1] x the person who loves charlie
You see nothing special about yourself.

[2] x the person who likes charlie
You see nothing special about Bob.

[3] x the person who loves me
You see nothing special about Bob.

[4] x the person who loves damon
You see nothing special about Charlie.

[5] x the person who loves damon
You see nothing special about Charlie.

[6] x the person who likes me
You see nothing special about Charlie.

[7] x the person who likes the person who likes me
You see nothing special about Bob.

[8] x the person who likes bob
You see nothing special about yourself.

[9] x the person who loves the person who likes me
You see nothing special about yourself.

[10] x the person who loves the person who loves me
You see nothing special about Damon.

[11] x the person who likes the person who loves bob
You see nothing special about Charlie.[/code]

though you lose the ability to have just plain “person” be meaningful the parser.

It is true that the compiler treats the yourself-object as a special case, and does not apply kind synonyms to it. This is a compile-time distinction, so it doesn’t apply to any other object that you assign as the player later.

Interesting, Otis. And if we try this:

It looks like it’s evaluating “person” to be NPCs only for the purposes of disambiguation, so the first two questions only get NPCs who love/like other NPCs.This with Understand “person” as yourself in; Understand “person” as Alice lets “person” refer to Alice.

So I guess “x the person who likes the person who likes me” could be “x (the person) (who likes the person) (who likes me)” (that is, Charlie) or “x (the person) (who likes (the person who likes me))” (that is, Bob). Interesting that it’s catching them both. And “x the person who loves the person who likes me” gives a command clarification prompt for “Charlie” because it could evaluate to either Charlie or Alice and the game is breaking the tie in favor of an NPC, I guess.

I will ponder. The problem with hand-rolling “person” at the beginning is that it gets annoying if you try to introduce more things into the relation (“x the rat that ate the malt that lay in the house that Jack built”) but I don’t actually have a plan for this anyway, it’s just throwing stuff at the wall and seeing how it works.

[edit: Oops. I see you already noticed all this above. Sorry I didn’t see you had made a new reply.]

After actually diagramming out the relationships in your example, I think there may be a bit more nuance. If the understand lines are set out per your original example, I think the parser breaks things up like:

x {the person} {who likes the {person}} {who loves Damon}

where each of the “who likes…” phrases add separate but overlapping logical constraints to which people might be suitable as the noun for the examining action. Because “person” has a standalone meaning of “anything of kind person” (in-scope things of kind person, at least), it seems to be interpret “who likes the person” as “a person who likes anyone else”. Thus Charlie qualifies as a candidate due to liking other people and loving Damon.

There’s some support for this theory in that if you remove the assertions that Charlie likes other people, the parser assumes Bob for “>x the person who likes the person who loves Damon”. Notably, it must also be interpreting the relationships transitively (i.e. {the person who likes {the person who loves Damon}}) in order for Bob to be considered as a candidate at all.

Your nursery rhyme example would be difficult since I think only current relations are accessible when defining grammar tokens. However, if you want to go so far as trying to write your own token routines, you might be able to get it to work.

Oh ha ha, I hadn’t even noticed it was in past tense. Yeah, if I were trying to do that I would just keep it strictly in the game tense–the relations would all be built in but it would be good to have a way of automating it so I didn’t have to write a different understand line for “person who…” “thing that…” “house that…” etc. for every understandable kind and every relation. But it doesn’t seem like there’d be any other nice way to tell Inform to choose the nested parsing rather than the sequential one. It’s OK, as I said I don’t actually have an application for this. (Maybe the thing to do is just have it concern relations among people.)

Writing my own token routines sounds pretty impossible. I think I’d wind up learning Python or something and writing my own parser before trying that; my recent experiences trying to poke the parser (to change disambiguation behavior) have not been very successful.