如何修改Prolog的move谓词实现回溯判断A、B是否可相等
Prolog move谓词修复方案
原代码核心问题
- 递归调用时传入的第三个参数
X未初始化,无法通过integer(Number)校验,直接执行报错 random(1, 2, X)的上界为开区间,仅能生成固定值1,无法触发给B加1的分支- if-then-else(
->)结构自带隐式 cut,会截断其他可选分支,不支持回溯获取结果
修正后代码
随机执行版本
% 终止条件:A与B相等时返回成功 move(A, B, _) :- A == B. % Number为1时给A加1 move(A, B, Number) :- integer(Number), Number =:= 1, C is A + 1, random(1, 3, NextNum), move(C, B, NextNum). % Number为2时给B加1 move(A, B, Number) :- integer(Number), Number =:= 2, C is B + 1, random(1, 3, NextNum), move(A, C, NextNum). % 支持首次调用时Number为变量的场景,自动生成初始操作值 move(A, B, Number) :- var(Number), random(1, 3, Number), move(A, B, Number).
回溯枚举版本
如果需要遍历所有合法操作序列,通过回溯返回所有可行解,可将随机生成操作数的逻辑替换为枚举:
% 终止条件:A与B相等时返回成功 move(A, B, _) :- A == B. % Number为1时给A加1 move(A, B, Number) :- integer(Number), Number =:= 1, C is A + 1, member(NextNum, [1, 2]), move(C, B, NextNum). % Number为2时给B加1 move(A, B, Number) :- integer(Number), Number =:= 2, C is B + 1, member(NextNum, [1, 2]), move(A, C, NextNum). % 支持首次调用时Number为变量的场景,枚举初始操作值 move(A, B, Number) :- var(Number), member(Number, [1, 2]), move(A, B, Number).
调用move(1,5,X)时,即可通过回溯得到true,X为初始调用生成/选择的操作数值。
内容的提问来源于stack exchange,提问作者Newbie700
相关产品推荐
相关产品推荐

