Как предикаты элементов в списке на основе типа элемента - PullRequest
0 голосов
/ 04 марта 2020

Учитывая список формата,

[item(a), item(b), item(c), other(d), other(e) ...]

, где число элементов не является фиксированным, равно как и число других, но элементы всегда предшествуют другим, как мне разбить список так, чтобы Я могу передать элементы и другие в разные предикаты.

Я пытался найти способы разбить список на основе элементов, но не могу найти способ сделать это.

Мне нужно написать предикат, который возьмет этот список, а затем передать элементы itemPredicate, а остальные - otherPredicate.

Если есть какая-либо другая информация, которую я могу предоставить, пожалуйста, дайте мне я знаю.

Ответы [ 3 ]

2 голосов
/ 04 марта 2020

Давайте начнем с предиката для классификации элементов. Как насчет

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 аналогично ...

1 голос
/ 04 марта 2020

Простой предикат разделения, который отделяет 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.

0 голосов
/ 04 марта 2020

Вы можете обобщить любой тип элементов

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
...