Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

I7 Planner extension V1 has been uploaded to ifarchive

13 views
Skip to first unread message

na...@natecull.org

unread,
Jun 7, 2006, 6:46:16 PM6/7/06
to
Uploaded via the Web form so not sure how long it will take...

Filename is I7PlannerV1.zip

I guess it appears in unprocessed and then should ultimately find its
way to
http://ifarchive.org/indexes/if-archiveXinfocomXcompilersXinform7Xextensions.html

steve....@gmail.com

unread,
Jun 7, 2006, 8:00:25 PM6/7/06
to
na...@natecull.org wrote:
> Uploaded via the Web form so not sure how long it will take...
>
> Filename is I7PlannerV1.zip

Surprising lack of introduction. Thanks anyway.

steve....@gmail.com

unread,
Jun 7, 2006, 8:08:23 PM6/7/06
to
I wrote:
> Surprising lack of introduction.

Oops, I forgot: it's self-documenting code. ;)

na...@natecull.org

unread,
Jun 7, 2006, 11:38:02 PM6/7/06
to

I did have a slightly more substantial post a few weeks back, when I
originally released it (though not to the ifarchive). And yes, the code
is documented, though somewhat minimally (via DOCUMENTATION section).
However raif is pretty high traffic at the moment and things tend to
scroll off so a precis is probably in order.

Planner is the I7 port of RAP, which is a cut-down bare-bones
goal-seeking library inspired by the Oz Project's HAP planner. I
released the original version for TADS around 1999, then an I6 version,
intended to release a Platypus version but got stuck, and now that I7
is out I've reimplemented it yet again.

You give it a triad of (relation, object, object) and a library of
rules that implement plans, and it then tries to make that statement
come true by backward-chaining a shortest path from the desired future
state to the current world state.

Its intelligence depends on what plans are programmed into it. Version
1 has some basic rules for travelling to rooms (using I7's built-in
shortest path routefinder), opening closed and locked objects, and
manipulating contained/supported objects. It does not yet cope
automatically with finding keys for locked doors, since that would
require completely rewriting the routefinder and I am lazy (and also
wanted to demo the non-routefinding aspects of Planner, since the first
question I often get is 'but doesn't I7 do routefinding automatically
so what's the point?')

There is an included demo 'game' which is amazingly lame but hopefully
shows a glimpse of what the engine is capable of and how to use it. The
syntax is rather scarily baroque but it's the best I can manage so far:
it really needs a language with list constructions, or at least more
generic data structures than the Z-machine provides. Hopefully it's
understandable. Drop me an email if you want help.

I don't pretend to actually know how to integrate Planner into a real
game. I wrote it because it was a fun thing to do, not because it
solves an actual problem.

I haven't yet specified licencing because I'm not sure what the
official Inform 7 standard for extensions will be (I presume CC-BY-SA,
but Public Domain may be more appropriate). Permission is hereby
granted to do whatever the heck you like with it.

chev...@gmail.com

unread,
Jun 8, 2006, 3:58:34 AM6/8/06
to
na...@natecull.org wrote:

> I don't pretend to actually know how to integrate Planner into a real
> game. I wrote it because it was a fun thing to do, not because it
> solves an actual problem.

I have high hopes for Planner. I'm hoping to use it to create a nasty
NPC that sneaks around looking for a weapon and ammunition and then
goes off trying to kill any NPCs that are friendly to the player and
then the player.

Alexander Deubelbeiss

unread,
Jun 9, 2006, 3:42:45 AM6/9/06
to
chev...@gmail.com wrote:

> I have high hopes for Planner. I'm hoping to use it to create a nasty
> NPC that sneaks around looking for a weapon and ammunition and then
> goes off trying to kill any NPCs that are friendly to the player and
> then the player.

And the PC's name will be Marjorie Hopkirk, of course.

Brian Campbell

unread,
Jun 9, 2006, 11:05:31 AM6/9/06
to
na...@natecull.org wrote:
> I haven't yet specified licencing because I'm not sure what the
> official Inform 7 standard for extensions will be (I presume CC-BY-SA,
> but Public Domain may be more appropriate). Permission is hereby
> granted to do whatever the heck you like with it.

Isn't the standard license the most permissive Creative Commons license
(CC-BY)? That's what it is according to
<http://inform-fiction.org/I7/Download%20-%20Extensions.html>, which is
admittedly under construction. It was my impression that that's what
license it had to be under to be eligible for the official I7
extensions page. Given that I7 extensions pretty much require you to
credit the author when you use them ("Include Locksmith by Emily
Short"), the creative commons attribution license makes perfect sense.
Of course, given that the public domain is even more permissive, that
would probably be fine, too.

-- Brian

steve....@gmail.com

unread,
Jun 10, 2006, 5:04:39 AM6/10/06
to
The extension has appeared in the ifarchive, thanks again. A few
questions.

I don't understand the claims you've made about how this version is
much different than previous versions. I look at it and I think, yes
it's the same algorithm. Could you identify where is the critical
difference, and why it's critical?

You complain that the language does not support lists. But you use
tables, and that seems to work fine. What's the advantage of doing the
same thing with lists?

You noted that the code is baroque, but it doesn't seem particularly
more (or less) baroque than other versions. What strikes me is how
unnatural it is, and I think this is what you mean -- but unnatural in
which way? By "baroque," do you mean that it reads like (*gasp*)
computer code? Are you making a point about programming in I7's NL-like
syntax?

If not the latter, could you share your feelings programming in I7's
NL-like syntax? This is the first bit of real programming I've seen
written in I7, and while I think it very obviously demolishes the NL
pretense, it also shows that I7 is a programming language (in the sense
that "programming language" is a good thing, after all). Still, it
seems counter-optimised for writing code; I wouldn't say baroque, as
that implies artistic. Kludgy perhaps?

Zonk the Troll Ghost

unread,
Jun 10, 2006, 10:51:02 AM6/10/06
to

steve....@gmail.com wrote:
> This is the first bit of real programming I've seen
> written in I7

Then what are, say, the full sample games written in I7? Examples of
non-programming? Wouldn't that imply that creating a complete work of
intereactive fiction with I7 doesn't require programming, an
implication that would undermine your thesis?

na...@natecull.org

unread,
Jun 11, 2006, 3:11:46 AM6/11/06
to
> I don't understand the claims you've made about how this version is
> much different than previous versions. I look at it and I think, yes
> it's the same algorithm. Could you identify where is the critical
> difference, and why it's critical?

It's the same core search algorithm, yes. The main difference is in how
it uses I7 rules to structure the rulebase. There are a few changes to
the internal storage of the planning table - no 'opcode' field, as it
uses Kind to distinguish between planning-relations and
planning-actions. Terminology has also changed to match I7, so it
refers to 'relations' rather than 'conditions'.

The way plans are written is similar to the I6 approach: each plan is
essentially a function responding to (actor, relation, object, object,
plan#, step#), but 'when' clauses in I7 rules are used to catch (actor,
relation, object, object). The 'plan [number]' and 'suggest [relation]
with [object] and [object]' phrase syntaxes are completely new. You
don't have to manually keep track of how many steps are in each plan
and report that number as 'step 0' as you did for I6. This should
making writing simple plans a lot easier.


> You complain that the language does not support lists. But you use
> tables, and that seems to work fine. What's the advantage of doing the
> same thing with lists?

When I originally wrote RAP, it was using TADS2 lists to store a plan.
So a plan there looked roughly like:

[
[
[<relation> <object1> <object2>]
[<relation> <object1> <object2>]
...
[<action> <object1> <object2>]
]
[
[ <relation> <object1> <object2>]
...
[<action> <object1> <object2]
]
...
]

so you could, from one 'generate me a plan' function, return a single
list construct containing a variable number of alternative plans, each
consisting of a variable number of steps. You could also put multiple
objects in each 'object' slot just by putting a list in, eo, eg, you
could handle >GET THE KEY AND THE PADLOCK as an action step. It could
also be expanded indefinitely if, for instance, at a later date you
decided you wanted to handle object specifications (>TAKE ALL THE RED
THINGS FROM THE BOX) etc, or add adverbs or a third object to
sentences. I never wrote code to handle any of these cases, and some of
them may have been impossible given the limitations of the TADS2
parser, but the capability for unlimited future expansion was certainly
there. Still is, in the TADS world.

Another very useful thing one could do with lists, which I didn't
implement in TADS but wrote some initial code to do in I6, was build a
capability for actors to not use *real* knowledge of the world state,
but each keep track of what they *believed* was the current state of
any given property of any given object. So they could, eg, when trying
to obtain a portable object, first try looking in the location where
they last knew it to be. This is a whole bigger kettle of fish, but it
would be the first step towards making RAP/Planner much more
interesting. Again, it *can* be implemented, to a first approximation,
using rigidly fixed-sized arrays in a Z-machine/I6 type world, but
doing so pretty much means that you force design constraints onto what
type of information can be stored, right up front. There's no
flexibility for change if the world model changes.

That's why lists are more flexible than arrays - they're infinitely
flexible. But they're also a real pain to implement in a language
because you have to build a dynamic memory allocator and garbage
collection system. TADS has this; the Z-machine really doesn't have
space to do it; Glulx has the capacity but would require the dynamic
memory allocation machinery built on top of it, and, probably, a new
language constructed from the ground up to use that capability.


> You noted that the code is baroque, but it doesn't seem particularly
> more (or less) baroque than other versions. What strikes me is how
> unnatural it is, and I think this is what you mean -- but unnatural in
> which way? By "baroque," do you mean that it reads like (*gasp*)
> computer code? Are you making a point about programming in I7's NL-like
> syntax?

Yes, the syntax reads like very tortured English in some cases - except
in the definition of rules, where it is mostly clearer. The main thing
that makes it cumbersome to me is the need to use lots of long 'when'
clauses on the rules, but also there is a fair bit of complication
based on the absence of any complex data structure type (not just
lists, but the simplest implementation of the 'plan' data structure
would use either lists or arrays). This is shared with the I6 version.

I probably need to write some documentation explaining exactly how the
'suggest...' phrase works, because it is not very straightforward, even
to me. The planning rules are reexamined for every step of every plan,
and that's not very efficient. But I don't think there's any more
straightforward way of doing what I'm trying to do, given the
facilities available in I6 and the Z-machine.

I should point out that creating extensible plans is pretty much
impossible to do properly in I6 compared to I7. The rule-based design
really, really shines here. Doesn't quite do everything right, but at
least each rule can be overridden. Trying to do that with object
inheritance was a nightmare of hooks and a large reason of why I
abandoned the project.


> If not the latter, could you share your feelings programming in I7's
> NL-like syntax? This is the first bit of real programming I've seen
> written in I7, and while I think it very obviously demolishes the NL
> pretense, it also shows that I7 is a programming language (in the sense
> that "programming language" is a good thing, after all). Still, it
> seems counter-optimised for writing code; I wouldn't say baroque, as
> that implies artistic. Kludgy perhaps?

Some random observations:

The 'phrase' construct is very powerful, but it can become very hard to
tell exactly what words in a sentence are purely syntax markers and
what are parameters.

The NL seems to work best when it is directly describing world model
elements. When one is writing code to deal with abstractions, it gets
trickier.

The table routines are pretty useful, though again I'm uncomfortable
with the way one is expected to just pile words into a phrase and hope
the compiler guesses correctly what is syntax, what is a literal, and
what is a variable name. Maybe parentheses will help here.

I don't like that I have to use lots and lots of globals, and that in
fact almost every operation (such as table operations) relies on lots
of implicit shared global state (such as which row is 'the current
row') that can break if, eg, you run a function between doing a table
row lookup and testing a table field. This seems to me a very 1950s way
of programming and I'd much prefer to be able to make things
function-call-safe. I think mostly this comes about because the
Z-machine is such a small machine, but it is also the way the I6
library is designed.


I'm interested, for the future, in trying to build a very small dynamic
language - maybe similar to Floo or Joy - on top of Glulx, with the
hope that this would make it possible to create an I7-like coding
environment inside the VM itself. I'm not sure that this is an entirely
sane dream, but given 3Ghz processors and a 2GB virtual RAM capacity
I'm not sure it's unfeasible either.

What if we were able to type something like this at a Glulxe prompt:

>CONSTRUCT MODE ENGLISH
Entering construction mode (English)

>>A CAT IS A KIND OF ANIMAL
Understood: (a cat) (is a kind of) (animal). Created new class 'Cat' as
child of class 'Animal'.

>>CONSTRUCT MODE LISP
Entering construction mode (Lisp)

>>(THING CAT TABBY)
Understood: (tabby) (is an instance of) (cat). Created new object
'Tabby' of class 'Cat'.

... and so on? There's probably a whole set of reasons why this is a
Bad Idea, but I'm kind of interested in exploring them.

Andrew Plotkin

unread,
Jun 11, 2006, 11:00:29 AM6/11/06
to
Here, na...@natecull.org wrote:
>
> That's why lists are more flexible than arrays - they're infinitely
> flexible. But they're also a real pain to implement in a language
> because you have to build a dynamic memory allocator and garbage
> collection system. TADS has this; the Z-machine really doesn't have
> space to do it; Glulx has the capacity but would require the dynamic
> memory allocation machinery built on top of it, and, probably, a new
> language constructed from the ground up to use that capability.

I have been seriously thinking about that dynamic malloc extension for
Glulx. It is not entirely trivial, but not too hard either. (I'd have
to either keep the heap organization description -- the equivalent of
the malloc arena -- in VM memory, or be able to serialize it for
save/restore. Neither is pleasant. I'm leaning towards the latter.)

Would it require a new language? I7 phrases for cons/car/cdr would let
you get some stuff done.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*
It's a nice distinction to tell American soldiers (and Iraqis) to die in
Iraq for the sake of democracy (ignoring the question of whether it's
*working*) and then whine that "The Constitution is not a suicide pact."

steve....@gmail.com

unread,
Jun 11, 2006, 6:02:39 PM6/11/06
to
Nate Cull wrote, quoting me:

> > I don't understand the claims you've made about how this version is

> > much different than previous versions. [...]


> > Could you identify where is the critical
> > difference, and why it's critical?
>
> It's the same core search algorithm, yes. The main difference is in how
> it uses I7 rules to structure the rulebase.

I looked at the code, and while I see that the rulebase is structured
differently, I don't see that it is structured in any way better. I see
the restructuring as minor and cosmetic. Could you please explain where
there's some substantial gain?

> There are a few changes to
> the internal storage of the planning table - no 'opcode' field, as it
> uses Kind to distinguish between planning-relations and
> planning-actions. Terminology has also changed to match I7, so it
> refers to 'relations' rather than 'conditions'.

I was thinking of eliminating the opcode in the TADS 3 version. I
decided to keep it because it makes things clearer.

> The way plans are written is similar to the I6 approach: each plan is
> essentially a function responding to (actor, relation, object, object,
> plan#, step#), but 'when' clauses in I7 rules are used to catch (actor,
> relation, object, object). The 'plan [number]' and 'suggest [relation]
> with [object] and [object]' phrase syntaxes are completely new. You
> don't have to manually keep track of how many steps are in each plan
> and report that number as 'step 0' as you did for I6. This should
> making writing simple plans a lot easier.

Oh, I've just worked on the TADS side of the thing. I was unaware of
these problems.

It's my sense that I6 is difficult to program in. It looks like I7, as
bad as it is syntactically for programming, is slightly better to
program in. Ironic, perhaps.

But you made some statement that this I7Planner is the first version
that's really usable. Now, I don't know whether or not the I6 version
was usable -- I never tried. Were you counting your TADS 2 version,
when you said this? Or were you meaning only that this is the first
usable planner available in Inform?

> > You complain that the language does not support lists. But you use
> > tables, and that seems to work fine. What's the advantage of doing the
> > same thing with lists?
>
> When I originally wrote RAP, it was using TADS2 lists to store a plan.
> So a plan there looked roughly like:
>
> [
> [
> [<relation> <object1> <object2>]
> [<relation> <object1> <object2>]
> ...
> [<action> <object1> <object2>]
> ]
> [
> [ <relation> <object1> <object2>]
> ...
> [<action> <object1> <object2]
> ]
> ...
> ]
>
> so you could, from one 'generate me a plan' function, return a single
> list construct containing a variable number of alternative plans, each
> consisting of a variable number of steps. You could also put multiple
> objects in each 'object' slot just by putting a list in, eo, eg, you
> could handle >GET THE KEY AND THE PADLOCK as an action step. It could
> also be expanded indefinitely if, for instance, at a later date you
> decided you wanted to handle object specifications (>TAKE ALL THE RED
> THINGS FROM THE BOX) etc, or add adverbs or a third object to

> sentences. [...]

So is the problem that you can't nest tables in I7? (I.e., an element
in the table is another table, or a pointer to a table.)

> Another very useful thing one could do with lists, which I didn't
> implement in TADS but wrote some initial code to do in I6, was build a
> capability for actors to not use *real* knowledge of the world state,
> but each keep track of what they *believed* was the current state of
> any given property of any given object.

Yes, it was easy to do this in TADS. The TADS 3 version supports this,
and quite a bit more.

> Yes, the syntax reads like very tortured English in some cases - except
> in the definition of rules, where it is mostly clearer.

To whom? The programmer?

> I should point out that creating extensible plans is pretty much
> impossible to do properly in I6 compared to I7. The rule-based design
> really, really shines here. Doesn't quite do everything right, but at
> least each rule can be overridden. Trying to do that with object
> inheritance was a nightmare of hooks and a large reason of why I
> abandoned the project.

I don't understand. What do you mean by "extensible plan"?

I suspect that this is the major point, so please elaborate.

> The NL seems to work best when it is directly describing world model
> elements. When one is writing code to deal with abstractions, it gets
> trickier.

The syntax is a programming syntax, desighed to be disguised as NL so
long as you're within the trivial target, which is basically filling in
a database. But outside of that, it's just a normal programming syntax,
right? Could you explain what you mean by "tricky"?

na...@natecull.org

unread,
Jun 11, 2006, 8:36:21 PM6/11/06
to

Andrew Plotkin wrote:
> I have been seriously thinking about that dynamic malloc extension for
> Glulx. It is not entirely trivial, but not too hard either. (I'd have
> to either keep the heap organization description -- the equivalent of
> the malloc arena -- in VM memory, or be able to serialize it for
> save/restore. Neither is pleasant. I'm leaning towards the latter.)

Mmm. I was thinking about writing an allocator in Glulx bytecode
itself, which I guess would be slow. Can't quite get my head around how
one would organise it though. There seem to be so many different
strategies, all not-quite-optimal, and storing the free list itself
would take up a fair bit of VM RAM.


> Would it require a new language? I7 phrases for cons/car/cdr would let
> you get some stuff done.

I suppose. It seems that one would really want a list constructor
syntax otherwise it would be just awkward to work with.

I mean, if all we wanted was lists, and not dynamic strings, it would
be a lot simpler to write an allocator since we'd be dealing with
fixed-size memory cells (say 8 bytes). And we could probably do that in
I7 right now just with a table...

... that's worth playing with, that is.

Maybe we can use I7 syntax. It might be powerful enough. It's more that
I find the syntax intractable for *me* to get my head around, I can
never quite predict what's legally parseable.

I like the idea of a fully dynamic language, but I also like
precompiled strings and not having to deal with allocating and
garbage-collecting arbitrary chunks.

vaporware

unread,
Jun 11, 2006, 8:45:25 PM6/11/06
to
na...@natecull.org wrote:
[snip]

> I don't like that I have to use lots and lots of globals, and that in
> fact almost every operation (such as table operations) relies on lots
> of implicit shared global state (such as which row is 'the current
> row') that can break if, eg, you run a function between doing a table
> row lookup and testing a table field. This seems to me a very 1950s way
> of programming and I'd much prefer to be able to make things
> function-call-safe. I think mostly this comes about because the
> Z-machine is such a small machine, but it is also the way the I6
> library is designed.

Actually, tables use local state. The current table and current row are
stored in the I6 variables ct_0 and ct_1, which are local to any
phrase/rule that uses table operations. You can't nest one table loop
inside another (or use "listed in" inside a table loop, etc.), but you
should be able to call one phrase that uses tables from another without
disturbing the latter's state.

vw

na...@natecull.org

unread,
Jun 11, 2006, 9:25:33 PM6/11/06
to

steve....@gmail.com wrote:

> I looked at the code, and while I see that the rulebase is structured
> differently, I don't see that it is structured in any way better. I see
> the restructuring as minor and cosmetic. Could you please explain where
> there's some substantial gain?

Primarily with rules.


> It's my sense that I6 is difficult to program in. It looks like I7, as
> bad as it is syntactically for programming, is slightly better to
> program in. Ironic, perhaps.

Not really, since I7 was intended to be easier to program in...

> But you made some statement that this I7Planner is the first version
> that's really usable. Now, I don't know whether or not the I6 version
> was usable -- I never tried. Were you counting your TADS 2 version,
> when you said this? Or were you meaning only that this is the first
> usable planner available in Inform?

I was counting TADS too. Your mileage may have varied, but a big
drawback with both previous versions is that it's very hard to define a
library of generic default plans and then override just the special
cases you want special plans for. If you're only ever writing a game
for yourself, that may not be so much of an issue.

With I7's rules, it's a lot easier to cleanly separate library and game
code. Not quite as easy as it could be, since 'when' clauses don't seem
to be ordered by specificity, but


> So is the problem that you can't nest tables in I7? (I.e., an element
> in the table is another table, or a pointer to a table.)

You can do that, yes. But every subtable has to be given a unique name
and defined separately. So it's a facility best used sparingly. And
there's no clean syntax for defining a nested data structure inside a
table. It *can* be done, I think, but it's not pretty, it takes manual
housekeeping work, and the code you'd type into your story file would
not directly represent the structure of the data.

It might be an alternative approach to using rules, though. I prefer
rules because you can mix plans with code - not so easy to do that with
a table. (Say phrases, yes. Or the name of a rule in a table row. But
if you're going to do that you might as well just wrap the whole thing
in a rule.)


> > Yes, the syntax reads like very tortured English in some cases - except
> > in the definition of rules, where it is mostly clearer.
>
> To whom? The programmer?

Admittedly I just looked at Basic Plans (there's a bug in Version 1,
hooray) and didn't find it as clear as when I was writing it. :) Needs
lots more comments.

I would also like a much terser syntax. Hmm. Maybe the jury's still out
on how readable it is compared to I6. I think I could write a rule
class that did everything I7 rules do and was more flexible for my
needs:

planning rule when the relation is being-in and the desired param1 is
broth and the desired param2 is the crucible:

vs

Rule
with rel being-in,
par1 broth,
par2 crucible,
plan [
...
]
;


That could have legs. Anyone up for an I7 -> I6 backport project?
Implement a rule system, scenes, regions, NPC actions, values, tables,
maybe crude object specifiers... the core bits of the world model and
semantics.Then we could do direct apples to apples comparisons of just
the NL syntax.

(If I6 had compile-time macros, we could create arbitrary syntax for
things like lists, and probably also be able to make naming a lot
simpler - reproduce I7's trick of defining parse, display and internal
names all at once. Maybe a simple extensible preprocessor with a macro
facility?)


> I don't understand. What do you mean by "extensible plan"?

What I said above about separating generic library behaviour from
specific situational plans.

steve....@gmail.com

unread,
Jun 12, 2006, 11:07:48 AM6/12/06
to
Nate Cull wrote:
> > I looked at the code, and while I see that the rulebase is structured
> > differently, I don't see that it is structured in any way better. I see
> > the restructuring as minor and cosmetic. Could you please explain where
> > there's some substantial gain?
>
> Primarily with rules.
[...]

> I was counting TADS too. Your mileage may have varied, but a big
> drawback with both previous versions is that it's very hard to define a
> library of generic default plans and then override just the special
> cases you want special plans for.

The TADS 3 version supporte special case overrides. (The same hook
could have been built into the TADS 2 version.) Again I am not seeing
how the I7 version makes a really significant advance.

The only shortcoming of the TADS 3 version here is that you'll need to
resolve conflicts by hand. (A conflict occurs when more than one
parameter has a custom override.) Is that the thing you're talking
about that the I7 version handles better? Or is there something else?

> > It's my sense that I6 is difficult to program in. It looks like I7, as
> > bad as it is syntactically for programming, is slightly better to
> > program in. Ironic, perhaps.
>
> Not really, since I7 was intended to be easier to program in...

Of course I didn't mean "The hat is on the table"-style programming,
but conventional procedural programming like we're talking about and
looking at in this context. The amusing thing to me is that a language
targeted to "The hat is on the table" might be nevertheless better at
procedural programming than I6.

na...@natecull.org

unread,
Jun 12, 2006, 6:31:45 PM6/12/06
to

steve....@gmail.com wrote:

> The TADS 3 version supporte special case overrides. (The same hook
> could have been built into the TADS 2 version.) Again I am not seeing
> how the I7 version makes a really significant advance.

I can't speak for TADS3, but TADS2 certainly does not have rules.

I'm not sure how many more ways you need me to say 'The answer is
rules.'

> Of course I didn't mean "The hat is on the table"-style programming,
> but conventional procedural programming like we're talking about and
> looking at in this context. The amusing thing to me is that a language
> targeted to "The hat is on the table" might be nevertheless better at
> procedural programming than I6.

Well, see. The thing is. This is the thing. IF programming is *not*
ever merely 'procedural programming'. It's a mix of declarative and
procedural forms. This requirement is intrinsic to the problem domain.
The best language for this would a language that allows both. I6 and
I7 and TADS all approach this from slightly different angles.

That being said, yes, I7 provides somewhat better facilities (in some
senses) even for your narrow definition of "purely procedural"
programming (even though this can never be separated completely from
the data structures that you're manipulating in IF) - and this is not
really surprising, because, duh. It's the second take on a language. Of
course it will attempt to improve.

steve....@gmail.com

unread,
Jun 12, 2006, 8:09:41 PM6/12/06
to
Nate Cull wrote, quoting me:
> > The TADS 3 version supporte special case overrides. (The same hook
> > could have been built into the TADS 2 version.) Again I am not seeing
> > how the I7 version makes a really significant advance.
>
> I can't speak for TADS3, but TADS2 certainly does not have rules.

TADS 3 doesn't have "rules" but the TADS 3 version of RAP does allow
for easy special-case overrides.

> I'm not sure how many more ways you need me to say 'The answer is
> rules.'

I think you were saying that "rules" makes it easy/easier to do special
case overrides. Is that the main benefit? Are there any other benefits
of the rules? ("The answer is rules" is not a terribly enlightening
answer -- sorry if I'm being dense.)

na...@natecull.org

unread,
Jun 12, 2006, 8:29:35 PM6/12/06
to

steve....@gmail.com wrote:

> > I'm not sure how many more ways you need me to say 'The answer is
> > rules.'
>
> I think you were saying that "rules" makes it easy/easier to do special
> case overrides. Is that the main benefit? Are there any other benefits
> of the rules? ("The answer is rules" is not a terribly enlightening
> answer -- sorry if I'm being dense.)

Yes, you are being dense.

na...@natecull.org

unread,
Jun 12, 2006, 9:17:38 PM6/12/06
to

steve....@gmail.com wrote:
> I think you were saying that "rules" makes it easy/easier to do special
> case overrides. Is that the main benefit? Are there any other benefits
> of the rules? ("The answer is rules" is not a terribly enlightening
> answer -- sorry if I'm being dense.)

The long answer:

Special case overrides is what it's all about. Rules are nothing *but*
special case overrides. There's a big difference between providing
hooks for certain operations and allowing everything to be
configurable. Seriously, please go read the I7 docs and play with it a
bit. I don't want to have to explain everything from first principles.

But some examples:

Suppose you want to provide a library of plans for implementing (open
object)

1) For a simple openable container: easy, get within reach of it, find
the key and unlock it if it needs one, open it. This is the case Basic
Plans implements.

2) How about if it's a container locked, but with a combination lock
rather than a key? Then maybe you want to find the code, then enter it.

3) If it's a door, similar thing, only a door can be in two places at
once.

4) What about if it's a pressure door on a spaceship? Maybe you need to
check the pressure is equalised or that you're wearing a spacesuit
first. Perhaps that's defined in your Space Stories library.

5) Maybe it's a one-off special door that can't be opened normally.
Maybe you have to break it down. Maybe you need to bribe a guard to
open it. Maybe.... an infinity of game- and object- specific
possibilities.

6) Maybe the same container or door behaves differently if it's in a
different state, or during a different scene of the game. Maybe it's an
ordinary lockable door wih key during all except Power Failure scene,
when the fallen electric cable makes it electrocute anyone who touches
the handle, so you need to be wearing the rubber gloves before opening
it. You don't want to rewrite all of your door code just to handle that
one case - but you need to break that case out on its own, or bzzt,
fried NPC.

7) The player has a sonic screwdriver that can bypass locks. (open, any
door, with sonic screwdriver) should be treated differently than (open,
door).

