Đrakenus
Đrakenus

Reputation: 540

Write FAIL at the sld tree leafs with no solutions

I have this piece of code posted below. Now I'd like to implement function which prints FAIL at the leafs which fails in this prolog tree. This is basically meta-interpreter which makes whole sld tree in DOT format to file.

prove_d(true,Goal,N,_):-!,
    gv_answer(N,Goal). %writtes TRUE at the end of leaf
prove_d(_,_Goal,N,D):-
    D=0, !, gv_stop(N). %writes ending brackets and closes file
prove_d((A,B),Goal,N,D):-!,
    D>0, D1 is D-1,
    resolve(A,C),
    conj_append(C,B,E),
    gv_node(N,(?-E),N1), %writes node and connects with parent node
    prove_d(E,Goal,N1,D1).
prove_d(_,_Goal,N,D):- % HL
    D=0, !, gv_stop(N).
prove_d(A,Goal,N,D):-
    D>0, D1 is D-1,
    resolve(A,B),
    gv_node(N,(?-B),N1),
    prove_d(B,Goal,N1,D1).

resolve(!, true):-
    !, (true ; throw(cut)).
resolve(A,true):-
    predicate_property(A,built_in),!,
    call(A).
resolve(A,B):-
    clause(A,B).

gv_fail(N0):- %where to place this?
    gv_id(N), %gets id for parent node
    writes([N,' [label="fail", shape=plaintext];']),
    writes([N0,' -> ',N,' [style=dotted, length=0];']).

The closest to solution is

prove_d((A,B),Goal,N,D):-!,
    D>0, D1 is D-1,
    resolve(A,C),
    conj_append(C,B,E),
    gv_node(N,(?-E),N1),
    (prove_d(E,Goal,N1,D1) ; gv_fail(N1)).

but this prints fail at the end of every leaf even with true at the end of the leaf.

I use swi-prolog.

EDIT: Because this code is little longer, here is complete program.http://pastebin.com/bQKD1Cyi

It works like this. You consult this file at start-up of prolog. Then in other file is program you want to visualise, so you call why/3, then it makes DOT output to separate file. You can use this website to visualise DOT output - http://webgraphviz.com/

EDIT2: Here is my program I test it on:

v(X):-p(X), s(X).
v(n).

p(a).
p(b).

s(a).
s(c).

the only solutions are v(n) and s(a), yet at goal s(a) it writes true and fail at the end of the leaf when only true should be there.

Upvotes: 1

Views: 128

Answers (1)

Yasel
Yasel

Reputation: 3118

The program is incomplete. Without the predicates gv_answer/2, gv_stop/1, gv_node/3, and so many others no included in your code, I can only give a partial answer, based in my appreciation of what is missing in your code. I think that you need a new clause in your prove_d/3 predicate, the last one, that will succeed in case the other fails. Also, you must modify the last clause prove_d/3, to avoid backtracking for the new clause. So, the predicate prove_d/3, will go like this:

prove_d(true,Goal,N,_):-!,
    gv_answer(N,Goal). %writtes TRUE at the end of leaf
prove_d(_,_Goal,N,D):-
    D=0, !, gv_stop(N). %writes ending brackets and closes file
prove_d((A,B),Goal,N,D):-!,
    D>0, D1 is D-1,
    resolve(A,C),
    conj_append(C,B,E),
    gv_node(N,(?-E),N1), %writes node and connects with parent node
    prove_d(E,Goal,N1,D1).
prove_d(_,_Goal,N,D):- % HL
    D=0, !, gv_stop(N).
prove_d(A,Goal,N,D):-
    D>0,!, D1 is D-1,
    resolve(A,B),
    gv_node(N,(?-B),N1),
    prove_d(B,Goal,N1,D1).
prove_d(_,_,N,_):- gv_fail(N).

I tried this predicate (saved in the file multiply.pl):

%Multiply members of a list
multiply([X], X):-!.
multiply([H|T], X):-multiply(T, M), X is M *H.

and this goal:

?- why(multiply([1,2,3],X), './sldtree.pl', './multiply.pl').

And the SLD tree looks ok to me. There is only one success and the leafs that show fails is because Prolog fails to do backtracking on those conditions. Maybe the issues is in your input program, or the SLD tree generated exceeds the default depth (10 levels), in that case you will never see the succeed.

Upvotes: 1

Related Questions