Консультации с атомом

Можно легко обратиться к файлу Prolog, используя consult/1 или [filename]..

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

example :-
    generate_stuff(X),
    write_to_file(X,'filename.pl'),
    consult('filename.pl'),
    predicate_in_filename.

Как мне сделать то же самое, но без записи X (кода) в файл? Мне не повезло с assert, который принимает термин в качестве входных данных, тогда как здесь у меня есть полный код в атоме.


person Fatalize    schedule 09.07.2016    source источник
comment
consult утверждает термины, содержащиеся в filename.pl. Вы можете написать предикат, который анализирует X и утверждает термины. Существует множество предикатов поддержки Prolog для извлечения терминов. Непонятно, как вы структурировали или использовали generate_stuff/1 в целом, но для generate_stuff может быть более целесообразно утверждать термины по мере их создания, а не собирать их все в виде гигантской строки и потом анализировать.   -  person lurker    schedule 09.07.2016
comment
@lurker Есть ли какой-нибудь предикат, который разбирает X на термины? read_term_from_atom/3 разбирает только первый, и мне было бы обременительно переписывать что-то, что разделяет термины в атоме.   -  person Fatalize    schedule 09.07.2016
comment
Если вы структурируете свой код, чтобы создавать свои материалы в виде одной большой строки (что я не рекомендую делать, если это возможно), ознакомьтесь с прологом SWI Чтение и запись терминов предикатов. Рассмотрите возможность настройки X как потока, а не файла.   -  person lurker    schedule 09.07.2016
comment
По крайней мере, почему generate_stuff нельзя составить список терминов или предложений?   -  person lurker    schedule 09.07.2016
comment
@lurker Скажем, rw должен генерировать предикат, который переворачивает, а затем записывать ввод. Я читаю первый символ, генерирую reverse(Input,V0), затем рекурсивно вызываю анализатор и добавляю ,\nwrite(V0), затем .. Я не понимаю, как я могу легко сделать то же самое с терминами вместо того, чтобы просто присоединять атомы друг к другу.   -  person Fatalize    schedule 09.07.2016
comment
Под списком терминов я имел в виду список атомов (или строк), каждый из которых по отдельности представляет один термин, а не один длинный атом, представляющий все термины. Похоже, что ваше решение было основано на ответе, который вы опубликовали.   -  person lurker    schedule 09.07.2016


Ответы (2)


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

Однако, если вы действительно хотите использовать атомы, а затем рассматривать их как структурированные термины, используйте atom_to_term/3, затем подтвердите пункт.

Например:

?- atom_to_term('p(X, Y) :- dif(X, Y)', T, Vs).
T =  (p(_G925, _G926):-dif(_G925, _G926)),
Vs = ['X'=_G925, 'Y'=_G926].

В вашем случае вы можете просто игнорировать Vs:

?- atom_to_term('p(X, Y) :- dif(X, Y)', T, _).
T =  (p(_G916, _G917):-dif(_G916, _G917)).
person mat    schedule 09.07.2016
comment
Проблема в том, что если у меня есть несколько терминов в атоме? например 'a.\nb.'. Здесь я мог бы разделить на новые строки и список карт atom_to_term, но это не так просто, если у меня есть разрывы строк внутри терминов (для удобочитаемости). - person Fatalize; 09.07.2016
comment
@Fatalize, тогда посмотри мой последний комментарий к твоему вопросу. - person lurker; 09.07.2016
comment
Вы действительно должны пересмотреть свое базовое представление. Избегайте использования атомов для структурированных данных. Кстати, то же самое касается строк: они почти всегда являются неправильным представлением. - person mat; 09.07.2016

Для потомков, вот как я это сделал, при условии, что у вас есть только один термин в каждом атоме списка:

%...
maplist(read_term_from_atom_, ListOfAtoms, ListOfTerms),
maplist(asserta, ListOfTerms),
%...

read_term_from_atom_(A, B) :-
    read_term_from_atom(A, B, []).
person Fatalize    schedule 09.07.2016
comment
Это менее общее, чем могло бы быть: вы можете использовать _ вместо [], а также разрешить переменные в предложениях. - person mat; 09.07.2016