我试图编写一个谓词来从列表列表中的每个列表中删除头部,并将尾部添加到新列表中。结果列表应作为第二个参数返回。
这是尝试:
construct_new(S,New) :-
New = [],
new_situation(S,New).
new_situation([],_).
new_situation([H|T], New) :-
chop(H, H1),
new_situation(T, [H1|New]).
chop([_|T], T).
你会这样称呼:
construct_new([[x,x],[b,c],[d,e,f]],S).
但是,这只会产生输出true.
。
答案 0 :(得分:3)
construct_new(Input,Output)
,适用于某些实例Input
列表。construct_new/2
中的第一个语句将Output
(a.k.a。New
)与空列表统一起来。 返回的列表应该在哪里可供调用者使用?这两个论点现已统一。 new_situation(Input,[])
new_situation([H|T],[])
,它以递归方式执行任务(步骤4,...),直到...... new_situation([],_)
,成功会丢弃您构建的中间列表。编写一个简单的递归谓词:
new_situation([],[]).
new_situation([[_|L]|T],[L|R]) :-
new_situation(T,R).
使用maplist
:
construct_new(S,R) :-
maplist(chop,S,R).
正如其他答案和评论所指出的那样,你的谓词命名很差。 construct_new
不是关系,而是行动,可以用来代表几乎任何东西。我倾向于喜欢chop
,因为它清楚地传达了斩首的行为,但这不是一个适当的关系名称。 重复的list_head_tail(L,H,T)
是声明性的,并将变量与其角色相关联。使用maplist
时,其他谓词(new_situation
)甚至不需要存在......
...即使guillotine/3很诱人。
答案 1 :(得分:3)
这可以通过DCG完成:
owth(Lists, Tails) :-
phrase(tails(Tails), Lists).
tails([]) --> [].
tails([T|Tails]) --> [[_|T]], tails(Tails).
产生这些查询:
| ?- owth([[x,x],[b,c],[d,e,f]], T).
T = [[x],[c],[e,f]] ? ;
no
| ?- owth(L, [[x],[c],[e,f]]).
L = [[_,x],[_,c],[_,e,f]]
yes
(owth
= 关闭他们的头!或者,如果使用其他方向,打开他们的头!)
如果您还想捕捉头部,可以按如下方式进行增强:
owth(Lists, Heads, Tails) :-
phrase(tails(Heads, Tails), Lists).
tails([], []) --> [].
tails([H|Hs], [T|Tails]) --> [[H|T]], tails(Hs, Tails).
答案 2 :(得分:2)
我们将meta-predicate maplist/[3-4]
与以下辅助谓词之一一起使用:
list_tail([_|Xs],Xs).
list_head_tail([X|Xs],X,Xs).
让我们运行一些查询!
?- maplist(list_head_tail,[[x,x],[b,c],[d,e,f]],Heads,Tails).
Heads = [x,b,d],
Tails = [[x],[c],[e,f]].
如果您仅对尾巴感兴趣,请将maplist/4
与list_head_tail/3
一起使用...
?- maplist(list_head_tail,[[x,x],[b,c],[d,e,f]],_,Tails).
Tails = [[x],[c],[e,f]].
......或者更简单,maplist/3
与list_tail/2
:
?- maplist(list_tail,[[x,x],[b,c],[d,e,f]],Tails).
Tails = [[x],[c],[e,f]].
答案 3 :(得分:1)
你也可以使用findall/3
:
?- L = [[x,x],[b,c],[d,e,f]],
findall(T, ( member(M, L), append([_], T, M) ), R).
R = [[x], [c], [e, f]].
(好的,技术上是一个双线程。无论哪种方式,你甚至不需要定义辅助谓词。)
但绝对更喜欢使用maplist
的{{1}}解决方案,如above所示。
如果您手动执行地图列表扩展,并将您的chop
命名为更好,那么您将获得:
chop/2
由于你可以在谓词的头部进行统一,你可以将其转换为:
lists_tails([], []).
lists_tails([X|Xs], [T|Ts]) :-
list_tail(X, T),
lists_tails(Xs, Ts).
但这与你在另一个答案中所拥有的相同。
练习:为什么我们不能说:
lists_tails([], []).
lists_tails([[_|T]|Xs], [T|Ts]) :-
lists_tails(Xs, Ts).