Found_in equivalent in I7

The found_in machinery is still present and working (at least in 6M62). It can be used with a special declaration. Here’s an example:

"Floating Object Container"

A room can be buckety.

Place is a room.

Other Place is east of Place. Other Place is buckety.

Yet Another Place is east of Other Place. Yet Another Place is buckety.

A container called a magical bucket is in Place.

Include (- with found_in [; if ((GetEitherOrProperty(location, (+ buckety +)))) rtrue; else rfalse; ]  -) when defining the magical bucket.

The call to GetEitherOrProperty() is a hedge against the I7 compiler deciding to represent the “either/or property” as an I6 property instead of an I6 attribute.

There are other ways to go about setting up the condition to decide whether or not the floating container is present in a room, if desired.

5 Likes

Messing about with this to see if it worked in Ver 10.1 led me to the discovery that trying to include I7 object name expansions in I6 property definitions like this elicits a compiler bug.

E.g.

Include (- with found_in (+ Lab +), -) when defining the flask

leads the compiler to crash with a ‘no current sentence’ error when compiling to 6M62, and when compiling to 10.1.2 leads to a truncated I6 object name reference:

with found_in I_Lab,

when the I6 object name is actually I_Lab_U1, causing I6 compilation to fail with the error 'no such constant as I_Lab.

Although now deprecated, this syntax is supposed to be still functional in 10.1.2.

In this instance the code can be made to successfully compile in 10.1.2 with this ugly fix, in which case found_in does function as expected:

Include (- with found_in (+ Lab +)_U1, -) when defining the flask

However, GetEitherOrProperty() appears to have disappeared from 10.1.2, so your code doesn’t compile

1 Like

Interesting. I still haven’t made the switch to 10.1, but I’m dabbling.

Following is a version that determines floating presence based on a relation instead of a property, which survives cursory testing in under 10.1.2.

"Found In v10.1.2"

Place is a room.

Other Place is east of Place.

Yet Another Place is east of Other Place.

Floating presence relates various things to various rooms. The verb to be found in means the floating presence relation. The verb to host means the reversed floating presence relation.

Include (-

[ FloatPresence obj loc ;
    if (obj && loc)
	    return (Relation_TestVtoV(obj, (+ floating presence relation +), loc, false));
    else
	    rfalse;
];

-).

A floating container is a kind of container.

Include (- with found_in [ toroom obj ; return (FloatPresence(obj, toroom)); ]  -) when defining a floating container.

A floating supporter is a kind of supporter.

Include (- with found_in [ toroom obj ; return (FloatPresence(obj, toroom)); ]  -) when defining a floating supporter.

A floating thing is a kind of thing.

Include (- with found_in [ toroom obj ; return (FloatPresence(obj, toroom)); ]  -) when defining a floating thing.

A floating animal is a kind of animal.

Include (- with found_in [ toroom obj ; return (FloatPresence(obj, toroom)); ]  -) when defining a floating animal.

There is a floating container called a magical bucket.

The magical bucket is found in Other Place and Yet Another Place.

There is a portable floating supporter called a magical tray.

The magical tray is found in Place and Other Place.

A cloud is a floating thing. Every room hosts it. The initial appearance of the cloud is "A lone cloud slowly crosses the sky."

A bird is a floating animal. The initial appearance of the bird is "A bird wheels far above you."

Every turn:
    if the remainder after dividing the turn count by three is zero:
	    now the bird is found in nowhere;
	    now the bird is found in a random room;
	    update backdrop positions;
	    if the player can see the bird and the player could not see the bird, say "A bird glides into view."
    
After jumping:
    if the magical bucket is found in the location:
	    now the magical bucket is not found in the location;
    otherwise:
	    now the magical bucket is found in the location;
    update backdrop positions;
    say "Bucket presence changed."

After waving hands:
    if the magical tray is found in the location:
	    now the magical tray is not found in the location;
    otherwise:
	    now the magical tray is found in the location;
    update backdrop positions;
    say "Tray presence changed."

Test me with "e  / e / wave / l / jump / l / w / wave / l".


