2014-10-09 170 views
1

對不起,這可能以前已經問過,但我找不到一個好的答案。SWI-Prolog:如何插入一個新的子句到數據庫

我正在寫一篇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-Prolog的以下內容:

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'謂詞的定義中存在拼寫錯誤。在謂詞定義的第一行末尾有一個'.'(結尾部分),而不是','(連詞)。 – 2014-10-09 13:16:40

+1

表達式'動態祖先/ 2'不屬於謂詞子句(在這種情況下爲'insere/2'),因爲它是一個指令,並且您已經在程序開始時發出了指令。我很驚訝你沒有收到錯誤信息。 – lurker 2014-10-09 14:15:51

+0

您是否需要使用愛丁堡風格的IO? – 2014-10-09 19:01:33

回答

0

tell開始寫入文件的開頭。所以你會覆蓋文件中的其他所有內容。你有這些選項:

  1. 把你的progenitor謂詞(和只是)在另一個文件中。

  2. 使用append/1portray_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

相關問題