Как создать переменную в предикате пролога - PullRequest
0 голосов
/ 03 марта 2019
list([]) :- !.
list([A|B], X) :- X = X + 1, list(B, X).

У меня есть следующий предикат, и я хочу определить размер списка.Во втором предикате, когда я изначально сталкиваюсь с предикатом, X не инициализируется.Как я могу проверить, имеет ли X значение, прежде чем делать его приращение.

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

X должен вернуть 7 в этом случае

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

В отношении этой части вашего примера кода:

X = X + 1

Очень распространенная ошибка для новичков в Прологе.`` = '' В Прологе означает «то же, что и».Следовательно, приведенный выше фрагмент кода объявляет «X такой же, как X + 1».По крайней мере, это должно быть:

X = Y + 1

Однако это не совсем то, что вам нужно, потому что:

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

Для того, чтобы Пролог поставил результат математикивычисление справа в переменную слева, используйте _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
   ?- 
*/
0 голосов
/ 04 марта 2019

В декларативных парадигмах инстанцирование невозможно (если вы не используете datafact или что-то подобное), поэтому для решения вашей проблемы можно было бы объявить, что пустой список имеет размер 0:

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

ByТаким образом, вы знаете, что длина списка L равна 1 + (длина хвоста L )

...