Usage

In order to use SLDNF Draw, you have to run ECLiPSe and consult sldnf.pl:

C:\home\Marco\dida\ia\sw\sldnfDraw>eclipse
ECLiPSe Constraint Logic Programming System [kernel]
Copyright Imperial College London and ICL
Certain libraries copyright Parc Technologies Ltd
GMP library copyright Free Software Foundation
Version 5.7 #35, Thu Mar  4 00:15 2004
[eclipse 1]: [sldnf].
sldnf.pl   compiled traceable 12864 bytes in 0.00 seconds

Yes (0.00s cpu)
[eclipse 2]:

Now you can draw the SLDNF tree for a goal. For example:

[eclipse 2]: draw_goal(X=Y+1,"tree.tex").

X = X
Y = Y
Yes (0.00s cpu)
[eclipse 3]:

As you can see in the example, the first parameter is a goal, and the second is the name of a file; in our case, tree.tex. Now, the file tree.tex contains exactly the LaTeX commands to draw the SLDNF tree for the goal X=Y+1.

Note that you cannot run LaTeX directly on the generated file, but you can copy & paste its content in your LaTeX documents, or you can include it in your LaTeX document by writing: \input{tree}

As the commands in the generated file tree.tex contain commands of the packages ecltree and epic, you have to put \usepackage{epic} and \usepackage{ecltree} in the preamble of your LaTeX file.

For example, the file envelope.tex is the minimal you need to generate an SLDNF tree with SLDNF Draw. If you put it in the same directory with the file tree.tex, you can now run LaTeX:

C:\home\Marco\dida\ia\sw\sldnfDraw>LaTeX envelope
This is e-TeX, Version 3.141592-2.1 (MiKTeX 2.4)
entering extended mode
(envelope.tex
LaTeX2e <2001/06/01>
(C:\texmf\tex\latex\base\article.cls
Document Class: article 2001/04/21 v1.4e Standard LaTeX document class
(C:\texmf\tex\latex\base\size12.clo)) (C:\texmf\tex\latex\eepic\epic.sty
Enhancements to Picture Environment. Version 1.2 - Released June 1, 1986
) (C:\texmf\tex\latex\ecltree\ecltree.sty
ECL Tree graph macro by isozaki, Nov. 12, 1990
) (envelope.aux) (tree.tex) [1] (envelope.aux) )
Output written on envelope.dvi (1 page, 284 bytes).
Transcript written on envelope.log.

and the file envelope.dvi will contain something like this: SLD tree for the goal X=Y+1.

A more interesting example

In order to generate SLDNF trees of one given program, you have to consult the program with all the predicates defined as dynamic predicates. In fact, SLDNF Draw is a meta-interpreter, and ECLiPSe requires you to declare the predicates as dynamic predicates if you want to access to the clauses by means of the clause/2 predicate.

Please, do not use the underscore symbol in your clause database, as it is a special symbol for LaTeX.

As an example, you could define a predicate member1/2 (member/2 is a predefined predicate in ECLiPSe, so it will complain if you try to re-define it) as follows:

:- dynamic member1/2.

member1(X,[X|T]).
member1(X,[H|T]):-
    member1(X,T).

Suppose you wrote the definition in the file prog.pl, you can now consult it:

[eclipse 1]: [sldnf].
sldnf.pl   compiled traceable 12864 bytes in 0.00 seconds

Yes (0.00s cpu)
[eclipse 2]: [prog].
*** Warning: Singleton variables in clause 1 of member1/2: T
*** Warning: Singleton variables in clause 2 of member1/2: H
prog.pl    compiled traceable 184 bytes in 0.00 seconds

Yes (0.00s cpu)
[eclipse 3]: draw_goal((member1(X,[1,2]),not member1(X,[1,3])),"tree.tex").

X = X
Yes (0.00s cpu)
[eclipse 4]:

and, by running LaTeX on the file envelope.tex, you get this tree.

Occur-check

SLDNF Draw can deal with occur-check as ECLiPSe does. You have to switch the occur-check on before loading the program.

For example, if the file prog.pl contains:

:- dynamic member1/2, double/2.

double([],[]).
double([X|R],[X,Y|T]) :- double(R,T).

member1(X,[X|T]).
member1(X,[H|T]):-
    member1(X,T).

then you can

[eclipse 1]: set_flag(occur_check,on).

Yes (0.00s cpu)
[eclipse 2]: [sldnf].
sldnf.pl   compiled traceable 12892 bytes in 0.01 seconds

Yes (0.01s cpu)
[eclipse 3]: [prog].
*** Warning: Singleton variables in clause 1 of member1/2: T
*** Warning: Singleton variables in clause 2 of member1/2: H
*** Warning: Singleton variables in clause 2 of double/2: Y
prog.pl      compiled traceable 3192 bytes in 0.00 seconds

Yes (0.00s cpu)
[eclipse 4]: draw_goal((double([A,B],L), member1([A,B],L)),"tree.tex").

A = A
B = B
L = L
Yes (0.01s cpu)

and (by running LaTeX on envelope.tex) you get this tree.

Built-in predicates

SLDNF Draw deals also with built-in predicates. This is useful, e.g., for the is/2 predicate. But beware! ECLiPSe compiles is/2 into a predicate in the module sepia_kernel, that, unluckily, contains an underscore. So, in this case, I suggest to use the alternative syntax, for a clause:

my_clause(len([],0),[]).
my_clause(len([H|T],N),[len(T,N1),N is N1+1]).

Now, you can do the following:

 


[eclipse 1]: [sldnf].
sldnf.pl   compiled traceable 12864 bytes in 0.00 seconds

Yes (0.00s cpu)
[eclipse 2]: [prog].
*** Warning: Singleton variables in clause 2 of my_clause/2: H
prog.pl      compiled traceable 3424 bytes in 0.01 seconds

Yes (0.01s cpu)
[eclipse 3]: draw_goal(len([1,2,3],N),"tree.tex").

N = N
Yes (0.00s cpu)

And you get this tree.

Concerning other built-in predicates, the program works (if the predicate does not do too strange things ...) but it will consider the built-in predicate as a "flat" predicate. Try, for example, the query:

draw_goal(member(X,[1,2,3]),"tree.tex").