Assuming you want your NPC to do these things and not just be content
with the generic 1) and 3) behaviour, then you're going to need a *lot*
of configurability. And there's three main objects involved in any
plan: the relation/condition, the first object, the second object.
Should all of these conditions be put on a method on the 'open' object?
The 'door' object? The 'sonic screwdriver' object? The 'power failure'
scene object?

This is where OO breaks down, because this logic does not belong with
any particular object of the three, so it can't be easily overridden
simply by subclassing one object and replacing one method. It's not a
matter of *specialising* already neatly compartmented functionality -
it's a matter of *completely throwing away and replacing arbitrarily
complex behaviour based on a tangled hierarchy of equally complex
conditions*. And it needs to be broken down into components that play
nicely with includable libraries, so the basic door rules go into Basic
Plans and the vacuum door rules go into Space Stories and my own game
Alien Time Doctor From Venus gets to use the sonic screwdriver
override... but not on Thursdays, when the moon is full and we're
playing as Godzilla in Venice.

You begin to see the complexity of the problem. If you don't, then
tough. The complexity remains regardless of your ability to see it.

Rules neatly solve this problem by abstracting override logic into,
essentially, a class of its own. Everything becomes a hook.

If you've developed an alternative configuration solution which is even
halfway as powerful as generic rules, do share. I'll be intrigued to
look at it.

na...@natecull.org

unread,
Jun 12, 2006, 9:55:38 PM6/12/06
to
A tangent:

Granted that I7 rules are so neat, I still find myself very cramped by
I7's 'look but don't touch' approach to the rest of the world model.
The compiler gets to play with lots of interesting markup such as
adjectives, definitions, relations, and the like, but I don't have
access to any of this at runtime.

This is a problem when it comes to wanting to write planning NPCs. The
complexity I just mentioned comes from the fact that writing plans is
essentially reverse-engineering the structure of the story world. So in
a game with planning NPCs, I'm writing rules twice: once to implement
the special-cases of the world behaviour, and once to make the NPCs
aware of this and know how to handle it.

This seems like a waste of both my time and the computer's, and
violates the principle of 'Don't Repeat Yourself'.

The logical thing to do would be to create data/code structures that
combine the two jobs: describing how the world works, and giving the
NPCs instructions on how to manipulate that world. I'd write code
*once*, and NPCs would Just Understand how to get things done. Then I
could stop micromanaging NPCs so much and get on with building the
world and creating puzzles and drama. Happiness for everyone, and much
more lifelike NPCs. Pretty much for free.

But I can't do this in Inform (6 or 7, but the gulf is wider in 7):
because only the compiler gets to touch the top-level description of
the world; because that description is written in such a complicated
and hard-to-parse language (pseudo-English) full of its own special
cases at the syntactic level let alone semantics, that merely turning
this into an abstract world definition must be a chore in its own right
and certainly not something to be done at runtime; because a lot of
this valuable information is either simply thrown away or compiled down
to inscrutable procedures with no runtime API; and leaving completely
aside the not-entirely-trivial question of source code access and
licencing - even if I did get to see NI source, can I then use any of
its algorithms in my game, or am I breaching copyright? This can be
solved by a rerelease with a sufficiently liberal licence, but the
basic design of the language syntax and compilation architecture can't
be.

The more I look at planning, the more I chafe at a language that ties
me to a very narrow, first-order view of the world. I want the
capability to read all of the world at runtime, to understand and
define new relations, to store arbitarily complex second- and
third-order data: 'where does character X believe character Y thinks
the location of the McGuffin is?'

And I probably want a sufficiently powerful logical-inferencing
language, like Prolog, to handle these kinds of things. Frankly, what I
want is a language simple, extensible and powerful enough to write the
compiler for an I7-like language, but available, along with all the
abstract syntax trees and world model inferences and intermediate
steps, at runtime.

