如何根据元素类型断言列表中的元素
How to predicate elements in a list based on element type
给定格式列表,
[item(a), item(b), item(c), other(d), other(e) ...]
其中项目的数量不固定,其他项目的数量也不固定,但项目总是在其他项目之前,我如何拆分列表以便我可以将项目和其他项目传递到不同的谓词中。
我一直在尝试找到根据元素拆分列表的方法,但找不到这样做的方法。
我需要编写一个谓词来获取此列表,然后将项目传递给 itemPredicate
,将其他项目传递给 otherPredicate
。
如果我可以提供任何其他信息,请告诉我。
让我们从对元素进行分类的谓词开始。怎么样
item_t(item(_), true).
item_t(other(_), false).
请注意,此谓词的真值有一个额外的参数。它只接受 item(_)
或 other(_)
元素。如果出现 unfit(x)
之类的内容,它将完全失败。现在想象一下,我们有一个谓词 takeWhilet/3
我们现在可以写
?- takeWhilet(item_t, [item(a), item(b), item(c), other(d), other(e)], Xs).
takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|_], []) :-
call(P_1, E, false).
takeWhilet(P_1, [E|Es], [E|Fs]) :-
call(P_1, E, true),
takeWhilet(P_1, Es, Fs).
使用 library(reif)
s 更漂亮 if_/3
:
takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|Es], Fs0) :-
if_( call(P_1, E)
, ( Fs0 = [E|Fs], takeWhilet(P_1, Es, Fs) )
, Fs0 = [] ).
现在,我们可以类似地定义 other_t/2
...
将 item(_)
与 other(_)
分开的简单拆分谓词可以按如下方式工作:
split([], [], []).
split([item(A) | T], [item(A) | IT], OL) :- split(T, IT, OL).
split([other(A) | T], IL, [other(A) | OT]) :- split(T, IL, OT).
并像这样使用它:
?- split([item(1), other(2), other(3), item(4), other(5)], X, Y).
X = [item(1), item(4)],
Y = [other(2), other(3), other(5)].
它甚至不需要 item
s 总是在 other
s 之前。
您可以概括为任何类型的项目
work(item,L) :-
format('args of \'item\' ~w~n', L).
work(other,L) :-
format('args of \'other\' ~w~n', L).
work(anything, L) :-
format('args of \'anything\' ~w~n', L).
work_element(Item) :-
Item =.. [A|L],
work(A, L).
my_split(In) :-
maplist(work_element, In).
例如:
?- my_split([item(a), item(b), item(c), other(d), other(e) , item(f), other(g)]).
args of 'item' a
args of 'item' b
args of 'item' c
args of 'other' d
args of 'other' e
args of 'item' f
args of 'other' g
true
给定格式列表,
[item(a), item(b), item(c), other(d), other(e) ...]
其中项目的数量不固定,其他项目的数量也不固定,但项目总是在其他项目之前,我如何拆分列表以便我可以将项目和其他项目传递到不同的谓词中。
我一直在尝试找到根据元素拆分列表的方法,但找不到这样做的方法。
我需要编写一个谓词来获取此列表,然后将项目传递给 itemPredicate
,将其他项目传递给 otherPredicate
。
如果我可以提供任何其他信息,请告诉我。
让我们从对元素进行分类的谓词开始。怎么样
item_t(item(_), true).
item_t(other(_), false).
请注意,此谓词的真值有一个额外的参数。它只接受 item(_)
或 other(_)
元素。如果出现 unfit(x)
之类的内容,它将完全失败。现在想象一下,我们有一个谓词 takeWhilet/3
我们现在可以写
?- takeWhilet(item_t, [item(a), item(b), item(c), other(d), other(e)], Xs).
takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|_], []) :-
call(P_1, E, false).
takeWhilet(P_1, [E|Es], [E|Fs]) :-
call(P_1, E, true),
takeWhilet(P_1, Es, Fs).
使用 library(reif)
s 更漂亮 if_/3
:
takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|Es], Fs0) :-
if_( call(P_1, E)
, ( Fs0 = [E|Fs], takeWhilet(P_1, Es, Fs) )
, Fs0 = [] ).
现在,我们可以类似地定义 other_t/2
...
将 item(_)
与 other(_)
分开的简单拆分谓词可以按如下方式工作:
split([], [], []).
split([item(A) | T], [item(A) | IT], OL) :- split(T, IT, OL).
split([other(A) | T], IL, [other(A) | OT]) :- split(T, IL, OT).
并像这样使用它:
?- split([item(1), other(2), other(3), item(4), other(5)], X, Y).
X = [item(1), item(4)],
Y = [other(2), other(3), other(5)].
它甚至不需要 item
s 总是在 other
s 之前。
您可以概括为任何类型的项目
work(item,L) :-
format('args of \'item\' ~w~n', L).
work(other,L) :-
format('args of \'other\' ~w~n', L).
work(anything, L) :-
format('args of \'anything\' ~w~n', L).
work_element(Item) :-
Item =.. [A|L],
work(A, L).
my_split(In) :-
maplist(work_element, In).
例如:
?- my_split([item(a), item(b), item(c), other(d), other(e) , item(f), other(g)]).
args of 'item' a
args of 'item' b
args of 'item' c
args of 'other' d
args of 'other' e
args of 'item' f
args of 'other' g
true