Dynamic predicate in Prolog

2019-09-13 01:43发布

I have started using Prolog and I am having this problem with a dynamic predicate - I don't get the right result.

This is my database:

:- dynamic mother/2.

mother(X,Y).

grandemother(X,Y) :- 
    mother(X,A),
    mother(A,Y).

These are some of the results I get:

1 ?- assert(mother(alice,lise)).
true.

2 ?- assert(mother(lise,kate)).
true.

3 ?- grandemother(alice,X). % should only give X = kate.
true ;
X = lise ;
X = kate ;
true ;
X = kate.

4 ?- grandemother(alice,lise). % should only give false.
true ;
true ;
true ;
false.

5 ?- grandemother(X,kate). % should only give X = alice.
true ;
true ;
X = alice ;
X = alice ;
X = lise.

I really don't know where the problem is, any ideas?

标签: prolog
1条回答
我命由我不由天
2楼-- · 2019-09-13 02:36

As @lurker said in his comment, the issue is your line mother(X,Y)., directly after the dynamic declaration.

To break down exactly what's happening, I'll look at grandemother(alice,X) (after your asserts of mother(alice,lise) and mother(lise,kate)):

grandemother(alice,X) :- mother(alice,A),mother(A,X).
mother(alice,A) unifies with mother(X,Y). This leaves A unbound. 
mother(A,X) unifies with mother(X,Y). This leaves both A and X unbound.

Therefore, grandemother(alice,X) succeeds without having to bind X.

We ask again, and this time:

mother(A,X) unifies with mother(alice,lise). (The second mother/2 fact.)

grandemother(alice,X) succeeds with X bound to lise. Ask again...

mother(A,X) unifies with mother(lise,kate).

X is kate. Again...

mother(A,X) cannot be unified any more. Backtrack further...
mother(alice,A) unifies with mother(alice,lise).
mother(lise,X) unifies with mother(X,Y). X is unbound.

X is unbound again, so we just get true. Again...

mother(lise,X) unifies with mother(lise,kate).

X is kate again. Any more?

mother(lise,X) cannot be unified any more. Backtrack further...
mother(alice,A) cannot be unified any more. Backtrack further...
No more backtracking to be done, so there are no more results.

So we get no more results.

The solution, as @lurker pointed out, is to remove mother(X,Y)., so that this unbound behaviour cannot occur.

查看更多
登录 后发表回答