我正在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方式,如果有人能提供见解,我会很高兴,提前谢谢!
答案 0 :(得分:3)
通过@mat添加答案:
与传统的命令式语言一样,你并没有真正的常量与变量。您有条款,就其绑定而言,条款可以是:
顶层的几个例子:
?- 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)
,其定义如下:
a
且Y为aa
或b
而Y是bbb
或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/1
,enqueue/3
,dequeue/3
)使用队列术语,那么"返回"将永远是一个自由变量。
您需要提出更具体的问题,以获得比此更具体的答案。
答案 1 :(得分:2)
您必须考虑不同变量之间的关系。
因此,如果要定义旧值和新值之间的转换,则需要一个额外的参数:
state0_state(OldState, NewState) :- NewState = <define yourself> .
这种关系的优点在于它们通常可以在所有方向上使用:例如,您可以使用它们来询问:哪些旧状态会产生特定的新状态?或者更一般地说:哪些过渡是可能的?