Something like PicoLisp (http://software-lab.de/ref.html) or Factor
(http://www.factorcode.org), perhaps.

Andrew Plotkin

unread,
Jun 12, 2006, 11:50:35 PM6/12/06
to
Here, na...@natecull.org wrote:
>
> Granted that I7 rules are so neat, I still find myself very cramped by
> I7's 'look but don't touch' approach to the rest of the world model.
> The compiler gets to play with lots of interesting markup such as
> adjectives, definitions, relations, and the like, but I don't have
> access to any of this at runtime.
>
> This is a problem when it comes to wanting to write planning NPCs. The
> complexity I just mentioned comes from the fact that writing plans is
> essentially reverse-engineering the structure of the story world. So in
> a game with planning NPCs, I'm writing rules twice: once to implement
> the special-cases of the world behaviour, and once to make the NPCs
> aware of this and know how to handle it.

I am all with the idea of not writing code twice. But how do you see
using first-class world-model elements (run-time relations, rules,
etc) to solve this problem? I mean, what would your ideal solution
look like?

The I7 model for this stuff is, I guess, exemplified by the "try
silently" system. The library separates a "report" stage in its rules,
so an NPC can try something and (if it doesn't work) either print an
NPC-specific complaint or try something else. (No, I have no idea how
you're supposed to suppress "check" rules in this process.)

I'm reasonably sure (without having used it) that this is a pain in
the ass. Nonetheless, it seems like the right idea: declare the
structure of cases and exceptions at compile time, and then make use
of it at runtime in two different contexts.

Kevin Forchione

unread,
Jun 13, 2006, 12:50:03 AM6/13/06
to
<steve....@gmail.com> wrote in message
news:1150157381.4...@i40g2000cwc.googlegroups.com...

> Nate Cull wrote, quoting me:
>> > The TADS 3 version supporte special case overrides. (The same hook
>> > could have been built into the TADS 2 version.) Again I am not seeing
>> > how the I7 version makes a really significant advance.
>>
>> I can't speak for TADS3, but TADS2 certainly does not have rules.
>
> TADS 3 doesn't have "rules" but the TADS 3 version of RAP does allow
> for easy special-case overrides.

The TADS 3 module could be rewritten to be rule based. Don't see why not. As
I understand it the "rules" of I7 are nothing more than routines that return
either true (if successful or failure) and false (if not applicable).
There's no reason why the TADS 3 RAP mechanism couldn't do the same, if
rules are the bread and butter of your existence.

--Kevin


vaporware

unread,
Jun 13, 2006, 1:01:06 AM6/13/06
to
Kevin Forchione wrote:
> The TADS 3 module could be rewritten to be rule based. Don't see why not. As
> I understand it the "rules" of I7 are nothing more than routines that return
> either true (if successful or failure) and false (if not applicable).
> There's no reason why the TADS 3 RAP mechanism couldn't do the same, if
> rules are the bread and butter of your existence.

Well, one nice thing about I7's rules is that the compiler
automatically sorts them by specificity, so an "opening the cell door
during Power Outage" rule will always have a chance to run before the
plain old "opening a door" rule.

vw

na...@natecull.org

unread,
Jun 13, 2006, 1:18:27 AM6/13/06
to

Kevin Forchione wrote:
> The TADS 3 module could be rewritten to be rule based. Don't see why not. As
> I understand it the "rules" of I7 are nothing more than routines that return
> either true (if successful or failure) and false (if not applicable).
> There's no reason why the TADS 3 RAP mechanism couldn't do the same, if
> rules are the bread and butter of your existence.

Yes, and I think the I6 version could do this too. And quite possibly
an OO approach to rules would give you more flexibility than the
fixed-at-compile-time rule syntax in I7. (TADS3 quite possibly already
does a large part of the things I'm after - fully dynamic VM, hackable
parser, I'm not entirely sure why I haven't tried using it yet. Mostly
fatigue from its perpetual beta-ness and a shock reaction to the size
of the library. And an irrational fondness for the Z-machine, but I'm
reconciling myself to abandoning that anyway.)

My point was that I7 gives you rules 'for free', and this is a
non-trivial win. In the process of reimplementing Planner to be
'I7-like' I found it was a much more natural solution for the
configurability problem that I'd been struggling with for ages.

Like scenes, regions, and state machines for actors, rules I think are
one of those simple constructs that could be put in a library even in
an existing language and make life a lot simpler for everyone.

na...@natecull.org

unread,
Jun 13, 2006, 2:23:02 AM6/13/06
to

Andrew Plotkin wrote:
> I am all with the idea of not writing code twice. But how do you see
> using first-class world-model elements (run-time relations, rules,
> etc) to solve this problem? I mean, what would your ideal solution
> look like?

Not entirely sure at this point. I suspect some of what I want can be
done by sufficiently cunning abstraction of the 'world logic' to use,
eg, table lookup rather than direct rules. But I think that using
tables will only take one so far.

Eg, in the 'Alchemy' demo v1, currently I have a hacked-together rule
that transmutes three objects into one if they are together in the
crucible. Since I used a 'to decide if' phrase called from inside a
rule to do this (it was the simplest thing that came to mind), this is
opaque to the planning code, so I have to have a similar set of
statements inside my plan. What I should do instead, and will in the
next version, is have a 'table of transmutations' that lists pairs or
series of reagants and the resulting product. That way, the 'to have an
object' planning rule can be written to consult the table of
transmutations in reverse, and calculate plans on the fly. That bit
seems easy enough, and can be done within the current I7 paradigm.

I suppose I am visualising a system where more of the world is data
rather than code. Hmm. A Planner-friendly implementation of the
electrified door perhaps, would have some kind of data structure saying
something like:

* when the electrical cable is touching anything conductive, that thing
is electrified
(except for the following exceptions, etc)
* for a door to be opened, it must first be unlocked
---- if violated, give a "it's locked" message
*** [rule inserted here] it must also be electrically safe for the
opener
---- if violated, electrocute the opener
** the opener must then be able to touch the door (or the device which
opens the door)
--- if violated, this case will probably be caught by parsing rules
anyway
** the opener can then >OPEN THE DOOR and it will succeed, changing the
door's state to Open and giving the standard open message

Urgh. This is glossing over a lot of important details. I can see a lot
of trickiness there, since this would meld together multiple flows of
execution and I'm not sure how easy it would be to understand. It also
runs against the problem you mentioned of there not being an easy way
to tell when a given rule 'succeeds' or 'fails'. If you succeed in
getting electrocuted, that's not exactly a 'failure' of an action -
something certainly happens, and world state ends up being changed. A
turn is used. But the door does not get opened.

But, um. I would like for the planning engine to at least somehow be
aware of the existence of rules relating to the door, and preferably
somehow to be aware of what they logically do.

... otoh, I would also like for there to be room for different actors
to have different levels of knowledge and possibly whole different sets
of plans, and not necessarily automatically know the 'correct'
behaviour that the world implements. But have 'read world's mind'
available as a default.

Still groping towards ideas, really.


> The I7 model for this stuff is, I guess, exemplified by the "try
> silently" system. The library separates a "report" stage in its rules,
> so an NPC can try something and (if it doesn't work) either print an
> NPC-specific complaint or try something else. (No, I have no idea how
> you're supposed to suppress "check" rules in this process.)

Yes, I suppose. It's approaching the problem from one angle, and I
think I'm coming at it from the other: rather than having the runtime
implementation of an action be the definitive state, have some kind of
coded representation of the interaction of rules be the definitive
dataset, with both plans and runtime checks being inferred from this.

I mean, this may be hard. This may be NP-hard. It's probably very close
to the place where symbolic AI research finally woke up with a hangover
and three-day stubble and went 'ennnh, let's go hack Java instead and
get rich'.

I dunno. It *seems* like it should be easy, somehow, to be able to
Prolog something up that goes:
* >OPEN [THING] is an action. It changes the state of [THING] from
Closed to Open except where these rules apply: ...
* We want [THING] to be open
* Do any of these rules apply to us?
* Yes, the door is currently electrified (Rule X)
* Opening an electrified door kills the opener (Rule Y)
* We don't want to die unless it's scene Heroic Sacrifice (Rule A)
* The gloves prevent against electrification (Rule Z)
* Therefore we need the gloves - go find em first

Currently we don't have a way to say "the gloves prevent against
electrification" . We can't do much of anything with I7 rules other
than run 'em and see what pops out. It would be nice to be able to run
rules backwards, for one thing. "Give me a list of the preconditions
necessary for this rule to fire. Now apply a filter to that list and
make the best resulting one our goal."

No idea quite how we'd specify these rules, something Prologish perhaps
though I don't quite grok Prolog. I probably need to learn but the
examples seem very contrived and not terribly real-worldy. (There is a
proto-IF system, though -
http://www.ainewsletter.com/downloads/if_docs/ - which could be fun to
play with and see if it's useful. Needs a good library and a much
better example than Duck World.)

I like I7's adjectives and relations, I think they're a first step
towards this sort of thing. "The door is electrified if a powered on
cable is touching it" seems like a fundamental sort of logical
construct to be able to write. Not implemented as a function, though,
since that's only one-way, but as logic.

I'm also thinking in terms of the whole business of updating the world
being somehow modelled as state transitions or the like: with actions
as arcs (obviously not your standard state diagram since we're not
quite talking discrete states, but whole sets of things). There's
probably AI/CS terminology for this that I don't have. But something
where we cleanly separate the *world effect* of actions from the
*narrative effect* and description of them. But then we also may want a
'Director' AI that seeks certain meta-world narrative states, like
scenes, or 'if the player seems lost, suggest some help', so we don't
necessarily want "narrative effects" to be completely outside the world
model either. But something where we can say "The result of (actor,
go, north) when (location = this room) is that their location changes
to (that room), and if (this other condition applies) a message is
generated." and then answer "Ignoring (ordinary success messages), what
actions given this actor's location could result in the actor being in
that room?"

I think the idea being that we would somehow mark up messages as
narrative-state important or unimportant. Most of the 'you go north'
housekeeping type messages don't alter the plot of a game. But 'you
have died' or 'you have a flashback' sort of things are chunks of
plot-dump in themselves, and are things that we want to know if they've
happened or not. We do this already - the "achieved" list, scoring,
learning topics during conversation. Not that hard to imagine a more
general mechanism for it.

Maybe I need to go hack on AIFT a bit and see if it's usable as a real
IF system. The author seems to dislike the classic Infocom interface
which does not bode entirely well.

Stephen Granade

unread,
Jun 13, 2006, 8:56:07 AM6/13/06
to
"Kevin Forchione" <ke...@lysseus.com> writes:

> <steve....@gmail.com> wrote in message
> news:1150157381.4...@i40g2000cwc.googlegroups.com...
> > Nate Cull wrote, quoting me:
> >> > The TADS 3 version supporte special case overrides. (The same hook
> >> > could have been built into the TADS 2 version.) Again I am not seeing
> >> > how the I7 version makes a really significant advance.
> >>
> >> I can't speak for TADS3, but TADS2 certainly does not have rules.
> >
> > TADS 3 doesn't have "rules" but the TADS 3 version of RAP does allow
> > for easy special-case overrides.
>
> The TADS 3 module could be rewritten to be rule based. Don't see why
> not.

I agree with what Nate said downstream: certainly it could. There's
nothing magical about rules that keeps you from adding them to any
language, provided you're willing to do the heavy lifting. Reducing
the concept to routines that return a boolean is skipping past the
really hard parts, though, namely, how do you decide rule precedence?
And how do you allow on-the-fly reordering of them? Given recent
discussions on this newsgroup, that's where the tricky bits are, and
it's a problem we don't yet have a great solution to.

Stephen

--
Stephen Granade
stephen...@granades.com

Andrew Plotkin

unread,
Jun 13, 2006, 9:30:52 AM6/13/06
to
Here, Stephen Granade <stephen...@granades.com> wrote:
> "Kevin Forchione" <ke...@lysseus.com> writes:
>
> > <steve....@gmail.com> wrote in message
> > news:1150157381.4...@i40g2000cwc.googlegroups.com...
> > > Nate Cull wrote, quoting me:
> > >> > The TADS 3 version supporte special case overrides. (The same hook
> > >> > could have been built into the TADS 2 version.) Again I am not seeing
> > >> > how the I7 version makes a really significant advance.
> > >>
> > >> I can't speak for TADS3, but TADS2 certainly does not have rules.
> > >
> > > TADS 3 doesn't have "rules" but the TADS 3 version of RAP does allow
> > > for easy special-case overrides.
> >
> > The TADS 3 module could be rewritten to be rule based. Don't see why
> > not.
>
> I agree with what Nate said downstream: certainly it could. There's
> nothing magical about rules that keeps you from adding them to any
> language, provided you're willing to do the heavy lifting. Reducing
> the concept to routines that return a boolean is skipping past the
> really hard parts, though, namely, how do you decide rule precedence?
> And how do you allow on-the-fly reordering of them?

And how do you efficiently carry out the rules? (See David Fisher's
efforts to customize the standard library messages.) Again, this is a
place where I7 could be improved -- you can do many clever
optimizations at compile-time when you have a complete rule model in
hand. Trying to put those improvements into a library-level
implementation would be much harder, because that's mutable at
runtime.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

If the Bush administration hasn't subjected you to searches without a warrant,
it's for one reason: they don't feel like it. Not because you're innocent.

Neil Cerutti

unread,
Jun 13, 2006, 11:48:36 AM6/13/06
to

In practice, I think you'll need to order your rules manually in
the code. The specificity of a rule can change through debugging,
and isn't necessarily obvious to the programmer.

--
Neil Cerutti
I think challenges keep you forever young. And I've discovered
the fountain of youth. I'm Peter Pan with this one. --Rick
Pitino

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php

Andrew Plotkin

unread,
Jun 13, 2006, 12:13:45 PM6/13/06
to
Here, Neil Cerutti <lead...@email.com> wrote:
> On 2006-06-13, vaporware <jmc...@gmail.com> wrote:
> > Kevin Forchione wrote:
> >> The TADS 3 module could be rewritten to be rule based. Don't see why not. As
> >> I understand it the "rules" of I7 are nothing more than routines that return
> >> either true (if successful or failure) and false (if not applicable).
> >> There's no reason why the TADS 3 RAP mechanism couldn't do the same, if
> >> rules are the bread and butter of your existence.
> >
> > Well, one nice thing about I7's rules is that the compiler
> > automatically sorts them by specificity, so an "opening the
> > cell door during Power Outage" rule will always have a chance
> > to run before the plain old "opening a door" rule.
>
> In practice, I think you'll need to order your rules manually in
> the code. The specificity of a rule can change through debugging,
> and isn't necessarily obvious to the programmer.

This has not been my experience. The specificity of a rule is part of
the game design, like the class hierarchy. If I change it, it's on
purpose.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

Just because you vote for the Republicans, doesn't mean they let you be one.

Stephen Granade

unread,
Jun 13, 2006, 1:33:33 PM6/13/06
to
Andrew Plotkin <erky...@eblong.com> writes:

> Here, Stephen Granade <stephen...@granades.com> wrote:
> > "Kevin Forchione" <ke...@lysseus.com> writes:
> >
> > > <steve....@gmail.com> wrote in message
> > > news:1150157381.4...@i40g2000cwc.googlegroups.com...
> > > > Nate Cull wrote, quoting me:
> > > >> > The TADS 3 version supporte special case overrides. (The same hook
> > > >> > could have been built into the TADS 2 version.) Again I am not seeing
> > > >> > how the I7 version makes a really significant advance.
> > > >>
> > > >> I can't speak for TADS3, but TADS2 certainly does not have rules.
> > > >
> > > > TADS 3 doesn't have "rules" but the TADS 3 version of RAP does allow
> > > > for easy special-case overrides.
> > >
> > > The TADS 3 module could be rewritten to be rule based. Don't see why
> > > not.
> >
> > I agree with what Nate said downstream: certainly it could. There's
> > nothing magical about rules that keeps you from adding them to any
> > language, provided you're willing to do the heavy lifting. Reducing
> > the concept to routines that return a boolean is skipping past the
> > really hard parts, though, namely, how do you decide rule precedence?
> > And how do you allow on-the-fly reordering of them?
>
> And how do you efficiently carry out the rules? (See David Fisher's
> efforts to customize the standard library messages.)

Plus, how do you specify when the rules hold true in a concise way?
When you get down to it, building this kind of an approach is
comparable to building a parser, and is not for the faint-of-heart.

steve....@gmail.com

unread,
Jun 13, 2006, 4:00:31 PM6/13/06
to
Nate Cull wrote:
> The long answer:

Thanks. This is what I was asking for.

> Special case overrides is what it's all about. Rules are nothing *but*
> special case overrides. There's a big difference between providing
> hooks for certain operations and allowing everything to be
> configurable.

I agree that you want everything to be configurable -- that's precisely
why I prefer procedural over rule-based programming. This motto "a
world of hooks," which Graham borrowed from Plotkin, seems to me PR for
the loss of control (and overview) which always accompanies rule-based
systems. If you want "everything to be configurable," you probably want
procedural programming. If you're satisfied with "providing hooks for
certain operations," rule-based programming might be the best choice.

> But some examples: [snip]

Ok, thanks for the examples -- they help, as always.

Your extended example would be handled by hooks which in TADS 3 are
built in to the system, but which could be easily added to the TADS 2
version.

You have remarked that I7 is good at separating default behavior from
specialized behavior. Note that the TADS 3 hooks also cleanly separate
default from specialized behavior.

The hooks work very simply: before returning the default plan for
opening an object, we first check if the object defines a custom plan
for its opening. Likewise with the plan for unlocking.

In the case of two-object actions (UnlockWith: unlock door with sonic
screwdriver), the "indirect object" (sonic screwdriver) can define some
specialized plan, just as the "direct object" can.

This latter case introduces the problem: what if both objects define
specialized plans? In this case, as I said upthread, you have to
resolve the conflict by hand. This means either overriding the main
plan object, to inform it which object's custom plan takes precedence,
or making the two objects' custom plans sufficiently aware of one
another.

(As I understand it, plan precedence is not a problem solved by I7
either.)

Nevertheless, perhaps this points to one (and perhaps the principle)
benefit of I7 generally, quite apart from RAP: that it is
relation-oriented, rather than object oriented. Or as you say...

> And there's three main objects involved in any
> plan: the relation/condition, the first object, the second object.
> Should all of these conditions be put on a method on the 'open' object?
> The 'door' object? The 'sonic screwdriver' object? The 'power failure'
> scene object?
>
> This is where OO breaks down, because this logic does not belong with
> any particular object of the three, so it can't be easily overridden
> simply by subclassing one object and replacing one method.

Again, sorry if I'm being dense, but the question remains: subtracting
the boilerplate I7 theory, how does this substantially improve planbase
design?

Let me try to help answer the question a little bit. I think there are
two ideas at work here:

"if trees," overt, or assembled from piecemeal:

In the TADS version, or in any conventional procedural version, you
have an overt tree of "if" statements, each branch of which returns
some plan. In the I7 version, as I understand it, you have a tree of
"if" statements, but the machine deduces the tree (really assembling
the tree) from individual statements, individual branches of what will
be internally the larger structure. The machine figures out the
relationships between the branches so you don't have to. (But don't you
feel like you've lost some view on the result?) Still, I like the
concept of assembling "if trees" from pieces. So yay I7 is cool.

"relation oriented" (RO) vs. OO:

This is a false distinction, at least as the distinction has been
discussed so far: OO is being given short shrift. OO is RO, really:
messaging is relation.

It is easy to devise an example where OO breaks down: the interrelation
of objects is so complex that a single object can't cover everything,
and messaging back and forth becomes messy. This does not mean that
relational logic would be better.

The initial problem is simply transformed into the problem of relation
(or rule) precedence.

Also, I don't think these easy-to-devise examples occur (practically
speaking) any more frequently than their equally-easy-to-devise
solutions. It's normally simple to figure out which object is the
conceptual master, and so which object should handle the process. When
it's necessary to modify, it's generally pretty clear where the
modification should go. The "problem" which RO programming pretends to
solve can be easily overstated in the first place.

na...@natecull.org

unread,
Jun 13, 2006, 8:10:08 PM6/13/06
to

steve....@gmail.com wrote:
> Thanks. This is what I was asking for.

Oh good.

> I agree that you want everything to be configurable -- that's precisely
> why I prefer procedural over rule-based programming. This motto "a
> world of hooks," which Graham borrowed from Plotkin, seems to me PR for
> the loss of control (and overview) which always accompanies rule-based
> systems. If you want "everything to be configurable," you probably want
> procedural programming. If you're satisfied with "providing hooks for
> certain operations," rule-based programming might be the best choice.

That's your right to have a contrary opinion, but don't expect everyone
to share it.

Procedural programming certainly gives you total control of the order
of of operations *within a single block of code* (such as a single
procedure or function), yes. However, it provides far less
configurability *between blocks of code*.

You may feel that you can accomplish everything you need to in IF
within single code blocks. I think you'll find otherwise when you've
played with a system for a while. Libraries, especially, will give you
trouble, as will any kind of code reuse. Your code will not be easily
modifiable, even by yourself, even within a single project.

> The hooks work very simply: before returning the default plan for
> opening an object, we first check if the object defines a custom plan
> for its opening. Likewise with the plan for unlocking.
>
> In the case of two-object actions (UnlockWith: unlock door with sonic
> screwdriver), the "indirect object" (sonic screwdriver) can define some
> specialized plan, just as the "direct object" can.

Okay, so here you're doing exactly what I was looking at in TADS2. This
is the standard, simple, OO approach to the problem, and it's the
approach that I consider to have failed to be flexible enough to be a
general solution.

> This latter case introduces the problem: what if both objects define
> specialized plans? In this case, as I said upthread, you have to
> resolve the conflict by hand. This means either overriding the main
> plan object, to inform it which object's custom plan takes precedence,
> or making the two objects' custom plans sufficiently aware of one
> another.


EXACTLY. You've just described the problem with the OO approach. If you
look at this long enough, you'll realise that a) this case comes up
very, very often in IF, b) attempting to make two objects aware of each
other violates OO encapsulation and leads to deep, hairy spaghetti
interconnections, and c) overriding the main plan object is a good
'emergency escape hatch' but basically ignores the OO inheritance
hierarchy completely and does not play well with any other conditions.


> (As I understand it, plan precedence is not a problem solved by I7
> either.)

If two rules in I7 have the same level of specificity, (>SHOOT BOND
WITH anything versus >SHOOT anyone WITH GUN), I believe the first one
listed applies - so you do have a manual override to finesse the
awkward cases. It's possible that corner cases exist which are
intractable, but the number of these conflicting rules is much smaller
than with only checking the plan, the direct or indirect object, and
doing so in a specified order. You can implement the TADS2/TADS3
behaviour as a *subset* of rule-based behaviour (any rule that doesn't
define a direct object, for instance, can be assumed to match all of
them, which is the same as a condition being checked 'before' checking
the direct object). And then you can catch many other more complicated
conditions.


> Nevertheless, perhaps this points to one (and perhaps the principle)
> benefit of I7 generally, quite apart from RAP: that it is
> relation-oriented, rather than object oriented. Or as you say...

You seem to be misunderstanding rather deeply here. Neither I7
relations nor Planner relations have anything to do with rules, per se.


> > And there's three main objects involved in any
> > plan: the relation/condition, the first object, the second object.
> > Should all of these conditions be put on a method on the 'open' object?
> > The 'door' object? The 'sonic screwdriver' object? The 'power failure'
> > scene object?
> >
> > This is where OO breaks down, because this logic does not belong with
> > any particular object of the three, so it can't be easily overridden
> > simply by subclassing one object and replacing one method.
>
> Again, sorry if I'm being dense, but the question remains: subtracting
> the boilerplate I7 theory, how does this substantially improve planbase
> design?

....

... in the way I just told you, several times over?

Look, I'm not pushing any particular barrow here except my own. I have
no idea what you mean by 'boilerplate I7 theory' but frankly it sounds
like a thinly veiled insult, and I'm not playing your Graham-hating
games. I'm not quoting anything. I''m stating what I've learned about
the system by playing with it. You might try doing the same. You'd
probably learn more than you would from talking here, since you don't
seem to be getting much understanding from what I'm saying.

>
> Let me try to help answer the question a little bit. I think there are
> two ideas at work here:
>
> "if trees," overt, or assembled from piecemeal:

Okay, yes, this is a good observation.


> In the TADS version, or in any conventional procedural version, you
> have an overt tree of "if" statements, each branch of which returns
> some plan.

Yes, but you also have two kinds of 'if trees' in OO languages like
TADS and I6: the 'if statement' in the procedures, *and* the object
class hierarchy of method inheritance. BOTH of these are ways of
creating 'generalised' versus 'specialised' behaviour, and they
interplay.

>In the I7 version, as I understand it, you have a tree of
> "if" statements, but the machine deduces the tree (really assembling
> the tree) from individual statements, individual branches of what will
> be internally the larger structure. The machine figures out the
> relationships between the branches so you don't have to.

The compiler constructs essentially a decision tree by ordering more
general rules before more specific rules, yes.

>(But don't you feel like you've lost some view on the result?)

A little, yes. Which is an ongoing debate, and is why there is the
option of dropping into procedural IF statements, which possibly
reveals a flaw in the design of the rules in that they're
insufficiently customisable.

But for the most part, it's fairly simple to tell which rule 'should
be' ordered before another: if it has more clauses, or if the clauses
refer to object kinds higher up in the OO hierarchy.

Admittedly, the I7 compiler currently doesn't order 'when' clauses
correctly, but I expect that to be fixed.

Ok, yes, and then there's procedural rules, and then there's being able
to abort the rule scanning with 'rule succeeds / rule fails' versus
letting multiple rules fire. These can complicate the flow of
interaction. And then there's knowing which top-level rulebooks are
consulted in which order, but that's a situation common to all IF
libraries, needing to know the basic phases of execution.

The nicer thing about rules is that usually they map *more closely* to
what you *intend* to say. Not always, but in many cases you want to
define a) general behaviour, b) special behaviour in some circumstances
(which, as I keep claiming, usually involves *more* complexity than
just checking noun/direct-object or second/indirect-object.


> This is a false distinction, at least as the distinction has been
> discussed so far: OO is being given short shrift. OO is RO, really:
> messaging is relation.

Er, what? Now you're using terminology that I don't think corresponds
to anything anyone else uses.

OO messaging is, um, messaging (and maps onto hierarchies of inherited
behaviour). Rules are rules. Relations are something else entirely.


> It is easy to devise an example where OO breaks down: the interrelation
> of objects is so complex that a single object can't cover everything,
> and messaging back and forth becomes messy. This does not mean that
> relational logic would be better.

Heck if I know what you mean by 'relational logic'. We're not talking
predicate calculus here.

> The initial problem is simply transformed into the problem of relation
> (or rule) precedence.

Precedence, yes. And as I keep saying, rules can model precedence
relationships which are much more complicated than simple trees.

OO handles trees well. Rules can do webs.

IF is more webby than it is tree-y.

> Also, I don't think these easy-to-devise examples occur (practically
> speaking) any more frequently than their equally-easy-to-devise
> solutions.

