You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prolog八皇后问题代码报错,请求技术协助

八皇后Prolog代码问题排查与修复

你的代码核心逻辑是正确的(通过排列保证行列不重复,通过对角线和/差的唯一性保证无冲突),但存在两处可优化的点,其中一处可能导致运行效率极低或潜在逻辑漏洞:

问题分析

  1. all_diff终止条件不严谨:
    原代码中all_diff([X])仅处理了单元素列表,但未定义空列表的终止规则。虽然八皇后场景下不会传入空列表,但这种写法不够通用,且可能在递归边界出现意外问题。
  2. 自定义排列生成效率低:
    手动实现的perm和delete_member逻辑正确,但递归顺序和实现方式导致排列生成的效率较低,在部分Prolog环境中可能需要很长时间才能返回结果。

修复后的代码

% 使用内置select/3实现高效排列生成
perm([], []).
perm(List, [X|Perm]) :-
    select(X, List, Rest),
    perm(Rest, Perm).

solve(P) :-
    perm([1,2,3,4,5,6,7,8], P),
    combine([1,2,3,4,5,6,7,8], P, S, D),
    all_diff(S),
    all_diff(D).

combine([X1|X], [Y1|Y], [S1|S], [D1|D]) :-
    S1 is X1 + Y1,
    D1 is X1 - Y1,
    combine(X, Y, S, D).
combine([], [], [], []).

% 修正all_diff的终止条件,添加空列表处理
all_diff([]).
all_diff([X|Y]) :-
    \+member(X, Y),
    all_diff(Y).

% 查询示例
?- solve(P).
?- setof(P, solve(P), Set), length(Set, L).

修改说明

  • 排列生成优化:用Prolog内置的select/3替代自定义的perm和delete_member,select(X, List, Rest)会从List中选取元素X,剩余元素存入Rest,递归生成排列,逻辑更直观且效率更高。
  • all_diff逻辑修正:添加all_diff([]).作为终止条件,单元素列表的情况会通过all_diff([X|Y])自然处理(此时Y为空,\+member(X, [])为真,再调用all_diff([])),逻辑更严谨。

修复后运行查询,solve(P)会逐个返回八皇后的可行解,setof查询会返回所有92个解,符合预期。

内容的提问来源于stack exchange,提问作者Amita Arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:37:52