幻方序言

Magic square prolog

我有这段代码,我想重构一个部分以提高效率。

num(1).
num(2).
num(3).
num(4).
num(5).              
num(6).              
num(7).               
num(8).
num(9).



nums(A,B,C,D,E,F,G,H,I):-
      num(A),num(B),num(C),              
      num(D),num(E),num(F),              
      num(G),num(H),num(I),    
      A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I, 
            B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I, 
                  C\==D,C\==E,C\==F,C\==G,C\==H,C\==I, 
                        D\==E,D\==F,D\==G,D\==H,D\==I, 
                              E\==F,E\==G,E\==H,E\==I, 
                                    F\==G,F\==H,F\==I, 
                                          G\==H,G\==I,
                                                H\==I.

square(A,B,C,D,E,F,G,H,I):-
         nums(A,B,C,D,E,F,G,H,I),
         S1 is A + B + C,
         S2 is D + E + F,
         S3 is G + H + I, 
         S4 is A + D + G,
         S5 is B + E + H,
         S6 is C + F + I,
         S7 is A + E + I,
         S8 is G + E + C,
         S1==S2,S2==S3,S3==S4,S4==S5,S5==S6,S6==S7,S7==S8.   
          
solution([A,B,C,D,E,F,G,H,I]):-square(A,B,C,D,E,F,G,H,I).

我想减少的部分是这个,我不知道如何使用一个函数,我需要避免在我使用大量代码的地方做这样的事情,而是创建一个我可以解决的函数几行

A\==B,A\==C,A\==D,A\==E,A\==F,A\==G,A\==H,A\==I, 
            B\==C,B\==D,B\==E,B\==F,B\==G,B\==H,B\==I, 
                  C\==D,C\==E,C\==F,C\==G,C\==H,C\==I, 
                        D\==E,D\==F,D\==G,D\==H,D\==I, 
                              E\==F,E\==G,E\==H,E\==I, 
                                    F\==G,F\==H,F\==I, 
                                          G\==H,G\==I,
                                                H\==I.

我建议你使用CLP(FD)来解决这类问题:

fd_square(Sol, Sum):-
  Sol=[A,B,C,D,E,F,G,H,I],
  Sol ins 1..9,
  all_distinct(Sol),
  maplist(#=(Sum),
    [
     A + B + C,
     D + E + F,
     G + H + I,
     A + D + G,
     B + E + H,
     C + F + I,
     A + E + I,
     G + E + C
    ]).

样本运行:

?- fd_square(Sol, Sum), label(Sol).
Sol = [2, 7, 6, 9, 5, 1, 4, 3, 8],
Sum = 15 ;
Sol = [2, 9, 4, 7, 5, 3, 6, 1, 8],
Sum = 15 ;
Sol = [4, 3, 8, 9, 5, 1, 2, 7, 6],
Sum = 15 ;
Sol = [4, 9, 2, 3, 5, 7, 8, 1, 6],
Sum = 15 ;
Sol = [6, 1, 8, 7, 5, 3, 2, 9, 4],
Sum = 15 ;
Sol = [6, 7, 2, 1, 5, 9, 8, 3, 4],
Sum = 15 ;
Sol = [8, 1, 6, 3, 5, 7, 4, 9, 2],
Sum = 15 ;
Sol = [8, 3, 4, 1, 5, 9, 6, 7, 2],
Sum = 15 ;
false.