I was wondering if there exists a tool that can draw a step-by-step search tree of a Prolog program? Thanks.
Take a look at sldnfdraw for swi-prolog it works like a charm, the only issue I found with it is that the terms cannot contain underscores, but I've already sent an email to its author reporting it.
It creates a tex file with a tree representation, then with some bash commands transform it to png for visualization.
latex file.tex
dvipdf file.dvi
pdfcrop file.pdf
pdftoppm file-crop.pdf|pnmtopng > file.png
I also recommend adding \usepackage[landscape]{geometry}
give extra space to the tree.
I solved it in a different way... take a look at: https://github.com/reahaas/prolog-trace-to-tree
I run the program in prolog with trace, that give me an output of the trace as text. Each step in a different line. Save this trace output to a file. it should look like this:
?- trace,there_is_way(telaviv,heifa).
Call: (9) there_is_way(telaviv, heifa) ? creep
Call: (10) there_is_way(telaviv, heifa, nil) ? creep
Call: (11) road_from(telaviv, heifa) ? creep
Call: (12) road(telaviv, heifa) ? creep
Fail: (12) road(telaviv, heifa) ? creep
Fail: (11) road_from(telaviv, heifa) ? creep
Redo: (10) there_is_way(telaviv, heifa, nil) ? creep
Call: (11) road_from(telaviv, _4236) ? creep
Call: (12) road(telaviv, _4236) ? creep
Then use this python code to print the calls trace tree: Its build the tree relying on the first word of the trace: {Call, Fail, Exit, Redo}.
notice: change the file path/name in the code (with open(...)).
from pptree import *
import os
def get_first_word(line):
if line is "":
return
words = line.split()
if len(words) > 0:
first_word = words[0]
return first_word
def add_node(current, line):
if current is None:
return Node("head" + line, None)
else:
return Node(line, current)
with open("/home/vagrant/openu/prolog/trace_monkey.txt", 'r') as trace_file:
current = None
while True:
line = trace_file.readline()
if line.strip() == "": # run till it face an empty string.
break
first_word = get_first_word(line)
if current is None:
call_tree = add_node(current, line)
current = call_tree
elif first_word == "Call:":
current = add_node(current, line)
elif first_word == "Exit:":
add_node(current, line) # get_assignment(line))
current = current.parent
elif first_word == "Fail:":
add_node(current, line)
current = current.parent
elif first_word == "Redo:":
current = add_node(current, line)
print_tree(call_tree)
This is the results:
To see the results, paste the text tree to notepad++ and zoom out :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With