2016-07-09 8 views
0

С профилем Prolog можно легко ознакомиться с помощью consult/1 или [filename]..Консультирование с атомом

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

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

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

+0

'consult' утверждает термины, которые находятся в' filename.pl'. Вы можете написать предикат, который анализирует через 'X' и утверждает термины. Существует множество предикатов поддержки Prolog для извлечения терминов. Непонятно, как вы структурировали или использовали 'generate_stuff/1' в целом, но для' generate_stuff 'более разумно было бы утверждать термины по мере их создания, а не собирать их как гигантскую строку и анализировать через них потом , – lurker

+0

@lurker Есть ли какой-либо предикат, который анализирует 'X' на термины? 'read_term_from_atom/3' только анализирует первый, и для меня было бы громоздкой переписывать то, что отделяет члены в атоме. – Fatalize

+1

Если вы структурируете свой код, чтобы создать свой «материал» как одну большую строку (которую я рекомендую против, если это возможно), ознакомьтесь с прологом SWI [Чтение и запись в терминах] (http://www.swi-prolog.org/pldoc/man? section = termrw) предикаты. Подумайте о настройке 'X' как потока, а не файла. – lurker

ответ

3

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

Однако, если вы действительно хотите использовать атомы, а затем обрабатывать их как структурированные термины, используйте 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)). 
+0

Проблема в том, что, если у меня есть несколько членов в атоме? например ' 'А. \ Nb.''. Здесь я мог бы разбить на новые строки и maplist atom_to_term, но это не так просто, если у меня тоже есть строки внутри терминов (для удобства чтения). – Fatalize

+0

@Fatalize, то см. Мой последний комментарий к вашему вопросу. – lurker

+1

Вы должны действительно пересмотреть свое основное представление. Избегайте использования атомов для структурированных данных. То же самое относится и к строкам: они почти всегда являются неправильным представлением. – mat

0

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

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

read_term_from_atom_(A, B) :- 
    read_term_from_atom(A, B, []). 
+0

Это менее общее, чем могло бы быть: вы можете использовать '_' вместо' [] ', а также разрешать * переменные * в предложениях. – mat