Okay, so now let’s talk about the syntax of assertions. First, before we get started, assertions and conditions both have something in common in their structure.
Generic Sentence Grammar
As noted in §13.2, 90% of assertions can be boiled down to the following syntax:
«noun phrase» «verb» [«adverb»] «noun phrase»
Where the noun phrase looks something like this:
«adjective»* «noun»? «relative phrase»?
And the relative phrase looks something like this:
(«preposition» | «participle» | which/that «verb») «noun phrase»
Conditions also follow the same basic syntax. Note that all the components of the noun phrase are marked as optional, but that’s not quite accurate – you must have at least one component. Furthermore, some constructs are allowed only in certain contexts (only in assertions, or only in conditions). For example, “«relative phrase» «verb» «noun»” is not allowed as a condition, but is allowed as an assertion.
The verb is perhaps the most interesting part of this, because it can be put into several forms:
- active or passive voice
- positive or negative
- past or present tense
- simple or perfect
- simple or progressive
Assertions however only allow the first two. They also allow simple or progressive tenses. Also, progressive seems to be unsupported in the passive voice and for the verbs to be and to be able to. Those two verbs also don’t support the passive voice. This kind of makes sense though, since most people wouldn’t use those forms anyway even if they are technically valid grammar.
I already posted a table of verb forms in the Conditions section, but that omitted progressive and passive forms, so here’s a more complete table. Or rather, three tables. I’m using the verb to carry as an example of a standard verb here.
Voice |
Tense |
Aspect |
Positive Form |
Negative Form |
active |
present |
simple |
carries/carry |
do/does not carry |
active |
present |
progressive |
is/are carrying |
is/are not carrying |
active |
present |
perfect |
has/have carried |
has/have not carried |
active |
present |
progressive perfect |
has/have been carrying |
has/have not been carrying |
active |
past |
simple |
carried |
did not carry |
active |
past |
progressive |
was carrying |
was not carrying |
active |
past |
perfect |
had carried |
had not carried |
active |
past |
progressive perfect |
had been carrying |
had not been carrying |
passive |
present |
simple |
is/are carried by |
is/are not carried by |
passive |
present |
perfect |
has/have been carried by |
has/have not been carried by |
passive |
past |
simple |
was carried by |
was not carried by |
passive |
past |
perfect |
had been carried by |
had not been carried by |
Here’s the same table for to be, simplified to omit the unsupported forms:
Tense |
Aspect |
Positive Form |
Negative Form |
present |
simple |
is/are |
is/are not |
present |
perfect |
has/have been |
has/have not been |
past |
simple |
was |
was not |
past |
perfect |
had been |
had not been |
And for to be able:
Tense |
Aspect |
Positive Form |
Negative Form |
present |
simple |
can |
cannot |
present |
perfect |
has been able to |
has not been able to |
past |
simple |
could |
could not |
past |
perfect |
had been able to |
had not been able to |
Anyway, knowing the grammar at this generic level isn’t the most useful, so let’s go ahead and make a list of everything that you can assert. This means specifying which verb to use in most cases.
Structural Assertions
I’m defining “structural assertions” as ones that directly make a statement about the model world. They define the things that exist, and how they relate to each other.
Assertion sentences support the use of pronouns. They don’t have any concept of gender however – you can use him, her, or them if you want, but it’s no different from using it. All of these refer to the subject of the most recent sentence that had one. The pronoun here is also supported, and refers to the most recently defined room. That means you can write something like “the size of it is 21”. In fact, this is so common that you can omit “of it” entirely and just write “the size is 21”.
Anyway, let’s start with basic declarative assertions – those that explicitly define something in the world. These usually take forms like the following:
«name» is/are [«adjectives»] «kind».
There is/are [«number»] «kind» [called «name»].
Note: You can also write something like “The puddle is scenery” even though scenery is defined as an adjective and not a kind. I think this might be a special exception for scenery, but I haven’t investigated.
Those assertions aren’t particularly interesting. Most assertions specify a relation. Such assertions can take on a form like the following:
[«preposition»] «name» «verb» [«preposition»] «name» [called «name»]
That definition is perhaps a bit too abstract to be useful, so here are a bunch of examples:
Examples
The Harbour is south of the Shopping Mall.
The wood-slatted crate is in the Gazebo.
Mr Jones wears a top hat.
The crate contains a croquet mallet.
West of the Hadean Pits is the Elysian Fields.
On the table is a scrumptious meal.
Miss Felix is interested in Mr Jones.
Interested in videogames is Felix.
On the table is a thing.
Three things are in the box.
Miss Trombone hides the pencil.
On the table is a box called a bowl.
A supporter called a comfy armchair is in the lounge.
East of the Debris Room is nowhere.
West of Thames Street End is north of Fisher’s Row.
The attic is a dark room above the Parlour.
The sky is everywhere.
So the abstract definition could be broken down into the following (possibly incomplete) list of possibilities, most of them using the verb to be:
«room or door» is/are «direction» of «room or door».
«direction» of «room or door» is/are «room or door».
«direction» of «room or door» is/are «direction» of «room or door».
«direction» of «room or door» is/are nowhere.
Nowhere is «direction» of «room or door».
«noun» is/are «kind» «preposition» «noun».
«noun» «verb» «noun».
«noun» is/are «preposition» «noun».
«preposition» «noun» is/are «noun».
«preposition» «noun» is/are «kind» called «name».
«kind» called «name» «verb» «noun».
«backdrop» is/are everywhere.
That’s still pretty abstract, but in my opinion it does give a better idea of the kinds of things that are possible. Note in particular the case where it’s safe to put more than just a name after “called” – this will only work if there’s no other verb before “called” in the sentence. Also, consider a “preposition” here to be any sequence of words that could be placed after to be, so in particular, it could be a participle rather than an actual preposition, or it could be the passive voice.
For some further explanation, suppose you define the following verbs:
The verb to quark means the X relation.
The verb to be in front of means the Y relation.
The verb to be able to carp means the Z relation.
Now all the following sentence forms become viable as assertions:
thing A quarks thing B.
thing C is quarking thing D.
thing E is quarked by thing F.
quarked by thing G is thing H.
thing I is in front of thing J.
in front of thing K is thing L.
thing M can carp thing N.
Notice the apparent inconsistency that the passive voice is invertible but the progressive tense is not. Notice also that progressive is not supported for the verb to be, and to be able doesn’t appear to support even the passive.
The result of those statements, as shown by the relations command, is:
X relates various things to various things:
Thing A >=> thing B
Thing C >=> thing D
Thing F >=> thing E
Thing G >=> thing H
Y relates various things to various things:
Thing I >=> thing J
Thing L >=> thing K
Z relates various things to various things:
Thing M >=> thing
Relation assertions don’t just define a relation between two things. They can also implicitly define the things involved in the relation. For example, suppose “hides” is defined as meaning a relation applying to one person and one trinket. Then the statement “Miss Trombone hides the pencil” will also implicitly define Miss Trombone as a person and the pencil as a trinket. This also works for enumerated values instead of things; and if you use the name of a kind of object, it ends up creating an object that doesn’t have a name.
Note that a statement like “Three apples are in the box” won’t necessarily create three apples. If “apple” isn’t already defined as a kind, it will instead create a single thing called “Three apples”.
Next is property assertions – specifying that something has a particular property. These can take the following forms:
«noun» is/are «adjective».
«property» of «noun» is/are «value».
«noun» has/have «property» «value».
As a special case, you can write a quoted string as a sentence of its own, without any preamble. Usually, this is equivalent to setting the description property of the value or object currently referred to by the pronoun it. However, if the object in question is a non-scenery thing, it sets the initial appearance property instead. Note that this functionality is not limited to built-in objects (rooms, things, and scenes) – any value or object that can have a description will support this.
You can link multiple sentences together with and, as long as they have the same verb and either the same subject or the same object. That is, if you have sentences “X is Y” and “X is Z”, you can write them as one sentence, “X is Y and Z”. Similarly, if you have sentences “X is Z” and “Y is Z”, you can write them as one sentence, “X and Y are Z”. This may not work in every conceivable case though, and in particular should be avoided on sentences using called, as the compiler may interpret the and as part of the first object’s name instead.
Finally, it’s possible to mass-define things using a table. The syntax for that looks like this:
«kind» [«preposition» «noun»] is/are defined by «table name».
The optional preposition can specify a relation applied to every defined thing. It must be a various-to-one or various-to-various relation. This syntax works for kinds of objects and also for enumerated values.
I think there’s maybe something lacking in the above explanation. It really isn’t easy to just give a list of every possible format that an assertion can be expressed in, after all. The fact that you can invent arbitrary verbs to be used in sentences complicates things too.
Defining Kinds
Assertions can be used to define new kinds. The basic format for this is:
«name» is a kind of («base kind» | value).
The base kind can be either a previously-known kind of object (including object itself), or the special word value. You must define the base kind before you can define any subkinds. Note that kinds of value don’t have a tree, so this isn’t a consideration.
Usually Inform automatically guesses the correct plural form of a kind. However, you can override its guess as follows, or even define multiple plurals:
plural of «kind» is «plural kind».
By default, a custom kind of value is neither an enumerable nor an arithmetic value. However, such a kind cannot be used for anything, so to finish defining it you need to actually give it some values. There are two ways to do this. The first makes it a kind of enumerated value.
«name of kind of value» is/are «values».
«values» is/are «name of kind of value».
In fact, notice that declaring the values for an enumerated value is exactly identical to declaring the existence of an object. This means that any enumerated kind of value can be extended with additional values at the author’s convenience – there doesn’t appear to be any way to prevent this. (It is however disallowed for some built-in enumerated types, such as truth states.)
The second way is to make it an arithmetic kind. You can declare any number of formats for an arithmetic kind, but the first such declaration for any arithmetic kind cannot use the scaled up/down or equivalent to clauses (but scaled at is allowed, though mutually exclusive with with parts). This syntax is quite long, so I’ve split it across multiple lines.
«format specification»
[( [singular/plural] , [in «name»] )]
specify/specifies «kind of value»
[with parts «part specification» (, «part specification»)* |
scaled (at | up/down by) «number» | equivalent to «value of same kind»].
Format specifications are kind of really complicated, in that they can be almost anything imaginable – other than double quotes, there doesn’t seem to be any kind of restriction on the characters you can use in a format specification. Generally speaking, the specification will be broken down into sequences of digits and non-digits. Even a decimal point is treated as a non-digit, unless it’s followed by a zero, in which case it declares the type to be real-valued rather than integer-valued. (I_think_ that’s the rule, at least.) Similarly, if the first run of digits is preceded by a minus sign, it means you’re allowed to write negative values of the kind, but otherwise a minus sign is just treated as another character. The format specification can contain spaces but does not have to, so you can declare kinds with a compact specification like $99.99
, or kinds that are written out in words like 99 feet 11 inches
.
When breaking down the format specification, each run of non-digits is associated with the following run of digits as its preamble. Runs of digits after the first are also treated as limits on that component, so in the feet and inches example above it won’t let you set the inches to 12 or higher.
A format specification can be given a name with in (which enables you to convert values of this kind into this format for output) and can be declared to be either plural or singular. The plurality affects which form is chosen for saying values of this kind – it’ll choose a singular form if the value is 1 and a plural form otherwise (in English at least, I don’t know how that carries over to other languages).
The part specification can give a name to each of the components, and also set options for them. It’s a comma-separated list, each element of which looks like this:
«name» [( [[preamble] optional] , [without leading zeros] )]
If the segment is optional, it can be omitted entirely when writing values of that type. If the preamble is optional, both the segment and its preamble may be omitted. Without leading zeroes controls how the value is printed when the segment has fewer digits than the specification.
Lastly, by default it’s an error to multiply an arithmetic kind by anything other than a plain number, but you can specify how arithmetic kinds are multiplied together. At least one format specification must be defined before you can do this.
«kind» times «kind» specify/specifies «kind».
Note also that you can’t write “X divided by Y specifies Z”. Instead you have to rearrange it to write “Y times Z specifies X”.
You can define new properties for specific objects, kinds of object, or kinds of enumerated values. (Arithmetic values are not allowed to have properties.) This can be done using statements like the following:
«kind or value» can be [either] «adjective» [or «adjective»].
«kind or value» can be [either] «adjective» (([,] or | ,) «adjective»)+ [( this is its/her/his/their «name» property )].
«kind or value» has/have «kind» [called «name»].
The first form creates an either/or property. If the opposite is not specified, it defaults to prefixing not to the adjective. This form doesn’t necessarily need to define a new adjective – it can also be used to specify that an existing either/or adjective can be applied to the new kind. If the property already exists, you can use either the adjective or its opposite here, or you can use both; but specifying a different opposite from the already-existing one is not allowed.
The second form creates a new enumerated kind of value with the specified name (defaulting to suffixing condition to the name of the object or kind) and adds a property with the same name as the new kind. Though the syntax definition above doesn’t make this clear, it must have at least three alternatives. Also, the new kind can still be extended with additional possible values using separate assertions later on.
The third form creates a property of the specified kind with the specified name (defaulting to the same name as the property). Note that when a property has the same name as its kind, and the kind is an enumerated value, you can use the values of that kind as adjectives describing the object or value that has the property. However, if the property has a different name, you can’t use the values as adjectives.
You can control default values for properties or specify implications between either/or adjectives using statements like the following:
«kind or value» is/are «adverb» «adjective».
(«adjective» «kind» | «correlative pronoun» «adjective») is/are «adverb» «adjective».
«property name» of «kind or value» is/are «adverb» «value».
«kind or value» «adverb» «verb meaning a property» «value».
Correlative pronoun here refers to any of the pronouns beginning with “some” or “any”. The possible adverbs are:
usually/normally
seldom/rarely
always
never
But not all these adverbs are supported in every type of sentence, and in fact, only the first form (X is «adv» Y) supports all four. The second form (something X is «adv» Y) doesn’t support always or never, and the last two that work with arbitrary-valued properties only support usually/normally.
It’s possible to define a kind and give it properties in a single statement like this:
«name» is/are a kind of («base kind» | value) that/which is «adjective» (and «adjective»)*.
«name» is/are a kind of («base kind» | value) with «property name» «value» (and «property name» «value»)*.
Each of these rolls up three statements into a single sentence. If you write “X is a kind of Y that is Z”, it’s equivalent to the following three statements:
X is a kind of Y.
X can be Z.
X is usually Z.
Similarly, if you write “X is a kind of Y with Z W”, it’s equivalent to the following three statements, automatically inferring the kind of W:
X is a kind of Y.
X has a (kind of W) called Z.
The Z of X is usually W.
Defining a global variable looks a lot like a declaring an object, but with a few extra words:
«name» is/are «kind» (that varies | variable).
«name» is/are initially «value».
A variable previously defined using the first form can also be given an initial value without using the word initially.
You can also declare constants with a similar assertion:
«name» is always «value».
The word every can be added to a normal relation assertion (merging with correlative pronouns, if present, to become everything etc) to make a broad assertion about kinds. If both sides of the relation are a kind, this even implicitly defines instances of the kind on the opposite side as every so as to make the statement true – this is called “assembly”. The general form is like this:
(every «kind» | «universal pronoun») «verb» [«number»] «kind» [( called «name» )].
[«number»] «kind» [( called «name» )] «verb» (every «kind» | «universal pronoun»).
(every «kind» | «universal pronoun») «verb» «value».
«value» «verb» (every «kind» | «universal pronoun»).
The called clause, if present, generates names for the implicitly-defined objects, substituting any pronouns or possessive pronouns in the specified name with the name of the owning object, in the possessive if applicable. The supported pronouns are it, he, she, and they, together with their possessive forms. The called statement doesn’t work if you specify a number.
If you want, you can give names to Unicode characters. Usually this would be done by an extension though.
«name» translates into Unicode as «number».
This is pretty similar to the syntax to specify the I6 name of something.
«name» translates into I6 as «quoted I6 identifier».
I’m starting to wonder if this gets too wordy, but… I do think a lot of these quirks are better documented in-place rather than linking to the official documentation or something. Anyway, there’s still one more bundle of assertions to cover…
Defining Other Things
You can define new actions with the following syntax:
«name» is an action «action specification»
The action specification is a sequence of one or more of the following:
applying to nothing
applying to one [visible/touchable/carried] thing.
applying to two [visible/touchable/carried] things.
applying to one ([visible/touchable/carried] thing | «kind») and one ([visible/touchable/carried] thing | «kind»).
out of world
requiring light
with past participle «participle»
For obvious reasons, you can’t have more than one applying clause. Also, actions applying to two things must include the pronoun it somewhere in the middle of their name, which divides the name into two parts – the part after it is considered the preposition of the new action. Be careful – the compiler will accept a name ending in it, but it won’t be able to recognize the action in action descriptions, so this should be avoided.
Defining action variables looks almost exactly the same as defining properties:
«action name» action has «kind» called «name» [( matched as «quoted word» )].
The main differences are the matched as clause (which defines a preposition for matching this variable in action descriptions) and the fact that called is required.
You can group actions together as “behaviours” or “kinds of action”. The general pattern for this is as follows:
«description of action» is «behaviour name».
Such assertions for the same name are cumulative. The descriptions permitted for behaviours are a little limited – requested actions and actions with a specified actor (including an actor) can’t be added to behaviours.
A scene is just a regular enumerated value, so new scenes can be declared in the same way as other things. Specifying when they begin and end however use some special statements:
«scene» begins when «condition».
«scene» begins when play begins.
«scene begins when «scene» begins/ends.
«scene» ends [«ending name»] when «condition».
«scene» ends [«ending name»] when «scene» begins/ends.
A scene can have multiple begin conditions, but each ending can only be given a single condition. Fortunately, the when «condition» form is a full-fledged condition, so it can use and. It is possible to define a general (nameless) ending in addition to named endings; I’m not sure if this is useful however.
Relations can be defined as follows:
«name» relates various «kind» to various «kind» [with fast route-finding].
«name» relates one «kind» [( called «name» )] to various «kind» [with fast route-finding].
«name» relates various «kind» to one «kind» [( called «name» )] [with fast route-finding].
«name» relates one «kind» [( called «name» )] to one «kind».
«name» relates various «kind» to each other [with fast route-finding].
«name» relates one «kind» [( called «name» )] to another.
«name» relates one «kind» to another [( called «name» )].
«name» relates «kind» [( called «name» )] to kind.
«name» relates «kind» [( called «name» )] to «kind» [( called «name» )] when «condition».
The second-to-last form is particularly interesting in terms of whether Inform defaults to various or one. In fact, that relation will be one-to-various if a called clause is used and various-to-one otherwise. So it’s probably better to always specify whether each side is various or one. (I assume it’s also possible to omit one/various on one side but specify it on the other, but again, I wouldn’t recommend it.)
The form creating an equivalence relation (in groups) also accepts the with fast route-finding clause, but I think this is a mistake, as it doesn’t make sense to route-find through an equivalence relation (for any two things, there’s either no route at all, or a single-step route). Relations that don’t have various on at least one side will raise an error if you try to specify it.
It’s worth noting that a called clause in the definition of a non-calculated relation actually defines properties on the related kinds, which are automatically kept in sync with the relation. So, changing the relation updates the property and vice versa.
Verbs can be defined as follows:
To «verb» is a verb [( «conjugation» )].
The verb to «verb» [( «conjugation» )] means/implies ([reversed] «relation» | «property»).
Note that the name of a relation always ends in relation and the name of a property always ends in property. So, the second form will always end in one of those words. The first form defines a verb that is sayable but has no other meaning.
It’s also worth noting that defining a verb to mean a property also defines an implicit, nameless relation that automatically relates the holder of the property to its value, as if you had written something like the following:
My-property-relation relates a thing (called A) to a value (called B) when the «property-name» of A is B.
Despite not automatically defining them as verbs, Inform7 knows the conjugations of most English irregular verbs, so you usually don’t need to specify the conjugation manually. However, if you want to do so, it’s a comma-separated list of one or more of the following (I think they must also be in the specified order):
he/she/it «present singular»
they «present plural»
he/she/it «past»
he/she/it is «past participle»
I don’t think there’s any way to specify the present participle, probably because it’s always regular in English.
There are two special cases of verbs: to be, and to be able to. Inform7 has special handling for defining a verb that begins with either of those. It’s not permitted to specify the conjugation in this case.
If you define a verb beginning with to be (but not beginning with to be able to), then the sentence defines a preposition rather than a verb. Everything after to be in the definition becomes the preposition.
Similarly, if you define a verb beginning with to be able to, it’s defined not as a regular verb but as something that can follow can or could in a sentence.
You can create new rulebooks or activities with an assertion:
«name» rules/rulebook is/are «kind of rulebook».
«name» is/are «kind of activity».
This is pretty much a normal declaration, the only quirk being that the word something is treated specially in the name of an activity. Here a «kind of rulebook» or «kind of activity» uses the syntax explained in the Composite Kinds section.
Activities and rulebooks can both have semi-local variables. This looks exactly like adding a property to an object, except that the called part is required rather than optional:
«rulebook or activity» has/have «kind» called «name».
For rulebooks, you can specify the default outcome, or define a set of named outcomes. Both of these only work for rulebooks that don’t produce a value, with one exception – you can specify that a rulebook producing a value has default failure (or no outcome, which is the default anyway and thus redundant). (Though I say it’s not allowed, there’s a bug that the compiler allows you to do it anyway and then just does weird stuff at runtime, potentially even crashing.)
«rulebook» has/have default failure/success.
«rulebook» has/have default no outcome.
«rulebook» has/have outcomes «list of outcomes».
The list of outcomes is one or more of the following, joined by commas and/or and:
«name»
«name» ( success [- the default] )
«name» ( failure [- the default] )
«name» ( no outcome [- the default] )
Note that a named outcome corresponding to no outcome will never be treated as the outcome of a rulebook. Thus, it only serves to give a nicer name to the make no decision phrase when used in the rulebook in question.
I haven’t tested whether it works correctly to have multiple outcomes defined as failure.
Lastly, you can adjust the contents of an existing rulebook or conditionally control when rules trigger with statements like the following:
«rule» is listed [before/after «rule» | instead of «rule» | first/last] in «rulebook».
«rule» is not listed in («rulebook» | any rulebook).
«rule» (does nothing | substitutes for «rule») [when «condition»].
I think that pretty much covers every possible form of non-imperative assertion, and it really is a lot… but please let me know if you can think of something that I’ve forgotten. I’ll add imperative assertions (including Understand) in a later post.