2016-04-06 41 views
3

我期望做的是從列表中生成一個子列表,其中每個成員都滿足謂詞。因此,在一個名爲heightMatchList(Person1,HeightMatchList)的函子中,我希望通過調用genderMatchList並將GenderMatchList的成員添加到HeightMatchList來查看GenderMatchList的每個成員,如果這些成員滿足謂詞heightMatch(Person1,Person2),其中Person2是GenderMatchList的成員正在接受審查。序言:生成一個滿足謂詞的成員的子列表

該程序應該基於幾條信息來匹配人。我想使用這個子列表方法而不是使用bagof或findall的原因是,我只想搜索符合滿足性別要求的人羣中的高度要求的候選人。我試着在網上搜索生成的子列表,其中成員滿足謂詞,但他們通常回來bagof或findall。這是不合適的,因爲搜索空間不僅限於列表。

任何幫助將不勝感激。

代碼:

different(Person1,Person1):- 
    !, 
    fail. 
different(_,_). 

gender(Person,Gender):- 
    person(Person,Gender,_,_,_,_,_,_). 

genderPref(Person,GenderPref):- 
    person(Person,_,GenderPref,_,_,_,_,_). 

height(Person,Height):- 
    person(Person,_,_,Height,_,_,_,_). 

heightPref(Person,Height):- 
    person(Person,_,_,_,Height,_,_,_). 

weight(Person,Weight):- 
    person(Person,_,_,_,_,Weight,_,_). 

weightPref(Person,WeightPref):- 
    person(Person,_,_,_,_,_,WeightPref,_). 

petPref(Person,PetPref):- 
    person(Person,_,_,_,_,_,_,PetPref). 

genderMatch(Person1,Person2):- 
    gender(Person1,Gender1), 
    genderPref(Person2,Gender1), 
    gender(Person2,Gender2), 
    genderPref(Person1,Gender2), 
    different(Person1,Person2). 

heightMatch(Person1,Person2):- 
    height(Person1,Height1), 
    heightPref(Person2,Height1), 
    height(Person2,Height2), 
    heightPref(Person1,Height2), 
    different(Person1,Person2). 

weightMatch(Person1,Person2):- 
    weight(Person1,Weight1), 
    weightPref(Person2,Weight1), 
    weight(Person2,Weight2), 
    weightPref(Person1,Weight2), 
    different(Person1,Person2). 

petMatch(Person1,Person2):- 
    petPref(Person1,Pet), 
    petPref(Person2,Pet), 
    different(Person1,Person2). 

match(Person1,Person2):- 
    genderMatch(Person1,Person2), 
    heightMatch(Person1,Person2), 
    weightMatch(Person1,Person2), 
    petMatch(Person1,Person2). 

genderMatchList(Person,GenderMatchList):- 
    findall(X,genderMatch(Person,X),GenderMatchList). 

編輯:

如果需要一些測試數據:

person(alice,female,male,small,medium,average,average,dog). 
person(barry,male,female,medium,small,average,average,dog). 
person(clara,female,female,tall,tall,average,average,cat). 
person(danny,male,female,small,medium,average,average,cat). 
person(elise,female,male,medium,small,average,average,dog). 
person(fred,male,female,tall,small,average,average,dog). 
person(grace,female,female,small,medium,average,average,dog). 
person(harry,male,female,medium,tall,average,average,cat). 
person(isabella,female,male,tall,tall,average,average,cat). 
person(jack,male,female,small,medium,average,average,dog). 
person(katie,female,female,medium,tall,average,average,dog). 
person(larry,male,female,tall,tall,average,average,cat). 
person(mel,female,male,small,medium,average,average,cat). 
person(nathan,male,female,medium,small,average,average,dog). 
person(olivia,female,female,tall,small,average,average,dog). 
person(peter,male,female,small,medium,average,average,cat). 
person(quinn,female,female,medium,tall,average,average,cat). 
person(robert,male,female,tall,tall,average,average,dog). 
person(sophie,female,male,small,medium,average,average,dog). 
person(tom,male,female,medium,small,average,average,cat). 
person(ursula,female,female,tall,small,average,average,cat). 
person(vincent,male,female,small,medium,average,average,dog). 
person(wendy,female,male,medium,tall,average,average,dog). 
person(xavier,male,female,tall,tall,average,average,cat). 
person(yvonne,female,female,small,medium,average,average,cat). 
person(zed,male,female,medium,small,average,average,cat). 
+2

