2014-10-09 2 views
1

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

Я пишу назначение Пролога, в котором мы должны написать базу данных со вставкой, удалением и т. Д. Я сейчас застрял на части вставки. Я пытаюсь использовать tell, листинг и сказал для этого, но результаты часто непредсказуемы, удаляя случайные части файла. Вот полный код моей базы данных, banco.pl:

:- dynamic progenitor/2. 
progenitor(maria,joao). 
progenitor(jose,joao). 
progenitor(maria,ana). 
progenitor(jose,ana). 

insere(X,Y) :- dynamic progenitor/2, assert(progenitor(X,Y)). 
tell('banco.pl'), listing(progenitor), told. 

Я затем запустить следующее на SWI-Пролог:

insere(luiz,luiza). 

И получаем следующий результат на banco.pl:

:- dynamic progenitor/2. 

progenitor(maria, joao). 
progenitor(jose, joao). 
progenitor(maria, ana). 
progenitor(jose, ana). 

Примечание что предложение, которое я пытался вставить, даже не в файле, и строки, определяющие commit и insere, отсутствуют.

Как бы это сделать правильно?

+0

У вас есть опечатка в вашем определении предиката 'insere/2'. В конце первой строки определения предиката есть '.' (конец предложения) вместо', '(conj). –

+1

Выражение 'dynamic progenitor/2' не входит в предложение предиката (' insere/2' в этом случае), так как это директива, и вы уже выпустили директиву в начале программы. Я удивлен, что вы не получили сообщение об ошибке. – lurker

+0

Нужно ли использовать IO в стиле Эдинбург? –

ответ

0

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

  1. положить ваши progenitor предикат (и просто) в другом файле.

  2. append/1, чтобы написать в конец файла с portray_clause. это только помогает для insert, но вы заявили, что хотите также delete.

  3. прочитать другие пункты в списке и перепечатывать их, а затем использовать listing/1:

(текст для форматирования)

read_all_other_clauses(All_Other_Clauses):- 
    see('yourfilename.pl'), 
    read_all_other_clauses_(All_Other_Clauses,[]), 
    seen. 

read_all_other_clauses_(Other,Acc0):- 
    (read(Clause) -> 
    (Clause = progenitor(_,_) -> % omit those clauses, because they'll be printed with listing/1 
    read_all_other_clauses_(Other,Acc0); 
    read_all_other_clauses_(Other,[Clause|Acc0])); 
    Other = Acc0). % read failed, we're done 

operation(Insert, X,Y):- 
    (call,(Insert) -> 
     assert(progenitor(X,y)); 
     retract(progenitor(X,y))), 
    read_all_other_clauses(Others), 
    tell('yourfilename.pl'), % After the reading! 
    maplist(portray_clause,Others), %Maplist is a SWI built-in, easy to rewrite, if you don't have it. 
    listing(progenitor/2), 
    told. 

insert(X,Y):- operation(true,X,Y). 
delete(X,Y):- operation(fail,X,Y). 

Обратите внимание, что вы можете использовать read_all_other_clauses только для вашего delete , если вы измените строку с пропущенным комментарием. Тогда вы можете использовать решение, предложенное в № 2 для вашего insere

Смежные вопросы