七週七語言:Prolog Day 3

第三天

Prolog真是一位解題高手,Sudoku是我非常喜歡的一個遊戲,Programming Logically!

不過對於不熟悉Prolog謂詞的而言,又成了一個比較頭疼所事,如果不告訴我可以用fd_all_difference來判斷一個列表中元素沒有重複值,真的不會想到用“謂詞”。
其實覺得用Prolog來解決一下AI問題是很有用的,比如做一個棋類遊戲的AI,告訴Prolog規則,恐怕就能將我擊敗:-|

先找了一下Prolog的輸出謂詞:

   geto(X) 如 X與輸入流中的下一個字符匹配,則目標成功。
    get(X) 如 X與輸入流中的下一個打印字符匹配,則目標成功
   skip(X) 讀入並跳過當前輸入流中的字符,直到找到一個可與X匹配的字符
   read(X) 讀入當前輸入流的下一個項,並使之與X匹配
    put(X) 把整數X輸出到當前輸出流(X必須例化)
        nl  對當前輸出流輸出控制符"回車換行"
    tab(X) 輸出X個空格符到當前輸出流(X必須例化)
  write(X) 把項X輸出到當前輸出流
display(X) 與write(X)相似,只是它忽略運算符說明,以結構形式輸出項
 op(X,Y,Z) 說明名爲Z的運算符,其優先級爲X,結合規則爲Y

  • 修改數獨解決器來解決6*6數獨和9*9數獨問題

    6*6 和 9*9 其實都一樣,不過修改下Puzzle的構造

    valid([]).
    valid([Head|Tail]) :-
       fd_all_different(Head),
       valid(Tail).
    
    sudoku(Puzzle, Solution) :-
       Solution = Puzzle,
       Puzzle = [S11, S12, S13, S14, S15, S16,
                 S21, S22, S23, S24, S25, S26,
                 S31, S32, S33, S34, S35, S36,
                 S41, S42, S43, S44, S45, S46,
                 S51, S52, S53, S54, S55, S56,
                 S61, S62, S63, S64, S65, S66],
       fd_domain(Puzzle, 1, 6),
       
       Row1 = [S11, S12, S13, S14, S15, S16],
       Row2 = [S21, S22, S23, S24, S25, S26],
       Row3 = [S31, S32, S33, S34, S35, S36],
       Row4 = [S41, S42, S43, S44, S45, S46],
       Row5 = [S51, S52, S53, S54, S55, S56],
       Row6 = [S61, S62, S63, S64, S65, S66],
    
       Col1 = [S11, S21, S31, S41, S51, S61],
       Col2 = [S12, S22, S32, S42, S52, S62],
       Col3 = [S13, S23, S33, S43, S53, S63],
       Col4 = [S14, S24, S34, S44, S54, S64],
       Col5 = [S15, S25, S35, S45, S55, S65],
       Col6 = [S16, S26, S36, S46, S56, S66],
    
       Square1 = [S11, S12, S13, S21, S22, S23],
       Square2 = [S14, S15, S16, S24, S25, S26],
       Square3 = [S31, S32, S33, S41, S42, S43],
       Square4 = [S34, S35, S36, S44, S45, S46],
       Square5 = [S51, S52, S53, S61, S62, S63],
       Square6 = [S54, S55, S56, S64, S65, S66],
    
       valid([Row1, Row2, Row3, Row4, Row5, Row6,
             Col1, Col2, Col3, Col4, Col5, Col6,
             Square1, Square2, Square3, Square4, Square5, Square6]).
    		
  • 讓數獨解決器輸出格式更美觀的解決方法

    這其實無非在每一行結束的時候換行- -
    可以選擇在Sudoku規則中放一個輸出每一行的謂詞序列,不過不清楚Prolog在“回答”的時候是如何格式化的:-(
    在文件中加入以下代碼即可“格式化”地輸出解題的結果。

    write('\n'), write(Row1),
    write('\n'), write(Row2),
    write('\n'), write(Row4),		  
    ...
    		
  • 採用一個皇后列表的方式解決八皇后問題。使用一個1~8範圍內的數字代表每個皇后,而不是元組。通過皇后在列表中的位置獲取其行號並且通過其在列表中的值獲得其列號。

    其實書中的‘optimized_queens’就是可以用1~8來代表皇后的,因爲每一行肯定有一個皇后,所以可以用行號或者列號來代表皇后。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章