在数据结构上实现关系

时间:2013-04-03 11:08:28

标签: prolog

我有以下简单的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是一个家庭中的孩子,如果一个人存在于一个家庭,一个人的工资和日期一个人的出生)

好的,直到现在我没有问题。

然后我有以下与上一个程序相关的练习:编写一个计算每个家庭所有孩子总薪水的规则

所以我必须计算一个我称之为ChildrenIncoming的值,它表示属于特定家庭的所有子项的工资(表示家庭数据结构中的子项的人员数据结构中的最后一个值)的总和< / p>

我发现实现此功能存在许多问题。

我从更简单的任务开始(例如检索丈夫的工资),如下所示:

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

我试图计算一些类似于它的ChildIncoming值(它是不完整的并且不起作用):

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

如果一个家庭(有丈夫作为家长)有空子列表,则孩子的总入学人数为0。

然后我引入了一个规则(错误),在非空子列表的情况下应该计算这个值。

这条规则背后的原因是:

1)非空儿童名单包含人。

2)非空列表可以分为列表头部(即人)和尾部子列表(人员列表)

3)头部是一个人并有薪水

4)尾巴包含人,每个人都有薪水

但我不知道如何以正确的方式将这些想法混合起来以获得所需的结果(儿童名单中所有人的总投入值)

我不知道这种或推理是好还是我从一开始就错了。

2 个答案:

答案 0 :(得分:2)

如果将这些谓词添加到family / 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 .

答案 1 :(得分:-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.

评论是意大利语,但我认为查看代码很简单,理解它意味着什么: - )