Можем ли мы создать факт из кода Prolog?

#list #prolog

#Список #пролог

Вопрос:

Моя цель — разбить данный список списков таким образом, чтобы я мог получить доступ к отдельным спискам с тем же именем. У меня есть следующий список:-

 mylist([[1,2],[2,3],[3,4],[4,6]]).
  

Я хочу разбить список на [1,2], [2,3], [3,4], [4,6] чтобы я мог получить доступ к элементам (например, [1,2]) по отдельности.

Для этого я могу создать новый факт из отдельных элементов списка? Я могу разделить элементы на отдельные списки. Но я хочу преобразовать эти отдельные списки в факты. Нравится:-

 mylist([[1,2],[2,3],[3,4],[4,6]]).
  

должно стать следующим:-

 node([1,2]).
node([2,3]).
node([3,4]).
node([4,6]).
  

И тогда я должен иметь доступ к каждому списку, используя «узел».

Комментарии:

1. Смотрите assertz/1 , а также расширение термина времени компиляции, с term_expansion/2

Ответ №1:

Другой ответ хорош (особенно forall решение), но вот что вы могли бы сделать, если бы знали свой список во время компиляции и хотели добавить node/1 факты в базу данных во время компиляции.

Этот код упрощен из примера, доступного в самом низу этой страницы:

В вашем файле (я назову его nodes.pl ):

 term_expansion(nodes_list(NL), Nodes) :-
        maplist(to_node, NL, Nodes).

to_node(X, node(X)).

nodes_list([[1,2],[2,3],[3,4],[4,6]]).
  

Когда я просматриваю файл, я получаю:

 ?- [nodes].
true.

?- listing(node).
node([1, 2]).
node([2, 3]).
node([3, 4]).
node([4, 6]).

true.
  

Две детали:

  1. Расширенный предикат здесь nodes_list/1 не будет находиться в базе данных.
  2. Предложение term_expansion/2 должно предшествовать определению nodes_list/1 в исходном файле.

Ответ №2:

Отличный ответ (возможно, лучший), рекомендованный (в комментариях) CapelliC:

 ?-forall(member(X,[[1,2],[2,3],[3,4]]),assertz(node(X))).
  

Вы также могли бы написать:

 my_list(L):- member(X,L),assertz(node(X)).
  

Пример:

 ?- my_list([[1,2],[2,3],[3,4]]).
true ;
true ;
true.
?- node([1,2]).
true ;
false.
  

Другим способом, благодаря рекомендации Капеллика, было бы:

 ?- maplist(X>>assertz(node(X)), [[1,2],[2,3],[3,4]]).
  

Комментарии:

1. возможно: ‘?- maplist(X>>assertz(node(X)), [[1,2],[2,3],[3,4]]).`

2. Да, это отличная реализация, спасибо, что указали на это, я отредактирую ответ.

3. ?-forall(member(X,[[1,2],[2,3],[3,4]]),assertz(node(X))). было бы гораздо более переносимым и практически эффективным, как решение lambda maplist

4. Еще раз спасибо, я не думал использовать forall/2 спасибо!!

5. Вы должны поместить forall решение наверх, это самый идиоматичный способ его достижения. Вы также можете увидеть здесь немного больше объяснений и пример с assertz .