2010-11-16 16 views
6

Prolog öğreniyorum ve Yapay Zeka Programlama Prolog adlı bir kitap okuyorum. Pratik olarak bu kitaptaki örneklerden birini nasıl genişleteceğimi öğrenmek istiyorum. Birisi lütfen yardım edebilir mi?Prologların listesini al Prolog

parent(pam, bob). %pam is a parent of bob 
parent(george, bob). %george is a parent of bob 

nasıl bana ebrunun veli listesini verecek bir prolog yüklemi yazarsınız:

bu gerçekleri söyle? Örneğin:

list_parents(bob, L). 

L = [pam, george] ; 
L = [george, pam] ; 
true. 

cevap

2

bu deneyin: verimsiz bir yöntem oldu

parent(pam, bob). %pam is a parent of bob 
parent(george, bob). %george is a parent of bob 
list_parents(A, Es, [X|Xs]) :- parent(X, A), \+ member(X, Es), list_parents(A, [X|Es], Xs). 
list_parents(A, Es, []). 

, daha iyi bir yöntem "çözümler" Üst düzey yüklemi gerekecektir.

list_parents (X, Ys) - çözeltiler (ana, [X, W], 1, Ys) tüm çözümler hile olabilir findall/3 gibi yüklem

+1

ben "çözümler" yüklemi ile ilgili Sorununuza bir takip soru haberi: https://stackoverflow.com/questions/47233986/higher-order- bu yürütülmesi bize ilk seçenek olarak aynı sonucu verir Çözümler – mrsteve

12

bir: Sadece

list_parents(P, L) :- 
    findall(Parent, parent(Parent, P), L). 

koymak, findall/3 'backtrack-mümkün' hedef parent(Parent, P) içinde Parent için tüm bağlamaları bulur ve Parent tüm bağlamaları L listesine koyar. Bunun kopyaları kaldırmayacağını unutmayın, ancak bir grup oluşturmak için geri dönmeden önce sort/2L yapabilirsiniz. Bu yürütülüyor: Eğer Prolog uygulanmasında findall/3 yoksa

?- list_parents(bob, L). 
L = [pam, george]. 

, böyle elle yapabileceği:

list_parents(P, L) :- 
    list_parents(P, [], L). 

list_parents(P, Acc, L) :- 
    parent(Parent, P), 
    \+ member(Parent, Acc), !, 
    list_parents(P, [Parent|Acc], L). 
list_parents(_, L, L). 

Bu sürüm bir akümülatör-sürümüne kapalı list_parents/2 çağrıları gönderir list_parents/3. İkincisi, daha önce görmediğimiz sürece Parent bağlamalarını toplamaya çalışır (\+ member denetimi) ve Acc listesine yeni Parent bağlamalarının bulunamayacağı listeyi döndürür.

?- list_parents(bob, L). 
L = [pam, george]. 
+1

'findall'u kullanarak, –

+0

için Google’a keskin bir şekilde denediğim şeydi, findall uygulamanız tekrarlanan öğeler için bir hesap oluşturmuyor. Veritabanında varsa: 'ebeveyn (hannah, carl). ebeveyn (hannah, carl). ana (bob, carl) .' kuralı çıktılarınız [hannah, bob]. Ama eğer sen findall ile deneyeceksen [hannah, hannah, bob] –