2009-09-15 41 views
9

Câu chuyện sau đây là từ N. Wirth's (1976) Thuật toán + Cấu trúc = Chương trình.Làm thế nào tôi có thể thực hiện, "Tôi là ông của riêng tôi", trong Prolog?

Tôi kết hôn với một góa phụ (chúng ta hãy gọi W cô) người đã có một con gái trưởng thành (gọi cô ấy D). Cha tôi (F), người đã đến thăm chúng tôi khá thường xuyên, đã yêu cô gái con gái và cưới cô ấy. Do đó, cha tôi đã trở thành con rể của tôi và con gái bước của tôi đã trở thành mẹ tôi. Một số tháng sau đó, vợ tôi đã sinh một con trai (S1) , người trở thành người anh em của cha tôi, cũng như là người chú của tôi. Người vợ của cha tôi, đó là, con gái riêng của tôi, cũng có một con trai (S2).

Tôi đang cố gắng để mô hình hóa các mối quan hệ trong prolog vậy cuối cùng tôi sẽ có thể gõ:

| ?- grandfather(i,i). 

Và tôi sẽ nhận được một "Yes", hoặc "Không" trên có hay không tôi là ông nội của tôi.

Đây là mã tôi đã viết cho đến nay (grandpa.pl):

aunt(X,Y):- 
    sibling(X,Z), 
    parent(Z,Y), 
    female(X). 

brother(X,Y):- 
    sibling(X,Y), 
    male(X). 

brother_in_law(X,Y):- 
    child(X,Z), 
    married(Z,W), 
    parent(W,Y), 
    not(sibling(X,Y)), 
    male(X). 

brother_in_law(s1,f). 

child(X,Y):- 
    parent(Y,X). 

daughter(X,Y):- 
    parent(Y,X), 
    child(X,Y), 
    female(X). 

daughter(d,w). 

father(X,Y):- 
    parent(X,Y), 
    male(X). 

father(f,i). 

father_in_law(X,Y):- 
    child(X,Z), 
    married(Y,Z), 
    not(child(X,Y)), 
    male(X). 

grandparent(X,Y):- 
    parent(X,Z), 
    parent(Z,Y). 

grandmother(X,Y):- 
    grandparent(X,Y), 
    female(X). 

grandfather(X,Y):- 
    grandparent(X,Y), 
    male(X). 

grandchild(X,Y):- 
    child(X,Z), 
    child(Z,Y). 

married(X,Y):- 
    wife(X,Y), 
    female(X). 

married(X,Y):- 
    husband(X,Y), 
    male(X). 

married(i,w). 
married(f,d). 

mother(X,Y):- 
    parent(X,Y), 
    female(X). 

parent(X,Y):- 
    child(Y,X). 

sibling(X,Y):- 
    parent(Z,X), 
    parent(Z,Y). 

sister(X,Y):- 
    sibling(X,Y), 
    female(X). 

son(X,Y):- 
    parent(Y,X), 
    male(X). 

son(s1,w). 
son(s2,d). 

son_in_law(X,Y):- 
    child(X,Z), 
    not(child(X,Y)), 
    married(Z,Y), 
    male(X). 

son_in_law(f,i). 

step_daughter(X,Y):- 
    child(X,Z), 
    married(Z,Y), 
    not(child(X,Y)), 
    female(X). 

step_daughter(d,i). 

step_parent(X,Y):- 
    married(X,Z), 
    parent(Z,Y), 
    not(parent(X,Y)). 

step_father(X,Y):- 
    step_parent(X,Y), 
    male(X). 

step_mother(X,Y):- 
    step_parent(X,Y), 
    female(X). 

step_mother(d,i). 

uncle(X,Y):- 
    sibling(X,Z), 
    parent(Z,Y), 
    male(X). 

uncle(s1,i). 

Ngay bây giờ tôi đang gặp rất nhiều rắc rối với các định nghĩa hình tròn vì vậy mà tôi nhận được vào vòng lặp vô hạn khi chạy truy vấn : ông nội (i, i).

Ví dụ, tôi có:

