2014-10-09 169 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

相关问题