How to stop repetitions in rules in prolog

2019-05-24 14:59发布

In my prolog rule

marriedcouple(X,Y) :-
    parent( (X,Z), bornin(_) ),
    parent( (Y,Z), bornin(_) ),
    female(X),
    male(Y)
    ;
    male(X),
    female(Y),
    different(X,Y).

when a parent has two kids, the couple shows twice. How can we prevent this ?

标签: prolog
2条回答
\"骚年 ilove
2楼-- · 2019-05-24 15:29

Just an theoretical solution through double-not:

marriedcouple(Dad, Mum) :-
    male(Dad), female(Mum),
    not(notMarriedcouple(Dad,Mum)).

notMarriedcouple(Dad, Mum) :-
    male(Dad), female(Mum),
    not((parent(Dad, Child), parent(Mum, Child))).
查看更多
疯言疯语
3楼-- · 2019-05-24 15:47

Given that you've got female/1 & male/1 predicates the predicate becomes quite simple.

marriedcouple(X,Y) :-
    parent( (X,Z), bornin(_) ),
    parent( (Y,Z), bornin(_) ),
    female(X),
    male(Y).

However, if you want to see if X and Y are not the same use the (\==)/2 operator for "not identical" or (\=)/2 for "not unifiable".


Pradeep, based on your comment below, here is a more complete solution.

In order to prevent the same answer coming back twice there's a number of choices. We can build a list of solutions and only add a newly found solution if it isn't already in the list. Or use an approach that incorporates state using the assert/1 predicate.

I've chosen the latter.

?- solve.

solve :-
    marriedcouple(Dad, Mum),
    not( found( marriedcouple(Dad, Mum) ) ),
    assert( found( marriedcouple(Dad, Mum) ) ),
    write( [Dad, Mum] ),
    nl,
    fail.

marriedcouple(Dad, Mum) :-
    parent(Dad, Child),
    parent(Mum, Child),
    male(Dad),
    female(Mum).

male(aaron).
male(adam).

female(betty).
female(eve).

parent(aaron, callum).
parent(aaron, david).
parent(adam, abel).
parent(adam, cain).
parent(betty, callum).
parent(betty, david).
parent(eve, abel).
parent(eve, cain).

When I run this I get the following:

[aaron,betty];
[adam,eve];
No.

Be careful using assert/1 predicates as you may introduce unwanted side-effects into your programs. You may need to do appropriate retract/1 calls too.

查看更多
登录 后发表回答