(1 ms) có {trace} | ? - ông nội (i, i). 1 1 Gọi: ông nội (i, i)?
2 2 Gọi: ông bà (i, i)?
3 3 Gọi: cha mẹ (i, _103)?
4 4 Gọi: con (_127, i)?
5 5 Gọi: phụ huynh (i, _151)?
6 6 Gọi: con (_175, i)?
7 7 Gọi: cha mẹ (i, _199)?
8 8 Gọi: con (_223, i)?
9 9 Gọi: phụ huynh (i, _247)?
10 10 Gọi: con (_271, i)?
11 11 Gọi: phụ huynh (i, _295)?
12 12 Gọi: con (_319, i)?
13 13 Gọi: cha mẹ (i, _343)?
14 14 Gọi: con (_367, i)?
15 15 Gọi: cha mẹ (i, _391)?
...

Điều này là do con tự định nghĩa như đã có một phụ huynh, và phụ huynh xác định mình đã có một đứa con (như bạn sẽ thấy trong các vị từ trên tôi đã đăng).

Có ai có thể giúp tôi xác định lại các vị từ của mình cho các mối quan hệ này để tôi có thể xác định xem tôi có phải là ông của riêng tôi không?

+0

Heh, tôi thực sự đã phải làm điều đó cho lớp AI của tôi. Tôi tự hỏi nếu tôi vẫn còn mã ... Tôi sẽ nhìn khi tôi về nhà. Tôi nhớ nó cũng làm tổn thương não tôi. –

+5

Họ sử dụng Prolog ở West Virgina? ;-) –

+0

@ T.E.D .: Shh! TheTXI sẽ nghe bạn! –

Trả lời

3

nhiên prolog của tôi đã được một thời gian dài trước đây nhưng những gì về loại bỏ

parent(X,Y):- 
    child(Y,X). 

và chỉ cần thay thế bất kỳ sử dụng parent(A,B) với child(B,A)? Bạn vẫn có thể thêm sự thật về cha mẹ vì quy tắc nghịch đảo vẫn có sẵn - bạn cũng có thể loại bỏ điều đó nhưng trong trường hợp đó bạn không thể sử dụng bất kỳ sự thật nào về cha mẹ nữa và bạn sẽ phải viết tất cả các sự kiện của bạn dưới dạng con (a, b) cũng.

Giống như vậy phải không?

1

Lưu ý rằng kiến ​​thức của tôi về Prolog là cũ (và không bao giờ mà sâu) ...

Tôi nghĩ rằng bạn cần phải thực hiện cha mẹ (hoặc con) tiểu học (không phụ thuộc vào mối quan hệ khác).

child(X,Y):- 
    parent(Y,X). 

parent(X,Y):- 
    child(Y,X). 

là điều có thể gây ra các vòng lặp.

5

Tôi đã gỡ bỏ tất cả mọi thứ đó là không cần thiết trong mã của bạn và thay đổi một vài điều và đây là những gì tôi đã kết thúc với:

% married(Husband, Wife) 
married(i,w). 
married(f,d). 

Người ta sẽ giả sử rằng married(X,Y) :- married(Y,X), nhưng nó dẫn đến chứng tròn khó chịu, vì vậy chúng tôi sẽ chỉ đưa chồng đầu tiên theo quy ước.

Giới thiệu về tình huynh đệ, vấn đề tương tự phát sinh. Chúng ta cần phải xem xét cha mẹ bước như cha mẹ thực sự, bởi vì câu đố phụ thuộc vào nó. Chúng tôi biết bạn không bao giờ có thể là tổ tiên sinh học của riêng bạn!

Tuy nhiên, parent(X,Y) :- parent(Z,Y), married(X,Z) chạy vào cùng một vấn đề, vì vậy tôi chỉ thực hiện bio_parent biểu thị tính cha mẹ sinh học.

bio_parent(f,i). 
bio_parent(w,d). 
bio_parent(w,s1). 
bio_parent(i,s1). 
bio_parent(d,s2). 
bio_parent(f,s2). 

