如何在Prolog中将事实累积为一个值

时间:2018-12-15 14:54:29

标签: prolog

以下是事实:

% structure: salary([Name, Last Name], salary_amount).

salary([bartholomew, simpson], 0).    
salary([homer, simpson], 40000).    
salary([lisa, simpson], 500).    
salary([maggie, simpson], 0).    
salary([marge, simpson], 10000).

这是我断言所有薪水的谓词

entire_family(X,Income) :-
    bagof(_,salary([_, X],Income), _).

输出

Income = 0 ;    
Income = 40000 ;    
Income = 500 ;    
Income = 0 ;    
Income = 10000.

我需要它来输出

Income: 50500 (total salaries of the Simpson family)

如果有人对我有任何提示,请告诉我!

1 个答案:

答案 0 :(得分:1)

虽然答案是逻辑编程语言Prolog,但解决方案更容易理解为functional问题,即将事实filters放入列表,然后folds放入列表一个值。

将事实过滤到列表中

salary_to_list(L) :-
    findall(S,salary(_,S),L).

示例:

?- salary_to_list(L).
L = [0, 40000, 500, 0, 10000].

将列表折叠成一个值

sum(L,S) :-
    foldl(plus,L,0,S).

示例:

?- foldl(plus,[2,3,4],0,S).
S = 9.

将两个问题放在一起。

entire_family(Income) :-
    salary_to_list(L),
    sum(L,Income).

示例:

?- entire_family(Income).
Income = 50500.

整个来源

:- use_module(library(apply)).

salary([bartholomew, simpson], 0).
salary([homer, simpson], 40000).
salary([lisa, simpson], 500).
salary([maggie, simpson], 0).
salary([marge, simpson], 10000).

salary_to_list(L) :-
    findall(S,salary(_,S),L).

sum(L,S) :-
    foldl(plus,L,0,S).

entire_family(Income) :-
    salary_to_list(L),
    sum(L,Income).

参考文献:

SWI-Prolog:
Finding all Solutions to a Goal-findall / 3
library(apply): Apply predicates on a list -foldl / 4
Special purpose integer arithmetic-加号/ 3

序言的力量:
Higher-order Predicates