我在Prolog中思考困难。这句话的错误是什么:
numberList([], 0).
numberList([H|T], Limit) :-
H is Limit,
numberList(T, Limit - 1).
我想
?- numberList(X,Limit).
将[Limit, Limit-1 ... 1]
确定为Limit的给定值的唯一解,即
?- numberList(X, 100).
会产生X = [100, 99, 98, ..., 1].
。
我的猜测是,我的理解存在一些非常错误,因为这不能起作用。我不一定要求解决我想要做的事情,我只想理解为什么我的第一次尝试是错误的。
答案 0 :(得分:3)
潜伏在这里有两个主要问题:
1-您在正确的地方获得统一和算术运算很麻烦
2-你没有检查你的输入
关于1- (is)/2
的备注用于执行算术,例如,它将1
减去Limit
。 (is)/2
可以但不应该用于将变量统一到已经评估的算术表达式。 (=)/2
应该优先考虑(统一)。
关于2-的备注,即使你使运算符正确,你的程序也会循环。稍后会详细介绍。
只需自己切换操作员就不会获得太多收益,所以这是正确的方法:
numberList([], 0).
numberList([Limit|T], Limit) :-
NewLimit is Limit - 1,
numberList(T, NewLimit).
在这里你可以看到我在第二个条款的头部隐含地使用统一,另一种方式是将它放在下面:
numberList([], 0).
numberList([H|T], Limit) :-
H = Limit,
NewLimit is Limit - 1,
numberList(T, NewLimit).
但现在,正如您通过尝试此程序所看到的那样,它会找到一个正确的解决方案,但如果您要求另一个;
,则会循环。
原因可能更难以发现初学者的眼睛:当Prolog成功并返回解决方案时,它只能通过探索执行期间留下的选择点来找到新的解决方案。在此,唯一的选择点是Limit
为0
时。因此它会尝试第二个子句而不是第一个子句,然后循环直到达到NegativeInfinity
。可悲的是,由于到达那里的行程很长,所以之前会溢出。这个问题的解决方案是为第二个子句添加一个保护,指定Limit
应该大于0
或者为第一个子句添加一个切口甚至更好:两者都做。问你自己是否有麻烦!
答案 1 :(得分:0)
"限制 - 1"正在被认为是一个函数调用,用C语言,它可以工作。它要求/命令Prolog"找到一个减法函数,用Limit-variable和1"来调用它。它要求Prolog理解"限制 - 1"作为函数调用结果,但Prolog理解"限制 - 1"作为复合项减法(Limit,1),它是来自一阶逻辑的谓词
" H是限制"这也被认为是函数调用
Prolog没有功能(???),我认为这个说法对C人来说是一个很大的障碍。而不是函数(与C等一样,与数学一样),Prolog有谓词(如谓词逻辑,一阶等)
Function是命令微处理器的命令。相反,谓词将数据呈现给微处理器,以便用微处理器的眼睛看,将数据呈现给微处理器以进行感知。
谓词描述一个世界,描述该世界中对象之间的某些关系,微处理器试图验证这些关系。微处理器试图证明这些关系确实存在于它的知识中。这些关系可以在其知识中多次存在,因此微处理器可以返回多个结果(又称非确定性)
Prolog是一种很棒的编程语言,可能我应该写出精彩的描述语言,梦幻般的模式识别语言,梦幻般的推理/演绎语言(简单的推理/演绎,它不是一种"人工智能",数字电子逻辑门中的推论/推论)。我以前是一个渴望的Visual Studio程序员,但我已经研究了Prolog几年了。C语言等用于命令,Prolog语言等用于描述。