2

Let's say I have this Prolog program:

loves(vincent, mia).
loves(marcellus, mia).
jealous(A, B) :- loves(A, C), loves(B, C).

With query jealous(A,B). I'm very new to Prolog and I'd like to know how is it possible to see the exact order the program will be running and taking its ways for this query? I have tried using trace, jealous(A,B). command but it has only given me that:

Isn't there any more detailed solution for that? :/

enter image description here

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
eyesima
  • 215
  • 4
  • 15

2 Answers2

3

Have you seen the Prolog Visualizer?

When you get to the page be sure to click on the icons in the upper right to learn more.

enter image description here

Enjoy.


Screenshot after step 10 of 49.

enter image description here

Screenshot for example given after all steps.

enter image description here


The Prolog Visualizer uses a slightly nonstandard way to enter a query by ending the query with a question mark (?), e.g.

jealous(A,B)?

If you do not post a query in the input area on the left you will receive an error, e.g.

enter image description here

The input for the Prolog Visualizer for your example is

loves(vincent, mia).
loves(marcellus, mia).
jealous(A, B) :- loves(A, C), loves(B, C).
jealous(A,B)?

When the Prolog Visualizer completes your example, notice the four results in green on the right

enter image description here


If you are using SWI-Prolog and after you understand syntactic unification, backtracking and write more advanced code you will find this of use:

Overview of the SWI Prolog Graphical Debugger


For other useful Prolog references see: Useful Prolog references

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • 1
    This is exactly what I needed thank you so much! :) – eyesima Mar 09 '21 at 22:05
  • @eyesima You are welcome. The real thanks should go to the [authors](https://github.com/cdglabs/prolog-viz#credit) of the code and [Falco](https://github.com/fnogatz?tab=repositories) who had a link to it that lead me to the code. – Guy Coder Mar 10 '21 at 10:52
1

If the Prolog system has callable_property/2 and sys_rule/3, then one can code
a smart "unify" port as follows, showing most general unifiers (mgu's`):

:- op(1200, fx, ?-).

% solve(+Goal, +Assoc, +Integer, -Assoc)
solve(true, L, _, L) :- !.
solve((A, B), L, P, R) :- !, solve(A, L, P, H), solve(B, H, P, R).
solve(H, L, P, R) :- functor(H, F, A), sys_rule(F/A, J, B),
   callable_property(J, sys_variable_names(N)),
   number_codes(P, U), atom_codes(V, [0'_|U]), shift(N, V, W),
   append(L, W, M), H = J, reverse(M, Z), triage(M, Z, I, K),
   offset(P), write_term(I, [variable_names(Z)]), nl,
   O is P+1, solve(B, K, O, R).

% triage(+Assoc, +Assoc, -Assoc, -Assoc)
triage([V=T|L], M, R, [V=T|S]) :- var(T), once((member(W=U, M), U==T)), W==V, !,
   triage(L, M, R, S).
triage([V=T|L], M, [V=T|R], S) :-
   triage(L, M, R, S).
triage([], _, [], []).

% shift(+Assoc, +Atom, -Assoc)
shift([V=T|L], N, [W=T|R]) :-
   atom_concat(V, N, W),
   shift(L, N, R).
shift([], _, []).

% offset(+Integer)
offset(1) :- !.
offset(N) :- write('\t'), M is N-1, offset(M).

% ?- Goal
(?- G) :-
   callable_property(G, sys_variable_names(N)),
   shift(N, '_0', M),
   solve(G, M, 1, _).

Its not necessary to modify mgu's retrospectively, since a solution to a
Prolog query is the sequential composition of mgu's. Here is an example run:

?- ?- jealous(A,B).
[A_0 = X_1, B_0 = Y_1]
    [H_1 = mia, X_1 = vincent]
    [Y_1 = vincent]
A = vincent,
B = vincent ;
    [Y_1 = marcellus]
A = vincent,
B = marcellus ;
Etc..

This is a preview of Jekejeke Prolog 1.5.0 the new predicate sys_rule/3, its inspired by the new predicate rule/2 of SWI-Prolog, but keeps the clause/2 argument of head and body and uses a predicate indicator.