I disagree. The examples of where the simple OO approach fails are easy
to devise because they occur so often. The solutions are not easy to
devise.


>It's normally simple to figure out which object is the
> conceptual master, and so which object should handle the process.

>When
> it's necessary to modify, it's generally pretty clear where the
> modification should go.


No, it is not, and it is not. This is my point.

The interesting corner case of IF - NOT the generic behaviour, the
customisations, which is what makes a game unique and fun - is all
about situations where there is *no* conceptual master - or if there
is, it is NOT one of the two or three obvious objects interacting. It's
a higher-level 'if this and this and this' rule.

Kevin Forchione

unread,
Jun 13, 2006, 11:50:02 PM6/13/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e6mo7p$r33$1...@reader2.panix.com...

> Here, Neil Cerutti <lead...@email.com> wrote:
>> On 2006-06-13, vaporware <jmc...@gmail.com> wrote:
>> > Kevin Forchione wrote:
>> >> The TADS 3 module could be rewritten to be rule based. Don't see why
>> >> not. As
>> >> I understand it the "rules" of I7 are nothing more than routines that
>> >> return
>> >> either true (if successful or failure) and false (if not applicable).
>> >> There's no reason why the TADS 3 RAP mechanism couldn't do the same,
>> >> if
>> >> rules are the bread and butter of your existence.
>> >
>> > Well, one nice thing about I7's rules is that the compiler
>> > automatically sorts them by specificity, so an "opening the
>> > cell door during Power Outage" rule will always have a chance
>> > to run before the plain old "opening a door" rule.
>>
>> In practice, I think you'll need to order your rules manually in
>> the code. The specificity of a rule can change through debugging,
>> and isn't necessarily obvious to the programmer.
>
> This has not been my experience. The specificity of a rule is part of
> the game design, like the class hierarchy. If I change it, it's on
> purpose.

Fortunately for the TADS version, such rules could be sorted during
pre-init.

--Kevin


steve....@gmail.com

unread,
Jun 14, 2006, 8:07:44 AM6/14/06
to
Nate Cull writes:

> Procedural programming certainly gives you total control of the order
> of of operations *within a single block of code* (such as a single
> procedure or function), yes. However, it provides far less
> configurability *between blocks of code*.

Program flow is the relationship between objects. OO doesn't get going
until you write code that references other code; but once it's going,
it's really interlaced in a good way.

> You may feel that you can accomplish everything you need to in IF
> within single code blocks.

In their interrelation, yes. By messaging and querying other objects
from within one object.

In your excitement, I think you have mischaracterized OO programming,
forgetting that it is also essentially relational.

> I think you'll find otherwise when you've
> played with a system for a while.

Just any old system, or do you have a particular system in mind? :)

> [Y]ou're doing exactly what I was looking at in TADS2. This


> is the standard, simple, OO approach to the problem,

That's right, and it seems to be working fine of course.

> and it's the
> approach that I consider to have failed to be flexible enough to be a
> general solution.

When you have two competing customizations, you have to resolve the
conflict by hand no matter what system you use. That this is necessary
is not a failure of the system, but a fact of the project.

> a) this case comes up
> very, very often in IF

It comes up often that more than one object or more than one piece of
data is involved in the logic, but it does not come up often that this
means there is some great disaster.

> b) attempting to make two objects aware of each
> other violates OO encapsulation and leads to deep, hairy spaghetti
> interconnections

Such programming as "if(self.location == b.location)..." does not
constitute a violation of OO encapsulation, or a hairy spaghetti. You
seem to be imagining an OO where all methods and properties are
private. (Odd indeed, to call this OO -- OOP always involves multiple
objects because their relation is the whole point of the model.)

> c) overriding the main plan object is a good
> 'emergency escape hatch' but basically ignores the OO inheritance
> hierarchy completely and does not play well with any other conditions.

It splits the decision code, but so does relation-based programming.
The fact that you need some logic which relates the objects does not
mean that OO is broken.

> You can implement the TADS2/TADS3
> behaviour as a *subset* of rule-based behaviour (any rule that doesn't
> define a direct object, for instance, can be assumed to match all of
> them, which is the same as a condition being checked 'before' checking
> the direct object).

I'm sorry, but I can't follow your logic. You might be saying something
substantial here, so perhaps you can explain.

> > > And there's three main objects involved in any

> > > plan: the relation/condition, the first object, the second object.[...]


> > > This is where OO breaks down, because this logic does not belong with
> > > any particular object of the three, so it can't be easily overridden
> > > simply by subclassing one object and replacing one method.

[...]


> Look, I'm not pushing any particular barrow here except my own.

Let's just say that this reminds me of the argument Plotkin makes when
arguing for a rule-based IF system, an argument seminal to I7, and
repeated by its designer in his description of the system.

> I have
> no idea what you mean by 'boilerplate I7 theory'

That OO is somehow broken because its objects' behavior is
interdependent. (Or, to put it crudely, that objects have to reference
one another.) Don't get me wrong, though -- I like Plotkin's argument
nevertheless, and I expect it's ground for further productive thought.

> but frankly it sounds
> like a thinly veiled insult

Not at all -- I just mean that this is what one might excitedly (and
somewhat inaccurately) say about rule-based systems in general (under
the aegis of "first principles," perhaps), and I'd rather hear more
about what this has to do with designing a planbase.

> [R]ules can model precedence


> relationships which are much more complicated than simple trees.
>
> OO handles trees well. Rules can do webs.

I think that this is your main point, in a nutshell. In anticipation of
what I hope will be your elaboration, let me try to unpack this
statement: that rule-based (relation-based) programming can handle
web-like logic, as opposed to tree-like logic.

I'll take a very simple example, but one which I think represents
web-like logic: moving around a game-object in a game. Let's say for
simplicity that there are only three objects involved when an object is
moved: the initial location, the destination, and the object being
moved.

Around these three objects, the web: basically we want, during the
move, to make sure that all three objects to agree that the move is
permissible. This isn't terribly webby, of course, but it's more
complicated than it might appear at first blush: at minimum we must
check if the initial location will allow the object to be moved (into
the destination); check if the destination will allow the object to be
moved into it (from the initial location); check if the object will
allow itself to be moved (from the initial location and to the
destination).

These three checks are all relational -- indeed they each involve at
least two and really all three objects. Now, if you're staring blankly
at the blank screen, trying to imagine a single code block to handle
this, I can imagine that relation-based programming is going to look
pretty appealing.

