Prolog 如何基于元素类型断言列表中的元素

Prolog 如何基于元素类型断言列表中的元素,prolog,meta-predicate,Prolog,Meta Predicate,给出了格式列表 [item(a), item(b), item(c), other(d), other(e) ...] 如果项目的数量不是固定的,其他项目的数量也不是固定的,但是项目总是在其他项目之前,那么如何分割列表,以便将项目和其他项目传递到不同的谓词中 我一直在试图找到根据元素分割列表的方法,但找不到这样做的方法 我需要编写一个谓词来获取此列表,然后将这些项传递给itempedite,将其他项传递给otherPredicate 如果我能提供任何其他信息,请告诉我。让我们从一个谓词开始对元

给出了格式列表

[item(a), item(b), item(c), other(d), other(e) ...]
如果项目的数量不是固定的,其他项目的数量也不是固定的,但是项目总是在其他项目之前,那么如何分割列表,以便将项目和其他项目传递到不同的谓词中

我一直在试图找到根据元素分割列表的方法,但找不到这样做的方法

我需要编写一个谓词来获取此列表,然后将这些项传递给
itempedite
,将其他项传递给
otherPredicate


如果我能提供任何其他信息,请告诉我。

让我们从一个谓词开始对元素进行分类。那怎么办

item_t(item(_), true).
item_t(other(_), false).
注意,这个谓词的真值有一个额外的参数。它只接受
项()
其他()
元素。如果出现类似于
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\u3
,更加美观:

takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|Es], Fs0) :-
   if_( call(P_1, E)
      , ( Fs0 = [E|Fs], takeWhilet(P_1, Es, Fs) )
      , Fs0 = [] ).

现在,我们可以定义
其他\u t/2
类似地…

让我们从一个谓词开始对元素进行分类。那怎么办

item_t(item(_), true).
item_t(other(_), false).
注意,这个谓词的真值有一个额外的参数。它只接受
项()
其他()
元素。如果出现类似于
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\u3
,更加美观:

takeWhilet(_P_1, [], []).
takeWhilet(P_1, [E|Es], Fs0) :-
   if_( call(P_1, E)
      , ( Fs0 = [E|Fs], takeWhilet(P_1, Es, Fs) )
      , Fs0 = [] ).

现在,我们可以定义
other\u t/2
类似地…

一个简单的拆分谓词,将
项(
其他(
分开,可以如下工作:

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之前。

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

您可以推广到任何类型的项目

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

欢迎任何改进。为了避免我忘记哈斯克尔的前奏曲,欢迎任何改进。还有,为了避免我忘记Haskell的前奏曲。如果
其他
参数是相同类型的列表,即项目和其他,您可以如何修改此参数?我不确定您想要实现什么。可能会给出一个输入和输出示例和/或针对已更改的场景提出一个新问题。如果
其他
参数是相同类型的列表(即项目和其他),您将如何修改此问题?我不确定您想要实现什么。可能会给出一个输入和输出示例和/或针对已更改的场景提出一个新问题。