如何正确编写Prolog listtran翻译谓词及解决子句分散报错问题
Prolog数词翻译问题解决方案
一、测试方法
你现有的listtran/2逻辑已经可以满足双向翻译需求,不需要额外编写新的自定义谓词,直接运行你预期的两条查询语句即可验证效果:
- 拉丁转英文查询:
?- listtran([unus,novem,duo],X).
运行后返回结果:X = [one,nine,two]. - 英文转拉丁查询:
?- listtran(X,[one,seven,six,two]).
运行后返回结果:X = [unus,septem,sex,duo].
如果需要批量自动测试,也可以编写简单的测试谓词,示例如下:
test_listtran :- % 测试拉丁转英文 listtran([unus,novem,duo], [one,nine,two]), % 测试英文转拉丁 listtran([unus,septem,sex,duo], [one,seven,six,two]), % 测试空列表边界 listtran([], []), write("所有测试通过").
运行?- test_listtran.如果输出所有测试通过就说明代码逻辑正确。
二、报错解决方案
你遇到的Clauses of listtran/2 are not together in the source-file报错,是因为Prolog语法要求同一个谓词的所有子句必须连续写在源文件中,不能被其他谓词的子句隔开,你的代码存在两个问题导致报错:
- 多余的前置声明:
listtran(L,E).这行是无效的空事实,Prolog不需要提前声明谓词 - 子句不连续:你先写了
listtran的空事实,中间插入了所有tran/2的子句,之后才写listtran的两个规则子句,相当于listtran的子句被tran的子句隔开了
修正后的完整代码如下:
/*Write a predicate listtran(L,E) which translates a list of Latin number words * to the corresponding list of English number words. */ %% 翻译映射子句 tran(unus,one). tran(duo,two). tran(tres,three). tran(quattuor,four). tran(quinque,five). tran(sex,six). tran(septem,seven). tran(octo,eight). tran(novem,nine). %% listtran规则 % base case: empty list listtran([], []). % inductive cases: listtran([L | T0], [E | T1]) :- tran(L, E), % translate the head of the list listtran(T0, T1). % translate the tail of the list, using recursion
修改后重新加载源文件即可消除报错,正常运行查询。
内容的提问来源于stack exchange,提问作者The Coder
相关产品推荐
相关产品推荐

