функция пролог, возвращающая ячейки памяти вместо значений - PullRequest
1 голос
/ 28 марта 2012

только что начал программировать с прологом, и у меня возникло несколько проблем.Предполагается, что моя функция принимает значение X и копирует его N раз в M. Моя функция возвращает список из N номеров ячеек памяти.Вот код, есть идеи?

duple(N,_,M):- length(M,Q), N is Q.
duple(N,X,M):- append(X,M,Q), duple(N,X,Q).

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

Это не адреса памяти.Это свободные переменные.То, что вы видите, это их внутренние имена в выбранной вами прологической системе.Тогда, как указал @chac (+1 между прочим), третье предложение не имеет смысла!Возможно, вы можете попытаться рассказать нам, что вы имели в виду, чтобы мы могли пролить свет на то, как это правильно сделать.

Я собираюсь дать вам две реализации вашего предиката, чтобы попытаться показать вам правильный синтаксис Prolog:

duple1(N, X, L) :-
    length(L, N),
    maplist(=(X), L).

Здесь, в вашем предикате duple1/3, мы говорим прологу, что длина результирующего списка L равна N, и затем мы говорим ему, что каждый элемент L должен бытьобъединяется с X для предиката для хранения.

Еще один способ сделать это - создать результирующий список "вручную" с помощью рекурсии:

duple2(0, _X, []).
duple2(N, X, [X|L]) :-
    N > 0,
    NewN is N - 1,
    duple1(NewN, X, L).

Хотя, обратите внимание, потому что мы используем>/2, is и -/2, то есть арифметика, мы запрещаем прологу использовать этот предикат несколькими способами, такими как:

?- duple1(X, Y, [xyz, xyz]).
X = 2,
Y = xyz.

Это работало раньше, в нашем первом предикате!

Надеюсь, это помогло.

2 голосов
/ 28 марта 2012

Полагаю, вы называете свой предикат, например, так:

?- duple(3,xyz,L).

и вы получите

L = [_G289, _G292, _G295] ;
ERROR: Out of global stack

Если вы попробуете

?- length(X,Y).
X = [],
Y = 0 ;
X = [_G299],
Y = 1 ;
X = [_G299, _G302],
Y = 2 ;
X = [_G299, _G302, _G305],
Y = 3 ;
X = [_G299, _G302, _G305, _G308],
Y = 4 .
...

Вы можете видеть, что происходит:

Ваш запрос будет соответствовать указанному *M*, отображая список из M неустановленных переменных (ячеек памяти), затем продолжайте возвращаться и генерировать еще более длинные списки, пока не останется место в стеке. Ваше второе правило никогда не сработает (и я не очень понимаю его цель).

Генератор проще написать так:

duple(N,X,M) :- findall(X,between(1,N,_),M).

тест:

?- duple(3,xyz,L).
L = [xyz, xyz, xyz].
...