使用'不同(X,Y): - DIF(X,Y).'代替。 – false

回答

2

你可以編寫發現性別和身高的人相匹配的謂詞:

person_hgmatch(Person1,Person2) :- % Person2 is a 
    genderMatch(Person1,Person2),  % gender match for Person1 AND 
    heightMatch(Person1,Person2).  % height match for Person1 

現在您可以獲得例如巴里逐一:

?- person_hgmatch(barry,X). 
X = alice ? ; 
X = mel ? ; 
X = sophie ? ; 
no 

在此基礎上,你可以寫一個斷言,讓你列表中的所有比賽:

person_allhgmatches(Person,M) :- 
    findall(X,person_hgmatch(Person,X),M). 

    ?- person_allhgmatches(barry,X). 
X = [alice,mel,sophie] 

我認爲這將是更容易有(一)謂詞( s)描述匹配的所有要求,並且只在最後彙總,而不是從一開始就爲每個匹配標準操縱列表。

關於你對不同的定義/ 2:你是否知道謂詞dif/2?它完成了你打算用不同的/ 2做的事情。例如您的謂詞heightMatch/2可能看起來像這樣具有DIF/2:

heightMatch(Person1,Person2):- 
    dif(Person1,Person2), 
    height(Person1,Height1), 
    heightPref(Person2,Height1), 
    height(Person2,Height2), 
    heightPref(Person1,Height2). 

無需反覆折騰切:-)

+0

謝謝,我已經考慮過這種方法,但我想找到一種方法,prolog可以有效地找到結果。然而,如果gender_mach已經失敗,那麼它好像在person_hgmatch中不會嘗試滿足heightMatch。我認爲prolog會測試謂詞的所有要求,不管是什麼。 我不知道dif,所以謝謝!很高興知道。但我想在這個作業中炫耀一下,我知道如何使用剪輯,所以我會保持它的方式。 –

2

要搜索應聘者(!)從人池已經滿足性別要求

,Prolog有關係數據模型滿足高要求,所以只是加入的所有要求:

match_requirements(Person, Requirements, Candidate) :- 
    person(Candidate,_,_,_,_,_,_,_), 
    forall(member(R, Requirements), call(R, Person, Candidate)). 

例如:

?- match_requirements(barry,[genderMatch,heightMatch],P). 
P = alice ; 
P = mel ; 
P = sophie ; 
false. 
+0

謝謝,看起來跟蹤似乎是如果第一個要求不滿意,那麼它會尋找另一個候選人,而不是檢查第二個要求。所以我認爲這是獲得我正在尋找的一種簡潔方式。 我在匹配上運行了一個跟蹤,看起來它實際上也是類似的,如果genderMatch不滿意,它不會查找heightMatch。相反,它會找到一個新的人。在這兩種情況下,prolog有什麼不同? –

+0

主要區別在於,我把一個人/ 8取得了一個候選人,因爲forall/2是一個失敗驅動的循環,**取消了**參數內部發生的變量綁定。但顯然我們需要約束力。調用foreach/2而不是forall/2應該保留綁定,並允許放棄/ 8調用,但我沒有選擇它,所以我沒有測試過。如果你可以測試它的行爲會很好。 – CapelliC

+0

foreach/2在丟棄person/8時返回相同的結果。但跟蹤看起來更長,所以我認爲/ 8與人/ 8可能會更有效率。 –