Prolog初学者求助:编写len谓词计算任务列表总时长
搞定Prolog任务列表总时长计算的len谓词问题
嘿,作为Prolog初学者踩这种语法和逻辑坑太正常了,我来帮你把问题理清楚,然后给出能正常运行的代码。
首先先明确你的需求:你需要一个len/2谓词,输入任务列表,输出所有任务的时长总和,比如查询?- len([d, j, l, n], Time).要返回Time = 15。你已经定义了这些任务时长事实:
duration(a,5). duration(b,7). duration(c,3). duration(d,4). duration(e,10). duration(f,4).
(注:你示例里用到的j、l、n没在给定的duration里,我根据结果反推补充了对应的事实,不然跑不出15的结果)
先说说你尝试的代码里的问题
- 命名冲突:你用了
length/2作为自己的谓词名,但这是Prolog的内置谓词(用来求列表元素个数的),这会直接覆盖内置功能,导致逻辑混乱。 - 语法错误:你写的
length([X], duration(X, T), Time)是个3元谓词,但你需要的是2元的(输入列表,输出总时长),参数数量不匹配肯定报错。 - 递归逻辑不完整:你的
sum谓词没写完,而且也没把它和计算时长的逻辑关联起来,根本没法实现累加。
正确的实现思路
Prolog的递归谓词要分基准情况和递归情况:
- 基准情况:空列表的总时长肯定是0,没任务就没时长嘛。
- 递归情况:对于非空列表
[任务 | 剩余任务],先拿到当前任务的时长,再递归算出剩余任务的总时长,最后把两者加起来就是总时长。
完整可运行的代码
% 你给定的任务时长事实 duration(a,5). duration(b,7). duration(c,3). duration(d,4). duration(e,10). duration(f,4). % 补充示例需要的j、l、n的时长(不然跑不出Time=15) duration(j,3). duration(l,5). duration(n,3). % 实现你要的len/2谓词(如果怕和内置length混淆,也可以叫total_duration/2) len([], 0). len([Task | RestTasks], TotalTime) :- % 拿到当前任务的时长 duration(Task, TaskTime), % 递归计算剩余任务的总时长 len(RestTasks, RestTotal), % 累加得到总时长 TotalTime is TaskTime + RestTotal.
测试一下
运行你的示例查询:
?- len([d, j, l, n], Time).
会得到你想要的结果:
Time = 15.
额外小提示
如果不想和内置的length/2搞混,建议把自己的谓词命名得更有意义,比如total_task_duration/2,这样代码可读性也更高~
内容的提问来源于stack exchange,提问作者Matthew Ridge
相关产品推荐
相关产品推荐

