Prolog - 功能?常量?

时间:2014-10-20 10:00:59

标签: prolog

我正在prolog工作,碰到了一些我还没有真正掌握的东西。 无变量和常量符号和函数的工作,例如:

test(a,T) :- /* change constant a, put result in T */
test(b,T) :- /* change constant b, put result in T */
test(f(X,Y),T) :- /* change function f and possibly the terms X and Y */

这可行吗?我真的不明白这些非变量的putitng方式,如果有人能提供见解,我会很高兴,提前谢谢!

2 个答案:

答案 0 :(得分:3)

通过@mat添加答案:

与传统的命令式语言一样,你并没有真正的常量与变量。您有条款,就其绑定而言,条款可以是:

  • 尚未设定值的条款,也称为未绑定变量
  • 完全绑定的术语,意味着它们不包含任何仍未绑定的元素,也称为 ground 术语
  • 甚至部分绑定条款

顶层的几个例子:

?- X = Y.
X = Y.

X和Y现在都是相同的未绑定变量术语。

?- 3 = X.
X = 3.

X的值绑定为3.

?- X = foo(a, b).
X = foo(a, b).

X与复合词foo(a, b)绑定。 X现在是#34; ground":

?- X = foo(a, b), ground(X).
X = foo(a, b).

?- X = foo(Y, b).
X = foo(Y, b).

X绑定到部分术语foo(Y, b)。这里的Y是一个未绑定的变量。如果您询问X是否为地,则查询失败:

?- X = foo(Y, b), ground(X).
false.

谓词可以描述术语之间的关系。例如,内置谓词plus/3描述了以下关系:

?- plus(1, 2, 3).
true.

?- plus(1, 2, X).
X = 3.

?- plus(X, 2, 4).
X = 2.

现在到最后一个示例:您在test(f(X,Y), T)中,f(X,Y)不是函数:它是一个带有arity 2的复合词,因此,f/2。您可以对其进行评估,就好像它是谓词一样,或者以某种方式对其进行更改以在第二个参数中获得不同的术语。例如,要切换参数顺序:

switch(f(X, Y), f(Y, X)).

通过这种方式,您可以提出以下查询:

?- switch(f(1,2), T).
T = f(2, 1).

?- switch(T, f(a,b)).
T = f(b, a).

?- switch(f(1,X), T), X = foo(bar, baz).
X = foo(bar, baz),
T = f(foo(bar, baz), 1).

因此,如果您想要一个非常人为的谓词foo(X, Y),其定义如下:

  • 如果X为a且Y为aa
  • ,则为true
  • 如果X是b而Y是bbb
  • 如果X是复合词f/2,则Y是复合词g/2,其中f/2的参数的顺序被切换。

实现:

foo(a, aa).
foo(b, bbb).
foo(f(A, B), g(B, A)).

部分绑定的术语,也称为部分数据结构,带有"孔"在它们中,有许多不同的用途。实现先进先出队列的一种天真的方式可能是:

% empty_queue(Q) creates an emtpy queue
empty_queue(q(Q,Q)).

% enqueue(Q0, X, Q) enqueues X to the queue Q0, resulting in Q
enqueue(q(Front, [X|Back]), X, q(Front, Back)).

% dequeue(Q0, X, Q) dequeues X from the queue Q0, resulting in Q
dequeue(q([X|Front], Back), X, q(Front, Back)).

你可以亲眼看看它是如何工作的,以及如何打破它(尝试将你尚未排队的元素出列!)。有更好的方法来建立队列,但这只是为了说明如何使用部分数据结构。如果您仅通过这三个谓词(empty_queue/1enqueue/3dequeue/3)使用队列术语,那么"返回"将永远是一个自由变量。

您需要提出更具体的问题,以获得比此更具体的答案。

答案 1 :(得分:2)

您必须考虑不同变量之间的关系

因此,如果要定义旧值和新值之间的转换,则需要一个额外的参数:

state0_state(OldState, NewState) :- NewState = <define yourself> .

这种关系的优点在于它们通常可以在所有方向上使用:例如,您可以使用它们来询问:哪些旧状态会产生特定的新状态?或者更一般地说:哪些过渡是可能的?