Prolog加载同一文件偶数次后执行maplist相关查询出现未知过程错误
故障成因
该错误是SWI-Prolog编译maplist/3闭包调用时生成的辅助谓词缺失导致的:
- 代码中
maplist(espacos_fila(h), Puzzle, Espacos_h_l)属于带预绑定参数的闭包调用,SWI-Prolog编译espacos_puzzle/2时,会自动生成名为__aux_maplist/3_espacos_fila+1的私有辅助谓词,专门调用绑定了首参数h的espacos_fila/3。 - 同一交互会话中重复加载同一文件时,SWI-Prolog默认会先清除旧谓词定义再重新编译,旧辅助谓词会被一并删除;若增量编译缓存未正确触发新辅助谓词生成,就会触发“未知过程”错误。
- 中止会话重新加载时,编译缓存被完全清空,所有辅助谓词会被重新生成,故障随即消失。
解决方法
按优先级从高到低选择执行:
- 加载文件时手动禁用缓存,使用命令:
?- load_files('projecto1.pl', [redefine_module(true), if(changed), silent(false)]).替代默认的consult/1加载方式。 - 在
espacos_fila/3的定义前添加元谓词声明,根据实际参数的输入输出属性调整标记::- meta_predicate espacos_fila(+, +, -).该声明会引导编译器使用标准元调用逻辑,不生成临时辅助谓词。 - 手动替换
maplist闭包调用为显式递归,完全规避辅助谓词生成:- 新增以下递归谓词:
aplica_espacos_fila(_, [], []). aplica_espacos_fila(Direcao, [Linha | RestoLinhas], [EspacosFila | RestoEspacos]) :- espacos_fila(Direcao, Linha, EspacosFila), aplica_espacos_fila(Direcao, RestoLinhas, RestoEspacos). - 将原第129行的
maplist(espacos_fila(h), Puzzle, Espacos_h_l)替换为:aplica_espacos_fila(h, Puzzle, Espacos_h_l)
- 新增以下递归谓词:
- 每次重新加载前手动清除相关谓词定义:
?- abolish(espacos_puzzle/2), abolish(espacos_fila/3).再执行加载操作。
验证步骤
加载完成后执行:- listing(espacos_puzzle). 检查编译后的代码是否存在正确的辅助谓词引用,再运行原查询即可。
内容的提问来源于stack exchange,提问作者Javier de Muller Santa-María
相关产品推荐
相关产品推荐

