This class is generally not instantiated by client code - instead, clients use the sortByRanking() class method to rank a list of production matches.
CommandRanking : ResolveResults
The most important thing is whether or not we have irresolvable noun phrases (vocabNonMatchCount). If one of us has a noun phrase that refers to nothing anywhere in the game, it's not as good as a phrase that at least matches something somewhere.
Next, if one of us has noun phrases that cannot be resolved to something in scope (nonMatchCount), and the other can successfully resolve its noun phrases, the one that can resolve the phrases is preferred.
Next, check for insufficient numbers of matches to counted phrases (insufficientCount).
Next, check for noun lists in single-noun-only slots (listForSingle).
Next, if we have an empty "but" list in one but not the other, take the one with the non-empty "but" list (emptyButCount). We prefer a non-empty "but" list with an empty "all" even to a non-empty "all" list with an empty "but", because in the latter case we probably failed to exclude anything because we misinterpreted the noun phrase to be excluded.
Next, if we have an empty "all" or "any" phrase due to "but" exclusion, take the one that's not empty (allExcludedCount).
Next, prefer a command that addresses an actor (actorSpecifiedCount) - if the actor name looks like a command (we have someone named "Open Bob," maybe?), we'd prefer to interpret the name appearing as a command prefix as an actor name.
Next, prefer no unstructured word lists as noun phrases (miscWordList phrases) (miscWordListCount).
Next, prefer interpretations that treat less text as uninterpreted literal text. By "less text," we simply mean that one has a shorter string treated as a literal than the other.
Prefer no indefinite noun phrases (indefiniteCount).
Prefer no truncated plurals (pluralTruncCount).
Prefer no noun phrases ending in adjectives (endAdjCount).
Prefer no truncated words of any kind (truncCount).
Prefer fewer pronouns. If we have an interpretation that matches a word to explicit vocabulary, take it over matching a word as a pronoun: if a word is given explicitly as vocabulary for an object, use it if possible.
Prefer no missing phrases (missingCount).
Prefer the one with fewer subcommands - if one has fewer subcommands than the other, it means that we were able to interpret ambiguous conjunctions (such as "and") as noun phrase conjunctions rather than as command conjunctions; since we know by now that we both either have or don't have unresolved noun phrases, we'd rather take the interpretation that gives us noun phrases than the one that involves more separate commands.
Prefer the tree that matches more tokens.
Prefer the one with more structural noun phrases in the verb. For example, if we have one interpretation that's DETACH (X FROM Y) (where X FROM Y is a 'locational' phrase that we treat as the direct object), and one that's DETACH X FROM Y (where X is the direct object and Y is in the indirect object), prefer the latter, because it has both direct and indirect object phrases, whereas the former has only a direct object phrase. English speakers almost always try to put prepositions into a structural role in the verb phrase like this when they could be either in the verb phrase or part of a noun phrase.
If all else fails, prefer the one that is initially less ambiguous. Ambiguity is a weak test at this point, since we might end up narrowing things down through automatic "logicalness" tests later, but it's slightly better to have the match be less ambiguous now, all other things being equal.
This routine is designed to run entirely off of our rankingCriteria property. In most cases, subclasses should be able to customize the ranking system simply by overriding the rankingCriteria property to provide a customized list of criteria objects.
Note that this can be used as a class-level method.