P. 1
Logic Programming through Prolog

Logic Programming through Prolog

|Views: 692|Likes:
Published by api-19625511

More info:

Published by: api-19625511 on Nov 28, 2009
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less





In this chapter are collected some notes on the parts of picoProlog that surround
and support the execution mechanism discussed in the preceding two chapters.
There is a parser that reads picoProlog programs and builds the internal struc-
tures that represent them, with a lexical analyser and symbol table, all built
using conventional compiler techniques. There are also routines that manage
the different areas of storage that are used to store and execute picoProlog pro-
grams. The purpose of this chapter is to provide information that will be useful
in projects that extend or improve the picoProlog system.
PicoProlog is implemented in a tiny subset of Pascal that avoids nested pro-
cedures and functions, procedures and functions that take other procedures or
functions as arguments, conformant array parameters, arrays indexed by types
other than integer, sets, typed file I/O, floating-point numbers, pointers, enu-
merated types, variant records, non-local goto statements and with statements.
By keeping to this small subset, the author hopes to make the program easier
to translate into other languages, and easier to understand by those who do not
know Pascal very well.
On the other hand, we extend the Pascal subset by using macros. The source
code of the picoProlog system must be passed through a simple macro processor
before it is submitted to the Pascal compiler. The primary reason for this is that
Pascal’s record and pointer types are almost useless for the kind of programming
involved in efficient implementation of Prolog. In Pascal, records have a fixed size,
and there is no alternative to the primitive storage allocation facility provided by

new and dispose. So instead of using records and pointers, most of the data in

picoProlog is kept in a big array mem. Instead of records, we allocate contiguous
segments of mem, and instead of pointers, we use indexes into the array. The seg-
ments of mem allocated for different records of the same kind can have different
sizes, provided we take care that one record does not overlap another one.
There is a big disadvantage of this decision to ignore the data structuring
features of Pascal, because in place of the usual notation p↑.val for the val field


17.1 Macros 165

of the record pointed to by p, we are forced to write something like mem[p+ 2].
This is obscure, and likely to cause bugs if the layout of records is ever changed,
especially if different kinds of record have different information at offset 2. A
partial solution to this problem would be to define a family of Pascal functions
for accessing the fields of each kind of record. For example, one of them would
be a function Val that takes a pointer value p (represented by an integer), and
returns the contents of the record’s val field, taken from the mem array:

function Val(p: integer): integer;


Val := mem[p+ 2]


This is a little inefficient, since each access to a field of a record would require a
function call. More seriously, it does not provide a way of changing the fields of
a record, because you cannot write an assignment like Val(p) := 3 and hope that
it will be equivalent to mem[p+ 2] := 3. A better solution is to use macros. We
could define t val as a macro so that the expression t val(p) is textually replaced
by mem[p + 2] before the program is compiled. This avoids the inefficiency
of a function call, and works whether the expression appears on the left-hand
side of an assignment or one the right-hand side. For example, the assignment

t val(p) := t val(q) is textually expanded into mem[p+2] := mem[q+2], a legal

Pascal statement that has the desired effect.

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->