However, if you know how to program (and you do, so you probably know
where I'm heading), you'll break this into stages, each stage
representing one of the things you want to check. You'll decide where
each bit of code goes by figuring out which object is making the
decision at each stage. You'll "notify" each object involved in the
relation, from within a larger wrapper method (e.g., the moving
object's main "move" method). And it will be perfectly customizable.

I'm not saying that there's no rationale whatsoever for relation-based
programming, or that the complaint against OOP is completely unfounded:
it is possible to devise examples where OOP-style relation is not
perfectly sturdy. But in the vast number of cases, these webs you
imagine can be broken down into straightforward OOP-style relations
with minimal effort.

In any case, pretending that the concept of relation is foreign to OO
is just plain silly.

vaporware

unread,
Jun 14, 2006, 8:45:04 AM6/14/06
to
steve....@gmail.com wrote:
> Nate Cull writes:
[...]

> > [R]ules can model precedence
> > relationships which are much more complicated than simple trees.
> >
> > OO handles trees well. Rules can do webs.
[...]

But it's not always clear which object *should* make the decision at
each stage. Which object should be consulted first: the initial
location, the destination, or the item being moved?

And what if a decision depends on the state of two objects: nothing can
be moved between X and Y, but all other moves are permissible? You can
flip a coin to pick X or Y, and put the code there, but having to make
an arbitrary choice like that seems like a sign that the paradigm is
breaking down.

vw

Kyle Pierce

unread,
Jun 14, 2006, 9:26:47 AM6/14/06
to
na...@natecull.org wrote:
> No idea quite how we'd specify these rules, something Prologish perhaps
> though I don't quite grok Prolog. I probably need to learn but the
> examples seem very contrived and not terribly real-worldy. (There is a
> proto-IF system, though -
> http://www.ainewsletter.com/downloads/if_docs/ - which could be fun to
> play with and see if it's useful. Needs a good library and a much
> better example than Duck World.)
>

BTW, thanks for sharing your work on Planner. I got some good insights
into actually implementing an algorithm in I7 from studying your code.
I studied the TADS3 version before, and the I7 version is a good bit
shorter and more readable. But I have the impression it would be easier
still for me to do something like that in Prolog. This is partly
because I know Prolog better, but also, Prolog's rule engine is simple
and its behavior is pretty transparent, because it is based on a single
algorithm. Maybe at some point I7 will be that transparent to me, but I
sort of doubt it.

So, I am more tempted than ever to go back to working in Prolog. I
spent some time running the Amzi IF library and studying the source
files. That was nice of Amzi to make their IF library publicly
available, and I guess you can modify the files template.pro and
template_english.pro to make your own games. But to compile your own
version of the library you would have to buy their commercial Prolog
system. Probably anyone who is motivated enough to learn a language as
powerful as Prolog would want to be able to do that.

There are other good Prologs that are free. If you're interested in
pursuing anything with Prolog beyond the Amzi IF library, you might
check out SWI-Prolog.org. Theirs is one of the leading Prolog compilers
and it's free software. I've been using SWI-Prolog myself for many
years.

Kyle

steve....@gmail.com

unread,
Jun 14, 2006, 9:57:54 AM6/14/06
to
vaporware wrote:
> But it's not always clear which object *should* make the decision at
> each stage.

That is true. It's not always clear -- I'm not arguing that it is
always clear. However, the frequency of this, and the problematics when
it does happen, the problem's importance and the urgency of its
solution -- these things can be very easily exaggerated.

> Which object should be consulted first: the initial
> location, the destination, or the item being moved?

This is a separate question. Everything else being equal, you would
probably prefer to order the operations to reflect their natural order:
an object is removed from one location before it is placed in another.
When do you notify the object itself? Doesn't matter: fine either way.

> And what if a decision depends on the state of two objects: nothing can
> be moved between X and Y, but all other moves are permissible? You can

> flip a coin to pick X or Y, and put the code there[...]

No, you'd probably want to put the code in the first place it makes
sense. So, in your example, the code would go in the
remove-notification. Either way is fine, though, so if you want to put
it in the insert notification for some reason, go right ahead.

> but having to make
> an arbitrary choice like that seems like a sign that the paradigm is
> breaking down.

Why's that? The fact that there may be more than one correct way to do
something doesn't seem to directly imply that there's a problem.

Andrew Plotkin

unread,
Jun 14, 2006, 10:14:10 AM6/14/06
to
Here, steve....@gmail.com wrote:
> vaporware wrote:
> > But it's not always clear which object *should* make the decision at
> > each stage.
>
> That is true. It's not always clear -- I'm not arguing that it is
> always clear. However, the frequency of this, and the problematics when
> it does happen, the problem's importance and the urgency of its
> solution -- these things can be very easily exaggerated.

So can the ease and naturalness of breaking down a set of rules into
object behaviors.

Perhaps you should try implementing a complicated bit of game logic in
an OO manner and a rule-based manner, to compare them. Experience is
an excellent antidote to worries about exaggeration.

There are bugs in _So Far_ that I never bothered fixing, because it
was too much work to drop in the fixes in every object and action
where they were needed. (I'm thinking of the prohibitions on making
noise in certain areas.) These would be very simple I7 rules.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

You don't become a tyranny by committing torture. If you plan for torture,
argue in favor of torture, set up legal justifications for torturing
someday, then the moral rot has *already* set in.

vaporware

unread,
Jun 14, 2006, 10:21:30 AM6/14/06
to
steve....@gmail.com wrote:
> vaporware wrote:
[...]

> > Which object should be consulted first: the initial
> > location, the destination, or the item being moved?
>
> This is a separate question. Everything else being equal, you would
> probably prefer to order the operations to reflect their natural order:
> an object is removed from one location before it is placed in another.
> When do you notify the object itself? Doesn't matter: fine either way.

But sometimes that will be wrong, and you may have general conditions
applying to the initial location that should be overridden in special
cases by a condition on the destination.

Point is, it's a question you're forced to tackle in a purely OO
system, and you have to structure your code unnaturally to deal with
it. There is no need, in a rule based system, to have a fixed schedule
of which objects are checked in which order. There's no need for the
library or extension author to pick a default order.

> > but having to make
> > an arbitrary choice like that seems like a sign that the paradigm is
> > breaking down.
>
> Why's that? The fact that there may be more than one correct way to do
> something doesn't seem to directly imply that there's a problem.

They both work, but they're both awkward. They don't reflect the
author's intent; a rule about moving things between two rooms doesn't
naturally belong to either room. Rule based programming lets you
separate the rule from its components.

vw

Kevin Forchione

unread,
Jun 14, 2006, 11:12:05 AM6/14/06
to
<na...@natecull.org> wrote in message
news:1150175907....@g10g2000cwb.googlegroups.com...

>
> Kevin Forchione wrote:
>> The TADS 3 module could be rewritten to be rule based. Don't see why not.
>> As
>> I understand it the "rules" of I7 are nothing more than routines that
>> return
>> either true (if successful or failure) and false (if not applicable).
>> There's no reason why the TADS 3 RAP mechanism couldn't do the same, if
>> rules are the bread and butter of your existence.
>
> Yes, and I think the I6 version could do this too. And quite possibly
> an OO approach to rules would give you more flexibility than the
> fixed-at-compile-time rule syntax in I7. (TADS3 quite possibly already
> does a large part of the things I'm after - fully dynamic VM, hackable
> parser, I'm not entirely sure why I haven't tried using it yet. Mostly
> fatigue from its perpetual beta-ness and a shock reaction to the size
> of the library. And an irrational fondness for the Z-machine, but I'm
> reconciling myself to abandoning that anyway.)

Yes, ironically when people talk about an alternate target language other
than I6, they're describing those elements that TADS 3 possesses.

--Kevin


Kevin Forchione

unread,
Jun 14, 2006, 11:17:03 AM6/14/06
to
"Stephen Granade" <stephen...@granades.com> wrote in message
news:m3lks1z...@sargent.dyndns.org...

> I agree with what Nate said downstream: certainly it could. There's
> nothing magical about rules that keeps you from adding them to any
> language, provided you're willing to do the heavy lifting. Reducing
> the concept to routines that return a boolean is skipping past the
> really hard parts, though, namely, how do you decide rule precedence?
> And how do you allow on-the-fly reordering of them? Given recent
> discussions on this newsgroup, that's where the tricky bits are, and
> it's a problem we don't yet have a great solution to.

That's one of the dynamics of systems development. I7 pioneers and approach,
and the other systems pick the best bits and leverage them. In a sense I7 is
doing proof-of-concept for this rules approach, and once these discussions
have sorted out most of the issues inherent then it will be up to I7 to
attempt to implement a solution, if it proves too difficult to implement
under it's current infrastructure then another system will no doubt
successfully implement one based on that analysis.

--Kevin


na...@natecull.org

unread,
Jun 14, 2006, 11:38:23 PM6/14/06
to

Kyle Pierce wrote:

> BTW, thanks for sharing your work on Planner. I got some good insights
> into actually implementing an algorithm in I7 from studying your code.

Yay. :)

> I studied the TADS3 version before, and the I7 version is a good bit
> shorter and more readable. But I have the impression it would be easier
> still for me to do something like that in Prolog. This is partly
> because I know Prolog better, but also, Prolog's rule engine is simple
> and its behavior is pretty transparent, because it is based on a single
> algorithm. Maybe at some point I7 will be that transparent to me, but I
> sort of doubt it.

Yes, Prolog is looking more appealing to me too. But I never learned
more than the basic textbook logic examples (' father(X,Y) :- male(X),
child(Y,X) ') and am still quite unsure how to even begin handling, eg,
I/O in it.

> There are other good Prologs that are free. If you're interested in
> pursuing anything with Prolog beyond the Amzi IF library, you might
> check out SWI-Prolog.org. Theirs is one of the leading Prolog compilers
> and it's free software. I've been using SWI-Prolog myself for many
> years.

Oh good. I've installed SWI-Prolog on my Dapper box, but I'm sort of
stymied as to how to get hacking. Can you recommend any good
introductions (preferably from a 'I know imperative programming, how
the heck do I do stuff?' angle?)

Prolog excites me on one level, but it also seems so... sterile. Can
everything in the world really be represented as Horn clauses?

Kyle Pierce

unread,
Jun 15, 2006, 9:07:13 AM6/15/06
to
na...@natecull.org wrote:

> > There are other good Prologs that are free. If you're interested in
> > pursuing anything with Prolog beyond the Amzi IF library, you might
> > check out SWI-Prolog.org. Theirs is one of the leading Prolog compilers
> > and it's free software. I've been using SWI-Prolog myself for many
> > years.
>
> Oh good. I've installed SWI-Prolog on my Dapper box, but I'm sort of
> stymied as to how to get hacking. Can you recommend any good
> introductions (preferably from a 'I know imperative programming, how
> the heck do I do stuff?' angle?)
>
> Prolog excites me on one level, but it also seems so... sterile. Can
> everything in the world really be represented as Horn clauses?

As far as representing things in the world, I think the problem you are
seeing is that, in contrast to Inform or TADS, in Prolog this remains
more of a do-it-yourself task (and not a technical limitation). The
Prolog code that comes with that Amzi IF download is the first I've
seen that makes an effort to handle basic IF functionality. Maybe it
could be done in a better way but right now that code is the best
starting point I know of.

Prolog is based on a lower-level, more-powerful rule engine that
doesn't have the additional layers of semantic wrapping built into I7.
Not only that, but for some reason the documentation for AI languages
typically features pretty lame and limited examples (in which words
like "foo" often show up a lot).

But if we want to work more directly with the rule engine itself, then
we have to go pretty far behind the scenes, where things are, yes, a
bit sterile. Look at the Z-machine, though -- until you add the
semantic wrapping, it all looks pretty sterile, doesn't it?

The thing I appreciate most about the IF community is the wealth of
rich descriptions that are grounded in good observations and intuitions
about the world. I am not a gamer by any stretch, but I am fascinated
by the potential for creating interesting "story puzzles" that are sort
of a take-off on IF as I understand it.

Also I would suggest clicking on the "Links" link on the left of the
SWI home page, and looking at some of the tutorials and even textbooks
that are available online. I hope to have some time soon to convert the
Amzi IF code to SWI-Prolog. Yes there is an ISO standard Prolog but as
you might expect there are some differences between compilers. I will
keep you posted if and when I have more to offer, and if you have
questions I will try to answer them.

Kyle

Kyle Pierce

unread,
Jun 15, 2006, 10:05:44 AM6/15/06
to
I meant to include this reference to a tutorial that is for SWI-Prolog
specifically:

http://www.cse.ucsc.edu/classes/cmps112/Spring03/languages/prolog/PrologIntro.pdf

Hope this helps,

Kyle

steve....@gmail.com

unread,
Jun 15, 2006, 10:45:37 AM6/15/06
to

Kyle Pierce wrote, Quoting Nate Cull:

> > Prolog excites me on one level, but it also seems so... sterile. Can
> > everything in the world really be represented as Horn clauses?
[...]

> But if we want to work more directly with the rule engine itself, then
> we have to go pretty far behind the scenes, where things are, yes, a
> bit sterile. Look at the Z-machine, though -- until you add the
> semantic wrapping, it all looks pretty sterile, doesn't it?

I'd like to add that there are ways to extend Prolog to enable it to
handle a broader logic, such as PTTP. I would also like to say how
impressed I am how far one can go with simple Horn clauses; not sterile
-- quite the contrary!

Kyle Pierce

unread,
Jun 15, 2006, 12:26:14 PM6/15/06
to
Something else I neglected to point out about Prolog, that is relevant
to IF developers who are interested in parsing: Prolog was originally
invented as a programming language in which to write natural language
applications, and thus Prolog is a very elegant language for expressing
grammars. Prolog even has a builtin syntax (the DCG or Definite Clause
Grammar) especially created for writing grammars. It is often said that
with Prolog one gets a builtin parser for free.

If you google "Prolog DCG" you can find all sort of references. There
are some examples of DCG usage in the Amzi IF source code:
specifically, the filenames that fit the pattern *_english.pro. I
included part of one here:

% These grammar rules define the vocabulary words or
% phrases for the different parts of speech. For example, the
% internal command token, 'take', is recognized from input
% strings beginning with "get" or "pick up".

% The verbs have the number of arguments to make it
% easier to distinguish between put with one argument
% and put with two arguments. The internal token
% for the one argument version is 'drop', and is 'put'
% for two.

% The first vocabulary entry for each of the words will
% be used when presenting the player with hints.
verb(drop,1) --> [drop].
verb(drop,1) --> [put].
verb(drop,1) --> [hang].
verb(examine,1) --> [examine].
verb(examine,1) --> [x].
verb(examine,1) --> [look,at].
verb(go_direction,1) --> [go].
verb(go_place,1) --> [go,to].
verb(go_place,1) --> [go].
verb(help,0) --> [help].
verb(hint,0) --> [hint].
verb(inventory,0) --> [inventory].
verb(inventory,0) --> [i].
verb(look,0) --> [look].
verb(options,0) --> [options].
verb(options,1) --> [options].
verb(put_at,2) --> [put].
verb(put_at,2) --> [hang].
verb(quit,0) --> [quit].
verb(score,0) --> [score].
verb(take,1) --> [take].
verb(take,1) --> [get].
verb(take,1) --> [take].
verb(take,1) --> [grab].
verb(take,1) --> [pick,up].
verb(take_off,1) --> [take,off].
verb(wear,1) --> [wear].
verb(wear,1) --> [put,on].

% The grammar rules can refer back to the game. This
% rule says anything is a verb if it appears in the game
% logic's action clause. This lets the game be played
% using internal tokens during development.
verb(V,_) --> [V], { a_verb(V) }. % a catch all

% As with the other tokens, the first entry is the one
% that will be used in hints and in short descriptions to
% the player. So the 'cloak' will be referred to as
% "velvet cloak" and the 'hook' as "brass hook".

% The adjectives for items can be simply enumerated
% here with the items, as with "velvet cloak", but if it
% is desired to handle more complex and arbitrary sequences
% of adjectives, then an additional 'adjectives' grammar
% rule is needed, as is used here.
object(cloak) --> [velvet, cloak].
object(cloak) --> [cloak].
object(hook) --> [brass, hook].
object(hook) --> adjectives(hook), [hook].
object(hook) --> adjectives(hook), [peg].
object(hat) --> [hat].

steve....@gmail.com

unread,
Jun 15, 2006, 6:17:45 PM6/15/06
to
Andrew Plotkin wrote, quoting me:

> > That is true. It's not always clear -- I'm not arguing that it is
> > always clear. However, the frequency of this, and the problematics when
> > it does happen, the problem's importance and the urgency of its
> > solution -- these things can be very easily exaggerated.
>
> So can the ease and naturalness of breaking down a set of rules into
> object behaviors.

That is also true, but packing the process in a black box is a
sacrifice, so the rule-based regime remains at a disadvantage, even if
it can do one or two things slightly better.

> Perhaps you should try implementing a complicated bit of game logic in
> an OO manner and a rule-based manner, to compare them.

BTDT, but this is beside the point. Quite apart from the real and
imagined gains of rule-based programming (including or ignoring the
sacrifice involved), I was asking *how* a planner written in I7
leverages this, and *why* it's important. These questions have not been
sufficiently answered. I'm probably better off asking a newsgroup which
specializes in logic programming (or AI), but I was hoping Nate could
answer the question.

(By the way.... Have you yet performed this experiment?)

> There are bugs in _So Far_ that I never bothered fixing, because it
> was too much work to drop in the fixes in every object and action
> where they were needed. (I'm thinking of the prohibitions on making
> noise in certain areas.) These would be very simple I7 rules.

You'd weigh this with/against the (in-)convenience of programming the
rest of the game in I7. The fact that I7 does this-or-that better means
very little.

na...@natecull.org

unread,
Jun 15, 2006, 6:54:57 PM6/15/06
to

steve....@gmail.com wrote:
> That is also true, but packing the process in a black box is a
> sacrifice, so the rule-based regime remains at a disadvantage, even if
> it can do one or two things slightly better.

The I7 rule engine is not a black box. I'm not sure why you keep saying
this. It has clearly defined precedence behaviour, of roughly the same
order as Prolog. It's a lot simpler and more predictable than Prolog
in many respects. (Prolog doesn't appear to sort its rules by order of
specificity, which I find frustrating; otoh, Prolog rules can trigger
their own subgoals which is much more complex behaviour than I7's rule
engines. I7 also doesn't have cuts or backtracking, which I find quite
hard to predict.)

One of my projects in learning Prolog will be to try to implement an
I7-like most-general-predicate first search, as well as a Planner-like
breadth-first search.

> BTDT, but this is beside the point. Quite apart from the real and
> imagined gains of rule-based programming (including or ignoring the
> sacrifice involved), I was asking *how* a planner written in I7
> leverages this, and *why* it's important. These questions have not been
> sufficiently answered. I'm probably better off asking a newsgroup which
> specializes in logic programming (or AI), but I was hoping Nate could
> answer the question.

I did answer the question, several times. I explained exactly using
rules helps me to overcome real problems I encountered using my former
TADS2 OO method. You ignored my answer and claimed I was seeing a
problem that wasn't there. That's your choice, but that you didn't want
to hear what I had to say is not the same as me not saying it.

steve....@gmail.com

unread,
Jun 15, 2006, 7:32:26 PM6/15/06
to
Nate Cull wrote:
> The I7 rule engine is not a black box. I'm not sure why you keep saying
> this. It has clearly defined precedence behaviour, of roughly the same
> order as Prolog.

Now you're being silly. Prolog is also a black box language, of course.
All rule-based languages are black-box languages, because the process
is written in a different language.

> It's a lot simpler and more predictable than Prolog
> in many respects.

This is also silly. Prolog has very few "respects" for comparison. In
fact, Prolog is the simplest language I can think of, off hand. The
logic is simpler, and unoccluded by a parse web.

> One of my projects in learning Prolog will be to try to implement an
> I7-like most-general-predicate first search, as well as a Planner-like
> breadth-first search.

Super.

> > I was asking *how* a planner written in I7
> > leverages this, and *why* it's important. These questions have not been

> > sufficiently answered.[...]


>
> I did answer the question, several times.

Thank you for your efforts, but as I said, these questions have not
been sufficiently answered. I hope we don't pretend that they have
been, as this would be obstructive. You have addressed the questions,
and I appreciate the effort, but most of this does not apply
specifically to the real work of writing planners and their databases.

The best I've gotten is that the I7 Planner is slightly better at
handling cases where both objects have custom plans -- and even this
minor claim is a bit stretched, since you have to program the tiebreak
no matter what language.

steve....@gmail.com

unread,
Jun 15, 2006, 7:52:57 PM6/15/06
to
vaporware wrote, quoting me:

> > This is a separate question. Everything else being equal, you would
> > probably prefer to order the operations to reflect their natural order:
> > an object is removed from one location before it is placed in another.
> > When do you notify the object itself? Doesn't matter: fine either way.
>
> But sometimes that will be wrong, and you may have general conditions
> applying to the initial location that should be overridden in special
> cases by a condition on the destination.

Well, you could very easily code that also, but your larger point is of
course correct: that if you continue to add this kind of problem on top
of this kind of problem, you'll run into the situation where a built-in
algorithm designed to handle such situations is preferable.

> Point is, it's a question you're forced to tackle in a purely OO
> system, and you have to structure your code unnaturally to deal with
> it.

Don't know what you mean by "it," but you might favor tackling the
problem in a purely OO system, rather than tackling it in a rule-based
system. There are advantages to both, and both are unnatural.

> There is no need, in a rule based system, to have a fixed schedule
> of which objects are checked in which order.

There's a (perceived) degree of freedom, but they are checked in an
order. One of my prejudices against rule-based systems is that you
don't get a bird's eye view of such things.

> There's no need for the
> library or extension author to pick a default order.

No, this is incorrect. If you want to make good overrides, you have to
know the order they come in.

> [A] rule about moving things between two rooms doesn't


> naturally belong to either room.

If you want to disallow movement from A to B, the code would most
logically go in A. If you think of the "move" as a construct itself,
yes you could say the code belongs in the "move" construct.

> Rule based programming lets you
> separate the rule from its components.

To the extent that such is useful, and to the extent that this
overcomes the costs, hooray for rule-based programming. I'd like to see
a much better rule-based system than I7, which I appreciate as a very
useful (though somewhat misguided) testing ground.

Andrew Plotkin

unread,
Jun 15, 2006, 11:56:42 PM6/15/06
to
Here, steve....@gmail.com wrote:
> Andrew Plotkin wrote, quoting me:
> > > That is true. It's not always clear -- I'm not arguing that it is
> > > always clear. However, the frequency of this, and the problematics when
> > > it does happen, the problem's importance and the urgency of its
> > > solution -- these things can be very easily exaggerated.
> >
> > So can the ease and naturalness of breaking down a set of rules into
> > object behaviors.
>
> That is also true, but packing the process in a black box is a
> sacrifice, so the rule-based regime remains at a disadvantage, even if
> it can do one or two things slightly better.

This is the great thing about getting into discussions with you,
Steve. I know it'll be two posts, max, before you simply declare your
position to be correct. Then we can all move on!

(Bonus points when you quote someone who disagrees with you as support
for your side!)



> > Perhaps you should try implementing a complicated bit of game logic in
> > an OO manner and a rule-based manner, to compare them.
>
> BTDT, but this is beside the point. Quite apart from the real and
> imagined gains of rule-based programming (including or ignoring the
> sacrifice involved), I was asking *how* a planner written in I7
> leverages this, and *why* it's important. These questions have not been
> sufficiently answered.

Easier specification of complex conditions and goals, because subcases
can be described in localized code. (The compiler collates them them
together when generating the code, in the appropriate logical
structure). Thus, greater scalability, because less time need be spent
organizing pieces of code that are unconnected from a design
standpoint. There you go. Don't worry, this won't be on the test.

(Also, bonus points to you for parallel structure. The gains may be
real or imagined; the sacrifice may be considered or ignored. Guess
that means the sacrifice is real!)

> (By the way.... Have you yet performed this experiment?)

Yes. Then I posted a 350-line article discussing how it came out. Enh,
you'd have to have been there.



> > There are bugs in _So Far_ that I never bothered fixing, because it
> > was too much work to drop in the fixes in every object and action
> > where they were needed. (I'm thinking of the prohibitions on making
> > noise in certain areas.) These would be very simple I7 rules.
>
> You'd weigh this with/against the (in-)convenience of programming the
> rest of the game in I7. The fact that I7 does this-or-that better means
> very little.

And now we can move on!

Bonus points for deciding that when Nate disagrees with you, he's just
being silly. I also see that pretending you're wrong would be
obstructive.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

If the Bush administration hasn't thrown you in military prison without trial,
it's for one reason: they don't feel like it. Not because you're an American.

Andrew Plotkin

unread,
Jun 16, 2006, 12:14:56 AM6/16/06
to
Here, na...@natecull.org wrote:
>
> One of my projects in learning Prolog will be to try to implement an
> I7-like most-general-predicate first search, as well as a Planner-like
> breadth-first search.

For what it's worth, I have assumed all along that Prolog can do what
I want (the whole vaguely-specified and hand-wavy cloud of What I
Want.)

However, my only use of Prolog was a few weeks in CS 15-312, and it
made my head hurt. (I never did understand why the dichotomy between
red cuts and green cuts was a false one. Sorry -- I know my status as
an ivory-tower theoretician will never recover...)

This is why I've been trying to come up with a simpler model (i.e.,
not requiring the full generality of Prolog's engine). This may of
course turn out to be a fool's errand. But since I am (to date) still
hung up on defining my needs, I haven't worried about what kind of
logical deduction engine those needs will require.

Your desire to link planning rules with world-customization rules is
helpful. Well, helpful in that I've added it to What I Want, thus
complicating my life. :)

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

steve....@gmail.com

unread,
Jun 16, 2006, 12:49:25 AM6/16/06
to
Andrew Plotkin wrote, quoting me:
> > packing the process in a black box is a
> > sacrifice, so the rule-based regime remains at a disadvantage, even if
> > it can do one or two things slightly better.
>
> This is the great thing about getting into discussions with you,
> Steve. I know it'll be two posts, max, before you simply declare your
> position to be correct.

Of course I don't mean that rule-based programming is ultimately at a
disadvantage, only that it comes at a cost.

I simply point out that, if we're comparing two systems that do about
the same thing, the rule-based system is at a disadvantage (because
it's black-boxed), even if it achieves some slightly better results in
certain cases.

> (Also, bonus points to you for parallel structure. The gains may be
> real or imagined; the sacrifice may be considered or ignored. Guess
> that means the sacrifice is real!)

I don't know what you're talking about, but yes, the sacrifice is real.
Ask anyone who works in knowledge-base systems. You lose an overview of
the code.

> > (By the way.... Have you yet performed this experiment?)
>
> Yes. Then I posted a 350-line article discussing how it came out. Enh,
> you'd have to have been there.

Sorry, too much noise; didn't catch it. Looking forward to reading it.

> Bonus points for deciding that when Nate disagrees with you, he's just
> being silly. I also see that pretending you're wrong would be
> obstructive.

Now you are being silly. I hope that when we agree or disagree, we can
do so on substance. My person has nothing to do with the ideas under
discussion.

vaporware

unread,
Jun 16, 2006, 12:59:27 AM6/16/06
to
steve....@gmail.com wrote:
> vaporware wrote, quoting me:
> > > This is a separate question. Everything else being equal, you would
> > > probably prefer to order the operations to reflect their natural order:
> > > an object is removed from one location before it is placed in another.
> > > When do you notify the object itself? Doesn't matter: fine either way.
> >
> > But sometimes that will be wrong, and you may have general conditions
> > applying to the initial location that should be overridden in special
> > cases by a condition on the destination.
>
> Well, you could very easily code that also, but your larger point is of
> course correct: that if you continue to add this kind of problem on top
> of this kind of problem, you'll run into the situation where a built-in
> algorithm designed to handle such situations is preferable.
>
> > Point is, it's a question you're forced to tackle in a purely OO
> > system, and you have to structure your code unnaturally to deal with
> > it.
>
> Don't know what you mean by "it," but you might favor tackling the
> problem in a purely OO system, rather than tackling it in a rule-based
> system. There are advantages to both, and both are unnatural.

"It" is the problem of which object you check first. When all your
checks are done in methods that belong to particular objects, you have
to give one object first crack at the problem: you can't run part of
the direct object's check method, then part of the indirect object's
check method, then the rest of the direct object's check method, etc.
Well, you *could* break it up into several methods and have your system
make multiple passes over each object - but then when you write a new
check method, you have to consider every other pass in every other
object to decide where to put it.

> > There's no need for the
> > library or extension author to pick a default order.
>
> No, this is incorrect. If you want to make good overrides, you have to
> know the order they come in.

Ah, but it is correct. Nowhere in the Inform 7 library does it say "for
the verb 'inserting it into', checks will be run on the direct object
before the indirect object". A rule like "instead of inserting a coin
into the jukebox" will run before "instead of inserting something metal
into anything", not because the jukebox is asked before the coin, but
because the rule is more specific - the game author sets the order by
writing more or less specific conditions.

Now, the rules *do* run in an order, but that order isn't explicitly
set. If you need to stick a new rule in a particular place in the
order, you just look at the index and see how the compiler has ordered
them.

> > [A] rule about moving things between two rooms doesn't
> > naturally belong to either room.
>
> If you want to disallow movement from A to B, the code would most
> logically go in A. If you think of the "move" as a construct itself,
> yes you could say the code belongs in the "move" construct.

I'm not buying it; that seems like an arbitrary choice. Different
orderings make sense in different situations. If movement from room A
to room B is blocked because there's a chair wedged up against the door
inside B, it seems to me the check rule naturally belongs to B, where
you can put it near the descriptions of the door and the chair, the
grammar definitions to put the chair against the door, etc. But if it's
blocked because there are guards in A keeping you away from the door,
the rule naturally belongs to A, or even to the guards.

> > Rule based programming lets you
> > separate the rule from its components.
>
> To the extent that such is useful, and to the extent that this
> overcomes the costs, hooray for rule-based programming. I'd like to see
> a much better rule-based system than I7, which I appreciate as a very
> useful (though somewhat misguided) testing ground.

I must join the other posters in questioning how much time you've
actually spent with I7. My experience, both from writing a large game
(and a few small ones) and reading source code, has been that the code
is more readable and more writable when it's organized by scene, task,
or concept, rather than by the need for all the code in one object to
be inside the same pair of braces.

vw

Dannii

unread,
Jun 16, 2006, 1:40:50 AM6/16/06
to
> > [A] rule about moving things between two rooms doesn't
> > naturally belong to either room.
>
> If you want to disallow movement from A to B, the code would most
> logically go in A. If you think of the "move" as a construct itself,
> yes you could say the code belongs in the "move" construct.

Some rules, like a door locked on one side, belong only to A.
Some rules would likewise belong only to B.
Then there would be others, like having a broken leg, that aren't
related to either room.

(and the same goes for regions in I7 I would guess)

Kevin Forchione

unread,
Jun 16, 2006, 3:14:00 AM6/16/06
to
"vaporware" <jmc...@gmail.com> wrote in message
news:1150433967.8...@c74g2000cwc.googlegroups.com...

> "It" is the problem of which object you check first. When all your
> checks are done in methods that belong to particular objects, you have
> to give one object first crack at the problem: you can't run part of
> the direct object's check method, then part of the indirect object's
> check method, then the rest of the direct object's check method, etc.
> Well, you *could* break it up into several methods and have your system
> make multiple passes over each object - but then when you write a new
> check method, you have to consider every other pass in every other
> object to decide where to put it.

So the solution, I gather, in the rule-based approach, is the evaluation of
a series of rules moving from the specific to the general, in which the
"rule" selected dictates the action? And the issue of controversy is the
ordering of such rules (presumably because they are scattered about in
source code) so that they are evaluated in a manner that seems logical and
expected for the author? Do I have this right?

--Kevin


Neil Cerutti

unread,
Jun 16, 2006, 8:28:26 AM6/16/06
to

Yes, I think that's right. Most folks are satisfied with the
ordering by specificity, and are just uncertain about the
consequences and complications of manually prioritizing equally
specific rules.

--
Neil Cerutti
I'm traveling to all 51 states to see who can stop 85. --Chad
Johnson

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php

steve....@gmail.com

unread,
Jun 16, 2006, 10:17:05 AM6/16/06
to

vaporware wrote, quoting me:

> When all your
> checks are done in methods that belong to particular objects, you have
> to give one object first crack at the problem: you can't run part of
> the direct object's check method, then part of the indirect object's
> check method, then the rest of the direct object's check method, etc.
> Well, you *could* break it up into several methods and have your system
> make multiple passes over each object[...]

This reminds me of what TADS 3 does when resolving the objects of the
command. It tentatively resolves one object, then resolves the other
object (whose resolution can depend on those tentative results), then
goes back and resolves the first object more definitely.

> - but then when you write a new
> check method, you have to consider every other pass in every other
> object to decide where to put it.

You may be surprised to hear that this is much less of a big deal than
it sounds like, in practical cases.

> > > There's no need for the
> > > library or extension author to pick a default order.
> >
> > No, this is incorrect. If you want to make good overrides, you have to
> > know the order they come in.
>
> Ah, but it is correct.

Sorry -- you're right: you don't need to set the order because the
compiler does that. I must have misread your original post.

> Nowhere in the Inform 7 library does it say "for
> the verb 'inserting it into', checks will be run on the direct object
> before the indirect object".

Really? I'd have thought that you'd want to be able to customize this,
which would imply that there's an overrideable default.

> Now, the rules *do* run in an order, but that order isn't explicitly
> set. If you need to stick a new rule in a particular place in the
> order, you just look at the index and see how the compiler has ordered
> them.

Right. How comfortable do you find that arrangement? Do you have a
procedural-bone complaining that this is somehow wrong? Or does it just
give you a happy rulebase feeling?

> > > [A] rule about moving things between two rooms doesn't
> > > naturally belong to either room.
> >
> > If you want to disallow movement from A to B, the code would most
> > logically go in A. If you think of the "move" as a construct itself,
> > yes you could say the code belongs in the "move" construct.
>
> I'm not buying it; that seems like an arbitrary choice. Different
> orderings make sense in different situations.

That's true. I just meant the code goes in A in the otherwise blank
case. Whatever situation you specify, it's pretty easy to come up with
the most natural procedural solution.

As Plotkin pointed out a few months ago, the problem really only comes
in when you have in conflict several directives of different kinds.

steve....@gmail.com

unread,
Jun 16, 2006, 10:25:57 AM6/16/06
to
Andrew Plotkin wrote:
> > (By the way.... Have you yet performed this experiment?)
>
> Yes. Then I posted a 350-line article discussing how it came out. Enh,
> you'd have to have been there.

Still can't find it -- could some one point it out for me please? (I
assume the article was posted on RAIF....)

Rikard Peterson

unread,
Jun 16, 2006, 10:33:23 AM6/16/06
to
"" wrote in
news:1150467957.1...@y41g2000cwy.googlegroups.com:

> Andrew Plotkin wrote:
>>
>> Yes. Then I posted a 350-line article discussing how it came out.
>> Enh, you'd have to have been there.
>
> Still can't find it -- could some one point it out for me please?
> (I assume the article was posted on RAIF....)

You're looking for "[I7] My first month with I7" (June 1)
news:e5lu7p$27d$1...@reader1.panix.com

Rikard

John Roth

unread,
Jun 16, 2006, 10:55:13 AM6/16/06
to

This is a point well worth remembering: I7 is explicitly an
exploration of a certain approach to writing IF. It's stated
that way right up front. If Mr. Nelson had gotten everything
right at the start, it will be the first time in history that a
pioneer managed that trick.

The other thing worth noting is that there seems to be very few
professional software developers with a reasonably wide range
of experiance on this discussion. Experiance with multiple
languages that have very different approaches (procedural,
OO, functional, logic and so forth (not to mention Forth)) is very
humbling.

I'm bemused by pronouncements that "you can't do thus and
so with OO." Every pronouncement I've seen is a standard
situation with standard solutions - at least if you've got the
experience and have good access to the design patterns literature.

Existing OO frameworks for IF may not handle those scenarios
very well; that's more a limitation of the framework than a
limitation of the basic OO paradigm.

John Roth

vaporware

unread,
Jun 16, 2006, 11:27:52 AM6/16/06
to
steve....@gmail.com wrote:
> vaporware wrote, quoting me:
[...]

> > Nowhere in the Inform 7 library does it say "for
> > the verb 'inserting it into', checks will be run on the direct object
> > before the indirect object".
>
> Really? I'd have thought that you'd want to be able to customize this,
> which would imply that there's an overrideable default.

I think you're missing the point. There is no ordering of objects at
all - checks aren't run on one object before the other. The rules are
just run in the order of specificity, which means some rules involving
the direct object might be intermingled with rules involving the
indirect object.

> > Now, the rules *do* run in an order, but that order isn't explicitly
> > set. If you need to stick a new rule in a particular place in the
> > order, you just look at the index and see how the compiler has ordered
> > them.
>
> Right. How comfortable do you find that arrangement? Do you have a
> procedural-bone complaining that this is somehow wrong? Or does it just
> give you a happy rulebase feeling?

I haven't had to do it much.. the most I've really had to do is
substitute one rule for another. As long as you can articulate the
reason why your new rule needs to go where it does, it should be easy
enough to identify the existing rule you need to attach it to.

> > > If you want to disallow movement from A to B, the code would most
> > > logically go in A. If you think of the "move" as a construct itself,
> > > yes you could say the code belongs in the "move" construct.
> >
> > I'm not buying it; that seems like an arbitrary choice. Different
> > orderings make sense in different situations.
>
> That's true. I just meant the code goes in A in the otherwise blank
> case. Whatever situation you specify, it's pretty easy to come up with
> the most natural procedural solution.

*shrug* I think you just find it "natural" because you're used to that
style, and used to having to make a decision in the first place as to
which object the test will belong to.

vw

Joe Mason

unread,
Jun 16, 2006, 4:48:48 PM6/16/06
to
On 2006-06-15, steve....@gmail.com <steve....@gmail.com> wrote:
> Now you're being silly. Prolog is also a black box language, of course.
> All rule-based languages are black-box languages, because the process
> is written in a different language.

That's a very strange definition of "black box".

Joe

Adam Thornton

unread,
Jun 16, 2006, 5:43:47 PM6/16/06
to
In article <1150469713.8...@g10g2000cwb.googlegroups.com>,

John Roth <John...@jhrothjr.com> wrote:
>If Mr. Nelson had gotten everything
>right at the start, it will be the first time in history that a
>pioneer managed that trick.

Counterexample: Gutenberg.

Well, OK, the technology of printing got a lot cheaper per page. But
the actual OUTPUT got no better.

Adam

steve....@gmail.com

unread,
Jun 16, 2006, 5:46:08 PM6/16/06
to
Joe Mason wrote, quoting me:

> > All rule-based languages are black-box languages, because the process
> > is written in a different language.
>
> That's a very strange definition of "black box".

Far from strange -- quite common (the most common I would think), and
indeed it's the obvious meaning where the problem of rule-based systems
is under discussion.

The term is used in two other contexts in CS: "black box testing" is
the process of checking a program by examining its output (and not
looking at the program itself); machine learning (borrowing the term's
usage in physics) is sometimes described as deducing an unknowable
"black box" function.

Joe Mason

unread,
Jun 16, 2006, 10:15:08 PM6/16/06
to
On 2006-06-16, steve....@gmail.com <steve....@gmail.com> wrote:
> Joe Mason wrote, quoting me:
>> > All rule-based languages are black-box languages, because the process
>> > is written in a different language.
>>
>> That's a very strange definition of "black box".
>
> Far from strange -- quite common (the most common I would think), and
> indeed it's the obvious meaning where the problem of rule-based systems
> is under discussion.

So if a system is written using more than one language, one language
magically becomes opaque?

NI is almost a "black box" because the code hasn't been released yet,
although we do have complete sources to the I6 layer. Prolog is not a
black box in any sense, because we don't simply have a set of inputs and
outputs, we have enough specifications to write the complete
interpreter, and several open source options to choose from.

> The term is used in two other contexts in CS: "black box testing" is
> the process of checking a program by examining its output (and not
> looking at the program itself); machine learning (borrowing the term's
> usage in physics) is sometimes described as deducing an unknowable
> "black box" function.

In black box testing, we are limiting ourselves to not look at the box's
interior to be sure our test coverage doesn't depend on the internal
implementation. It's only a black box because we refuse to look inside
it. If the goal is to understand the algorithm for rules precedence,
why would you limit yourself like that?

Joe

Gene Wirchenko

unread,
Jun 16, 2006, 11:20:31 PM6/16/06
to
"John Roth" <John...@jhrothjr.com> wrote:

[snip]

>I'm bemused by pronouncements that "you can't do thus and
>so with OO." Every pronouncement I've seen is a standard
>situation with standard solutions - at least if you've got the
>experience and have good access to the design patterns literature.
>
>Existing OO frameworks for IF may not handle those scenarios
>very well; that's more a limitation of the framework than a
>limitation of the basic OO paradigm.

Nice hammer. You do have other tools, right? (Silver bullets do
not count.)

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.

Kyle Pierce

unread,
Jun 17, 2006, 8:17:04 AM6/17/06
to
Andrew Plotkin wrote:
> For what it's worth, I have assumed all along that Prolog can do what
> I want (the whole vaguely-specified and hand-wavy cloud of What I
> Want.)
>
> However, my only use of Prolog was a few weeks in CS 15-312, and it
> made my head hurt. (I never did understand why the dichotomy between
> red cuts and green cuts was a false one. Sorry -- I know my status as
> an ivory-tower theoretician will never recover...)

Yeah, I never quite understood those red and green cuts until I
realized how simple it is: that's how you tell the humans from the
aliens -- just cut them. Sorry, couldn't resist.

Anyhow, speaking of Prolog vs. I7, there's an obvious difference that I
haven't determined to be a win for one or the other. In I7, when a rule
fails or succeeds, evaluation of its rulebook ends. In Prolog, each
predicate can have multiple clauses and so is sort of like a rulebook.
The rule engine evaluates the individual clauses until one of them
succeeds. Given this, you write predicates so that they will match (and
exclude, if desired) the most general case first.

So what... it didn't occur to me before I7 came along that two
rule-based languages could be so different. Interesting if you're into
such things.

>
> This is why I've been trying to come up with a simpler model (i.e.,
> not requiring the full generality of Prolog's engine). This may of
> course turn out to be a fool's errand. But since I am (to date) still
> hung up on defining my needs, I haven't worried about what kind of
> logical deduction engine those needs will require.

One simpler model than Prolog is Datalog, a sort of query language that
can be installed on top of Prolog (see des.sourceforge.net, e.g.).

Kyle

Andrew Plotkin

unread,
Jun 17, 2006, 1:55:35 PM6/17/06
to

I would say that the ordering of logical specificity (narrowness)
solves *part* of the ordering problem for rules. It is the
uncontroversial part -- it's easy to explain and the system can do it
automatically. However, it is not sufficient: not all rules have a
specificity ordering, and the author needs a way to customize ordering
anyhow.

(This has nothing to do with the comparison of rule models to object
models. I'm just disagreeing with the idea that specificity is *the*
solution to the basic problem.)

Andrew Plotkin

unread,
Jun 17, 2006, 2:02:52 PM6/17/06
to
Here, John Roth <John...@jhrothjr.com> wrote:
>
> I'm bemused by pronouncements that "you can't do thus and
> so with OO."

It's only bemusing if "thus and so" is an algorithm to be implemented.

When you're talking about the task of easily creating, extending, or
maintaining software, it's perfectly reasonable to say "This approach
just doesn't hold up." This is, after all, exactly the kind of thing
people say when they boost OO over simple imperative programming. (Or,
to work in examples, Java over Basic. Can you implement thus and so in
Basic? Sure; what you can't do is *do that easily and maintainably.*.)

> Existing OO frameworks for IF may not handle those scenarios
> very well; that's more a limitation of the framework than a
> limitation of the basic OO paradigm.

Here, I just disagree. A paradigm (or whatever term) is a way of
approaching a problem. Not all problems are equally amenable to being
approached from an OO standpoint.

steve....@gmail.com

unread,
Jun 17, 2006, 3:53:01 PM6/17/06
to
Andrew Plotkin wrote:
> I would say that the ordering of logical specificity (narrowness)
> solves *part* of the ordering problem for rules. It is the
> uncontroversial part -- it's easy to explain and the system can do it
> automatically. However, it is not sufficient: not all rules have a
> specificity ordering, and the author needs a way to customize ordering
> anyhow.

I agree. A rule-based system *also* requires the user to do this (what
I have been calling simply "tiebreaking") by hand.

> (This has nothing to do with the comparison of rule models to object

> models.[...])

It's a similarity between the two models, don't you think?

Kevin Forchione

unread,
Jun 17, 2006, 3:53:13 PM6/17/06
to
"Kyle Pierce" <kpst...@gmail.com> wrote in message
news:1150546624....@r2g2000cwb.googlegroups.com...

> Anyhow, speaking of Prolog vs. I7, there's an obvious difference that I
> haven't determined to be a win for one or the other. In I7, when a rule
> fails or succeeds, evaluation of its rulebook ends. In Prolog, each
> predicate can have multiple clauses and so is sort of like a rulebook.
> The rule engine evaluates the individual clauses until one of them
> succeeds. Given this, you write predicates so that they will match (and
> exclude, if desired) the most general case first.

That kind of behavior is actually indicative of much of the I6 library. The
behavior of rules and rulebooks is a natural extension of the library.

--Kevin


Kevin Forchione

unread,
Jun 17, 2006, 4:39:37 PM6/17/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e71fmn$sd3$1...@reader2.panix.com...

Thanks. I'm interested in understanding the I7 model and not in arguing
about some hypothetical alternative or whether one model is superior to
another. As a species programmers seem to go into "pounce on the weakness"
mode rather than "grasp the whole" and then we receive our education
piecemeal and strained through their gritted teeth.

--Kevin


Kevin Forchione

unread,
Jun 17, 2006, 4:48:01 PM6/17/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e71g4c$sd3$2...@reader2.panix.com...

> Here, John Roth <John...@jhrothjr.com> wrote:
>>
>> I'm bemused by pronouncements that "you can't do thus and
>> so with OO."
>
> It's only bemusing if "thus and so" is an algorithm to be implemented.
>
> When you're talking about the task of easily creating, extending, or
> maintaining software, it's perfectly reasonable to say "This approach
> just doesn't hold up." This is, after all, exactly the kind of thing
> people say when they boost OO over simple imperative programming. (Or,
> to work in examples, Java over Basic. Can you implement thus and so in
> Basic? Sure; what you can't do is *do that easily and maintainably.*.)
>
>> Existing OO frameworks for IF may not handle those scenarios
>> very well; that's more a limitation of the framework than a
>> limitation of the basic OO paradigm.
>
> Here, I just disagree. A paradigm (or whatever term) is a way of
> approaching a problem. Not all problems are equally amenable to being
> approached from an OO standpoint.

That's true. Now the question that springs to mind is are there areas of our
IF domain that OO works better at, while another paradigm is better at
another area, and can we live with a mixed paradigm model even when the
result is a superior design? Has the community somewhere documented the best
paradigms for various areas of IF programming? And if so, then have the
languages being designed addressed those paradigms adequately?

--Kevin


Andrew Plotkin

unread,
Jun 18, 2006, 1:34:44 AM6/18/06
to
Here, steve....@gmail.com wrote:
> Andrew Plotkin wrote:
> > I would say that the ordering of logical specificity (narrowness)
> > solves *part* of the ordering problem for rules. It is the
> > uncontroversial part -- it's easy to explain and the system can do it
> > automatically. However, it is not sufficient: not all rules have a
> > specificity ordering, and the author needs a way to customize ordering
> > anyhow.
>
> I agree. A rule-based system *also* requires the user to do this (what
> I have been calling simply "tiebreaking") by hand.

In my (I6) experience, the OO model *prevents* the author from
customizing the ordering. Or rather, makes it tremendously more work
than it should be (given the primacy of this kind of decision in IF
design).

But, as I said:

> > (This has nothing to do with the comparison of rule models to object
> > models.[...])
>
> It's a similarity between the two models, don't you think?

No. It's an aspect of the common problem that the two models are
solving.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

"Bush has kept America safe from terrorism since 9/11." Too bad his
job was to keep America safe *on* 9/11.

Andrew Plotkin

unread,
Jun 18, 2006, 10:48:31 AM6/18/06
to
Here, Kevin Forchione <ke...@lysseus.com> wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:e71g4c$sd3$2...@reader2.panix.com...
> > Here, John Roth <John...@jhrothjr.com> wrote:
> >>
> >> Existing OO frameworks for IF may not handle those scenarios
> >> very well; that's more a limitation of the framework than a
> >> limitation of the basic OO paradigm.
> >
> > Here, I just disagree. A paradigm (or whatever term) is a way of
> > approaching a problem. Not all problems are equally amenable to being
> > approached from an OO standpoint.
>
> That's true. Now the question that springs to mind is are there areas of our
> IF domain that OO works better at, while another paradigm is better at
> another area, and can we live with a mixed paradigm model even when the
> result is a superior design?

I find it hard to say, because I don't think we have enough experience
with rule systems yet.

When IF design systems started using OO models (and I count TADS 2 and
Inform 5 as having done that off the starting block) it was clearly a
good move. A lot of world model specification falls easily into the
pattern of objects with properties. (Object descriptions, room exits,
containers with contents and open/closed flags -- all the obvious
stuff.) Object classes and inheritance were useful too.

I7 still contains all that stuff (except that it excludes multiple
inheritance of classes.) Object descriptions are still properties,
containers still have an open/closed flag, etc. I think this is mostly
I6 legacy, rather than a roots-up design model based on the idea of
rules.

When I was first imagining an IF rules model, I assumed it would
include a lot of what we think of as OO mechanisms. For example,
instead of having a "description" property for objects, I was
imagining:

Rule for describing coins: say "It's a coin."
Rule for describing the worn penny: say "It's a worn copper penny."

Rule for describing the lantern: say "An ancient Gnomish aluminum
lantern."
Rule for describing the lantern when the lantern is lit: say "An
ancient Gnomish aluminum lantern, glowing half as bright as a dead
firefly."

(Well, I wasn't imagining I7-like syntax, but I'll stick to that for
clarity. Yes, it's verbose and warrants some abbreviated syntax for
common cases. :-)

Note that we have a class property which is (effectively) inherited by
all coins, but overridden for one instance. You can call that an OO
paradigm. But then you have the lantern, which has a method whose
dispatch is based on two different properties ("description" and
"lit"). That's not very OO-like at all. And of course you could wind
up with

Rule for describing the lantern when the lantern is lit and the hour
is after dusk and the hour is before dawn and the player's mind
contains Gnomish rune knowledge: ...

Similarly, you will certainly want to write action rules like
"touching when the object is a brick", "touching when the object is a
coin", "touching when the object is a penny". That can reasonably be
described as OO dispatch based on an argument type (with inheritance).
But then the conditions get more complicated.

So in this sense, rules are a superset of OO functionality; or at
least, they encompass the most common OO patterns in IF design. And
while you can of course implement rules *using* an OO model -- that's
what the I7 compiler *does* -- the value to the author is in not
having to think about that level of the implementation.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

9/11 did change everything. Since 9/12, the biggest threat to American
society has been the American president. I'd call that a change.

Andrew Plotkin

unread,
Jun 18, 2006, 11:17:49 AM6/18/06
to
Going back to the question of comparing OO and rule models...

Let me give an account of an old IF pattern: before/after rule
customizations. This is something which was in Inform from the
beginning (or at least from the first release of I5).

Despite the name, the before/after mechanism is intended to allow both
overrides (replacement of default behavior) and actual before/after
rules (additional behavior which is scheduled before or after the
default behavior). In your typical Inform game, overrides are much
more heavily used; but both options are available.

Standard OO languages have a single pattern for before/after work
(that I know of): you write a subclass method that looks like
"do_my_stuff; super()" or "super(); do_my_stuff;"

This is kind of a pain. From an IF standpoint, it's mixing
implementation with design. You are unnecessarily put in charge of
calling *that other function* when writing your customization, when
all you wanted was to put some code *before* that other function.

(And this is the *conceptual* difference of the rule model, in a
nutshell. Each piece of code stands by itself, and is not responsible
for any other bit. Until the author decides to *pick up* that
responsibility -- in particular instances. In OO, when you're writing
an override method, you are "on the inside" for that method, and (to
some extent) for the whole class and its superclass too. The language
may offer tools to limit that responsibility ("private" modifiers,
etc) but that's not inherent to the OO idea.)

I can even cite an example here. I6 has a notion of "touchable
objects" -- a coin in a closed glass box is untouchable. The default
actions (taking, feeling, etc) refuse to work on untouchable objects.
Now, if you're writing some code that says "The coin feels cold", how
do you have to do it in I6? Essentially, the standard OO "super()"
pattern:

before [;
Touch:
if (ObjectIsUntouchable()) rtrue;
print_ret "The coin feels cold.";
]

And I'll tell you off the bat that I never remember to do this. It's a
pain in the butt and it's not worth the code clutter. I allow the
notion of untouchability to *break* in my code, except for the few
places where there *is* a closeable glass box, and then I swear and
mutter and put the cruft in.

And it's cruft because, conceptually, I don't care about the
touchability rules at all; I want to specify how the object feels,
*after* touchability, *instead of* the default touching message. And
I7 does achieve this. (Albeit in a multistage way which I think is
more confusing than it has to be.)

Eric Eve

unread,
Jun 18, 2006, 12:07:07 PM6/18/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e73p3v$gf0$1...@reader2.panix.com...

ISTM that it may be useful to introduce a discussion at this point.
There's OO in what we might call the simulationist sense, which
seems to be what you're describing above, in which we're thinking
primarily of programming objects that represent objects in the game
world, and there's OO in the more abstract sense, in which we're
talking about a style of programming which makes use of
encapsulating code and properties in classes and objects (which may
or may not correspond to physical objects in the game world). Of
course there's an overlap between the two, in that OO in the
simulationist sense uses programming objects in the more abstract
sense, but by the "simulationist" sense (perhaps not the best term I
could have chosen, but it was the first that came to mind),
programming objects on the whole represent physical objects in the
game world. This seems to be what you have in mind in talking about
I5/I6/TADS 2. Again, this seems to be the model you had primarily in
mind in pointing out potential problems with the OO approach and the
potential superiority of a rule-based approach.

However, there's no reason why an OO IF system has to work in such a
way that programming objects usually represent physical objects in
the game world. In TADS 3, for example, programming objects are used
for a whole lot of other things (such as preconditions, agenda
items, conversational responses and travel connectors), many of
which perform functions not completely dissimilar to rules in I7.
Indeed, if someone wanted to write a rulebook extension for TADS 3,
s/he would almost certainly start by defining a RuleBook class and a
Rule class, and the rules would probably be instantiated as
programming objects. In this scenario, OO programming could be a way
of implementing a rule-based system, so I'm not even sure that the
two are incompatible. That is, I'm not sure a rule-based system is
incompatible with an OO one in the abstract sense, although it is,
of course, distinct from an OO system in the narrowly simulationist
sense.

I wonder if part of the reason why Steve and you are disagreeing
over the merits of rule-based vs. OO systems for IF is that each
have different OO systems in mind; Steve is coming from his
experience with TADS 3 (I'd guess) while you're coming from your
experience with I6 (I'd guess). In following earlier parts of this
exchange I rather felt myself tending to agree with Steve, insofar
as I've yet to find the OO approach as implemented in TADS 3
seriously get in the way of what I'm trying to do, and I've seldom
felt any kind of arbitrariness in choosing which object to attach
stuff to to be a problem (e.g. one of the examples discussed
up-thread was on handling special behaviour when moving X from room
A to room B; in TADS 3 one would probably define the behaviour on a
TravelConnector object linking room A to room B, so the problem
whether the behaviour properly belongs to A, B or X is something of
a pseudo-problem). Even where one does have to make a relatively
arbitrary choice (e.g. between the direct and indirect objects of a
command), this seldom feels much like a problem in practice -- but
that's another point and a bit tangential to what I'm trying to say
here.

This is in no way intended to be polemical against either I7 or
rule-based systems in general, but I wonder if some of the alleged
shortcomings of the OO model apply more to OO in its more
simulationist than its more abstract sense, and whether this might
be a source of potential misunderstanding in this discussion.

-- Eric


Kevin Forchione

unread,
Jun 18, 2006, 2:18:22 PM6/18/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e73qqt$rbk$1...@reader2.panix.com...

So what you'd like to see would be something like:

when the coin is touched, say "the coin feels cold."

Something like that? Seems reasonable to me, and yes, the OO pattern you
describe is very common in TADS protgramming.

--Kevin


Andrew Plotkin

unread,
Jun 18, 2006, 5:59:01 PM6/18/06
to
Here, Eric Eve <eric...@nospamhmc.ox.ac.uk> wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:e73p3v$gf0$1...@reader2.panix.com...

> >
> > When IF design systems started using OO models (and I count TADS 2
> > and Inform 5 as having done that off the starting block) it was
> > clearly a good move. A lot of world model specification falls
> > easily into the pattern of objects with properties. (Object
> > descriptions, room exits, containers with contents and open/closed
> > flags -- all the obvious stuff.) Object classes and inheritance
> > were useful too.
>
> ISTM that it may be useful to introduce a discussion at this point.
> There's OO in what we might call the simulationist sense, which
> seems to be what you're describing above, in which we're thinking
> primarily of programming objects that represent objects in the game
> world

I was, in fact, keeping the more abstract sense of OO in mind. Inform
has always (mildly) encouraged thinking beyond the simple "objects are
model-world objects" idea, by allowing you to use Inform-language
objects (and their OO mechanisms) for any purpose. It has never been
fully OO itself, in that there are no object representations of verbs,
scopes, or other IF programming abstractions. But that road has never
seemed very tempting, either.

> I wonder if part of the reason why Steve and you are disagreeing

I think you mean Kevin and I, or possibly John Roth.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

If the Bush administration hasn't shipped you to Syria for interrogation, it's
for one reason: they don't feel like it. Not because of the Eighth Amendment.

Andrew Plotkin

unread,
Jun 18, 2006, 6:01:09 PM6/18/06
to
Here, Kevin Forchione <ke...@lysseus.com> wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:e73qqt$rbk$1...@reader2.panix.com...
> >
> > I can even cite an example here. I6 has a notion of "touchable
> > objects" -- a coin in a closed glass box is untouchable. The default
> > actions (taking, feeling, etc) refuse to work on untouchable objects.
> > Now, if you're writing some code that says "The coin feels cold", how
> > do you have to do it in I6? Essentially, the standard OO "super()"
> > pattern:
> >
> > before [;
> > Touch:
> > if (ObjectIsUntouchable()) rtrue;
> > print_ret "The coin feels cold.";
> > ]
> >
> > And I'll tell you off the bat that I never remember to do this. It's a
> > pain in the butt and it's not worth the code clutter. I allow the
> > notion of untouchability to *break* in my code, except for the few
> > places where there *is* a closeable glass box, and then I swear and
> > mutter and put the cruft in.
> >
> > And it's cruft because, conceptually, I don't care about the
> > touchability rules at all; I want to specify how the object feels,
> > *after* touchability, *instead of* the default touching message. And
> > I7 does achieve this. (Albeit in a multistage way which I think is
> > more confusing than it has to be.)
>
> So what you'd like to see would be something like:
>
> when the coin is touched, say "the coin feels cold."

That's what I've got now. But, again, one example doesn't prove
anything; I had something like that in I6. For that matter, I had
something like that when I was homebrewing IF parsers in BASIC.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

If the Bush administration hasn't shipped you to Syria for interrogation, it's
for one reason: they don't feel like it. Not because of the Eighth Amendment.

Kevin Forchione

unread,
Jun 18, 2006, 11:14:38 PM6/18/06
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:e74ib5$4h4$1...@reader2.panix.com...

>> I wonder if part of the reason why Steve and you are disagreeing
>
> I think you mean Kevin and I, or possibly John Roth.

I hadn't realized we were disagreeing. At least I'm not aware of any
statements you've made that I have an argument with.

--Kevin


steve....@gmail.com

unread,
Jun 19, 2006, 7:32:00 AM6/19/06
to
Andrew Plotkin wrote:
> I was, in fact, keeping the more abstract sense of OO in mind.

And I have been, for that matter, keeping away from blurring the
distinction between OO and rule-based models, by focusing mostly on
simple "simulationist OO" rather than producing such arguments as "OO
is a model, whereas rule is an implementation" -- though this is
certainly correct.

I think the complaint against a simulationist implementation of OO
(Plotkin, vaporware, etc.) should be addressed on its own grounds. It's
a legitimate complaint, and germane to both I6 and, at least to a
degree, TADS 3.

It's a legitimate complaint, that we would rather be able to express
relationships between objects, and we want those expressions crunched
and ordered for us to the extent possible -- a legitimate complaint,
but how important, and how important are the things we must give in
trade? There's where I think the main disagreement lies.

Another potential confusion: people might be taking problems in I6 and
blaming the OO model rather than the implementation.

Magnus Olsson

unread,
Jun 19, 2006, 8:16:25 AM6/19/06
to
In article <e6lcmb$ol4$1...@reader2.panix.com>,
Andrew Plotkin <erky...@eblong.com> wrote:
>Here, na...@natecull.org wrote:
>>
>> Granted that I7 rules are so neat, I still find myself very cramped by
>> I7's 'look but don't touch' approach to the rest of the world model.
>> The compiler gets to play with lots of interesting markup such as
>> adjectives, definitions, relations, and the like, but I don't have
>> access to any of this at runtime.
>>
>> This is a problem when it comes to wanting to write planning NPCs. The
>> complexity I just mentioned comes from the fact that writing plans is
>> essentially reverse-engineering the structure of the story world. So in
>> a game with planning NPCs, I'm writing rules twice: once to implement
>> the special-cases of the world behaviour, and once to make the NPCs
>> aware of this and know how to handle it.
>
>I am all with the idea of not writing code twice. But how do you see
>using first-class world-model elements (run-time relations, rules,
>etc) to solve this problem? I mean, what would your ideal solution
>look like?

Isn't there also a problem with the NPC's acting from their *idea*
of how the world works, and not from how the world actually works?
You've touched on this in another post: if the key to the safe really
is hidden behind a book in the library, but the NPC last saw it in a
desk drawer in the study, you want the NPC to look in the drawer, not
behind the book.

And, on a less trivial level, if the NPC has a different idea of what
the actual rules are, you want one set of rules for running the game
world and one set of rules to be used by the NPC. For example, a
rather simulationist game could actually implement Newton's laws to
handle the way dropped objects fall - but one NPC may believe in
Aristotelian mechanics and another one may believe that gravity is
magic and can be influenced by his sister's state of mind... :-)

--
Magnus Olsson (m...@df.lth.se)
PGP Public Key available at http://www.df.lth.se/~mol

steve....@gmail.com

unread,
Jun 19, 2006, 9:09:02 AM6/19/06
to
Magnus Olsson wrote:
> Isn't there also a problem with the NPC's acting from their *idea*
> of how the world works, and not from how the world actually works?

The TADS 3 version of RAP demonstrates how to base the NPC's behavior
on his beliefs. It's pretty simple, whether we want this to vary on the
believed "state" of objects (such as their location) or on "behavior"
(like which plan is likely to work for any given goal). In the first
case, instead of consulting the property directly, we consult the NPC's
knowledge database. In the latter case, we activate and deactivate
plans programmatically, such as when the NPC observes the PC doing
something that the NPC did not formerly know how to do, or when the NPC
realizes that the going plan isn't going to work.

Now it is true that we don't want our NPCs to be omniscient; that we
normally want them to act on their beliefs, rather than on a direct
knowledge of the game-state. Nevertheless, it would be a huge step
forward if we could derive plans directly from the game. It would be
*much* easier to flag/filter non-obvious behavior than it would be to
write a total planbase for any non-trivial game, and whatever
knowledge-limitations we want must be coded in either case.

Andrew Plotkin

unread,
Jun 19, 2006, 9:55:43 AM6/19/06
to
Here, Magnus Olsson <m...@df.lth.se> wrote:
>
> Isn't there also a problem with the NPC's acting from their *idea*
> of how the world works, and not from how the world actually works?
> You've touched on this in another post: if the key to the safe really
> is hidden behind a book in the library, but the NPC last saw it in a
> desk drawer in the study, you want the NPC to look in the drawer, not
> behind the book.

Yes, it's come up.

I'd say (and I think Nate said this too) that if the system is
designed correctly, then the NPC's default state of knowledge will be
the world. In other words, the (easy) default should be for the NPC to
directly use the world-model rules for its planning. The author could
then customize this, either way -- there can be (doable) actions that
the NPC will not try, and there can be impossible things that the NPC
*will* try (and fail, due to world rules.)

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

If the Bush administration hasn't subjected you to searches without a warrant,
it's for one reason: they don't feel like it. Not because you're an American.

steve....@gmail.com

unread,
Jun 19, 2006, 10:50:50 AM6/19/06
to
Andrew Plotkin wrote:
> I'd say (and I think Nate said this too) that if the system is
> designed correctly, then the NPC's default state of knowledge will be
> the world.

"Correct" might be a bit strong, but designing a library which could
inform a planner would be a big advance for planners anyway.

> In other words, the (easy) default should be for the NPC to
> directly use the world-model rules for its planning. The author could

> then customize this[....]

That's right. Or as Nate wrote...

> I would also like for there to be room for different actors
> to have different levels of knowledge and possibly whole different sets
> of plans, and not necessarily automatically know the 'correct'
> behaviour that the world implements. But have 'read world's mind'
> available as a default.

Unfortunately, I don't think this is very practicable given modern IF
technology. (Note, however, that you can write Prolog that recurses its
own rules -- not that this solves the problem, but it's interesting.)

Richard Bos

unread,
Jun 20, 2006, 6:09:24 PM6/20/06
to
Andrew Plotkin <erky...@eblong.com> wrote:

> I would say that the ordering of logical specificity (narrowness)
> solves *part* of the ordering problem for rules. It is the
> uncontroversial part -- it's easy to explain and the system can do it
> automatically. However, it is not sufficient: not all rules have a
> specificity ordering, and the author needs a way to customize ordering
> anyhow.

Not necessarily. It is also possible to give the author a way to write
his rules such that ordering doesn't matter. Prolog was originally
intended to be used that way. It's harder, though, both for the compiler
writer and the user-programmers.

Richard

steve....@gmail.com

unread,
Jun 20, 2006, 11:53:55 PM6/20/06
to
Richard Bos wrote:
> It is also possible to give the author a way to write
> his rules such that ordering doesn't matter. Prolog was originally
> intended to be used that way.

Was it? I didn't know that much about its origins. As it's used now,
the order in the sourcecode determines precedence, and it's very
important indeed.

Richard Bos

unread,
Jun 21, 2006, 4:10:37 PM6/21/06
to
steve....@gmail.com wrote:

Yes, in theory it was; I believe that they never did manage to get this
working in practice.

It would be just gorgeous for quantum computing, though.

Richard

steve....@gmail.com

unread,
Jun 22, 2006, 10:56:40 PM6/22/06
to

Richard Bos wrote, quoting me:

> > Richard Bos wrote:
> > > It is also possible to give the author a way to write
> > > his rules such that ordering doesn't matter. Prolog was originally
> > > intended to be used that way.
> >
> > Was it? I didn't know that much about its origins. As it's used now,
> > the order in the sourcecode determines precedence, and it's very
> > important indeed.
>
> Yes, in theory it was; I believe that they never did manage to get this
> working in practice.

The dream exceeded the capacity of the code. That's pretty common.
Rule-base programming sounds extremely good at first, until you realize
that you have to deal with the same sh*t you have to deal with anyhow
(tiebreaking, etc.), and then you realize that you are, well not back
where you started, but doing the same thing, only differently.

Compare: in theory, I7 roxors, but in practice, it hasn't solved the
major problems intrinsic to writing code.

> It would be just gorgeous for quantum computing, though.

And improbability-machine programming might make a smashing success
of...

0 new messages