【发布时间】:2015-05-31 18:00:15
【问题描述】:
我想在 prolog 中编写一个代码,获取一个列表并找到它的正数并将它们添加到一个新列表中,如下所示:
?- findPositives([-1,2,3,-5,-7,9],Result)
Result : [2,3,9]
如何编写此代码?
【问题讨论】:
-
您是否尝试过可以展示的解决方案?
标签: prolog
我想在 prolog 中编写一个代码,获取一个列表并找到它的正数并将它们添加到一个新列表中,如下所示:
?- findPositives([-1,2,3,-5,-7,9],Result)
Result : [2,3,9]
如何编写此代码?
【问题讨论】:
标签: prolog
使用tfilter/3:
positive_truth(N, true) :-
N >= 0.
positive_truth(N, false) :-
N < 0.
?- tfilter(positive_truth, [-1,2,3,-5,-7,9],Result).
Result = [2,3,9]
或者,使用library(clpfd):
pos_truth(Expr, Truth) :-
Expr #>= 0 #<==> Bool,
bool01_truth(Bool, Truth).
bool01_truth(0,false).
bool01_truth(1,true).
?- tfilter(pos_truth, [-1,2,3,-5,-7,9],Result).
Result = [2,3,9].
?- tfilter(pos_truth, [X,Y],Result).
Result = [], X in inf.. -1, Y in inf.. -1
; Result = [Y], X in inf.. -1, Y in 0..sup
; Result = [X], X in 0..sup, Y in inf.. -1
; Result = [X, Y], X in 0..sup, Y in 0..sup.
【讨论】:
tfilter/3,它很可能是不正确的。
这是最简单的方法:
find_positives( Ns , Ps ) :- findall( X , ( member(X,Ns) , X > 0 ) , Ps ) .
但我怀疑您的讲师希望您自己找出递归解决方案。因此...
find_positives( [] , [] ) .
find_positives( [N|Ns] , [P|Ps] ) :- N > 0 , find_positives(Ns,Ps) .
find_positives( [N|Ns] , Ps ) :- N =< 0 , find_positives(Ns,Ps) .
请注意,您可以通过引入确定性切割来保存比较,因此:
find_positives( [] , [] ) .
find_positives( [N|Ns] , [P|Ps] ) :- N > 0 , ! , find_positives(Ns,Ps) .
find_positives( [_|Ns] , Ps ) :- find_positives(Ns,Ps) .
并通过“软切”/连词 (->/2) 折叠第 2 和第 3 子句来使其更简洁:
find_positives( [] , [] ) .
find_positives( [N|Ns] , R ) :-
( N > 0 -> R = [P|Ps]; R = Ps ) ,
find_positives(Ns,Ps) .
这是否提高理解力取决于您。
【讨论】:
N = P。您的第二次成功为 find_positives([1],[]),但应该失败。