Hi, this is just a question I have about how ($object is $relation $parent) works, since it seems to me like it doesn’t behave like other predicates.
Specifically, what I am curious about is if, say, (#apple is #in #room) and we “take apple”. In the standard library just says effectively (now) (#apple is #heldby #player). What I don’t understand is that the old predicate is never negated, e.g. (now) ~(#apple is #in #room). It would seem based on how I think other predicates work that would be needed, but it seems not to be so.
What’s going on here?
There are four kinds of dynamic predicates: Global flags, global variables, per-object flags, and per-object variables. Global variables have to be declared:
(global variable (current player $))
The other three kinds are distinguished by the number of parameters:
(I am the walrus) %% no parameter -> global flag
(#rose is red) %% one parameter -> per-object flag
(#hovercraft is full of #eels) %% two parameters -> per-object variable
In the case of per-object variables, the first parameter always indicates the object, and the second parameter is the value of the variable. That’s just how per-object variables work, by definition, and I agree with you that it’s different from other kinds of predicates. But it’s very useful.
($X is $Y $Z) is an access predicate (a kind of alias, or hygienic macro) for two per-object variables:
($X has relation $Y) and
($X has parent $Z).
So when you do
(now) (#apple is #heldby #player), you’re actually setting two separate per-object variables:
(now) (#apple has relation #heldby)
(now) (#apple has parent #player)
In both cases, the first parameter identifies what object to modify, and the second parameter is the value to store in the per-object variable.
Oh, that’s interesting! I read the definition of ($object is $relation $parent) but it didn’t click that that was what was going on with:
@($Obj is $Rel $Parent)
%% The order of the following queries is critical when $Obj is unbound.
*($Obj has parent $Parent)
*($Obj has relation $Rel)
So @ defines an alias macro; interesting. I have neglected to read the language section of the manual in depth, clearly it’s time I do so. Thank you again for your patience!