Reciprocal Relationships

So the rules specifically state that a completely reciprocal relationship must be between two of the same kind of thing (marriage relates one person to another) and never between two things of different kinds (marriage relates one man to one woman). But…why? Or rather, what do I do if I need a proper reciprocal relationship between two things?

My situation is some containers with displays that control them, and I have various functions that need to be performed, such as:

[code]Instead of consulting a display about “[open pod]”:
try opening the pod controlled by the noun.

Instead of examining a display:
if the pod controlled by the noun is open:
say “POD OPEN”;
otherwise if the pod is occupied:

Instead of examining a pod:
say “Beside the pod is a [color of the controller of the noun] display.”[/code]

And so on. But I’m constantly tripped up by Inform not knowing which pod I’m referring to, despite the fact that there can only ever be one. How can I make this work?

Is this in the newer build? Because for example this works,

Contacting relates various men to various women. 

The verb to contact (it contacts, they contact, it contacted, it is contacting) implies the contacting relation. 

I’m probably not understanding the problem.

I need to connect exactly one pod to exactly one display. Otherwise when I say “if the pod is open…” etc, Inform won’t be able to parse it because it won’t know which pod.

Can you try “a random pod controlled by the noun,” etc.? If there’s always one and only one, that will get you the one and only one. You’ll have to make sure that there is always one and only one by hand, though. (In your example it seems like you might not need to change the controller in the course of play, so that wouldn’t be such a problem.)

Actually I’m encountering a rather more fundamental problem than that:

[code]Status is a kind of value. The statuses are normal, abnormal, and failed.

A pod is a kind of container. A pod is usually enterable, openable, fixed in place, and closed. A pod is either active or inactive. A pod is either occupied or unoccupied.“Opposite the door is a cryo pod. Beside it is a [if the status of the controller of the noun is normal]green[otherwise if the status of the controller of the noun is abnormal]yellow[otherwise]red[end if] display.”

A display is a kind of thing. A display is always fixed in place. A display has a status. The description is usually “BEGIN CRYO[line break]OPEN POD[paragraph break]”

Controlling relates one display (called the controller) to one pod. The verb to control (he controls, they control, he controlled) implies the controlling relation.
The verb to be controlled by implies the reversed controlling relation.

The cryo room is a room.

In the cryo room is Pod 1. Pod 1 is a pod. Display 1 is part of Pod 1. Display 1 is a display. Display 1 controls Pod 1. The status of Display 1 is normal.[/code]

This gives the run-time error “Attempt to use a property of the ‘nothing’ non-object.” Why is it having trouble with the status if-statement? (It works if I change “the status of the controller of the noun” to “the status of Display 1.”)

(Before anyone suggests it, I have eight pods, so I’d rather not brute force it by coding each one individually.)

The error is displayed because you’re using the word “noun”, but the text is displayed in response to the looking action which has no noun (the noun is nothing). If you use “item described” instead it should work.

That’s a very good question, Katz. Ask it on the suggestions forum, perhaps?

As I understand it, this would violate the type assumptions that Inform relies on. Currently, if you say something like “The bone is in the box”, the containment relationship gives Inform enough information to know that the box must be a container, and the bone can be any kind of thing.

If you have a reciprocal relationship that can relate two different kinds of things, Inform doesn’t know on the basis of relationship statements what kinds to assign to the participants, and it can’t use that information to check the validity of syntax. In your example, “Pat is married to Chris” is fine as long as Inform can assign both Pat and Chris the kind of “person”; as soon as it has to make one male and one female, it runs into trouble.

(I think I’m philosophically untroubled by this, myself: there’s an argument to be made that a relationship cannot be meaningfully reciprocal unless the participants are fundamentally viewed as the same kind of thing.)

I agree with Emily; it’s to make all the sentence verbs unambiguous. You can define a verb for the relation and another verb for the reversed relation, which you’ve done, and that allows you to do what you want. I’m pretty sure.

It’s not a matter of reciprocity so much as exclusivity. The relationship doesn’t have to be the same in each direction; it just has to be between precisely two objects. I’m turning out some astoundingly ugly code to compensate for the fact that when I say “the pod controlled by Display 1”, the game doesn’t know which pod I’m talking about.

(Although, philosophically, I can think of plenty of things that seem to have an identical relationship but could be classed as different types–matched shoes, for instance.)

Just “a random pod controlled by Display 1” should work. (Does when I test the sample code.) “A random” tells Inform to pick any it has available; you as the author know there can only be one.

There’s a suggestion on the books that we allow just “the pod controlled…” in this kind of situation ( … ?ref=title), but this hasn’t been implemented yet and is not completely trivial.

You can also phrase it as:

if a pod (called P) is controlled by Display 1: [do something with P]

Again, you as the author know that there is such a pod, so the test is logically irrelevant. It just reassures the compiler.

…however, I can see why this is confusing. A one-to-one relation isn’t completely symmetrical, and I don’t see why it couldn’t be. For example you can say

Foo relates one person (called owner) to one vehicle.

But not

Foo relates one person (called owner) to one vehicle (called ride).

It should be equally sensible to talk about “the car’s owner” as “Steve’s ride”.

There’s also an efficiency difference, under the covers. “if somebody foos the car” compiles to a direct lookup test, but “if somebody reverse-foos Steve” compiles to a loop over all people. This gives the correct result, but it trades off speed for property storage, and that’s likely to be a bad choice (especially on Glulx).

I was thinking about this problem this morning. It’s not overly complicated to implement such a relationship using plain old properties:

[code]The Control Room is a room.

A pod is a kind of thing.
A display is a kind of thing.

A pod has a display called the controller.
To decide which pod is the pod controlled by (D - a display):
Repeat with P running through pods:
if D is the controller of P, decide on P;

The green display is a display in the control room.
The blue display is a display in the control room.

The green pod is a pod in the control room. The controller of it is the green display.
The blue pod is a pod in the control room. The controller of it is the blue display.

Instead of examining a display:
say “The [noun] controls [the pod controlled by the noun].”;

Instead of examining a pod:
say “The [noun] is controlled by [the controller of the noun].”;[/code]
If you wanted to boost efficiency, you could do some caching:

[code]A display has a pod called the target.

When play begins:
Repeat with P running through pods:
Now the target of the controller of P is P.[/code]
If you ever wanted to change the “relation,” you’d have to update the cached value, of course.

To decide which pod is the pod controlled by (D - a display): Repeat with P running through pods: if D is the controller of P, decide on P;

While I was writing this, I wondered: Is there a way to write this loop as a description? Something like:

a random pod which has a controller of D

That doesn’t work, and replacing “of” with “equal to” didn’t work either - is there a verb that implies the property “relation”?

A relationship is cached properties, under the hood. We’ve always been able to code that way. But the point of relations is to do the same job more succinctly.

No, but you can invent one by means of a conditional relation.

Contact relates a pod (called P) to a display (called D) when the controller of P is D. The verb to be joined to implies the contact relation.

Then “a random pod joined to the …” will work.