Prolog:3x3の魔法陣の解を求める
gprologのFDの練習として、SPINで以前に書いた3x3の魔法陣の解を求めてみます。gprologのソースファイルにはサンプルが含まれています。その中にmagsq.plがあり、魔法陣のサイズを指定できるものがあります。
ソース ms.pl
/* 魔法陣 */ ms(MS) :- MS = [ V11, V12, V13, V21, V22, V23, V31, V32, V33 ], /* 各要素は1〜9である。*/ fd_domain(MS, 1, 9), /* 各要素の値は異なる。*/ fd_all_different(MS), /* 行の和は15である。*/ V11 + V12 + V13 #= 15, V21 + V22 + V23 #= 15, V31 + V32 + V33 #= 15, /* 列の和は15である。*/ V11 + V21 + V31 #= 15, V12 + V22 + V32 #= 15, V13 + V23 + V33 #= 15, /* 対角の和は15である。*/ V11 + V22 + V33 #= 15, V31 + V22 + V13 #= 15, fd_labeling(MS). /* 出力用の述語 */ pp([V11, V12, V13, V21, V22, V23, V31, V32, V33]) :- write(V11), write(' '), write(V12), write(' '), write(V13), nl, write(V21), write(' '), write(V22), write(' '), write(V23), nl, write(V31), write(' '), write(V32), write(' '), write(V33), nl.
実行
$ gprolog GNU Prolog 1.4.5 (64 bits) Compiled Mar 17 2020, 23:55:22 with gcc By Daniel Diaz Copyright (C) 1999-2020 Daniel Diaz | ?- ['ms.pl']. : | ?- ms(Ans),pp(Ans). 2 7 6 9 5 1 4 3 8 Ans = [2,7,6,9,5,1,4,3,8] ? ; 2 9 4 7 5 3 6 1 8 Ans = [2,9,4,7,5,3,6,1,8] ? ; 4 3 8 9 5 1 2 7 6 Ans = [4,3,8,9,5,1,2,7,6] ? ; 4 9 2 3 5 7 8 1 6 Ans = [4,9,2,3,5,7,8,1,6] ? ; 6 1 8 7 5 3 2 9 4 Ans = [6,1,8,7,5,3,2,9,4] ? ; 6 7 2 1 5 9 8 3 4 Ans = [6,7,2,1,5,9,8,3,4] ? ; 8 1 6 3 5 7 4 9 2 Ans = [8,1,6,3,5,7,4,9,2] ? ; 8 3 4 1 5 9 6 7 2 Ans = [8,3,4,1,5,9,6,7,2] ? ; (1 ms) no