Prolog生成指定范围三元列表时触发实例化错误,求解决方案
问题排查与解决办法
错误原因
你遇到的实例化错误,本质是Prolog的算术比较运算符(>=/=<)要求两边必须是已实例化的数值。你的代码执行顺序是先把X/Y/Z和未实例化的列表S的元素绑定,此时X/Y/Z还是无具体值的变量,执行比较时Prolog无法处理,直接抛出错误。
另外你自定义的first/2/second/2/third/2只是建立了变量和列表元素的关联关系,并没有生成具体数值来实例化这些变量,这也是问题的关键。
解决办法
方法一:用模式匹配+原生between/3(推荐)
直接用列表模式匹配提取元素,同时用Prolog原生的between/3生成指定范围内的数值,这是最符合Prolog风格的写法,完全不会触发错误:
konst(S) :- between(0, 3, X), between(0, 4, Y), between(0, 5, Z), S = [X, Y, Z].
between/3会逐个生成范围内的数值并实例化X/Y/Z,之后构造列表S的操作完全合法,执行?- konst(S).会依次输出所有符合要求的三元列表。
方法二:保留自定义谓词,调整执行顺序
如果一定要保留你自己写的first/2等谓词,只需调整代码顺序,先通过between/3生成具体数值,再绑定到列表元素:
first(A, L) :- L = [K|_], A = K. second(A, L) :- L = [_|R], R=[F|_], A = F. third(A, L) :- L = [_|R], second(A, R). konst(S) :- between(0, 3, X), between(0, 4, Y), between(0, 5, Z), first(X, S), second(Y, S), third(Z, S).
这样X/Y/Z先被实例化为具体数值,再通过自定义谓词绑定到列表S的对应位置,避免了未实例化变量的比较错误。
内容的提问来源于stack exchange,提问作者Zoomyboy
相关产品推荐
相关产品推荐