Lưu ý rằng chúng tôi phải rõ ràng về cả cha lẫn mẹ, vì không có cách nào để kết luận sinh lý làm cha mẹ từ hôn nhân! Ngoài ra, cách của bạn đặc điểm kỹ thuật là vấn đề. Bạn có cái gì đó như:

son(X,Y) :- child(X,Y), male(X). 
son(a,b). 

Tuy nhiên, từ những quy tắc Prolog không thể suy ra child(a,b), vì vậy bạn đã kết thúc hộ con trai người không trẻ em! Điều này đã xảy ra một vài lần trong mã của bạn. Nếu bạn lấy được b từ a, hãy luôn ghi rõ a là sự thật! Thoạt nhìn, điều này có vẻ giống như một thiếu sót của Prolog, nhưng nó không phải là. Hãy nhớ rằng mọi mệnh đề chỉ là một cách để chứng minh một vị từ nào đó. Trong ví dụ trên, bạn đã nói rằng mọi trẻ em nam đều là con trai và cũng có thể là a chỉ là con trai của b. Không nơi nào được nói rằng là một đứa trẻ nam là cách duy nhất mà ai đó có thể là con trai, a có thể chỉ là ngoại lệ.

Điều tiếp theo hơi phức tạp khi định nghĩa của chúng tôi về married buộc chúng tôi phải đối xử với cha của cha mẹ bước riêng biệt. Tuy nhiên, chúng tôi thống nhất họ để bố mẹ bước .

step_father(X,Y) :- married(X,Z),bio_parent(Z,Y),\+bio_parent(X,Y). 
step_mother(X,Y) :- married(Z,X),bio_parent(Z,Y),\+bio_parent(X,Y). 
step_parent(X,Y) :- step_father(X,Y). 
step_parent(X,Y) :- step_mother(X,Y). 

Như tôi đã nói ở trên, chúng ta cần xem xét bố mẹ là cha mẹ!

parent(X,Y) :- step_parent(X,Y). 
parent(X,Y) :- bio_parent(X,Y). 

grandparent(X,Y):- 
    parent(X,Z), 
    parent(Z,Y). 

Cũng có một số lỗi khác trong mã của bạn mà tôi đã thực hiện, tôi chỉ cho bạn thấy một số ví dụ để bạn có thể học từ đó.

Đầu tiên, ở đây bạn nói rằng các bà vợ đã kết hôn và nam chồng đã kết hôn. Vì vậy, các bà vợ sẽ không có gia đình. Nên là cách khác vòng mặc dù, những người kết hôn nữ được gọi là vợ!

% wrong: 
% 
% married(X,Y):- 
% wife(X,Y), 
% female(X). 
% 
% married(X,Y):- 
% husband(X,Y), 
% male(X). 
% 
% right: 
% wife(X,Y) :- married(Y,X). % according to our new definition of 'married' 
% husband(X,Y) :- married(X,Y). 

Ở đây tôi đã thêm dòng cuối cùng, như bạn thường không xem xét bản thân anh chị em ruột của riêng bạn:

% sibling(X,Y):- 
% parent(Z,X), 
% parent(Z,Y), 
% X \= Y. % added this 

Những ngoái hai là sự thật về vị sai một lần nữa. Bạn về cơ bản ghi đè lên số tiền của Prolog với họ. Họ nên được khấu trừ, không được ghi là sự thật!

% son_in_law(f,i). 
% step_mother(d,i). 

Bây giờ, hãy thử chương trình như thế này. Và đừng ngạc nhiên: Bạn sẽ không phải là người duy nhất làm ông bà của riêng mình! ;-)

0
couples(i,w). 
mother_of(w,d). 
father_of(f,i). 
couples(f,d). 
son_in_law(f,i). 
mother_of(d,i). 
mother_of(w,s1). 
mother_of(d,s2). 
grand(F,C):- son_in_law(F,C),couples(H,D),mother_of(D,C). 
grand(F,C):- father_of(F,D),father_of(D,C). 

truy vấn

?-grand(i,i). 
Các vấn đề liên quan