-1

私は、データ構造を使用して、夫、妻、子供のリストで構成される家族を表す次の単純な 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).

家族 (夫を父として持つ) に空の子供リストがある場合、子供の合計着信数は 0 です。

次に、空でない子リストの場合にこの値を計算するルール (間違った) を導入しました。

この規則の背後にある理由は次のとおりです。

1) 空ではない子リストに person が含まれています。

2) 空でないリストは、リストのヘッド (人物) と末尾のサブリスト (人物のリスト) に分けることができます。

3) 頭は人で、給料がある

4) テールには人が含まれ、それぞれに給与があります

しかし、これらのアイデアを正しい方法でどのように組み合わせて、望ましい結果(子リスト内のすべての人物の総着信の値)を取得するかはわかりません

このような理屈がいいのか、最初から間違っているのかはわかりません。

4

2 に答える 2

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 .
于 2013-04-03T15:04:33.473 に答える
-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.

コメントはイタリア語ですが、コードを見るとその意味を理解するのは非常に簡単だと思います:-)

于 2013-04-03T15:35:05.950 に答える