我想要创建一个谓词,它识别一个单词(在本例中为“保存”),并开始保存下一个单词,直到符号/单词"end“出现为止。
它应该是这样的:
?- save.
one
two
end
true.用于保存的谓词:
save(X) :- assert(listitem(X)).然后我就这样开始了:
save :- read(save).
read:- X -> save(X).
end --> 'end'.问题是,我可以添加尽可能多的单词,但如果我想用"end“停止命令,程序就会失败,实际上单词还没有保存。
谓词的哪一部分是错误的?我很乐意得到帮助。提前谢谢你!
发布于 2013-12-16 05:27:27
这是一些非常混乱的代码。这是你想要的
:- dynamic listitem/1.
readline(Line) :-
% this is an SWI extension, but it's very handy
read_line_to_codes(user, Codes),
atom_codes(Line, Codes).
save :-
readline(X),
(X \= end -> (assertz(listitem(X)), save)
; true).可能性很大,在您没有带来的代码中,您所缺少的只是; true的效果:当您找到end时,您已经完成了,而不是失败了。但你在这里有很多问题。
save/0调用read/1,这是一个系统谓词。所要做的就是从用户处读取一个单词(以句点结尾!)注意它不是“保存”这个词。不幸的是,在Prolog中,没有句号的读取整行在某种程度上是一项相当重要的任务,因此在我的解决方案中出现了大量代码。read/0。X -> save(X)几乎肯定不是您想要的。这是谓词中X的第一次出现,所以在它有值之前对它进行有条件的测试可能没有多大好处。end --> 'end'.是一个DCG规则,但是您没有在任何地方使用phrase/2来调用它(也没有直接使用带有差异列表的end/2 )。assert/1是一个很坏的习惯。asserta/1和assertz/1谓词不仅是可移植的,它们还让读者更好地了解事实数据库的影响。dynamic声明listitem/1,这将提高可移植性和提高可读性。发布于 2013-12-16 14:30:37
我会使用一种‘状态机’的方法:它太简单了!
:- dynamic listitem/1.
loop(Mode) :- read(W), loop(Mode, W).
loop(_, stop).
loop(skip, save) :- loop(save).
loop(skip, _) :- loop(skip).
loop(save, W) :- assertz(listitem(W)), loop(save).测试:
1 ?- loop(skip).
|: asd.
|: save.
|: ok.
|: ok1.
|: stop.
true
.
2 ?- listing(listitem).
:- dynamic stackoverflow:listitem/1.
stackoverflow:listitem(ok).
stackoverflow:listitem(ok1).
true.https://stackoverflow.com/questions/20602788
复制相似问题