SWI-Prolog:如何将新子句插入数据库 [英] SWI-Prolog: how to insert a new clause to a database

查看:50
本文介绍了SWI-Prolog:如何将新子句插入数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,这可能以前有人问过,但我找不到好的答案.

I'm sorry, this has probably been asked before but I can't find a good answer.

我正在写一个 Prolog 作业,其中我们必须编写一个带有插入、删除等功能的数据库.我目前卡在插入部分.我正在尝试为此使用 tell、listing 和telled,但结果通常是不可预测的,删除文件的随机部分.这是我的数据库的完整代码,banco.pl:

I'm writing a Prolog assignment, in which we must write a database with insert, delete, etc. I'm currently stuck on the insert part. I'm trying to use tell, listing and told for this, but the results are often unpredictable, deleting random parts of the file. Here's the full code of my database, 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 上运行以下命令:

I then run the following on SWI-Prolog:

insere(luiz,luiza).

并在 banco.pl 上得到以下结果:

And get the following result on banco.pl:

:- dynamic progenitor/2.

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

请注意,我尝试插入的子句甚至不在文件中,并且缺少定义 commit 和 insere 的行.

Note that the clause I tried to insert isn't even in the file, and the lines defining commit and insere are missing.

我该如何正确执行此操作?

How would I do this correctly?

推荐答案

tell 开始写入文件的开头.所以你覆盖了文件中的所有其他内容.您有以下选择:

tell starts writing to the beginning of the file. so you're overwriting everything else that was in the file. you have these options:

  1. 将您的 progenitor 谓词(仅此而已)放在另一个文件中.

  1. put your progenitor predicate (and just that) in another file.

使用append/1portray_clause 写入文件的末尾.这仅对 insert 有帮助,但您表示您也希望 delete.

use append/1 to write to the end of the file with portray_clause. this only helps for insert, but you stated that you want delete too.

将其他子句读入列表并重新打印,然后使用listing/1 :

read the other clauses into a list and reprint them, then use 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

Note that you could use the read_all_other_clauses for your delete only, if you change the line with the omit comment. Then you could use the solution proposed in #2 for your insere

这篇关于SWI-Prolog:如何将新子句插入数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