How do I check whether a person is in the presence of another object?

I’m completely stuck. I want to check if one thing is in the presence of another. Something like so:

Every turn:
	if a person is in the presence of the scalpel:
		say "Hello."

I understand in the presence of is the test to determine if another item is present but I get a compiler error:

Problem. In the sentence 'if a person is in the presence of the scalpel'  , I was expecting to read a condition, but instead found some text that I couldn't understand - 'a person is in the presence of the scalpel'.
I was trying to match this phrase:

 if (a person is in the presence of the scalpel - a condition): 
But I didn't recognise 'a person is in the presence of the scalpel'.

What is the correct way to do this?

Perhaps “if a person is in the location of the scalpel” or “if a person (called surgeon) can touch the scalpel” ?

Untested guesses. I think “in the presence of” only applies to actions performed by characters and not basic object proximity.

This is a sorta-confusing bit of Inform – I believe “in the presence of” is used when you’re talking about an action, like you can use it to construct rules of the form “before jumping in the presence of the scalpel.” But for conditionals in your example, where no action is involved and you’re just testing the state of the world, you want to use “the location of”, like “if the location of Fred is the location of the scalpel” (note that Inform also doesn’t like it when you try to do a logical test on something as nonspecific as “a person”, so if you want the rule to apply to every character in the game, you might need to do a “with X running through…” kind of thing).

The documentation on “the location of” is here; you might also be interested in the “enclosed by” relation discussed lower down on that page. There’s also a lot of really good, but fairly advanced, discussion in this thread that might be useful about the subtleties of containers, supporters, and so on that might wind up being relevant to what you’re trying to do.

1 Like

These both work. Annoyingly, I wrote the example below before checking yours, and used “if the location of the scalpel encloses a person”. I’ve changed it now to your first example as that reads much better. No doubt there is room for further improvement!

"Scalpel" by Jonathan

The Operating Theatre is a room. "A corridor is to the west."

The surgeon is a person in the Operating Theatre.

A chair is an enterable container in the Operating Theatre.

A scalpel is in the Operating Theatre.

The Corridor is west of the Operating Theatre.

Every turn:
	if a person is in the location of the scalpel:
		say "The scalpel is located with [the list of people enclosed by the location of the scalpel].";
	otherwise:
		say "The scalpel has been left unattended."
		
Instead of jumping:
	if the surgeon is in the Operating Theatre:
		now the surgeon is in the Corridor;
	otherwise:
		now the surgeon is in the Operating Theatre;
	say "The surgeon moves to the [location of the surgeon].";
		

What does’t work is “if the location of the scalpel contains a person” – as if you sit on the chair you don’t count as being contained by the location (you’re enclosed by it, but contained by the chair).

1 Like

‘In the presence of’ is subtly different from simply being enclosed by the same location as, since it also takes account of concealment (see WI 7.12 and Example 99: Today Tomorrow). So to fully replicate it, perhaps:

if a person is enclosed by the location of the scalpel and the scalpel is not concealed:

being touchable by a person is a subtly different concept again…

EDIT after a little experimentation, it’s more particularly the case that to be ‘in the presence of’ something, that something must be in scope for the actor (but not necessarily visible or touchable or not concealed):

for example, in the above scenario if you make the scalpel concealed, or the room dark, or enter a cupboard and close the door, you’re no longer ‘in the presence of’ the scalpel, but if you add a rule to place the scalpel in scope, you’re back in its presence in all these scenarios even though it remains concealed and/or not visible and/or not touchable.

So in a nutshell, ‘in the presence of …’ means ‘when the … is in scope’, and the reason an actor is not ‘in the presence of’ a concealed object is simply because such an object is not ordinarily in scope.

EDIT 2 This is confirmed by the I6 generated by ‘in the presence of’, which calls the I6 routine TestScope(object, actor).

The fact that ‘in the presence of’ is defined by scope explains why in I7 it only exists in the context of actions, which is the only meaningful context for scope. There is no other straightforward way to test for scope in I7 (the I6 routine TestScope(object, actor) could be used if necessary).

For more details on scope in I7, see here.

2 Likes

A quibble: I’m not sure that it’s fair to say that actions are the only meaningful context for scope checks. The “can see” test also makes use of scope checking, and it can be usefully applied in a check of the current world state.

The suggestion that @DeusIrae ruled out above, i.e. a check using a non-specific person such as

Every turn when a person can see the scalpel:
    <do stuff>

is functional and will work as expected, translating into I6 code that means “if there exists a person X such that the scalpel is in scope for X…”. Example code:

"Person X"

Place is a room.

Other Place is east of Place.

An openable closed container called a box is in Other Place.

A scalpel is in the box.

Every turn when a person can see the scalpel:
    say "<Scalpel in sight of someone.>[line break]"

Bob is a man.

