recursion - 如何在 Prolog 中的 append/3 之后退出递归
问题描述
door_between(bed_room, hidden_chamber).
door_between(hidden_chamber, basement).
rev(L,R) :- my_reverse(L,[],R).
my_reverse([H|T],A,R) :- my_reverse(T,[H|A],R).
my_reverse([],A,A).
path_from(Src,Dest,Path) :-
path_from(Src,Dest,[],Path),
rev(Path,Z),
append(Src,Z,Z).
path_from(S,S,P,P).
path_from(S,D,P,NV) :-
(door_between(S,A) ; door_between(A,S)),
\+ member(A,P),
path_from(A, D, [A|P], NV).
这是我在房间的无向图中查找路径的代码。它似乎在递归期间得到了正确的结果,但在某个点调用 *Redo 我不明白为什么,这里是跟踪。
path_from(bed_room,basement,X).
* Call: (8) path_from(bed_room, basement, _12282) ? creep
* Call: (9) path_from(bed_room, basement, [], _12282) ? creep
Call: (10) door_between(bed_room, _12624) ? creep
Exit: (10) door_between(bed_room, hidden_chamber) ? creep
Call: (10) lists:member(hidden_chamber, []) ? creep
Fail: (10) lists:member(hidden_chamber, []) ? creep
* Redo: (9) path_from(bed_room, basement, [], _12282) ? creep
* Call: (10) path_from(hidden_chamber, basement, [hidden_chamber], _12282) ? creep
Call: (11) door_between(hidden_chamber, _12630) ? creep
Exit: (11) door_between(hidden_chamber, basement) ? creep
Call: (11) lists:member(basement, [hidden_chamber]) ? creep
Fail: (11) lists:member(basement, [hidden_chamber]) ? creep
* Redo: (10) path_from(hidden_chamber, basement, [hidden_chamber], _12282) ? creep
* Call: (11) path_from(basement, basement, [basement, hidden_chamber], _12282) ? creep
* Exit: (11) path_from(basement, basement, [basement, hidden_chamber], [basement, hidden_chamber]) ? creep
* Exit: (10) path_from(hidden_chamber, basement, [hidden_chamber], [basement, hidden_chamber]) ? creep
* Exit: (9) path_from(bed_room, basement, [], [basement, hidden_chamber]) ? creep
Call: (9) rev([basement, hidden_chamber], _12636) ? creep
Call: (10) my_reverse([basement, hidden_chamber], [], _12638) ? creep
Call: (11) my_reverse([hidden_chamber], [basement], _12644) ? creep
Call: (12) my_reverse([], [hidden_chamber, basement], _12650) ? creep
Exit: (12) my_reverse([], [hidden_chamber, basement], [hidden_chamber, basement]) ? creep
Exit: (11) my_reverse([hidden_chamber], [basement], [hidden_chamber, basement]) ? creep
Exit: (10) my_reverse([basement, hidden_chamber], [], [hidden_chamber, basement]) ? creep
Exit: (9) rev([basement, hidden_chamber], [hidden_chamber, basement]) ? creep
调用:(9) 列表:附加(卧室,[隐藏房间,地下室],[隐藏房间,地下室])?蠕变
* Redo: (11) path_from(basement, basement, [basement, hidden_chamber], _12282) ? creep
Call: (12) door_between(basement, _12636) ?
(打破代码块的粗体行是我关心的行,它由 path_from/3 中的 append(Src,Z,Z) 触发。)在调用:(9)追加时,结果列表是我想要这个特定测试用例的答案,我假设 append 将返回 [bed_room, hidden_chamber, basement],但接下来是 *Redo,我真的很困惑为什么,我只是对递归的概念?我想我只需要一个小小的推动,我就可以把头绕过去。
解决方案
推荐阅读
- google-chrome-devtools - 如何在 Chrome DevTools 的 Coverage 选项卡中按使用百分比对所有资产进行排序?
- javascript - 如何更新嵌套数组中的特定元素
- python - 如何使用列表推导来总结动态数量的子列表?
- java - appwidget 每天上午 12 点更新 textview
- r - R函数查找最接近给定值的数组中的值的索引
- typescript - Cloud Function 不起作用 - 查询和更新 firestore
- javascript - api 请求数据的动态过滤 - Javascript React。什么是最好的方法?
- r - 使用全局变量而不是参数 - 节省内存?(右)
- qemu - libvirt-go DomainEventLifecycleRegister“无法初始化域事件计时器”
- python - 为没有值的特定列填充零(Python)