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
答案 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
?-
*/