[comp.lang.prolog] setof / prolog compiler

bimbart@kulcs.uucp (Bart Demoen) (08/19/88)

In article <290@quintus.UUCP> Richard A. O'Keefe writes:

>(b) setof/3 only really has a logical reading when all the solutions
>    it returns are ground.  (Consider the fact that
>        setof(X, member(X, [_,_]), [A,B])
>    will bind A, B to two variables satisfying A @< B,
>    but then you can do A=2, B=1 and presto! the result is found to
>    have been in the wrong order.)

I think the above argument says more about the non-logical reading of @</2
when its arguments are variables, than about setof/3

In article <288@quintus.UUCP> Richard A. O'Keefe writes:

> [Tokenisers for Prolog in C, I understand.
>  Parsers for Prolog in C, I understand.
>  Peephole optimisers and assemblers for WAM instructions in C, I understand.
>  It's the bit in the middle I need to have explained.
> ]

I will not attempt to explain something, just tell part of the BIMpcomp story.

I wrote the compiler (actually, parser + WAM code generator; assembler is a
later pass by someone else) for BIMprolog and I am still maintaining it and
changing it.

The current version of the compiler is in C and for quite some
years, maintaining and changing it, has been easy and fun.
The main reason is that I wrote the first version of this compiler in Prolog
- an old version Maurice Bruynooghe wrote - and later translated it to C (after
a short and much regretted stage of Pascal).
The original Prolog version of the compiler - and so the first C version as
well - generated no indexing instructions (SWITCH...), had a very bad temporary
register allocation, did not optimise arithmetic, had no notions of a module
system, couldn't handle mode declarations, didn't detect determinacy ... still,
it has been not difficult at all to add all these things in C: the first
version in C was so close to the Prolog version that it really was
declarative C.
Now I am considering to restart this process: rewrite the compiler in BIMprolog
so that it incorporates our - the assembler guy is involved too now - current
ideas about compiling Prolog, but then certainly I will translate the compiler
to C again; such a translation takes surprisingly little time and it pays off
for the users. There is just one condition on the Prolog code to be translated:
it should be very close to deterministic.

Perhaps you understood that I like Prolog mainly for rapid prototyping reasons.

Perhaps this is the right moment to dwell on one of the reasons why I sometimes
prefer to change C code than to change Prolog code: in the compiler a node of a
term is represented as (I have simplified a bit)

in C:

struct term_node { char *name ;
		   int arity ;
		   struct term_node *arglist ;
		   struct term_node *nextarg ;
		 }


in Prolog I might use a datastructure like:

term_node(_name,_arity,_arglist,_nextarg)
where _name would be an atom, _arity an integer, and _arglist and _nextarg of
the form term_node/5 (or [] in the base case)


now, suppose I want to add an attribute to a term_node, let's say the
source line number in which the term_node occurred (useful while generating
debugging information for instance)

in C I would change the declaration to

struct term_node { char *name ;
		   int arity ;
		   struct term_node *arglist ;
		   struct term_node *nextarg ;
		   int source_line_number ;
		 }

and my C program would, without any other changes, still compile and run happily
and I can use this new attribute in a few places without affecting anything else

the 'equivalent' change to the Prolog program could be to change the arity of
the structure term_node/4 to 5; but that requires some - perhaps a lot of -
changes to other Prolog code, even without ever using this new attribute

of course I know that I can (perhaps should ?) write 'selectors' in Prolog so
that the code changes after a change of datastructure as above are minimized,
still, in C I have to make no changes at all; moreover, the consistent use of
these 'selectors' will make my Prolog program slower ... unless the Prolog
compiler can do some partial evaluation (and partial evaluation is a thing you
better not try to implement in C ...)


Bart Demoen			

bimbart@kulcs.uucp		bart@sunbim.uucp
Dept. of Computer Science	BIM
Celestijnenlaan 200A		Kwikstraat 4
B-3030 Leuven			B-3078 Everberg
Belgium				Belgium

ok@quintus.uucp (Richard A. O'Keefe) (08/21/88)

In article <1404@kulcs.kulcs.uucp> bimbart@kulcs.UUCP (Bart Demoen) writes:
>In article <290@quintus.UUCP> Richard A. O'Keefe writes:
>>(b) setof/3 only really has a logical reading when all the solutions
>>    it returns are ground.  [Example deleted.]

>I think the above argument says more about the non-logical reading of @</2
>when its arguments are variables, than about setof/3

Well, no.  That was just one example.  Let me provide another example:
	| ?- A = 1, B = 1,
	|    setof(X, (X = A ; X = B), L).
Result:	L = [1]

	| ?- setof(X, (X = A ; X = B), L),
	|    A = 1, B = 1.
Result:	L = [1,1]

All we have in this example is setof/3 and (=)/2.
I _like_ setof/3, and have no trouble with it, but that's because I know
what its limitations are (such as only being intended to return ground
results) and work within them.

As for the rest of Demoen's article, thanks.  I will remark only that
one of the things logic programming is supposed to be good for is being
the subject of source-to-source transformations.