2017-02-25 59 views
2

我要總結的列表的元素是這樣的:和元素

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) 

回答

2

問題是,如果T是一個列表,則不能添加T.你可以很容易地解決使用is_list/1是succeds如果T是一個列表:

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 ; 

並繼續...

+0

到您的最後一個查詢的答案是不完整的。例如,sum([[]],0)'缺失。 – false

+0

@false,謝謝!編輯答案.. – coder

1

另一種方法:

% 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

0

您可以使用扁平/ 2加與foldl/4或束縛水飽和度,Prolog的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).