家庭数据库prolog查询

时间:2014-11-06 21:46:41

标签: prolog logic

我正在使用以下家庭数据库来练习prolog。我想......

找到孩子总收入的母亲的名字和姓氏 超过140,000英镑,至少有一个孩子失业。规则也应该回归 失业儿童/儿童的名字,以及儿童的总和 收入

到目前为止,我有这个代码...帮助将不胜感激,真的在这个练习上挣扎。谢谢:))

(Fname,Sname,Income):- 
family(person(_,_,_,_),person(Fname,Sname,_,_),Children),
total(Children,Income),
Income > 140000.

total([Person|List],Sum):-
salary(Person,S),   % S: salary of the first person
total(List,Rest),   % Rest: sum of salaries of others
Sum is S + Rest.

family(
person(pat,marx,date(10,march,1944),unemployed),
person(charlotte,marx,date(11,february,1946),unemployed),
[
    person(aine,marx,date(17,april,1985),unemployed),
    person(louis,marx,date(25,june,1980),works(harriott,32000)),
    person(pearl,marx,date(10,june,1981),unemployed),
    person(pat_jr,marx,date(11,march,1983),works(world_of_food,850000)),
    person(ricky,marx,date(18,february,1987),unemployed)
]
).

family(
person(fred,chomsky,date(3,october,1955),works(bean_counters,100000)),
person(sarah,chomsky,date(19,october,1961),works(supercomms, 60000)),
[   
person(amos,chomsky,date(1,july,1984),works(sell_cell, 80000))
]
).

family(
person(ted,marx,date(10,july,1948),unemployed),
person(adelheid,marx,date(9,december,1948),unemployed),
[   person(ted_jr,marx,date(14,april,1988),works(world_of_food,90000)),
    person(jenny,marx,date(23,may,1984),unemployed),
    person(margaret,marx,date(23,may,1984),unemployed),
    person(sadie,marx,date(23,may,1984),unemployed),
    person(louis,marx,date(22,august,1979),unemployed),
    person(alan,marx,date(9,may,1990),unemployed)
]

)。

family(
person(ted,russell,date(21,may,1938),retired),
person(victoria,russell,date(9,november,1944),retired),
[   person(betty,russell,date(18,august,1971),works(boat_house,65000)),
    person(jack,russell,date(27,may,1965),works(green_machine,15000)),
    person(joan,russell,date(9,april,1963),works(green_machine,15000)),
    person(penelope,russell,date(9,april,1963),works(green_machine,15000)),
    person(enda,russell,date(2,november,1968),works(exc-u-vate,15000)),
    person(amos,russell,date(27,may,1965),works(green_machine,15000)),
    person(algernon,russell,date(2,november,1968),works(exc-u-vate,15000)),
    person(cal,russell,date(9,october,1970),works(sell_cell,30000))
]

)。

family(
person(bill,kant,date(7,august,1942),works(fibrefast,100000)),
person(ann,kant,date(9,october,1945),works(roulada,100000)),
[   person(mark,kant,date(25,april,1970),works(harriott,36000)),
    person(cal,kant,date(22,december,1966),works(harriott,35000)),
    person(simon,kant,date(27,january,1965),works(harriott,31000)),
    person(sol,kant,date(17,november,1964),unemployed),
    person(andrew,kant,date(9,march,1968),works(harriott,32000)),
    person(joan,kant,date(27,january,1965),works(harriott,34000))
]

)。

family(
person(ted,russell,date(6,june,1950),works(mopper-ups,25000)),
person(helen,russell,date(10,june,1951),works(harriott,110000)),
[   person(maura,russell,date(21,february,1972),works(sparrow_hotel,19000)),
    person(simon,russell,date(24,december,1970),works(zoom-away,50000)),
    person(victoria,russell,date(23,january,1971),works(volts,49000)),
    person(andrew,russell,date(24,june,1969),works(sparrow_hotel,35000)),
    person(cal,russell,date(15,april,1974),works(sparrow_hotel,55000)),
    person(milly,russell,date(21,february,1972),works(sparrow_hotel,19000))
]

)。

1 个答案:

答案 0 :(得分:0)

这是一个非常奇怪的数据库布局,但这并不需要阻止我们。首先是规则的负责人,我们将要回归的事情:

q(MotherFirst, MotherLast, UnemployedKids, CombinedIncome) :-

我们在这里考虑家庭,所以让我们匹配它们并取出母亲的信息:

    family(_, person(MotherFirst, MotherLast, _, _), Children),

那里的下划线对应于父亲,母亲的出生日期和职业。这些都与问题无关,所以忘了它们。接下来我们需要对孩子们进行一些处理:我们需要找到失业者并获得综合收入。我会做两次遍历,因为它对我来说比较简单。首先是他们的收入总和:

    total_income(Children, CombinedIncome),
    CombinedIncome > 140000,
    unemployed(Children, UnemployedKids),
    UnemployedKids = [_|_]. % ensure we have at least one unemployed kid

我已经把任务打破了一点点;让我们继续写下一些帮助:

% compute the total income for a list of people
total_income([], 0).
total_income([person(_, _, _, works(_, Amount) | People], Total) :- 
    total_income(People, Subtotal),
    Total is Subtotal + Amount.

% find the unemployed people in a list of people
unemployed([], []).
unemployed([person(FN, LN, DOB, unemployed) | People], 
           [FN | Unemployed]) :-
    !, % cut so that we don't enter the next rule with someone who is unemployed
    unemployed(People, Unemployed).
unemployed([_|People], Unemployed) :- unemployed(People, Unemployed).

使用library(aggregate)或甚至某些折叠(可能使用library(lambda)可以大大简化这两种方法,但这是一个简单的经典"(罗嗦)解决方案。