Prolog是使用静态还是动态范围?

时间:2012-12-07 01:12:22

标签: prolog

当我在创建Prolog列表后运行查询时,Prolog如何使用范围来解决它?我知道剪切运算符!会影响结果。它是通过影响范围来实现的吗?

1 个答案:

答案 0 :(得分:2)

首先要做的事情是:prolog是否使用动态范围?不,它没有,并且之所以没有,是因为prolog需要跟踪定义的变量,因此任何新的赋值都将引用初始变量 - 而不是分配给该变量名的最后一个值。

另一方面,Bash使用动态范围,因此,在i循环中使用变量for,在另一个函数中使用变量i,这恰好发生在在循环执行期间调用 - 或者不调用 - 将影响彼此的i值。

这可能不是很简单,所以,举个例子:

#!/bin/bash
function my_first_I() {
    I=10;
}
function my_second_I() {
    I=100;
}

I=1; echo $I;
my_first_I; echo $I;
my_second_I; echo $I;

输出:

$ ./script.sh
1
10
100

这里的诀窍是变量正在搞乱一个与众不同的变量。

现在,正如您可能已经意识到的那样,您无法在prolog中进行此操作:

#!/usr/bin/swipl
my_first_I(I) :- I is 10.
my_second_I(I) :- I is 100.

test(I) :-
    I is 1,
    write(I), nl,
    my_first_I(_),
    write(I), nl,
    my_second_I(_),
    write(I), nl.

输出:

?- test(I).
1
1
1
I = 1.

这个例子只是简单地指出,在prolog中,变量是在它自己的局部范围内定义的,没有泄漏到另一个函数的定义中。

现在,第二部分:!如何运作? Prolog生成的逻辑编程解决方案是在应用unification algorithm之后得出的。在此过程中,树状结构以DFS方式构建,根据变量可能假设的值对语句执行评估。在每次叶级扩展之后,Prolog会回溯到下一次可用的扩展。

如果找到!,则会停止广度扩展,切断本地解决方案的其他可能值,并且只执行树中更深层次的扩展。 Here!运算符的一种非常简单的用法。