Как мне получить список из списка ассоциаций в Прологе, а затем либо добавить к нему, либо создать его, если он не существует?

Извиняюсь за запутанный заголовок, но суть того, что я пытаюсь сделать, заключается в том, что у меня есть хеш-таблица/список ассоциаций с кучей ключей, каждый из которых соответствует списку.

Моя проблема заключается в том, что я в основном хочу создать предикат, который добавляет элемент в список по ключу, но этот ключ может даже не иметь созданного списка (вся пара ключ- > значение может даже не существовать), и я не знаю, как сказать get_assoc, но если списка нет, создайте его, а затем добавьте, в противном случае просто добавьте его в список, возвращенный из get_assoc.

Итак, как мне создать список, если он еще не существует? Я не уверен, рассматриваю ли я эту проблему с точки зрения Пролога, поэтому не стесняйтесь указывать мне в этом направлении, если это необходимо.


person Doug Smith    schedule 17.09.2015    source источник
comment
Похоже, ваша более фундаментальная проблема заключается в том, что вы не знаете, как вы хотите представить свою хэш-таблицу? Вы не показали, как выглядит ваша хеш-таблица.   -  person lurker    schedule 17.09.2015
comment
Сначала решите, что вам понадобится: хэш-таблица, RB-дерево, AVL-дерево. Затем проверьте, доступны ли они уже в библиотеке. В SWI-Prolog у вас есть (вместе с полным исходным кодом) как минимум RB-деревья (отслеживаемые и неотслеживаемые) и AVL-дерево в стандартной библиотеке.   -  person    schedule 17.09.2015


Ответы (1)


Итак, как мне создать список, если он еще не существует?

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

Пример:

:- use_module(library(assoc)).

chars_pos(Cs, Ps) :-
    empty_assoc(E),
    chars_pos(Cs, 1, E, Ps).

chars_pos([], _, Ps, Ps).
chars_pos([C|Cs], P, Pc, Ps) :-
    append_char(C, P, Pc, Pt),
    Q is P+1,
    chars_pos(Cs, Q, Pt, Ps).

append_char(C, P, Pc, Pu) :-
    ( get_assoc(C, Pc, Lc) -> Lu = [P|Lc] ; Lu = [P] ),
    put_assoc(C, Pc, Lu, Pu).

контрольная работа

?- atom_chars('hello world', Cs), chars_pos(Cs, Ps), assoc_to_list(Ps, Ls).
Cs = [h, e, l, l, o, ' ', w, o, r|...],
Ps = t(h, [1], >, t(d, [11], -, t(' ', [6], -, t, t), t(e, [2], -, t, t)), t(o, [8, 5], >, t(l, [10, 4, 3], -, t, t), t(w, [7], <, t(r, [9], -, t, t), t))),
Ls = [' '-[6], d-[11], e-[2], h-[1], l-[10, 4, 3], o-[8, 5], r-[9], w-[...]].
person CapelliC    schedule 17.09.2015