简体   繁体   中英

How to instantiate a variable in prolog predicate

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

I have the following predicate and I wish to determine the size of a list. In the second predicate, when I initially run into the predicate, X is not initialized. How can I check if X has a value before doing an increment it it.

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

X should return 7 in this case

On declarative paradigms, instantiation is not possible (unless you use datafact or something similar), so a way to solve your issue would be by declaring that the empty list has size 0:

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

By that way, you know that the length of a list L is 1+(length of L tail)

In regards to this portion of Your sample code :

X = X + 1

A very common mistake for people new to Prolog . The ``='' in Prolog means "is the same as" . Therefore the code segment above is declaring "X is the same as X + 1" . At the very least , it will have to be :

X = Y + 1

However that is not quite what You need , because :

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

For getting Prolog to put the result of a maths calculation on the right-hand-side into a variable on the left-hand-side , use _lhs_ is _rhs_ .

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

In regards to the question

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

when(ground(_variable_),(_thing_to_do)) is the best of available options .

Here is an example solution to the overall problem posed that utilizes some those concepts .

implementation

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_]  .

testing

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM