2013-11-01 3 views
1

Я искал по всему Интернету и по StackOverflow для ответа, но я понятия не имею. Я действительно не понимаю, как использовать Prolog, и я считаю, что это действительно запутывает. У меня есть решения в моей голове, но не могу написать их в Prolog, что очень расстраивает. Я застрял на первом этапе своего проекта.Ассоциированный список с именем

Мне нужно указать факт, который связывает имя со списком, поэтому мне не нужно вводить список каждый раз, когда я хочу что-то делать с ним.

, например:

list(a, [1,2,3]). 

тогда, когда я использую a в предикате, параметром является список. Я не имею понятия, как это сделать, я уже есть предикат, который работает, когда я называю это как

predicate([1,2,3]). 

но когда я называю его

predicate(a). 

Это не работает. Я думаю, что он не работает, потому что он обрабатывает a как параметр, который не имеет ничего общего с этим списком, поэтому я хочу знать, объявляет ли факт, что list(a, [1,2,3]). связывает a со списком или мне нужно что-то делать? Заранее спасибо

ответ

1

a - атом, основной тип данных, а не переменная со значением вашего списка. Также нет функционального синтаксиса в ваниле. Пролог: a никогда не будет оценен и заменен каким-либо другим значением. Если мы хотим, чтобы предикат сгенерировал или сохранил значение, мы делаем это, вызывая предикат с переменной и привязывая переменную к одному из аргументов предиката.

Если вы хотите вызвать список [1,2,3], вы бы просто включить факт утверждающий этот список:

a([1,2,3]). 

Затем, если вы хотите запросить предикат с участием этого списка

?- a(L), length(L, N). 

Сначала мы объединяем переменную L со значением, определяемым предикатом a/1 (что означает «a, который является предикатом 1-арий»), затем мы просим объединить длину L с переменной N.

Если вы хотите назвать списки с разными указателями, как указано предикатом list/2, который вы написали выше, вы можете сделать это, только вы вспомните значения по-другому, чем вы пытаетесь. Учитывая эти факты,

list(a, [1,2,3]). 
list(b, [3,2,1]). 

?- list(a, X), list(b, Y). 
X = [1, 2, 3], 
Y = [3, 2, 1]. 

Примечания: В SWI-Prolog, при взаимодействии с верхним уровнем мы можем присоединять $ к имени переменного, чтобы напомнить, что это последнее проиллюстрированное значение. Так что, если мы уже запускались выше запрос, мы можем вспомнить последнее значение L для других целей:

?- reverse($L, ReversedL). 
+1

Остерегайтесь: $ L работает только для «малых» (неуказанных) структур данных – CapelliC

1

Вы должны научиться Prolog базового синтаксиса, поскольку он имеет некоторые принципиальные отличия WRT других языков. Поскольку у вас есть базовое, я не продаю вам ничего «волшебного», но вот пример немного синтаксического сахара, который я приготовил для личного использования.

1 ?- [lifter]. 
% lifter compiled into lifter 0.08 sec, 12 clauses 
true. 

2 ?- [user]. 
|: a([1,2,3]). 
% user://1 compiled 0.01 sec, 2 clauses 
true. 

3 ?- reverse(a(°),L). 
L = [3, 2, 1]. 

Атом ° это «атлет»: запрос-выше трансформируются читать

?- a(X), reverse(X,L). 

Я не использую часто мой лифтер модуля, потому что это делает код более трудным для отладки , а синтаксическое усиление довольно мало ...

Пакеты SWI-Prolog предлагают альтернативу (извините, я никогда не использовал его ...): см. пакет func. Используете ли вы SWI-Prolog, вы можете попробовать его с помощью? - pack_install (func).

+0

Это замечательно! Я играл с написанием собственного функционального сахара (просто для удовольствия и практики, но также потому, что мне не нравится внешний вид синтаксиса пакетов func), и я шел по пути расширения '+ func (X) ', вызывая' func (X, Y) 'и заменяя первое значение Y. Конечно, это работает только с предикатами функции, которые имеют конечный выходной аргумент. Но мне нравятся ваши обозначения, потому что, я полагаю, это также позволит вам выбрать любую переменную для замены функтора? Так, например, 'plus (plus (°, 1,2), 1, 2) .' было бы правдой? Мне было бы интересно увидеть код вашего сахара. –

+0

@aBathologist: да, лифт позволяет снимать любые аргументы. Это эволюция первоначальной попытки, очень похожей на вашу. Я положу его на github и опубликую ссылку. – CapelliC

+0

@aBathologist: Я загрузил его на [github] (https://github.com/CapelliC/prolog-snippets) – CapelliC

0

Вот два способа привязать ваш список к переменной. Первый - это предопределенный факт, когда содержание факта «a» унифицировано/помещено в переменную «A» - переменные примечания должны начинаться в верхнем регистре.

Второй способ - просто определить переменную, содержащую список, как указано в «B» ниже.

Цель предиката 'useit' ниже - просто показать, что переменная может быть передана и использована .. в этом случае отображаются оба списка.

% predefined fact 
a([1,2,3]). 

useit(MyList) :- 
    write(MyList). 

declareit :- 

    % declare variable 'A' from fact 'a' 
    a(A), 
    useit(A), 

    % Declare B in real time, possibly from prior computation 
    B = [3,4,5], 
    useit(B). 


?- declareit. 
[1,2,3][3,4,5] 
true. 
Смежные вопросы