2017-01-02 50 views
1

比方說,我有3名兒童雙胞胎Prolog中會重複答案

person(pet,fox,date(5,may,2004),unemployed). 
person(jim,fox,date(5,may,2004),unemployed). 
person(george,fox,date(9,december,2002),unemployed). 

child(X):-X=person(pet,fox,date(5,may,2004),unemployed). 
child(X):-X=person(jim,fox,date(5,may,2004),unemployed). 
child(X):-X=person(george,fox,date(9,december,2002),unemployed). 

我想這些兒童

twins(Child1,Child2) :- 
    child(Child1),child(Child2), 
    Child1=person(Fname1,_,Date1,_), 
    Child2=person(Fname2,_,Date2,_), 
    Fname1\=Fname2, 
    Date1=Date2. 

問題是,當我問序言雙胞胎的雙胞胎(X, Y)。我會再次得到一些答案。如何防止呢?

?- twins(X,Y). 
X = person(pet, fox, date(5, may, 2004), unemployed), 
Y = person(jim, fox, date(5, may, 2004), unemployed) ; 
X = person(jim, fox, date(5, may, 2004), unemployed), 
Y = person(pet, fox, date(5, may, 2004), unemployed) ; 
false. 

回答

1

您可以通過在對的元素強加非對稱爲了防止產生所有排列的:

?- twins(X, Y), X @< Y. 
X = person(jim, fox, date(5, may, 2004), unemployed), 
Y = person(pet, fox, date(5, may, 2004), unemployed) ; 
false. 

這不僅消除了該查詢不必要的解決方案,但要實現這一在每致電twins/2您只需在twins/2的定義範圍內替換\=@<替代。 (在@<關係的兩個方面是自動的\=意義上的不平等,除非他們中的一個是一個變量。)

作爲另一條評論,你的數據庫的重複,既person/4事實和爲child/1是條款中的數據奇怪,不必要,而且非常容易出錯。

child(X) :- 
    person(FirstName, LastName, DOB, Status), 
    X = person(FirstName, LastName, DOB, Status). 
:你可以用引用您的 person/4數據庫這個單一條款取代 child/1你的三個子句定義