【问题标题】:Prolog solve SudokuProlog解决数独
【发布时间】:2017-06-20 19:27:56
【问题描述】:

我是 Prolog 的新手,在 swi-prolog.org 上找到了这个示例来解决数独问题。但我无法运行它。我查了一下same_length,只有same_length/2 而不是same_length/1。还有all_distinct/2 而不是all_distinct/0http://www.swi-prolog.org/pldoc/man?section=clpfd-sudoku

这是我的错误:

ERROR: d:/.../prolog/sudoku.pl:5:10: Syntax error: Operator expected
% d:/.../prolog/sudoku compiled 0.00 sec, 0 clauses
Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning: 
Warning: all_distinct/1, which is referenced by
Warning:        d:/.../prolog/sudoku.pl:16:8: 2-nd clause of blocks/3

这里是 SWI-Prolog 示例的代码:

    use_module(library(clpfd)). 

    sudoku(Rows) :-
        length(Rows, 9), maplist(same_length(Rows), Rows),
        append(Rows, Vs),
        Vs in 1..9,
        maplist(all_distinct, Rows),
        transpose(Rows, Columns),
        maplist(all_distinct, Columns),
        Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
        blocks(As, Bs, Cs),
        blocks(Ds, Es, Fs),
        blocks(Gs, Hs, Is).

blocks([], [], []). 
blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
        all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
        blocks(Ns1, Ns2, Ns3).

problem(1, [[_,_,_,_,_,_,_,_,_],
            [_,_,_,_,_,3,_,8,5],
            [_,_,1,_,2,_,_,_,_],
            [_,_,_,5,_,7,_,_,_],
            [_,_,4,_,_,_,1,_,_],
            [_,9,_,_,_,_,_,_,_],
            [5,_,_,_,_,_,_,7,3],
            [_,_,2,_,1,_,_,_,_],
            [_,_,_,_,4,_,_,_,9]]).

希望你能帮我找出我的错误。

【问题讨论】:

  • 此代码的链接在哪里?我对maplist(same_length(Rows, Rows), Rows) 的含义感到困惑。乍一看,其余部分在我看来并不疯狂。
  • 我已将其添加到说明中
  • 我自己从网站上复制并粘贴了代码,它可以工作。在您上次的编辑中,您删除了我在之前评论中指出的错字;我建议您需要再次尝试复制粘贴代码并根据链接页面运行查询,它会为您工作。
  • 我使用 swi Prolog 并在 sudoku.pl 中将其 1 对 1 复制并查阅此文件。但我仍然得到错误
  • 够有趣的。不,它有效。但我一点都没变

标签: prolog sudoku swi-prolog constraint-programming clpfd


【解决方案1】:

据我所知,它现在已经适合您了。不过,我仍然想借此机会向您展示一些可能对您有用的提示:

事实与指令

首先,为什么您在答案中发布的代码不起作用?

Prolog 消息已经给出了很好的指示:

警告:以下谓词未定义。 ... ... all_distinct/1,被引用

这表明您实际上在代码某处中使用了all_distinct/1不是all_distinct/2!),并且它不可用。

为什么?因为all_distinct/1library(clpfd) 中可用,而您没有导入该库

这是初学者中很常见的错误。查看您的程序中的以下行:

使用模块(库(clpfd))。

与您可能相信的相反,这确实不导入库!为什么?因为就目前而言,这只是 use_module/1 形式的 Prolog 事实,类似于以下事实:

名字(鲍勃)。

同样,它没有命名bob,而只是声明name(bob)持有

您想要的是使用 指令 来导入库。

指令:-(D)形式的术语,也可以写成:- D,因为(:-)/1是前缀运算符

因此,您的意思是:

:- 使用模块(库(clpfd))。

这是:-(T) 形式的术语,在加载文件时将作为指令处理。

方便定义

就我个人而言,我经常编写小型 Prolog 程序,其中大多数都使用 CLP(FD) 约束。在某些时候,我厌倦了将:- use_module(library(clpfd)). 添加到我的所有程序中,因此我在~/.emacs 中添加了以下定义:

(global-set-key "\C-cl" (lambda () (交互的) (插入“:- use_module(库())。”) (forward-char -3)))

当您现在按 C-c l 时,会在该点插入以下 sn-p:

:- 使用模块(库())。

并且点位于() 中,因此您只需键入库的实际名称,而不是其:- use_module...etc. 指令。

所以,要使用library(clpfd),我只需输入:

C-c l clpfd

过了一会儿,我也厌倦了,干脆将:- use_module(library(clpfd)).添加到我的~/.swiplrc配置文件中,因为我编写的几乎所有程序都执行整数运算,所以对我来说制作CLP( FD) 在我编写的所有 Prolog 程序中都有约束。例如,在 GNU Prolog 和 B-Prolog 等系统中也是如此。

但是,我仍然保留了 .emacs 的定义,因为有时我需要导入其他库,而且我发现输入整个 :- use_module... 指令太麻烦且容易出错。

【讨论】:

    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多