Prolog 列表序言中每个元素的事实
我想用Prolog解决这个问题。我想给出一个自然数列表,以查找列表中满足此条件的所有元素:Prolog 列表序言中每个元素的事实,prolog,Prolog,我想用Prolog解决这个问题。我想给出一个自然数列表,以查找列表中满足此条件的所有元素: 它左边的所有元素都比它小,右边的所有元素都比它大。 例如,给出一个列表[3,2,4,1,5,7,8,9,10,8]答案是5,7 到目前为止,我已经设法使这个函数,给定列表中的一个元素,如果该元素满足上述条件,它将返回true或false check(Elem, List) :- seperate(Elem, List, List1, List2), lesser(Elem, List1,
它左边的所有元素都比它小,右边的所有元素都比它大。
例如,给出一个列表[3,2,4,1,5,7,8,9,10,8]
答案是5,7
到目前为止,我已经设法使这个函数,给定列表中的一个元素,如果该元素满足上述条件,它将返回true或false
check(Elem, List) :-
seperate(Elem, List, List1, List2),
lesser(Elem, List1, X1),
bigger(Elem, List2, X2),
size(X1, L1),
size(X2, L2),
size(List, L3),
match(L1, L2, L3),
现在我想做另一个谓词,给定一个列表,它对列表中的每个元素进行上述计算。由于不止一个元素可能满足它,我想创建另一个列表,其中包含满足该问题的所有元素
问题类似于?-谓词名称([3,2,4,1,5,7,8,9,10,8],N)。
结果是元素列表
SRY如果我没有使用Prolog的正确术语,我将用顺序逻辑语言来描述我想要做的更具体的事情,尽管这样想不是一个好主意。如果我们把谓词检查看作是给定列表和元素列表的函数,它将返回真或假,元素是否满足问题的条件。现在我想解析列表中的每个元素,并为每个元素调用函数check。如果返回true,那么我会将该元素添加到另一个列表a.k.a结果中。我想在Prolog中执行此操作,但我不知道如何迭代列表。
我将对该问题采取不同的方法 我们希望找到所有符合“中间”值标准的值,中间值定义为大于列表中所有之前的值,小于列表中所有之后的值 将谓词mid(L,M)
定义为M
是L
的“中间”值:
mid([X|T], X) :- % The first element of a list is a "mid" if...
less(X, T). % it is less than the rest of the list
mid([X|T], M) :- % M is a "mid" of [X|T] if...
mid(T, X, M). % M is a "mid" > X
% (NOTE: first element is not a "mid" by definition)
mid([X|T], LastM, X) :- % X is a "mid" > Y if...
X > LastM, % X > the last "mid"
less(X, T). % X < the rest of the list, T
mid([X|T], LastM, M) :- % Also, M is a "mid" if...
Z is max(X, LastM), % Z is the larger of X and the last "mid"
mid(T, Z, M). % M is the "mid" of T which is > Z
less(X, [Y|T]) :- % X is less than the list [Y|T] if...
X < Y, % X < Y, and
less(X, T). % X < the tail, T
less(_, []). % An element is always less than the empty list
然后可以使用findall
捕获它们:
mids(L, Ms) :-
findall(M, mid(L, M), Ns).
| ?- mids([3,2,4,1,5,7,8,9,10,8], Ms).
Ms = [5,7]
yes
| ?- mids([2], L).
L = [2]
(1 ms) yes
这可能不是计算效率最高的解决方案,因为它没有利用“mid”的两个属性。例如,“mid”将连续聚集在一起,因此一旦找到“mid”,如果随后遇到一个本身不是“mid”的元素,则继续搜索没有意义如果效率是一个目标,那么这些想法可以被运用到逻辑过程中
附录
由于@false提醒了我关于
maplist
,上面的谓词调用less(X,T)
可以被maplist替换(这里是一个使用DCGs的版本,假设我们想要进行算术比较
list_mid(L, M) :-
phrase(mid(M), L).
mid(M) -->
seq(Sm),
[M],
{maplist(>(M),Sm)},
seq(Gr),
{maplist(<(M),Gr)}.
seq([]) -->
[].
seq([E|Es]) -->
[E],
seq(Es).
您的check
关系有三个参数,但您的check2
关系用两个参数调用它。是否希望check
作为变量List2
返回一个只包含一项的列表,即Elem
?您编写的内容测试所有元素的check是否为真。您到底想要什么?不要这样做nk在“做这个做那个”中用“这意味着那个”来描述它@alpha我编辑了这篇文章,我忘记了一个参数。@用户检查工作正常。我不提供任何进一步的信息,因为它实际上做什么并不重要。现在我想做另一个谓词,给定一个列表,它对列表中的每个元素进行上述计算。对照什么列表?你是说,给定一个列表,你想运行c吗对照完整的原始列表对列表中的每个元素进行检查
?然后在检查2
中,如果有什么问题,您想对检查
的结果列表做什么?我找不到文字来感谢您!非常感谢您的时间和精力effort@Mario没问题。用逻辑语言表达问题,很好地映射到prolog goe要找到解决方案还有很长的路要走。mids([2],[2]).
失败。但左侧和右侧的所有元素都较小/较大。@false,是的,这是故意设计的。我不确定OP对极端值的作用。既然您提到了它,应该认为元素大于或小于空列表。我相应地更新了答案。酷(+1)。我正在考虑尝试DCG方法,但没有成功。哎呀,我想你指的是maplist(>(M),Sm)
和maplist(
list_mid(L, M) :-
phrase(mid(M), L).
mid(M) -->
seq(Sm),
[M],
{maplist(>(M),Sm)},
seq(Gr),
{maplist(<(M),Gr)}.
seq([]) -->
[].
seq([E|Es]) -->
[E],
seq(Es).
mid(M) -->
( [M]
| max(Mx),
[M],
{Mx < M}
),
min(M).
max(M) -->
[E],
maxi(E, M).
maxi(E, E) -->
[].
maxi(E, M) -->
[F],
{G is max(F,E)},
maxi(G, M).
min(_) -->
[].
min(M) -->
[E],
{M < E},
min(M).