Prolog Code - No idea what it does - prolog

I was wondering what this code does:
:- set_prolog_flag(toplevel_print_options,
[quoted(true), portray(true), attributes(portray), max_depth(100)]).
I have seen it in some of the sample codes my prof has posted on his website but I have no clue what it does. Thanks for your help in advance.

I believe it might have something to do with making program output more formatted (and thus, more readable or accessible.)
See this article: "Help... Prolog writes [x, y, z|...], I want the whole answer".
Basically, in the case of your code's settings... it looks like the code is just setting some formatting for output. The max_depth setting means that anything that is nested more than (100, in your case,) levels will then be written as .... The rest of the options just enable normal output.

Related

How to call facts and rules from another file

Case: I have a file, solution.pl, where I want to use the rules of another file (this is the definition of the program, not up to me, but I think it's somewhat common).
So I'm using Ciao Prolog and the syntax seems to be ensure_loaded('c:/Path').
but when I try to use the rules of the other file, it tells me he doesn't know what rule I'm trying to use.
On the other hand, if I write on the console that same lane, and then query again, it does work.
So I was wondering maybe the syntax for doing it on the console and on a file are different??
Could someone tell me a step by step so I can figure it out if I'm missing something? What I'm doing right now is loading the program as I would do with smaller programs, then try to query rules of the file included in the ensure_loaded command. And as I said, it does seem to work if write the command outside of the program.
in solution.pl, try
:- ensure_loaded('c:/Path').
or, if the source in c:/Path has a module directive - that is, it begins with :- module(name, [exported/arity, ...]).
:- use_module('c:/Path').

How do I view how Prolog got to its result/the path it took?

I have a simple Prolog predicate that spits accepts a variable, Result, that calculates a result then stores it in Result to be viewed. Sometimes I'm unsure how it comes to the answer it stores in Result and I'm curious if there's a way in Prolog to get it to show how it got to the answer, I guess show the path it took and how it built it up?
The predicate is something simple like solve(Input, Result). and Result can sometimes be peculiar.

SWI-Prolog : "false" where?

Normally when the goal fail I get back "false" i.e. the goal was not satisfied.
Is there a way to make SWI-Prolog to print predicate, line and/or sequence number of the sub-goal where it failed.
I don't want to trace the whole program just want some feedback sort of like in other programming languages.
I know it is not error to return false, but when debugging it will be nice to have this feedback to pinpoint problems. If it is possible of course.
thanks
You might also want to consider using the "failure-slice" technique described many times by #false: it has its own tag.
Also, check out this great answer. You can use the code shown there to make your own "debugger" that lets you do (among other things) exactly what you are after.
maybe
...p1, p2, (p3;backtrace(10)), p4,...
could also be useful to start tracing after p3 is failing:
...p1, p2, (p3;backtrace(10),trace), p4,...

Is it acceptable for a prolog procedure to work only one way?

I have a prolog program:
link(liverpool,preston).
link(liverpool,manchester).
link(preston,lancaster).
link(preston,manchester).
link(lancaster,carlisle).
link(lancaster,leeds).
link(carlisle,leeds).
link(manchester,leeds).
%checks to see if X is in the supplied list
inlist( X, [X|_]).
inlist( X, [_|Ys]) :- inlist( X, Ys).
merge([],L,L).
merge([H|T],BList,CList):-
inlist(H,BList),
merge(T,BList,CList).
merge([H|T],BList,[H|CList]):-
merge(T,BList,CList),
not(inlist(H,BList)).
Merge works if I call it like this:
merge([a,b,c],[d,e,f],Result). --> [a,b,c,d,e,f]
or more importantly, what it was designed to solve:
merge([a,b,c],[a,d,e,f],Result). --> [a,b,c,d,e,f]
but if I call merge like this:
merge(X,[d,e,f],[a,b,c,d,e,f]).
There is a stack overflow. Is this generally acceptable behavior for a function that is designed to work one way? Or is there some convention that functions should work in both ways?
Edit: merge works if you call it like this:
merge([a,b,c],X,[a,b,c,d,e,f]). --> [d,e,f]
First, you should not call these "functions". "Predicates" is the correct term.
It's generally desirable for Prolog predicates to work "both ways". But it's not always possible or worth the effort in a particular situation.
To inform about ways a predicate is intended to be used mode-declarations can be used. These declarations conventions are different from system to system. These declarations are mostly serve as a documentation for programmers and rarely used by compilers, but can be used by testing frameworks and other helper tools.
Examples of conventions for mode declarations:
SWI-Prolog: http://www.swi-prolog.org/pldoc/man?section=modes
ECLiPSe CLP: http://eclipseclp.org/doc/applications/tutorial003.html#toc10 (scroll to 2.7.3 Mode declaration)
Also there is a convention (described in "The Craft of Prolog", for example) that input parameters of a predicate come first, output parameters come last.

How can I provide Prolog asks questions to me

Assume that we have prolog knowledge base like this:
guilty(X) :-
commits(X,Y),
crime(Y).
crime(murder).
crime(theft)
When I ask this question:
?- guilty(john)
I want that Prolog asks me a question like that:
is commits(john, murder) ?
and I answer no then
is commits(john, theft) ?
if I answer yes Prolog says
**yes**
How can I make something like this?
Thanks..
You need a modified proof engine, that when encounters an unknown fact query the user about.
Doing it with some generality can be an interesting task, Google for metainterpreter Prolog, if you are interested in this argument, the first link provides you the valuable page A Couple of Meta-interpreters in Prolog by Markus Triska, where you can learn more.
For your question, would suffice a rule
commits(Person, Crime) :-
crime(Crime),
format('is ~w ?', [commits(Person, Crime)]),
read(yes).
test:
?- guilty(john).
is commits(john,murder) ?no.
is commits(john,theft) ?yes.
true.
note that read/1 requires a dot to terminate the input.
You want an 'interactive shell' for your little reasoner. Building one is not difficult, but beyond the scope of a stackoverflow question. This tutorial builds one in the 2nd or 3rd lesson and generally answers this question. It calls facts like your user answers 'working storage'.
http://www.amzi.com/ExpertSystemsInProlog/
Prolog "executes" things from left to right. Try:
guilty(X) :-
crime(Y),
commits(X,Y).
crime(murder).
crime(theft)
So then guilty(X) depends on commits(X,murder) and/or commits(X,theft)

Resources