Prolog:第一个重复值

编程入门 行业动态 更新时间:2024-10-21 19:44:02
本文介绍了Prolog:第一个重复值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我需要在列表中找到第一个重复值.

prep(3,[1,3,5,3,5]).应该是真的.

prep(5,[1,3,5,3,5]).应该是假的.

我想检查当前值和以前的列表成员是否相等,直到找到重复项,如果找到一个,它将测试与 X 是否相等,但我不知道如何在 Prolog 中做到这一点!

感谢您的帮助!谢谢

解决方案

这是一个使用 dif/2 实现声音不等式的纯版本.dif/2 由 B-Prolog、YAP-Prolog、SICStus-Prolog 和 SWI-Prolog 提供.

firstdup(E, [E|L]) :-成员(E,L).firstdup(E, [N|L]) :-非成员(N,L),第一dup(E,L).成员(E,[E|_L]).成员(E,[_X|L]):-成员(E,L).非成员(_E,[]).非成员(E,[F|Fs]):-差异(E,F),非成员(E,Fs).

优点是它也可以用于更一般的查询:

?- firstdup(E, [A,B,C]).E = A,A = B;E = A,A = C;E = C,B = C,差异(A,C);错误的.

在这里,我们得到三个答案:A 是前两个答案的副本,但有两个不同的理由:A 可能等于 B 或 C.在第三个答案中,B 是重复的,但只有当 C 与 A 不同时才会重复.

要理解定义,请阅读 :- 作为箭头 ←所以右边是你知道的,左边是你得出的结论.在开始的时候读那个方向的谓词通常会有点烦人,毕竟你可能很想遵循执行线程".但通常这条线索无处可去 –它变得太复杂而无法理解.

第一条规则如下:

如果E是列表L的一个元素,我们得出[E|L]有E 作为第一个副本.

第二条规则如下:

提供的E是L的第一个副本(不要惊慌说我们不知道...) 并且假设 N 不是 L 的元素,我们得出结论 [N|L] 具有 E 为第一次复制.

member/2 谓词在许多 Prolog 系统中提供,non_member(X,L) 可以定义为 maplist(dif(X),L).因此,人们会将 firstdup/2 定义为:

firstdup(E, [E|L]) :-成员(E,L).firstdup(E, [N|L]) :-地图列表(差异(N),L),第一dup(E,L).

I need to find the first duplicate value in a list.

prep(3,[1,3,5,3,5]). Should be true.

prep(5,[1,3,5,3,5]). Should be false.

I thought checking for equality with the current value and the previous list members until I find a duplicate, if it finds one it will test for equality with X but I have no idea how to do that in Prolog!

I appreciate any help! Thanks

解决方案

Here is a pure version using dif/2 which implements sound inequality. dif/2 is offered by B-Prolog, YAP-Prolog, SICStus-Prolog and SWI-Prolog.

firstdup(E, [E|L]) :- member(E, L). firstdup(E, [N|L]) :- non_member(N, L), firstdup(E, L). member(E, [E|_L]). member(E, [_X|L]) :- member(E, L). non_member(_E, []). non_member(E, [F|Fs]) :- dif(E, F), non_member(E, Fs).

The advantages are that it can also be used with more general queries:

?- firstdup(E, [A,B,C]). E = A, A = B ; E = A, A = C ; E = C, B = C, dif(A, C) ; false.

Here, we get three answers: A is the duplicate in the first two answers, but on two different grounds: A might be equal to B or C. In the third answer, B is the duplicate, but it will only be a duplicate if C is different to A.

To understand the definition, read :- as an arrow ← So what is on the right-hand side is what you know and on the left is what you conclude. It is often in the beginning a bit irritating to read predicates in that direction, after all you might be tempted to follow "the thread of execution". But often this thread leads to nowhere – it gets too complex to understand.

The first rule reads:

Provided E is an element of list L we conclude that [E|L] has E as first duplicate.

The second rule reads:

Provided E is the first duplicate of L (don't panic here and say we don't know that ...) and provided that N is not an element of L we conclude that [N|L] has E as first duplicate.

The member/2 predicate is provided in many Prolog systems and non_member(X,L) can be defined as maplist(dif(X),L). Thus one would define firstdup/2 rather as:

firstdup(E, [E|L]) :- member(E, L). firstdup(E, [N|L]) :- maplist(dif(N), L), firstdup(E, L).

更多推荐

Prolog:第一个重复值

本文发布于:2023-11-22 06:16:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1616290.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:第一个   Prolog

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!