Include (-

[ MoveFloatingObjects toroom i k l m address flag;
    if (toroom == nothing) toroom = real_location;
    if (toroom == nothing) return;
    objectloop (i) {
        address = i.&found_in;
        if (address ~= 0 && i hasnt absent) {
            if (ZRegion(address-->0) == 2) {
                m = address-->0;
                .TestPropositionally;
                if (m.call(toroom, i) ~= 0) move i to toroom; ! MODIFIED
                else { if (i in toroom) remove i; }
            } else {
                k = i.#found_in;
                for (l=0 : l<k/WORDSIZE : l++) {
                    m = address-->l;
                    if (ZRegion(m) == 2) jump TestPropositionally;
                    if (m == toroom || m in toroom) {
                        if (i notin toroom) move i to toroom;
                        flag = true;
                    }
                }
                if (flag == false) { if (i in toroom) remove i; }
            }
            if ((i ofclass K4_door) && (parent(i) == nothing)) {
            	move i to ((i.door_to).call());
            }
        }
    }
];

-) replacing "MoveFloatingObjects".

The variety of floating <X> kinds is to avoid interfering with the native found_in property for backdrops.

This is all very neat!

I’m also in transition to 10.1, and still struggling with all the minor changes to how things are done.

Interesting that your modified 6M62 MoveFloatingObjects routine appears to run OK in 10.1, as the 10.1 routine it replaces uses a number of different idioms to express equivalent statements- e.g. k=(_final_propertylength(OBJECT_TY, i, A_found_in)) instead of k = i.#found_in and m(toroom) instead of m.call(toroom). Presumably going forward these are the approved ways of doing things…

The goal of Inter seems to be to support as much of I6 syntax as possible, so if .# and .call are currently supported, I doubt they’re going to be removed.

I thought that, too, while checking things before posting, but when I tried to use that I6 code, it wouldn’t compile under 10.1.2. Also, if you look at the produced auto.inf, the code generated does look like the new version that you’re citing. My guess is that it’s a product of the I6-to-inter-to-I6 conversion.

