2013-04-03 86 views
0

的關係,我有以下簡單的Prolog程序,通過使用數據結構,代表丈夫,妻子和孩子列表組成的家庭:實現上的數據結構

family(
    person(bob, smith, date(7,may,1968), 30000), 
    person(ann, smith, date(18,july,1970), 32000), 

    [person(dave, smith, date(1,june,1984), 0), 
    person(edna, smith, date(25,may,1990), 0)] 
). 

family(
    person(mario, rossi, date(7,may,1968), 30000), 
    person(lucia, verdi, date(18,july,1970), 32000), 

    [person(luca, rossi, date(1,june,1984), 5000), 
    person(maria, rossi, date(25,may,1990), 0), 
    person(paolo, rossi, data(16, april, 1980), 10000)] 
). 

family(
    person(carlo, bianchi, date(7,may,1968), 30000), 
    person(flavia, blabla, date(18,july,1970), 32000), 

    [person(figlio1, bianchi, date(1,june,1984), 0), 
    person(figlio2, bianchi, date(25,may,2001), 0), 
    person(figlio3, bianchi, data(16, april, 1980), 10000), 
    person(figlio4, bianchi, data(10, april, 1978), 20000)] 
). 

family(
    person(no, no, date(7,may,1968), 30000), 
    person(no, no, date(18,july,1970), 32000), 
    [] 
). 


/* Regola che mostra i mariti: */ 
husband(X) :- family(X,_,_). 

/* Regola che mostra l mogli: */ 
wife(X) :- family(_,X,_). 

/* Regola che mostra i figli: 
    X è figlio se in una famiglia c'è una lista di figli e se X appartiene 
    alla lista dei figli: */ 
child(X) :- family(_,_,Children), 
     member(X,Children). 

這是非常簡單的。通過一些事實我代表的一些家人和我有一些規則來執行一些查詢(獲得丈夫的妻子,如果X是一個家庭一個孩子,如果一個人在一個家庭中存在,姓名及日期的工資一個人出生)

OK,到現在爲止我沒有問題。

然後,我必須與前面的程序下面的練習:編寫計算每個家庭

所以我必須來計算,我有打電話ChildrenIncoming值中的所有孩子們的總薪酬的規則代表的工資(在人的數據結構代表一個家庭的數據結構的孩子的最後一個值)都屬於特定家庭

我發現很多問題來實現這個功能了孩子的總和。

我從容易的任務開始(例如檢索丈夫的薪水)是這樣的:

husbandIncoming(HSurname, HIncoming) :- husband(HSurname), % Seleziona un cognome 
         salary(HSurname, HIncoming). 

我也嘗試計算ChildrenIncoming值試圖做類似的東西(這是不完整的,不工作):

childrenList(Husband,ChildrenList) :- family(Husband,_,ChildrenList). 

/* If ChildrenList is empty: ChildrenIncomung value 0 */ 
childrenIncoming(Husband,[],0). 

childrenIncoming(Husband,ChildrenList,ChildrenIncoming) :- 
    childrenList(Husband,ChildrenList), 
    ChildrenList = [Head|Tail], 
           childrenIncoming(Husband,Tail,TailIncoming), 
           salary(Head, ChildrenIncoming). 

第一件事是,我確定一個家庭由丈夫,所以我可以使用childrenList規則檢索ChildrenList (這個規則運作良好)。

然後,我會計算這個ChildreList中所有人的所有工資的總和,並且這樣做,我介紹了關係childrenIncoming必須計算它。

這種關係由事實,簡單地說開始:

childrenIncoming(Husband,[],0). 

如果一個家庭(其夫爲paterfamilias)有空兒列表,那麼孩子的總傳入0

然後我介紹一個規則(錯誤)應該在計算非空的孩子列表中的情況下,這個值。

這一規則背後的理由是:

1)不是空的孩子列表中包含的人。

2)一個非空的列表可以被分爲列表的頭(即人)和一個尾部子列表(人列表)

3)的頭部是一個人,並且具有工資

4)尾部包含個人,每一個有薪金

但我不知道如何來獲得期望的結果(所有的人的總傳入的價值的正確方法,這些想法混合在兒童列表中)

我不知道這個ki nd或推理是好的,或者如果我從一開始就錯了。

+0

遞歸,親愛的沃森。 –

+0

是的......我知道......我嘗試過,但是我所有的努力都失敗了......你能幫助我嗎? -/ – AndreaNobili

+2

@AndreaNobili:請在你的問題上付出更多努力。您將一個問題的一半文本複製到下一個文本,而無需對其進行校對。另外,使用拼寫檢查器。 – false

回答

2

如果添加這些謂詞家庭/ 3的事實

husband(family(H, W, C), P) :- family(H, W, C), H = person(P,_,_,_). 
children(family(_, _, C), C). 
income(P, I) :- P = person(_,_,_,I). 

childrenIncoming(Family, ChildrenIncoming) :- 
    children(Family, Children), 
    sum_income(Children, 0, ChildrenIncoming). 

sum_income([], Sum, Sum). 
sum_income([C|Children], SoFar, Sum) :- 
    income(C, I), 
    Updated is I + SoFar, 
    sum_income(Children, Updated, Sum). 

與此查詢你

?- husband(F, mario), childrenIncoming(F,I). 
F = family(person(mario, rossi, date(7, may, 1968), 30000), person(lucia, verdi, date(18, july, 1970), 32000), [person(luca, rossi, date(1, june, 1984), 5000), person(maria, rossi, date(25, may, 1990), 0), person(paolo, rossi, data(16, april, 1980), 10000)]), 
I = 15000 . 
+0

好的謂詞名稱「childrenIncoming」!生活就是這樣。 – hardmath

+0

Tnx。現在我將研究它。同時我找到了一個個人解決方案(看起來像一個同事的例子),起初看起來像你的。計算整個家庭的總收入...... Prolog很難! – AndreaNobili

-1

我也創建此一個計算特定家庭的所有成分的總呼入:

/* FATTO (CASO BASE): Se la lista dei figli è una lista vuota, non ci 
         sono figli quindi la somma dei redditi dei figli è 0 
*/ 
somma([],0). 

/* REGOLA (CASO GENERALE): La lista dei figli non è vuota quindi può essere 
    decomposta in un'HEAD (person(_,_,_,E) ed in una sottolista L. 

    SE è VERO che: il valore della somma di tutti gli elementi nella 
    sottolista L è S1 ed è VERO che il valore di S è S1+E allora è VERO 
    che la somma dei redditi nella lista [H|L] è S 

*/ 
somma([person(_,_,_,E)|L],S):- somma(L,S1), 
        S is S1+E. 

/* Una famiglia è identificata dal COGNOME DEL MARITO. 
    Il REDDITO TOTALE di una famiglia è la somma del reddito del marito + 
    reddito moglie + la somma dei redditi di tutti i figli nella lista 
    dei figli. 
*/ 
reddito(C,R):- family(person(_,C,_,RP), person(_,_,_,RM), FIGLI), 
      somma(FIGLI,RF), 
      R is RF+RP+RM. 

評論意大利語,但我認爲看代碼很漂亮簡單理解它是什麼意思:-)