如何在自定义Prolog谓词中访问数据库成员,实现书籍查询逻辑
如何在Prolog中实现书籍名称匹配查找?
嘿,我来帮你搞定这个Prolog的书籍查找问题!先理清楚你的核心需求:根据用户输入的书名,从现有的book/3事实库里匹配并返回对应的作者。先把你的现有代码和困惑理清楚,再给出完整的解决方案。
你的现有书籍数据库事实
book('C for Dummies', 'Chris Smith', 2000). book('C++ for Dummies', 'Chris Smith', 2002). book('Java for Dummies', 'Jason Rash', 1995). book('JavaScript for Dummies', 'Jason Rash', 2005). book('Prolog for Dummies', 'Pete Fagan', 1990).
现有谓词定义
main():- chooseusertype(Usertype), startas(Usertype), find_book(Booktitle). % 需读取用户输入并传递给find_book谓词 find_book(Booktitle, Result):- write(‘Enter the book title: ’), nl, read(Booktitle), % 遍历所有书籍数据,查找名称匹配用户输入的书籍 format(‘The author of ~w is ~w ~n’, [Booktitle, Result]). chooseusertype(X):- write('Log in as a librarian or guest?: '), read(X), format('Your log in type: ~w', [X]). startas('librarian'):- write('Logged in as librarian'), nl, write('Any update on the shelves?'). startas('guest'):- write('Logged in as guest'), nl, write('Let us help you find the book you are looking for!'), nl.
你的困惑点
你提到熟悉Java的循环实现逻辑:
for(int i=0; i<bookList.length;i++){ Book result = new Book(); if(bookList[i].name == Booktitle){ result = bookList[i]; } return result.author; }
但不知道怎么转成Prolog代码——这里要注意:Prolog是声明式语言,不需要你手动写循环遍历,它会通过自身的回溯机制自动匹配事实库中的条目。
你更新后的尝试
你已经对两个谓词做了修改,但还有一些细节需要调整:
更新后的find_book
find_book(Booktitle, Result):- write(‘Enter the book title: ’), read(Booktitle), book(Booktitle, _), format(‘The author of ~w is ~w ~n’, [Booktitle, Result]).
更新后的startas('guest')
startas('guest'):- write('Logged in as guest'), nl, write('Let us help you find the book you are looking for!'), find_book(Booktitle).
正确的Prolog实现方案
1. 核心逻辑:利用Prolog的事实匹配替代循环
Prolog的book/3事实本身就是一个小型数据库,当你调用book(Booktitle, Author, _)时,它会自动在所有book事实中匹配第一个参数等于Booktitle的条目,并把对应的作者绑定到Author变量——这就完全替代了Java里的循环+条件判断。
2. 完整修正后的代码
% 书籍数据库事实 book('C for Dummies', 'Chris Smith', 2000). book('C++ for Dummies', 'Chris Smith', 2002). book('Java for Dummies', 'Jason Rash', 1995). book('JavaScript for Dummies', 'Jason Rash', 2005). book('Prolog for Dummies', 'Pete Fagan', 1990). % 主入口谓词 main :- chooseusertype(Usertype), startas(Usertype), % 只有guest用户需要调用查找功能,librarian跳过 (Usertype = 'guest' -> find_book ; true). % 用户类型选择谓词 chooseusertype(X):- write('Log in as a librarian or guest?: '), read(X), format('Your log in type: ~w~n', [X]). % 不同用户类型的初始化提示 startas('librarian'):- write('Logged in as librarian'), nl, write('Any update on the shelves?'). startas('guest'):- write('Logged in as guest'), nl, write('Let us help you find the book you are looking for!'), nl. % 书籍查找核心谓词 find_book :- write('Enter the book title: '), nl, read(Booktitle), % 条件分支:找到书籍则输出作者,否则提示未找到 ( book(Booktitle, Author, _) -> format('The author of ~w is ~w ~n', [Booktitle, Author]) ; format('Sorry, we couldn\'t find the book "~w" ~n', [Booktitle]) ).
关键修正点说明
- 把中文全角引号
‘’改成英文半角',避免Prolog语法报错 - 调整
find_book的参数逻辑:不需要传入参数,内部直接读取用户输入并匹配事实 - 增加了“书籍未找到”的分支处理,提升用户体验
- 优化了
main谓词的流程:只有guest用户会触发书籍查找,符合业务逻辑
测试运行示例
当你在Prolog环境中运行main.:
- 输入
guest,进入查找流程 - 输入
Java for Dummies,程序输出:The author of Java for Dummies is Jason Rash - 输入不存在的书名(比如
Python for Dummies),程序输出:Sorry, we couldn't find the book "Python for Dummies"
内容的提问来源于stack exchange,提问作者furitetepporaa
相关产品推荐
相关产品推荐

