如何在prolog谓词中实例化变量

时间:2019-03-03 18:13:01

标签: prolog predicate

list([]) :- !.
list([A|B], X) :- X = X + 1, list(B, X).

我有以下谓词,我希望确定列表的大小。在第二个谓词中,当我最初遇到该谓词时,X未初始化。在递增X之前,如何检查X是否具有值。

?-list([a,b,c,d,e,f,g],X).

在这种情况下,X应该返回7

2 个答案:

答案 0 :(得分:0)

在声明式范例中,无法实例化(除非您使用datafact或类似的东西),因此解决问题的一种方法是声明空列表的大小为0:

list([],0) :- !.
list([A|B], X1) :- list(B, X0), X1 = X0 + 1.

通过这种方式,您知道列表 L 的长度为 1 +( L 尾部的长度)

答案 1 :(得分:-1)

关于您的示例代码的这一部分:

X = X + 1

对于Prolog新手来说,这是一个非常常见的错误。 Prolog中的``=''表示“与”相​​同。 因此,上面的代码段声明“ X与X + 1相同”。 至少必须是:

X = Y + 1

但是那不是您真正需要的,因为:

?- Y = 2 , X = Y + 1  .
X = Y + 1
Y = 2

要使Prolog将右侧的数学计算结果放入左侧的变量中,请使用_lhs_ is _rhs_

?- Y = 2 , X is Y + 1  .
X = 3
Y = 2

关于这个问题

How can I check if X has a value before doing an increment to it.

when(ground(_variable_),(_thing_to_do))是最好的可用选项。

以下是利用某些概念解决整体问题的示例解决方案。

实现

goal_expansion((_lhs_ =:= _rhs_),(when(ground(_rhs_),(_lhs_ is _rhs_))))  .

:- op(2'1,'yfx','list')  .

_list_ list [size:_size_] :-
_list_ list [size:_size_,shrink:_shrink_] ,
_list_ list [size:_size_,shrink:_shrink_,size:_SIZE_]  .

_list_ list [size:0,shrink:false]  .

_list_ list [size:_size_,shrink:true] :-
when(ground(_size_),(_size_ > 0))  .

[] list [size:0,shrink:false,size:0] .

[_car_|_cdr_] list [size:_size_,shrink:true,size:_SIZE_] :-
(_SIZE_ =:= _size_ - 1) ,
(_size_ =:= _SIZE_ + 1) ,
_cdr_ list [size:_SIZE_]  .

测试

/*
   ?- L list Z .
L = [],
Z = [size:0] ? ;
L = [_A],
Z = [size:1] ? ;
L = [_A,_B],
Z = [size:2] ? ;
L = [_A,_B,_C],
Z = [size:3] ?
yes

   ?- L list [size:0] .
L = [] ? ;
no
   ?- L list [size:1] .
L = [_A] ? ;
no
   ?- L list [size:2] .
L = [_A,_B] ? ;
no

   ?- [] list [size:S] .
S = 0 ? ;
no
   ?- [a] list [size:S] .
S = 1 ? ;
no
   ?- [a,b] list [size:S] .
S = 2 ? ;
no
   ?- [a,b,c] list [size:S] .
S = 3 ? ;
no
   ?- 
*/