首页 > 解决方案 > 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)

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

标签: prolog

解决方案


虽然答案在逻辑编程语言 Prolog 中,但解决方案更容易理解为功能性问题,它将事实过滤到列表中,然后将列表折叠成单个值。

将事实过滤到列表中

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:
查找目标的所有解决方案- findall/3
库(应用):在列表上应用谓词-foldl/4
特殊用途整数算术- plus/3

Prolog 的威力:
高阶谓词


推荐阅读