Давайте начнем с предиката для классификации элементов. Как насчет
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
аналогично ...