我想知道,我知道你可以assert用来添加事实或规则,或者如果你已经声明了谓词-:dynamic,但是这只允许在那个会话中保留所做的更改,例如,如果你关闭了Prolog窗口然后数据库更改丢失.
所以我想知道,有没有办法使它assert和retract谓词可以对Prolog .pl文件进行永久性更改?
谢谢
我现在检查X(Y)在我的小数据库中不是可接受的事实.由于X(Y)返回false,它将尝试断言它.(我知道当X是规则而不是事实时,这会出现问题)
ifNotAdd(X,Y):-
not(call(X,Y)),
!,
assert(X(Y)).
Run Code Online (Sandbox Code Playgroud)
例如,假设这个事实在DB中
mammal(dolphin).
Run Code Online (Sandbox Code Playgroud)
我问ifNotAdd(哺乳动物,大象).
我希望它能看到吗?哺乳动物(象).是假的,然后断言哺乳动物(大象).
显然是"断言(X(Y))." 线是错的,但我该用什么替换呢?我正在搜索prolog文档和论坛的答案,但到目前为止没有运气.我也试着写一些能够自己做的事情.
编辑 我需要编辑数据库,以便拥有一个用户可以与之交互的动态数据库.我正在构建一个参数机器,我需要允许用户告诉系统他们"确切知道这个事实",以便系统可以处理其域外的知识.
在http://en.wikipedia.org/wiki/Reason_maintenance中
干杯,
我正在.pl文件中开发一个算法,并在命令窗口中使用查询进行检查.我使用动态变量和收回/断言谓词.当我修改pl文件并单击"重新加载修改的文件"时,我有额外的事实,我不想要.
例如,在开始时我有计数器(0).
我做了一些事情,撤回并断言这个计数器,它变成了反击(7).然后,当我重新加载修改后的pl文件时,我有两个计数器(0).和柜台(7).
如何防止这种情况并且只有计数器(0).在一开始的时候?
提前致谢.
我是Prolog的新手,但我仍然坚持这个简单的命令.我已经加载了一个没有错误的知识库,每当我尝试断言(甚至帮助)时,我都收到以下消息:
uncaught exception: error(existence_error(procedure,assert/1),top_level/0)
{2}
Run Code Online (Sandbox Code Playgroud)
我究竟缺少什么?赞赏.
从阅读手册,我似乎无法找到两者之间的差异.
手册说:
建议使用retractall/1来擦除动态谓词的所有子句.
所以我选择retractall/1在我的程序中使用; 但是,我想知道区别是什么.
我编写了以下简单的代码,我希望当我写"男性"时,这段代码会问我一次"它是男性吗?" 如果我输入"否",它会在屏幕上写下"她是女性".
male :- ( print('is it male ? '),read(yes)) -> true; asserta( not(male)),female.
female:- not(male),print('she is female').
not(P) :- (call(P) -> fail ; true) .
Run Code Online (Sandbox Code Playgroud)
但此代码有以下错误:
uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1);
Run Code Online (Sandbox Code Playgroud)
swi-prolog中的错误是:
ERROR: asserta/1: No permission to modify static_procedure `not/1'
Run Code Online (Sandbox Code Playgroud) 我定义一个运算符如下:
:- op(500, xfx, =>).
Run Code Online (Sandbox Code Playgroud)
当我尝试这样的事情:
assert(a => b).
Run Code Online (Sandbox Code Playgroud)
Prolog引发了一个错误,上面写着"无权修改static_procedure(=>)/ 2".
有解决方案吗
我往往最终写入的Prolog代码涉及(在整个程序或状态的重要信息)的一些算术计算,通过:首先获得存储在谓词的值,然后重新计算的值,最后使用存储所述值的装置retractall和assert因为在Prolog中,我们不能使用两次赋值给变量is(因此几乎每个需要修改的变量都是全局的).我已经知道这在Prolog中不是一个好习惯.在这方面,我想问:
为什么在Prolog中这是一个不好的做法(虽然我自己不喜欢通过上面提到的步骤只是为了拥有一种灵活的(可修改的)变量)?
有哪些一般方法可以避免这种做法?小例子将不胜感激.
PS我刚开始学习Prolog.我确实有C语言的编程经验.
我想说的一个不好的例子(在win-prolog中)如下:
:- dynamic(value/1).
:- assert(value(0)).
adds :-
value(X),
NewX is X + 4,
retractall(value(_)),
assert(value(NewX)).
mults :-
value(Y),
NewY is Y * 2,
retractall(value(_)),
assert(value(NewY)).
start :-
retractall(value(_)),
assert(value(3)),
adds,
mults,
value(Q),
write(Q).
Run Code Online (Sandbox Code Playgroud)
然后我们可以查询如下:
?- start.
Run Code Online (Sandbox Code Playgroud)
在这里,它非常简单,但在实际程序和应用中,上面显示的全局变量方法变得不可避免.有时候,上面给出的列表就像assert(value(0))... 一样长,并且有更多的断言谓词来定义更多的变量.这样做是为了使不同功能之间的值的通信成为可能,并在程序运行期间存储变量状态.
最后,我想再知道一件事:尽管您提出了各种解决方案以避免它,但上述做法何时变得不可避免?
我正在阅读http://cs.union.edu/~striegnk/learn-prolog-now/html/node3.html#subsec.l1.kb1,但我在运行以下谓词时遇到问题:
SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 WEST 2007
| ?- woman(mia).
! Existence error in user:woman/1
! procedure user:woman/1 does not exist
! goal: user:woman(mia)
| ?-
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我将它写入文件并运行参考文件,它似乎工作正常...
我是否只允许在稍后查询它们的文件中定义谓词?我不能只在编辑器中做到这一点吗?
有人可以解释关于断言和撤回的Prolog逻辑视图吗?
例如,在下面的代码中,在第一次运行时Prolog返回true,在后续运行中返回false.我不知道为什么因为Prolog逻辑视图 asserta(nextBound(100))满足时,nice(X)在启动时仍然被值冻结,因此这个更改应该被忽略并且nextbound(100)必须为false.
nextBound(10000).
nice(X) :-
asserta(nextBound(100)),
retract(nextBound(10000)),
nextBound(100).
Run Code Online (Sandbox Code Playgroud)