2009-11-20 83 views
7

我想了解一些關於swi-prolog(超出基本的,無用的程序)。序言:通過示例學習

任何人都可以解釋(也許在僞代碼)這個數獨求解器和相關函數在做什麼?如果您需要更多參考資料,請參閱swi-prolog的CLP(FD)軟件包。

謝謝!

:- use_module(library(clpfd)). 
sudoku(Rows) :-             
     length(Rows, 9), maplist(length_(9), Rows),     
     append(Rows, Vs), Vs ins 1..9,        
     maplist(all_distinct, Rows),        
     transpose(Rows, Columns), maplist(all_distinct, Columns), 
     Rows = [A,B,C,D,E,F,G,H,I],         
     blocks(A, B, C), blocks(D, E, F), blocks(G, H, I).   


length_(L, Ls) :- length(Ls, L).         

blocks([], [], []).             
blocks([A,B,C|Bs1], [D,E,F|Bs2], [G,H,I|Bs3]) :-     
     all_distinct([A,B,C,D,E,F,G,H,I]),       
     blocks(Bs1, Bs2, Bs3).          


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

學習序言就像學習其他語言一樣。對原始人有良好的感覺,並且可以通過練習來剖析和理解任何程序。基本無用的程序是你的朋友。 – echo 2009-11-20 05:40:58

回答

3

數獨/ 1基本上描述了Sudoku解決方案必須滿足的約束,其中董事會被表示爲九個長度爲九的列表的列表。問題/ 2將部分實例化的板分配給問題編號。要使用它,你應該做

? - 問題(1,董事會),數獨(董事會)。

您應該閱讀the documentation中使用的謂詞。

10

序言是一種不同的思維方式:你必須邏輯思考。

首先A :- B, C, D表示如果B和C和D爲真,則A爲真(成功)

的代碼,你貼檢查一個數獨題的正確性的片段中,有三個條件:

  • 元素是行的所有不同
  • 元素是列
  • 元素都是不同所有不同的3×3塊

它是如何工作的?

數獨(行)爲真,如果:

  1. length(Rows, 9) - >有以行9個元件
  2. maplist(_length(9), Rows) - >列表中的每一個元件上maplist檢查謂詞(第一參數)(第二個參數)。這意味着每一行的長度必須是9.
  3. maplist(all_distinct, Rows) - >和以前一樣,但我們檢查每一行是否有不同的(不相等的成對)元素。
  4. transpose(Rows, Columns), maplist(all_distinct, Columns) - >我們轉了行成列的檢查,如果他們都不同也由垂直方式選擇它們
  5. Rows = [A,B,C,D,E,F,G,H,I] - >分裂排列表,並把每一個不同的變量A,B,C, D ...所以A將是第一行,B第二個等等
  6. blocks(A, B, C), blocks(D, E, F), blocks(G, H, I) - >這個謂詞對於三元組行必須爲真。

讓我們來談談blocks的一部分,這是很有趣的理解。我們希望檢查每個3x3塊包含不同的值。我們怎麼做到這一點?

假設有3行,對於第4到第6個(第2個塊)和第7-9個(第3個塊)的元素,每個行的前三個元素(第一個3x3塊)的條件必須爲真。

所以我們可以遞歸思考:blocks([],[],[])是平凡的,我們有空列表。

當您調用blocks謂詞時選擇了案例blocks([A,B,C|Bs1],[D,E,F|Bs2],[G,H,I|Bs3]),其參數與AT至少3個元素一起列出。因此,我們可以檢查A,B,C,D,E,F,G,H和I是否都是不同的,然後我們將blocks遞歸地用作參數剩餘列表(沒有前三個元素)。這是Prolog的內容!

所以blocks將首先被調用三行9個元素,它將檢查每行的前3個是不同的,並且自己調用3個包含6個元素的列表,再次檢查並自己調用3個3元素列表,再次檢查並用三個空列表(總是成功的trival case)自行調用。

+0

那麼「追加(行,Vs),Vs ins 1..9」呢?它的意義是什麼? – 2010-05-19 18:08:30