【问题标题】:SWI-Prolog: how to insert a new clause to a databaseSWI-Prolog:如何将新子句插入数据库
【发布时间】:2014-10-09 12:39:27
【问题描述】:

对不起,这可能以前被问过,但我找不到一个好的答案。

我正在编写一个 Prolog 作业,我们必须在其中编写一个带有插入、删除等功能的数据库。我目前卡在插入部分。我正在尝试为此使用tell、listing 和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 的行。

我该如何正确地做到这一点?

【问题讨论】:

  • 您在insere/2 谓词的定义中有错字。在谓词定义的第一行末尾有一个.(子句结尾)而不是,(连词)。
  • 表达式dynamic progenitor/2 不属于谓词子句(在这种情况下为insere/2),因为它是一个指令,并且您已经在程序开始时发出了该指令。我很惊讶您没有收到错误消息。
  • 你需要使用爱丁堡式的IO吗?

标签: prolog


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多