ПРОЛОГ — проверка правильности размещения

#prolog #puzzle #clpfd

#пролог #Головоломка #clpfd

Вопрос:

У меня есть головоломка, представляющая собой сетку 3 * 3 с номерами 1-8 в них, с пустым местом (0), которое я могу перемещать. Это конечное состояние головоломки:

 1 2 3 
8 0 4 
7 6 5
  

Все это «состояние» представлено состоянием (1,2,3,8,0,4,7,6,5) путем чтения по горизонтали. Мне нужна функция для проверки того, какие части находятся в правильных местах.

У меня есть:

 h(state(A,B,C,D,E,F,G,H,I),Z) :-
  

Теперь Z будет количеством частей в правильном месте.

 A = 1
B = 2
C = 3
D = 8
E = 0
F = 4
G = 7
H = 6
I = 5
  

Есть ли какой-нибудь простой способ выдать вывод для Z? Любая помощь будет оценена. Спасибо.

Ответ №1:

Вы уверены, что не можете хранить свою информацию в списках? Это своего рода то, как на традиционном языке вы используете массивы вместо просто набора переменных, если вам нужен способ перебора по ним.

Ответ №2:

Есть короткий способ выразить это в прологе, но для этого требуется CLP (FD).

 :- use_module(library(clpfd)).

h(State, Z) :-
    State =.. [state | Pos],
    maplist(equal, Pos, [0,1,2,3,8,0,4,7,6,5], Eq),
    sum(Eq, #=, Z).

equal(X, Y, E) :-
    E #<==> (X #= Y).
  

Ответ №3:

это кажется довольно простым в выполнении…

 h(state(A,B,C,D,E,F,G,H,I),Z) :-
    count_matching([A,B,C,D,E,F,G,H,I], [1,2,3,8,0,4,7,6,5], 0, Z).

count_matching([], [], N, N).
count_matching([A|As], [B|Bs], N, M) :-
    (   A == B
    ->  T is N   1
    ;   T is N
    ),
    count_matching(As, Bs, T, M).
  

SWI-Prolog aggregate library предлагает еще один простой способ решить вашу проблему:

 :- [library(aggregate)].

h(state(A,B,C,D,E,F,G,H,I),Z) :-
    aggregate_all(count,
      (nth1(Index, [1,2,3,8,0,4,7,6,5], Cell),
       nth1(Index, [A,B,C,D,E,F,G,H,I], Cell)), Z).
  

Использование aggregate_all является излишним: здесь более простая программа, использующая ту же схему (недетерминированный доступ к элементам через nth / 3):

 h(state(A,B,C,D,E,F,G,H,I),Z) :-
    findall(_,
      (nth1(Index, [1,2,3,8,0,4,7,6,5], Cell),
       nth1(Index, [A,B,C,D,E,F,G,H,I], Cell)), L),
    length(L, Z).