List 检查连续元素之间的差异是否相同

List 检查连续元素之间的差异是否相同,list,prolog,List,Prolog,我不熟悉在Prolog中使用算术 我做过一些小程序,但大部分都涉及逻辑。我试图实现一个函数,如果每个连续元素对之间的差异相同或不相同,该函数将返回true或false 我的输入如下:sameseqdiff([3,5,7,9],2) 我觉得我需要从列表中拆分前两个元素,找出它们的差异,然后将结果添加到新列表中。处理完所有元素后,检查新列表中的元素是否都相同 我已经学过一些Prolog如何建立关系和查询这些关系,但这似乎不适合Prolog 更新1:这就是我到目前为止想到的。我对这种语法是全新的,代码

我不熟悉在Prolog中使用算术

我做过一些小程序,但大部分都涉及逻辑。我试图实现一个函数,如果每个连续元素对之间的差异相同或不相同,该函数将返回
true
false

我的输入如下:
sameseqdiff([3,5,7,9],2)
我觉得我需要从列表中拆分前两个元素,找出它们的差异,然后将结果添加到新列表中。处理完所有元素后,检查新列表中的元素是否都相同

我已经学过一些Prolog如何建立关系和查询这些关系,但这似乎不适合Prolog

更新1:这就是我到目前为止想到的。我对这种语法是全新的,代码中仍然有一个错误,但我希望它能传达出我所要做的事情的总体想法

diff([X,Y|Rest], Result):-
    diff([Y,Z|Rest], Result2):-
       Result2 = Result,
       Z - Y = Result.
更新2:我知道我在这段代码上还有很多事情要做,但我会一直呆到这个周末,我还有其他事情要做。我想我更了解它的逻辑,我想我需要弄清楚只有在列表的其余部分至少还有两件事情要处理时,如何运行函数的最后一行

diff([X,Y|Rest], Result):-
    number(Y),
    Y-X=Result,
    diff([Rest], Result).
更新3:我相信我有我想要的功能。我注意到的唯一一个怪癖是,当我运行并输入如下内容时:
sameSeqDiffs([3,5,7],2)。
我会立即返回true,然后返回false。这是正确的操作还是我仍然遗漏了什么

sameSeqDiffs([X,Y], Result):-
    A is Y - X,
    A = Result.

sameSeqDiffs([X,Y,Z|T], Result):-
    sameSeqDiffs([Y,Z|T], Result).
更新4:我发布了一个关于这个的新问题……下面是链接:

Prolog的语法 语法有点错误:通常一个子句有一个类似于
foo(X,Y,Z)
,然后是一个箭头(
:-
),后面是一个主体。该正文通常不包含任何箭头
:-
。所以第二个箭头
:-
没有多大意义

谓词与统一 其次,在Prolog中,谓词没有输入或输出,谓词是
true
false
(它也可能出错,或陷入无限循环,但这是我们想要避免的典型行为)。它通过统一变量来传达答案。例如,调用
sameseqdiff([3,5,7,9],X)
。可以通过将
X
2
统一来成功,然后谓词(如果正确实现)将返回
true。

归纳定义 为了设计谓词,on通常首先要给出一个归纳定义:一个由一个或多个基本情况和一个或多个“递归”情况组成的定义(谓词由其自身的一部分定义)

例如,这里我们可以说:

(基本情况)对于正好包含两个元素的列表
[X,Y]
,谓词
相同的条件([X,Y],D)
成立,因为
D
Y
X
之间的差异

在Prolog中,这将类似于:

sameSeqDiffs([X, Y], D) :-
    ___.
sameSeqDiffs([X, Y, Z|T], D) :-
    ___,
    sameSeqDiffs(___, ___).
(需要填写

现在对于归纳的情况,我们可以根据自身定义一个
sameSeqDiffs/2
,当然参数不同。在数学中,有时定义函数f,例如f(i)=2×f(i-1);例如f(0)=1作为基数。我们可以用类似的方式为
sameSeqDiffs/2
定义归纳情况:

(归纳情况)对于两个以上元素的列表,列表中的所有元素具有相同的差异,前提是前两个元素具有差异
D
,并且在除第一个元素之外的元素列表中,所有元素也具有该差异
D

在Prolog中,这将类似于:

sameSeqDiffs([X, Y], D) :-
    ___.
sameSeqDiffs([X, Y, Z|T], D) :-
    ___,
    sameSeqDiffs(___, ___).
Prolog中的算术 开始用Prolog编程的人常犯的一个错误是,他们认为,就像在许多编程语言中一样,Prolog给某些函子添加了语义

例如,人们可以认为
A-1
将减少
A
。然而,对于Prolog来说,这只是
-(A,1)
,它不是减号,或者其他任何东西,只是一个函子。因此,Prolog不会对这些表达式求值。所以如果你写
X=A-1
,那么
X
就是
X=-(A,1)

那么我们如何进行数值运算呢?Prolog系统有一个谓词
is/2
,它通过将语义附加到右侧来计算右侧。因此,
is/2
谓词将解释这个
(+)/2
(-)/2
,等等。函子(
(+)/2
为加号,
(-)/2
为减号,等等)

因此,我们可以计算如下表达式:

A = 4, is(X, A - 1).
然后
X
将设置为
3
,而不是
4-1
。Prolog还允许编写
is
中缀,如:

A = 4, X is A - 1.

在这里,您需要计算两个元素之间的差异。

您的第二次尝试非常接近。应该是的

samediffs([X,Y | Rest],Result):-
结果是Y-X,
samediffs([Y | Rest],Result)。
您甚至不需要“从列表中拆分前两个元素”。这会自行解决的

怎么做?简单:调用
samediffs(List,D)
,在谓词的第一个条目上,通过调用
结果为Y-X
将尚未实例化的
D=Result
实例化为列表中第二个和第一个元素之间的计算差

在谓词的每个后续条目上,也就是说,对于列表中的每个后续元素对
X
Y
,调用
的结果是Y-X
将计算该对元素的差值,并将检查其数值相等性和
结果
,此时该结果保持先前计算的值

如果它们不相等,谓词将失败

如果是,递归