我只是在学习Prolog,我需要向函数提供一个包含正整数和负整数的列表,并且它应该返回子列表的列表,以便每个子列表仅包含连续的正数或仅包含连续的负数。我的意思是基于列表中存在的数字的符号,该功能应该破坏列表。
以下是输入和必需的输出:
f([],[]).
f([H|[]],L).
f([H,E|T],[[H,E|Tail1]|Tail]):-
H >=0,
E>=0,
f(T,[[Tail1]|Tail]).
f([H,E|T],[[H]|Tail]) :-
H>=0,
E<0,
f([E|T],Tail).
f([H,E|T],[[H,E|Tail1]|Tail]) :-
H<0,
E<0,
f(T,[[Tail1]|Tail]).
f([H,E|T],[[H]|Tail]) :-
H<0,
E>=0,
f([E|T],Tail).
到目前为止,我所取得的成就是:
{{1}}
运行上述功能时出现奇怪的跟踪。任何帮助都会很棒。谢谢:)
答案 0 :(得分:1)
您可以使用fold/4
拆分列表:
split(Input, LOutput):-
foldl(addorsplit, Input, state(_Sgn, LOutput), state(_, [[]])).
sgn(Num, Sgn):-
Sgn is sign(sign(Num)*2+1).
addorsplit(Item, state(Sgn, LOutput), state(NSgn, [Current|Tail])):-
sgn(Item, NSgn),
(Sgn = NSgn -> LOutput=[[Item|Current]|Tail] ; LOutput=[[],[Item|Current]|Tail]).
sgn/2
是一个帮助程序,可以让0代表肯定。
示例查询:
?- split([1,2,-3,-4,5,0,7],L).
L = [[1, 2], [-3, -4], [5, 0, 7]]
使用clp(FD)将允许执行更多常规查询:
split2(Input, LOutput):-
foldl(addorsplit2, Input, state(_Sgn, LOutput), state(_, [[]])).
sgn2(Num, 1):-
Num #>= 0.
sgn2(Num, -1):-
Num #< 0.
addorsplit2(Item, state(Sgn, LOutput), state(NSgn, [Current|Tail])):-
sgn2(Item, NSgn),
(Sgn #= NSgn -> LOutput=[[Item|Current]|Tail] ; LOutput=[[],[Item|Current]|Tail]).
现在您可以查询例如:
?- split2([X,1,-3,Y],L).
L = [[X, 1], [-3], [Y]],
X in 0..sup,
Y in 0..sup ;
;
L = [[X, 1], [-3, Y]],
X in 0..sup,
Y in inf.. -1 ;
;
L = [[X], [1], [-3], [Y]],
X in inf.. -1,
Y in 0..sup ;
;
L = [[X], [1], [-3, Y]],
X in inf.. -1,
Y in inf.. -1 ;