After jumping:
    now Bob is in Place;
    if the player can see Bob:
	    say "Bob appears in a puff of smoke.";
    otherwise:
	    continue the action.

Test me with "e / open box / close box / open box / get scalpel / w / drop scalpel / e / jump / w / take scalpel / e / drop scalpel / w".

As a broader point relevant to the original post, there are some conditional phrases that compile only in the context of what one might call “action conditions” (and I’m thinking that this may be what you meant to point out), which are typically found in rule preambles (but can be used elsewhere). These start with an action name, e.g.

jumping in the presence of an acrobat

and translate to code which means “if the current action meets [these conditions]…”. Some of these conditional phrases have alternate equivalent phrasing that can be used outside of action conditions. “In the presence of X” (where X is a thing) is one of them, with the equivalent “actor can see X”. Another is “during X” (where X is a scene), with equivalent “X is happening”. (I was thinking that there are more, but these are the only two that come to mind at the moment.)

It’s also true that there are certain scope changes that only apply while an action is being parsed. So, for example, various topic objects might be brought into scope while parsing an understand line such as

Understand "consider [any question]" as considering.

for a hypothetical considering action and associated hypothetical question objects. In such a case, questions will be in scope for the actor only during the parsing stage, not the between-parsing stages in which action processing and every turn rules are considered.

Ah, right – “a person” won’t work, but of course “any person” is fine. Thanks for the correction!

Mostly, except that being in scope is not quite the same as being visible- as described in this post sometimes things can be in scope even when not visible, or out of scope despite being visible.

As expected, your example translates to I6 code that tests visibility - TestVisibility(x,I128_scalpel) rather than simply scope (TestScope(I128_scalpel, x).

Although TestScope() is called in TestVisibility() as long as the object in question is illuminated (its parent offers light), the presence of conditions that must be fulfilled before TestScope is called illustrates how visibility subtly differs from ‘in scope’:

[ TestVisibility A B;
	if (~~OffersLight(parent(CoreOf(A)))) rfalse;
	if (suppress_scope_loops) rtrue;
	return TestScope(B, A);
];

Thus, in practical terms, the visibility relation is defined as something close to ‘being both illuminated and in scope’- but note that in certain conditions (when suppress_scope_loops is true) scope isn’t necessarily tested for in determining the visibility of even illuminated items and also despite its name TestScope() does not in itself fully define scope: for example directions test negative in TestScope() but are in scope nevertheless…

Conceptually, scope is defined by those objects that an actor is allowed to refer to in the course of the parser creating an action from a parsed command, which explains why philosophically its true context is properly only actions and also why it is subtly different from both visibility and touchability- both in concept and in its implementation in I7.

EDIT- my mistake- ‘if (~~OffersLight(parent(CoreOf(A))))’ tests whether the observer, not the observed object is illuminated. So it technically filters out situations where the observer is in the dark. That said, since visibility depends on a transparent path between the observer and the observed object, the result is the same, since if the observer is illuminated an object visible to the observer must by definition also be illuminated.

Marvelous! I think you’ve elucidated something important about the way that “in the presence of” works which WWI ignores, and it seems that the concepts of “visible” and “in scope” have been differentiated at least a bit better in I7 as compared to I6.

EDIT: That said, I think the OP’s original intent is better aligned with can see/can touch testing than with testing via in the presence of.

@Whoops_undo, if you are intent on using in the presence of (which, as the good doctor points out can be true even when touchability and visibility are not, such as when item X could see the unconcealed scalpel if light were available but either it or the scalpel is in a closed transparent container, or when you are deliberately modifying scope), then you can tie the check to a special-purpose action, such as

Existing is an action applying to nothing.

Every turn (this is the scalpel exists rule):
    try the scalpel existing.

After the scalpel existing in the presence of a person:
    say "<Scalpel in the presence of a person.>[line break]"

Note the use of an after rule; an every turn rule will generally only look at the current action as performed by the player, so you have to intercept the action processing for the scalpel’s existing action.

Also note the caveat about concealment pointed out by the good doctor: Concealed items will be in the presence of things from which they are concealed, but not the converse. If that’s an issue, then something like

Every turn (this is the people exist rule):
    repeat with P running through people:
	    try P existing.

After a person (called P) existing in the presence of the scalpel:
    say "<[P] in the presence of the scalpel.>[line break]"

but note that the player seems to require handling with its own rule (because the “a person” rule generates a routine with a hardcoded && (actor~=player) condition at the I6 level, so the player’s existing action is ignored by it):

After the player existing in the presence of the scalpel:
    say "<Player in the presence of the scalpel.>[line break]"

If you’re not averse to simple I6 hacking:

To decide whether (o - an object) is in scope for (p - a person): (- TestScope({o}, {p}) -).

(excluding directions, which will anomalously return negative) allows you to write, for example, ‘if the scalpel is in scope for the player’.

1 Like