Grouping things by property

How can I do what it says in the title? I tried messing with the grouping together syntax and couldn’t figure out how to do it.

A category is a kind of value. generic_category is a category. A thing has a category.

pickle_category is a category. Understand "pickle/pickles" as a thing when the item described is pickle_category.

Rule for printing the name of a thing when the item described is pickle_category:
	say "pickle";

Rule for printing the plural name of a thing when the item described is pickle_category:
	say "pickles";

sandwich_category is a category. Understand "sandwich/sandwiches" as a thing when the item described is sandwich_category.

Rule for printing the name of a thing when the item described is sandwich_category:
	say "sandwich";

Rule for printing the plural name of a thing when the item described is sandwich_category:
	say "sandwiches";

The kitchen is a room.

The player is in the kitchen.

1 pickle_category edible thing is in the kitchen.

1 sandwich_category edible thing is in the kitchen.

A mimic is a person in the kitchen. mimic is pickle_category.

If I don’t do anything, I get this:

kitchen
You can see two pickles and a pickle here.

If I add this:

Before listing contents:
	group pickle_category things together;

I get the equally strange this:

kitchen
You can see two sandwiches and a pickle here.

I have spent 2 months trying to work with a kinds-based alternative to using categories, since Inform was built to use kinds, but it just doesn’t seem feasible to do what I’m trying to do with kinds, so I’m circling back to properties… but this grouping issue is a major stumbling block. Can this be solved?

I think what’s going on is that Inform isn’t recognizing your Understand lines as being enough to differentiate the anonymous instances of “thing.” As I think we’ve discussed, Inform cares a lot about whether it can distinguish instances; for instance, it won’t try to disambiguate between indistinguishable instances of a category, and as I found out it seems to group indistinguishable instances of a category together no matter how you tell it to group things.

Anyway, the basic rule is that two instances of a kind are indistinguishable if Inform thinks there’s nothing the player can type to differentiate them. But there are some possibilities it doesn’t exist; if you have an Understand as a relation statement, Inform won’t consider that when trying to figure out if they’re indistinguishable; and I guess your Understand statements don’t work either. So Inform thinks you’ve got two indistinguishable things there (the ones that aren’t the mimic – the mimic has its own name so it’s not indistinguishable, and wouldn’t be even if it were privately named), and then it pluralizes them by picking the plural name of one. That’s why you get “two pickles” once and “two sandwiches” another time. I have no idea why it changes.

Anyway, Inform does recognize “Understand as a property” lines as distinguishing instances, so you can toss one of those in:

Understand the category property as describing a thing.

and then all three things will be separated, and you can use grouping together the way you want:

Before listing contents: group pickle_category things together as "pickles";

And maybe use some more rules for grouping together or whatever so you don’t get “two pickles (a pickle and a pickle).”

Aha! Ok, it hadn’t clicked for me in the other thread that the understand phrase was so important to this. I get that now! Phew…

So, this works, but as you said, the grouping activity lists out each thing after a “together as ‘some text’” phrase. It doesn’t appear that this activity is exposed to I7 in a way that can fiddle with that… is that right? The documentation doesn’t seem to have an example of how to just group the objects together normally without that parenthetical clarification that follows. I’m not sure how to proceed on that one… I would guess it would need to be an I6 extension.

Short of that, is there a way for me to suppress the grouping activity from ever happening at all, and have my own list generating rule run instead of it? Is that even a good idea?

Edit: From the other thread, you had created a rule to do something like this, matt, and it is well done to do what it does, but it did make performance very slow and you have to set up as many loops as how many different kinds (or categories) in this case, you expect in one place, and the more you expect, the more the performance hit.

Throwing out the parenthesized stuff isn’t so bad; the text is printed by a “for grouping together” rule so you just have to write a different “for grouping together” rule (see 18.14). In this particular case:

For grouping together pickle_category things: say "[listing group size in words] pickles".

Listing group size is just the number of things being listed together.

If you want to totally change the way this works, I think the thing you do is write a rule for listing nondescript items; see section 18.25. As ever, though, I have no idea if you can squeeze performance improvements out of it (though from what zarf said in the other thread it sounds as though getting rid of grouping altogether might be useful).

I was just posting this when you posted above:

[spoiler]Actually, I (possibly) have found a magic bullet for this.

A thing is always privately-named.

By denying access to the code name of the object, and relying solely on the understand phrases and printed name rules, I think this shoehorns everything into order. Please let me know if there is some horrible use case I’m not considering here.[/spoiler]

Alternatively to that, based on what you said above, is there a way to do something like this:

For grouping together things by category: say "[listing group size in words] [the item described]".

Some kind of working version of that pseudocode so that only a single rule has to be written?

Hmm, well you could try this:

For grouping together something (called the item): say "[listing group size in words] "; carry out the printing the plural name activity with the item.

But if you want this only to happen only when things have been grouped together because they’re in the same category, I don’t know. It may depend on whether the listing group is exposed to I7, then you could check whether everything in the listing group has the same category. But I’m not sure if you can get it without diving to I6.

Oh, the thing I keep forgetting to say is that you might want to look at the Room Description Control extension, which overrides the listing nondescript items activity. I notice that it has the following I6 phrase to handle grouping:

To decide whether (X - a thing) nominally matches (Y - a thing): (- ({X}.list_together == {Y}.list_together) -)

which might be what you need to get a list of everything that’s grouped together in the “for grouping” rules. This is from the old extensions website so you’d want to check that it’s still the same in 6L02.