I think you’re right- looking at [ MoveFloatingObjects...] in the 10.1 WorldModelTemplate it’s the same as in the 6M62 template (k=i.#found_in etc.)

grump. Last night I discovered that in v10 you can’t get at I7-defined properties from within I6 code with obj.(+ i7-property-name +) like you used to be able to do. I don’t know yet if there’s a workaround.

Graham’s been working to purge as many uses of the (+ +) syntax from the language as possible, and I suspect this is a casualty of that.

The alternative is to say:

A thing has a number called zork.
The zork property translates into Inter as "zork".

Then it has a known name at the I6 level which you can reference.

1 Like

As a KISS alternative, one could just include an equivalent of GetEitherOrProperty() into a 10.1 project to make your original code work…

However, in 10.1 that functionality seems to be superseded by the following function:

[ _final_propertyvalue K o p t;
    if (K == OBJECT_TY) {   !### properties/attributes for objects
        if (metaclass(o) == Object) {
            t = p-->0; p = p-->1;   !### get property/attribute type ID and move p to pointer to property 
            if (t == 2) { if (o has p) rtrue; rfalse; } !### type ID of 2 == attribute: return attribute value
            if (o provides p) return o.p; !### return property value
        }
        rfalse;  !### invalid object, or object does not provide property requested
    } else {     !### properties for kinds of values
        t = value_property_holders-->K;
        return (t.(p-->1))-->(o+COL_HSIZE);
    }
];

which returns the value of a I6 property/attribute of an object, or the value of a property of a value-
it is called with K (kind- (OBJECT_TY for objects, or the kind of value for values), o (the object or value), p (a property ID- which in the case of objects is used as an index to look up in an array the property/attribute type ID (with 2 indicating an attribute) together with a pointer to the actual property, then retrieves the attribute/property value as appropriate.

Unfortunately, like the .inf version of [MoveFloatingObjects;…], this can’t be compiled as an I6 inclusion in source because it seems to depend on structures (like the property type ID/property pointer array) created in the final iteration of inter->I6 conversion and which are not present in the original kit I6.

GetEitherOrProperty(object, property/attribute) depends in 6M62 on a hacky method (that is unavailable in 10.1.2) for deciding whether the second parameter is an attribute or a property, and I don’t know a way of determining in 10.1.2 source whether an I7 boolean property has been compiled as an I6 property or an attribute.

One hacky way round this would be to define a three-way property in I7 (including a redundant null value) rather than a boolean, or to define bucket-status as an (enumerated) value with 2 values buckety and non-buckety then assign rooms a bucket-status property, either of which would guarantee compilation as a property:

"test_Floating_Objects" by PB

bucket-status is a kind of value. The bucket-statuses are non-buckety and buckety.  Every room has a bucket-status.

Other Place is east of Place. Other Place is buckety.

Yet Another Place is east of Other Place. Yet Another Place is buckety.

A container called a magical bucket is in Place.

Include (- with found_in [; return (real_location.(+ bucket-status +)) -1; ]  -) when defining the magical bucket.

One neat solution is assign the buckety property from a table, which also ensures that even boolean properties are compiled as I6 properties rather than attributes:

"test_Floating_Objects" by PB

Some rooms are defined by the Table of Locations.

Table of Locations
room	buckety
Place	false
Other Place	true
Yet Another Place	true

Place is a room.

Other Place is east of Place.

Yet Another Place is east of Other Place.

A container called a magical bucket is in Place.

Include (- with found_in [; return real_location.(+ buckety +); ]  -) when defining the magical bucket.

EDIT as long as at least one instance of the property is defined in a table, the property will compile to an I6 property rather than an attribute. Elsewhere in the code property values can be asserted in the usual way, e.g. `The buckety of Other Place is true.’

I haven’t had a chance to test it, but I believe the “translates into Inter” syntax helps here too—it ensures the property is defined as a property (not an attribute) with a name you can reference in I6 code.

Ah- haven’t come across that yet- will explore!

It seems to be the preferred way to use I7 object, property, etc constants in I6 code now (rather than (+ +)).

I’ve checked it out, and it remains the case that either-or properties or truth state properties given a ‘… translates into inter as…’ or ‘…translates into I6 as…’ line compile by default to I6 attributes. So doesn’t help this situation, unfortunately.

Huh. I didn’t think that would be the case. That’s good to know.

If you know it’ll be an attribute, can you just [; return real_location has buckety; ]?

That’s true in a given known instance (and, to be fair, for most practical instances) but the the ‘purist’ problem in general is that should the Inform compiler run out of I6 attribute slots it will without warning start to compile binary I7 properties as I6 properties. I guess that’s a particular consideration for extension-writers…

Seems to work in the code I posted above? Trying to expand I7 adjectives with (+ I7_adjective +) doesn’t seem to work in 10.1.2 tho. I’ve filed a bug report.

But this won’t compile in 10.1 and works in 9.3/6M62

lab is a room.
mouse is a thing in the lab. mouse has a number called age.

When play begins: 
now the age of mouse is 12; 
foo mouse;


To foo (o - an object): (- Foo({o}); -)

Include (-
[ Foo o;
print o.(+ age +);
];
-)

I’d be tempted to say that anonymous properties work and named don’t, but this also works in 9.3/6M62 and fails to compile in 10.1:

lab is a room.
mouse is a thing in the lab. 
color is a kind of value. the colors are red, green, blue.
a thing has a color.

When play begins: 
now the color of mouse is green;
foo mouse;


To foo (o - an object): (- Foo({o}); -)

Include (-
[ Foo o;
print o.(+ color +);
];
-)

So I don’t know what’s going on.

It seems to depend on context what will work and what won’t. For I7 object names, they expand correctly in I6 functions but not in I6 properties; for I7 property names they expand correctly in I6 properties but not in functions; for I7 adjective names I haven’t yet found a context where they do expand correctly.

I think the overall conclusion is that the hybrid I7/I6 coding environment is multiply broken in unpredictable ways in 10.1.2 and will remain unreliable until or unless @GrahamNelson finds the time and/or inclination to fix it. Of course, since his general paradigm is to try to discourage hybrid coding, this may not be a priority for him, although it does mean a significant codebase no longer compiles in 10.2.1.

As far as I can see so far, the system for translating names from I7 to I6 and using the thus-known translated forms in I6 code as an alternative to expanding I7 names still seems to work, although that doesn’t help for adjectives, which can’t be translated.

2 Likes

Ah, true. I suppose a good stopgap would just be to bring back GetEitherOrProperty, and then we don’t need to care about the implementation details of attributes vs properties.