		PTN - Parse Tree Notation
		------------------------

An overview of PTN can be found in

Davison, A. & Haywood, E., "Parse Tree Notation" - Technical Report 94/6
	Dept of Computer Science University of Melbourne


This directory contains the following files:

README - this file
apps   - a directory containing example applications
src    - the Prolog source code for ptn

To install ptn -

	cd src
	make

To run an example -

	cd apps
	cd module		{for example}

READ the README file in the directory module


The Examples 
------------
Examples are in the directory ptn/apps, each in a separate directory.
The first two are written in PTN, the others were written before the PTN
translator!

expert1   - 	translating if <conditions> then <action> rules
		into Prolog - i.e. pre-compilation of the rules
		rather than interpretation at run-time.
proofs    - 	adding the "proof" as an argument to a predicate - 
		demonstrates a substantial speed up over building the proof
		as it is run.
module    - 	changing the functor name of all "local" predicates.

arith     -	) each demonstrate a different translation of  
function  -	) some higher level notation, into "raw" Prolog.
interm    - 	)			

phones    -	) are manipulating files which contain data
grades    -	) in a form other than a programming language, but they 
		have a simple grammar and they clearly demonstrate how 
		easy it is to extract information, and change the format 
		as required.


The Source
----------

The following files are in ptn/src

makefile    -  	commands to compile ptn - NU-Prolog 
io.nl 	    -  	all the general I/O predicates
tokens.nl   - 	general predicates manipulating tokens
parser.nl   - 	contains gr2nl code and other parsing predicates
ptn.nl 	    - 	contains the ptn2nl code
ptn_gr.gr   - 	grammar rules for ptn
unify.nl    - 	unification predicates
search.nl   - 	search predicates
np_depend.nl- 	NU-Prolog specific predicates used.


The guts of the program is in 'unify.nl' and 'search.nl'.

PTN is used to translate code written in PTN itself into raw Prolog -
for example

the PTN code:

P unify T ++2 << A::atom, S::something*>> 

will be translated  into

unify( P, pplus( T, sseq( [sub( atom, _, A), mult( something, _, S)]), 2))

The code to accomplish this translation can be found in ptn.nl
and examples of code written using it is in apps/proofs and apps/expert1

This has been implemented using NU-Prolog, and an attempt has been made 
to use the ISO- nearly standard Prolog built-ins. 
NU-specific predicates can be found in np_depend.nl, and it is left up to 
the user to provide the necessary.

The biggest problem I forsee is the use I have made of the tokenizer, built-in
to NU-Prolog and of the predicate getToken/2  These can be replaced by
whatever is supplied by your flavour of Prolog (or by using R.A.O'Keefe's
tokens code - which is available  - somewhere). 

		Writing a PTN program
		---------------------

The Grammar
-----------
The first thing is to write a grammar for the language you wish to
translate. This is written using standard Prolog DCG style and then
transformed into Prolog, where the parse tree construction is added
to the rules.

for example:

program --> clauses.

clauses --> clause, ['.'], clauses.
clauses --> [].

clause --> head, [':-'], body.
clause --> head.

Because the parsing stage is often time consuming, it is always best to
make the grammar as deterministic as possible. For example, the rule for
clause can be written:

clause --> head, body.

body --> [':-'], goal, restBody.
body --> [].


Once the grammar is written (and saved in a ".gr" file), it is translated 
into Prolog using gr2nl/1.
A ".nl" file is then generated, which can then be loaded.

One problem with a large grammar and non-deterministic rules is the time
factor, IF the tokens from the file will not parse, much backtracking
and attempts at parsing the tokens is made. The author has
not attempted to provide an error checking mechanism (as in "consult") for
example - it is up to the user to ensure syntactically correct input. 

Tokenizing
----------
There are one or two little foibles which may or may not be NU-Prolog
specific - for example ">>." will tokenize as a single token, '>>.', which
causes problems - so the code must include a space between the '>>' and 
the '.' . 
This is not the case with ">>," this will tokenize correctly as
as two tokens, '>>' and ','  - as required by the grammar in ptn_gr.gr.

Another potential problem is that '(' will tokenize as ' (' i.e. a space
before it - unless it is immediately preceded by a token that could
be a functor, so "fact(" will tokenize as 'fact' and '(', but "fact (" will
tokenize as 'fact' and ' (' - this may seem obvious, but normally whitespace
is ignored - "gaga, fred,    happy" would tokenize as 
'gaga' ',' 'fred' ',' 'happy' thus ignoring the spaces in this instance.

Explanation of NU-Prolog's tokens etc. is in np_depend.nl

Writing ptn code
----------------
Generally, a language translation is going to be on a per "clause" basis,
(for Prolog - maybe procedures in Pascal - or rules in the case of
an expert system)
In most of the examples in 'apps', the first unification of PTN is
to extract the clauses from the program parse tree. 

e.g.
	get_tokens( File, Tokens),
	parse( program, Tokens, PTree),
	PTree unify T ++1 Cls::clause* ,
	translate( Cls, NewCls),
	NewPTree unify T ++1 NewCls::clause*,
	write_tree( File2, NewPTree)

the clause parse trees Cls are translated into new clause parse trees, NewCls.
It is not necessary to "replace" a parse tree with the same type of tree,
it is possible to translate "rules" into "clauses" - see expert1 for
example.

A ".ptn" file is translated into a ".nl" file using the predicate ptn2nl/1,
the argument being the basename of the ".ptn" file.

The ".nl" can be loaded into ptn (also a compiled version of all the PTN 
built-ins) and run.

{Liz Haywood  - May 1994}

