[I7] Condition syntax in Inform 7

This seems like a fairly basic question, but I can’t really get a clear answer in the documentation. How does Inform 7 and/or syntax work?

I’ve written a condition like this:

It’s pretty clear I only want this rule to fire under two conditions:

Condition 1: L = Y, N = Z
Condition 2: L = X

But, in my experimentation, it appears that the rule fires when only one statement of condition 1 is true and condition 2 is false, treating it as if I wrote just “or” statements throughout.

I know I can resolve this if I write a phrase, but I was wondering if there was any way of making Inform understand my intent here.

No, it’s not. It could also be interpreted as requiring

Condition 1: L = Y, N = Z
Condition 2: L = Y, L = X

“But it’s obvious what I mean!” is not an excuse for well-formed logic. (Besides, the second version might be looking for the specific case where L = X and X = Y.)

While it’s clear to you, the language itself is actually pretty ambiguous. You should be able to use parentheses to clarify your intent:

Instead of doing something when (L is Y and N is Z) or (L is X): say "Something random."

[spoiler]The same sentence could also be a parsed perfectly validly like this:

Instead of doing something when (L is Y) and (N is Z or L is X): say "Something random."

This is evidently how Inform is reading your bare assertion.[/spoiler]

Only the first set of parens there is actually necessary; I added the other to make it easy to see at a glance what the two conditions are.

–Erik

Don’t feel bad, I have a lot of trouble with conditional syntax as well.

…and I was just checking to confirm whether parentheses work (they do!) but Erik got there first.

I haven’t used parentheses in I7 before, I suppose, because in natural English single statements are a very poor vehicle for precise logic assertions: the more English-y way you’d do this is with an ‘if… otherwise…’ statement. More lines of code, but more transparent.

The Glimmr extensions required a lot of parentheses for all the math-related stuff. Parens can also come in handy for working around bugs in I7’s parsing, both of math and of other things. So I’ve had to wallow in them much more than I’d like.

Ah OK. I realized where I went wrong. I tried using parentheses before, but they didn’t seem to work. My problem was one of wording.

What I wrote was something like this (not an actual piece of code from the project):

Instead of taking the skull when (the player is wearing the shirt and the player is wearing the pants) or (the player is not carrying the rock): say "No the skull is cursed you need to be unclothed or carrying the rock of curse protection."

Which, of course, is totally wrong. This somehow seemed more natural to me than the correct version, which was:

Instead of taking the skull when (the player is wearing the shirt or the player is wearing the pants) and (the player is not carrying the rock): say "No the skull is cursed you need to be unclothed or carrying the rock of curse protection."

Which would only fire either if the player is clothed or the player is not carrying the rock, which is what I intended. So, actually, it was pretty much my stupidity. Sorry for wasting your time.

Formal logic is not my strong suit :slight_smile:

Thanks!

I’m getting better at it. I’ve just never had to combine and/or statements in a single condition in Inform.

Well, it does seem that even the Inform 7 compiler is a bit buggy in his department as well, as seen here.

I tend to always use brackets, then you can be 100% sure.

Oh yeah, and it’s not just math. Complex descriptions can also require brackets to be interpreted correctly.

Math has the advantage of a well-defined order of precedence, so you can say that I7 gets certain cases wrong.

For parsing complex descriptions, it’s hard to say what should be going on.

I tend to avoid the issue by writing to-decide-whether phrases (or adjectives) that have the conditions split into separate lines:

To decide whether we are ready to foo: If L is Y and N is Z, yes; If L is X, yes; no.

If this was Facebook, I’d click “Like”.

That’s probably the clearest and most efficient way of doing it. You can also use definitions, like so.

Definition: a thing is fooable: if L is Y and N is Z, decide yes; if L is X, decide yes; decide no.

This will give you a new adjective. So now you can talk about “fooable things”.

Hope this helps.

Here’s me with a late opinion, because I had to look this up today.

I find the write-a-phrase-for-it solution to be way overkill for just achieving a complex conditional – there is no way I would define a brand new function for every complex conditional.

As Zarf already implied, order of operations in coding is ironclad and there is a way these things are expected to go – to treat the original example as ‘ambiguous’ without noting this, is a bit obtuse, perhaps intentionally so. (As in, I figure people know about the expected order of ops but don’t bring it up with Inform 7 for essentially political reasons – they don’t think the language should be held to that standard. However this makes for a very unhelpful response to somebody who clearly DOES have the standard expected coding order of ops in mind.) No offence.

Finally, to break the conditional up into separate if-then statements is not a good solution, because it forces me to rewrite the same code multiple times. The whole point of writing most complex conditionals is specifically to avoid having to replicate the same codeblock multiple times, without having to write a separate function for it, because you only need this behaviour in this one instance. I would only write a separate function if I know I am going to need to call it multiple times in different contexts. If I am not doing that, then I always want to write a complex conditional, instead.

The parenthesis advice was helpful – I had forgotten that they even work.

Paul.