繁体   English   中英

序言中list的总和

[英]Sum elements of list in prolog

我想对这样的列表元素求和:

sum([1,[2,3],4],S).

我曾经用过,但是有一个问题:

sum([],0).
sum([T|R],M) :- sum(R,S), M is T+S.

我收到以下错误:

ERROR: is/2: Type error: `[]' expected, found `[2,3]' (a list) ("x" must hold one character)

问题是,如果T是列表,则无法添加T。 如果T是列表,则可以成功使用is_list/1轻松解决:

sum([],0).
sum([T|R],M) :- (is_list(T) -> sum(T,N1),sum(R,S), M is N1+S
                 ; sum(R,S), M is T+S ).

例子:

?- sum([1,[2,3],4],S).
S = 10.

?- sum([1,2,3,4],S).
S = 10.

?- sum([1,[2],[3],4],S).
S = 10.

?- sum([1,[[2],[3]],4],S).
S = 10.

更好的方法是使用CLPFD:

:- use_module(library(clpfd)).

sum([],0).
sum([[]],0).
sum([T|R],M) :- (is_list(T) -> sum(T,N1),sum(R,S), M #= N1+S
                 ; sum(R,S), M #= T+S ).

现在,您可以查询更一般的问题,例如:

?- sum(L,N).
L = [],
N = 0 ;
L = [[]],
N = 0 ;
L = [N],
N in inf..sup ;
L = [N, []],
N in inf..sup ;
L = [_1836, _1842],
_1836+_1842#=N ;
L = [_1842, _1848, []],
_1842+_1848#=N ;
L = [_2142, _2148, _2154],
_2142+_2192#=N,
_2148+_2154#=_2192 ;
L = [_2148, _2154, _2160, []],
_2148+_2204#=N,
_2154+_2160#=_2204 ;
L = [_2448, _2454, _2460, _2466],
_2448+_2504#=N,
_2454+_2528#=_2504,
_2460+_2466#=_2528 ;

然后继续...

另一种方法:

% Old code, with vars renamed:
%sum([], 0).
%sum([Num|Tail], TotalSum) :- sum(Tail, TailSum), TotalSum is Num + TailSum.

% New code:
sum([], 0).
sum([Elem|Tail], TotalSum) :- 
    sum(Elem, ElemSum),
    sum(Tail, TailSum),
    TotalSum is ElemSum + TailSum.
sum(Num, Num).

演示: http : //swish.swi-prolog.org/p/cmzcsXrJ.pl

您可以在Swi-Prolog中使用flatten / 2 plus foldl / 4或sum_list / 2库谓词:

% flatten/2 + foldl/4 based implementation
sum_nested_list(List, Sum) :-
    flatten(List, Flat),
    foldl(plus, Flat, 0, Sum).

% flatten/2 + sum_list/2 based implementation
sum_nested_list(List, Sum) :-
    flatten(List, Flat),
    sum_list(Flat, Sum).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM