首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自然语言处理/命令(prolog)

自然语言处理/命令(prolog)
EN

Stack Overflow用户
提问于 2013-12-16 03:03:53
回答 2查看 324关注 0票数 2

我想要创建一个谓词,它识别一个单词(在本例中为“保存”),并开始保存下一个单词,直到符号/单词"end“出现为止。

它应该是这样的:

代码语言:javascript
复制
?- save.
one
two
end
true.

用于保存的谓词:

代码语言:javascript
复制
save(X) :- assert(listitem(X)).

然后我就这样开始了:

代码语言:javascript
复制
save :- read(save).
read:- X -> save(X).
end --> 'end'.

问题是,我可以添加尽可能多的单词,但如果我想用"end“停止命令,程序就会失败,实际上单词还没有保存。

谓词的哪一部分是错误的?我很乐意得到帮助。提前谢谢你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-16 05:27:27

这是一些非常混乱的代码。这是你想要的

代码语言:javascript
复制
:- 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时,您已经完成了,而不是失败了。但你在这里有很多问题。

  1. save/0调用read/1,这是一个系统谓词。所要做的就是从用户处读取一个单词(以句点结尾!)注意它不是“保存”这个词。不幸的是,在Prolog中,没有句号的读取整行在某种程度上是一项相当重要的任务,因此在我的解决方案中出现了大量代码。
  2. 任何东西都不会调用read/0
  3. 语法X -> save(X)几乎肯定不是您想要的。这是谓词中X的第一次出现,所以在它有值之前对它进行有条件的测试可能没有多大好处。
  4. end --> 'end'.是一个DCG规则,但是您没有在任何地方使用phrase/2来调用它(也没有直接使用带有差异列表的end/2 )。
  5. assert/1是一个很坏的习惯。asserta/1assertz/1谓词不仅是可移植的,它们还让读者更好地了解事实数据库的影响。
  6. 类似地,您没有dynamic声明listitem/1,这将提高可移植性和提高可读性。
票数 3
EN

Stack Overflow用户

发布于 2013-12-16 14:30:37

我会使用一种‘状态机’的方法:它太简单了!

代码语言:javascript
复制
:- 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).

测试:

代码语言:javascript
复制
1 ?- loop(skip).
|: asd.
|: save.
|: ok.
|: ok1.
|: stop.
true 
.

2 ?- listing(listitem).
:- dynamic stackoverflow:listitem/1.

stackoverflow:listitem(ok).
stackoverflow:listitem(ok1).

true.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20602788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档