如何创建一个名为busLineLonger的函数,它接收至少两个参数来决定总线是否更长?
*/This is how it works*/
* busStops(number_of_the_bus,number_of_stops)*/
/*?- busLineLonger([busStops(1,7),busStops(2,4),busStops(3,6)],5,WHICH).
* WHICH = [1,3].
仅使用比较性内容,例如@> < @ / == @。 对不起我的英文
编辑... 到目前为止,我已经想到了像这样的东西
busLineLonger([busStops(A,B)|R],N,[_|_]):-
N@>B,
busLineLonger(R,N,A).
答案 0 :(得分:2)
以下是使用meta-predicates进行操作的方法, reified test predicates, 和lambda expressions。
:- use_module(library(lambda)).
首先,我们像这样定义具体化的测试谓词(>)/3
:
>(X,Y,Truth) :- (X > Y -> Truth=true ; Truth=false).
接下来,我们根据以下元素定义三个 busLineLonger/3
(名为busLineLonger1/3
,busLineLonger2/3
和busLineLonger3/3
)的不同实现-predicates:maplist/3
,tfilter/3
,tfiltermap/4
和tchoose/3
。当然,最终我们只需要一个 ---但这不应该阻止我们探索我们的各种选择!
tfilter/3
和maplist/3
执行两个单独的步骤: 1.选择关注的项目。 2.将这些项目投射到感兴趣的数据中。
busLineLonger1(Ls0,N,IDs) :-
tfilter(\busStops(_,L)^(L>N), Ls0,Ls1),
maplist(\busStops(Id,_)^Id^true, Ls1, IDs).
tfiltermap/4
在这里,我们使用与以前完全相同的lambda表达式,但是我们通过了
他们两者到元谓词tfiltermap/4
。这样做有助于减少
节省一些资源。
busLineLonger2(Ls,N,IDs) :-
tfiltermap(\busStops(_,L)^(L>N), \busStops(Id,_)^Id^true, Ls,IDs).
以下是tfiltermap/4
的实施方式:
:- meta_predicate tfiltermap(2,2,?,?).
tfiltermap(Filter_2,Map_2,Xs,Ys) :-
list_tfilter_map_list(Xs,Filter_2,Map_2,Ys).
:- meta_predicate list_tfilter_map_list(?,2,2,?).
list_tfilter_map_list([],_,_,[]).
list_tfilter_map_list([X|Xs],Filter_2,Map_2,Ys1) :-
if_(call(Filter_2,X), (call(Map_2,X,Y),Ys1=[Y|Ys0]), Ys1=Ys0),
list_tfilter_map_list(Xs,Filter_2,Map_2,Ys0).
tchoose/3
这里我们不使用两个单独的lambda表达式,而是一个组合的表达式。
busLineLonger3(Ls,N,IDs) :-
tchoose(\busStops(Id,L)^Id^(L>N), Ls,IDs).
以下是tchoose/3
的实施方式:
:- meta_predicate tchoose(3,?,?).
tchoose(P_3,Xs,Ys) :-
list_tchoose_list(Xs,P_3,Ys).
:- meta_predicate list_tchoose_list(?,3,?).
list_tchoose_list([],_,[]).
list_tchoose_list([X|Xs],P_3,Ys1) :-
if_(call(P_3,X,Y), Ys1=[Y|Ys0], Ys1=Ys0),
list_tchoose_list(Xs,P_3,Ys0).
让我们看看他们的行动!
?- Xs = [busStops(1,7),busStops(2,4),busStops(3,6)], busLineLonger1(Xs,5,Zs).
Xs = [busStops(1, 7), busStops(2, 4), busStops(3, 6)],
Zs = [1, 3].
?- Xs = [busStops(1,7),busStops(2,4),busStops(3,6)], busLineLonger2(Xs,5,Zs).
Xs = [busStops(1, 7), busStops(2, 4), busStops(3, 6)],
Zs = [1, 3].
?- Xs = [busStops(1,7),busStops(2,4),busStops(3,6)], busLineLonger3(Xs,5,Zs).
Xs = [busStops(1, 7), busStops(2, 4), busStops(3, 6)],
Zs = [1, 3].
完成!
那么...... 底线是什么?
tchoose/3
的那个)是最好的。答案 1 :(得分:0)
您的代码中需要修复的一些事项:
[_|_]
,结果是自由变量......没有意义。您需要两种情况:一种情况B
大于N
并且您包含结果; B
小于或等于N
的另一个,并且您不包含该结果。可能的解决方案:
busLineLonger([],_,[]).
busLineLonger([busStops(A,B)|R],N,[A|S]) :- B>N, busLineLonger(R,N,S).
busLineLonger([busStops(_,B)|R],N,S) :- B=<N, busLineLonger(R,N,S).
?- busLineLonger([busStops(1,7),busStops(2,4),busStops(3,6)],5,WHICH).
WHICH = [1, 3]