On our list. Taken some baby steps in that direction. Don't Hold Your Breath.™
That is what I meant, but I want to be able to keep the selected package in the global environment while interacting with the REPL.
You know,
Okay, actually, why do you need the PROGRAM block at all? Why not just have FACT and RULE and GOAL blocks that can be used in any order, and/or can be put in a plain old Snap! stack? And the package thing I was asking for would just be a stack not including any goals.
And I guess I would make GOAL a reporter, which would report a stream, like the logic programming language in SICP. That's a really elegant way to cope with infinite loops; you'd get an infinite-length stream, which you could manipulate like any stream, printing the first ten items, etc. As you said earlier, this works elegantly only if all the desired solutions appear in a finite first-n-items of the stream.
So the FACT and RULE blocks could do some antibugging by reordering the database to put base cases first, etc. And look for obvious circularities like sibling(a,b) :- sibling(b,a). But all the real work is done in GOAL, which starts with an initial empty stream of environments and processes a query by resolving it with each item of the database; a resolution can omit an item from the stream of environments if this database item is incompatible with that environment, or it can expand an item from the stream of environments if the resolution gives rise to new bindings for that environment.
But why am I trying to say all this? It's in SICP 4.4 Logic Programming.
Oh yes, of course, but the joke is that they are acknowledging that there's no way that a comment on that one line of code can explain how it works. Rather, what you need is an overall understanding of the various data structures that make up a process, and also an understanding of how the PDP-11 hardware did memory management (and now I think about it, I must have been wrong in my description; the one register they changed must have been the pointer to the page table, in which page 0 contains all the processor registers). In other words, what you'd need is a node in the second depth level of the documentation tree.
It suddenly occurs to me that we are starting with different ideas of the task, and that partly explains why what I want is a little different from what you're doing. I think that your idea is to implement Prolog, period, and you happen to be using Snap! as the implementation language. But your example Amalog program really doesn't connect with Snap! in any substantial way; you write the program in 100% Prolog notation and you get an answer from Amalog and that's that. Maybe it's just your example that has that flavor rather than your view of the entire language. But I'm envisioning a user writing what's mainly a Snap! project, but using an Amalog extension that provides answers to queries, with a typical style of use wherein the GOAL block is inside a FOR EACH ITEM block that does something or other with each answer. In fact, maybe what GOAL reports isn't a stream of printable solutions, but rather a stream of environments of bindings of variables, and there's a separate ENVIRONMENT->SOLUTION that turns such an environment into a copy of the goal but with variables filled in. Or maybe even an intermediate ENVIRONMENT->VALUES that takes an environment in which variables can be bound to other variables or expressions and reports an environment, same data structure, but one in which every variable is bound directly to a constant value. And then VALUES->SOLUTION that etc.
So this is why you do things like putting a program name field in your program block. Lispians don't do that, generally; if you want to name something, you bind a variable to it. And even with respect to comments, what you really want is to attach a comment to a specific rule, but you don't like our notation for that. (I don't either, honestly, but since I don't do line-by-line commenting it isn't a problem for me!)
