2016-04-06 16 views
3

Yapmak istediklerim, her üyenin bir yüklemi karşıladığı listeden bir alt liste oluşturmaktır. Yani heightMatchList (Person1, HeightMatchList) adında bir functor'da, genderMatchList'i arayarak ve GenderMatchList üyelerini HeightMatchList'e ekleyerek bu üyelerin heightMatch'i (Person1, Person2), Person2'nin olduğu yerde yüklemeyi tercih ettiklerini görmek istiyorum. GenderMatchList üyesi inceleniyor.Prolog: Bir yüklemeyi karşılayan üyelerle bir alt liste oluşturma

Bu program, birkaç bilgi parçasını temel alan kişilerle eşleştirilmelidir. Bu alt liste yaklaşımını, bagof veya findall kullanmak yerine kullanmak istememin nedeni, sadece cinsiyet gereksinimlerini karşılayan bir insan havuzundan yükseklik gereksinimlerini karşılayan adayları aramak. Üyelerin bir yüklemi satmasını istedikleri alt listeleri oluşturmak için çevrimiçi arama yapmayı denedim, ancak genellikle torba veya fiyonk ile geri geliyorlar. Bu uygun değildir çünkü arama alanı sadece bir liste ile sınırlı değildir.

Herhangi bir yardım büyük memnuniyetle karşılanacaktır.

Kodu:

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). 

DÜZENLEME: Gerekirse

Bazı test verisi:

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

kullanımı 'da farklı (X, Y) - dif (X, Y) .' yerine. – false

cevap

2

Sen cinsiyet ve yükseklik bir kişi için maçları bulur bir yüklemi yazabilirsiniz:

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

Şimdi eşleştirmeleri alabilirsiniz. tek Barry bir: Size bir listedeki tüm maçları veren bir yüklem yazabilirsiniz Buna dayanarak

?- 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] 

Ben, (a) yüklem olması kolay olacağını düşünüyorum (s) Bir eşleşme için tüm şartları açıklayan ve her maç kriteri için listeyi başlangıçtan değiştirmek yerine, sonuçta sadece bir araya getirecek olanları açıklar.

Farklı/2 tanımınızla ilgili olarak: Bu fark/2 farkından haberdar mısınız? Farklı/2 ile yapmayı düşündüğünüz şeyi yapar. Örneğin sizin yüklem heightMatch/2 dif ile şuna benzer olabilir/2:

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

adaylar aramak istediğiniz

+0

Teşekkürler, bu yaklaşımı düşünmüştüm ama prologun sonucu verimli bir şekilde bulabileceği bir yol bulmak istedim.Ancak, person_hgmatch'te, genderMatch zaten başarısız olmuşsa, heightMatch'i tatmin etmeye çalışmaz gibi görünüyor. Prolog, ne olursa olsun, bir yüklem için tüm şartları test edeceğini düşündüm. Farklılık hakkında bir şey bilmiyordum, teşekkürler! Bunu bilmek güzel. Ama bu ödevde bir kesmeyi nasıl kullanacağımı bildiğimi göstermek istiyorum, ben de onu böyle devam ettireceğim. –

2

:-) kesim ile uğraşmak gerek yok ki (!)

: yani sadece tüm gereksinimlerini katılmak, zaten cinsiyet gereksinimleri

Prolog ilişkisel veri modeline sahip tatmin kişilik bir havuzdan yükseklik gereksinimlerini karşılamak

örnek:

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

Teşekkürler, izlemeye bakmak, ilk gereksinimin karşılanmaması gibi görünüyorsa, ikinci koşulu kontrol etmek yerine başka bir Aday arar. Bu yüzden aradığım şeyi almanın düzgün bir yolu olduğunu düşünüyorum. Eşleştiğim bir iz üzerinde çalıştım ve sanki benzer bir şey yapmış gibi görünüyor, eğer genderMatch tatmin olmazsa, heightMatch'i aramaz. Bunun yerine yeni bir insan bulur. Bu iki senaryoda prolog farklı olarak ne yapıyor? –

+0

Asıl fark, bir adayı almak için bir kişi/8 koydum, çünkü başarısız/başarısız bir döngüdür, ** argümanlarında ** değişkenleri bağlar. Ama açıkça bağlayıcıya ihtiyacımız var. Forall/2 yerine foreach/2 çağrısı, bağlayıcıları tutmalı ve kişi/8 aramayı bırakmasına izin vermeli, fakat ben bunu yapmamıştım ve bu yüzden test etmedim. Nasıl davrandığını test edersen iyi olur. – CapelliC

+0

foreach/2, kişi/8 bırakırken aynı sonuçları verir. Ama iz daha uzun görünüyor, bu yüzden kişi/8 ile forall/2 daha verimli olabileceğini düşünüyorum. –