我有一个任务要做一个“简单的”聊天机器人,现在我的主要问题是在一个接收原子列表的谓词中(例如:[“ good”,“ morning”]),并且应该返回一个可能的答案列表在结构中已经定义的谓词还需要过滤关键字,并且仅返回包含给定列表中关键字的答案。
我尝试检查列表中的元素是否已在任何定义的答案中定义。如果是,它将连接到返回列表。 (这个concat谓词是由老师定义的,基本上已经定义了append / 3。)
ans("Hello there", 0).
ans("Hello",0).
ans("Hi",0).
ans("Good Morning",0).
ans("Good Afternoon",0).
ans("Good Night",0).
answer([], List).
answer([H|T], List):- ans(H, _), concat(List, H, List), answer([T], List).
当我使用answer([“ good”],List)运行此程序时,它运行到无限(我认为它是一个无限循环,因为它需要很长时间才能运行,并给我一个错误,指出没有剩余空间了在堆栈中) 在这种情况下,输出应为[“早安”,“下午好”,“晚安”]。 感谢您能获得的所有帮助。
答案 0 :(得分:2)
从您的问题开始,我们这里有很多问题。
没有concat/3
和代码调用方式,任何人都不可能解决您的问题。您的谓词都没有一个参数,但是您说的是,如果用一个调用它,则代码将陷入无限循环。因此,我们能做的最好的就是推测,直到您用缺失的细节改善问题为止。
这是我推测的假设:concat/3
可能是append/3
。您正在呼叫answer(["good"], Ans)
。
在查看您的代码时,concat(List, H, List)
在我看来非常错误,原因有二:
List
进行突变,这在Prolog中是不可能的(变量一旦绑定就无法更改)。H
中提供要与List
串联的非列表。另一个问题是List
永远不会收到初始绑定,因此很可能您必须使用[]
的参数来调用此谓词,这意味着您将其同时视为输入和输出值。
我认为您的直觉在这里是正确的:您应该可以使用append/3
通过前缀查找事物。不幸的是,SWI-Prolog不再将字符串存储为列表,因此您必须使用另一个谓词:string_concat/3
。
我认为您无法在此处轻松获得所需的返回值。我认为您需要使用findall/3
或它的一个朋友来获取多个解决方案,并且,如果要提供可能的前缀列表,则将获得可能的解决方案列表。也许我在这里缺少明显的东西。无论如何,这是我找到的解决方案:
answer([], []).
answer([H|T], [Answers|R]) :-
findall(Answer,
(ans(Answer, _), string_concat(H, _, Answer)),
Answers),
answer(T, R).
这给了我以下输出:
?- answer(["Good"], L).
L = [["Good Morning", "Good Afternoon", "Good Night"]].
请更正您的问题,以便我们为您提供更多帮助!