Пролог Макс 2 одинаковых номера в списке - PullRequest
1 голос
/ 11 марта 2019

давайте перейдем прямо к делу.Я пытаюсь самостоятельно создать тектонический решатель судоку (не связанный со школой).И я искал пару вещей, чтобы заставить его работать, и я столкнулся с проблемой, может быть, больше людей.

Так как возможно иметь несколько одинаковых чисел в строке или столбце, напримересли судоку 10 x 10 и вам нужно заполнить число от 1 до 5, то твердый раствор будет 1,2,1,3,2,3,4,5,4,5.Поскольку все числа используются, а min и max равны 2. Теперь остается вопрос, как мне написать предикат, который принимает в List и возвращает True или false на основе чисел в списке.

, так какНевозможно использовать сборку в предикате all_distinct, но, возможно, выглядит так, потому что теперь вместо всех отличных все различны, если есть 2 одинаковых числа, если вы следуете за мной.

Я пыталсясделать некрасивый фиксированный предикат, но он никуда меня не приведет.пример.

distinct_but_2(A,B,C,D) :-
(   A = B
->  A \= C,
    A \= D),
(   A = C
->  A \= B,
    A \= D),
(   A = D
->  A \= B,
    A \= C),
(   B = A
->  B \= C,
    B \= D),
(   B = C
->  B \= A,
    B \= D),
(   B = D
->  B \= A,
    B \= C),
(   C = A
->  C \= B,
    C \= D),
(   C = B
->  C \= A,
    C \= D),
(   C = D
->  C \= A,
    C \= B),
(   D = A
->  D \= B,
    D \= C),
(   D = B
->  D \= A,
    D \= C),
(   D = C
->  D \= A,
    D \= B).

В котором я просто пытаюсь сказать, что если A = B, то это так, что оно не равно всем остальным, но мне все еще не хватает того, что все элементы должны иметьдругой элемент, который такой же.

Вот другой пример, который я пробовал

    distinct_but_2(A,B,C,D) :-
(isEqual(A,B), isEqual(C,D), notIsEqual(A,C), notIsEqual(A,D));
(isEqual(A,C), isEqual(B,D), notIsEqual(A,B), notIsEqual(A,D));
(isEqual(A,D), isEqual(B,C), notIsEqual(A,B), notIsEqual(A,C)).

isEqual (A, B): - A = B.

notIsEqual (A,B): - A \ = B.

Результат запроса Different_but_2 (1,1,2,2).было бы правдой, но он говорит, что у него есть и другое решение.что это ложьИ я просто не могу понять, почему.

Итак, последний вопрос: можно ли создать предикат, который проверяет список, если все элементы имеют одинаковые минимальный и максимальный элементы?

* Обратите внимание, что я не создал предикат, который принимает список, поскольку я пытался заставить его работать для 4 элементов, но я должен взять список.

1 Ответ

0 голосов
/ 11 марта 2019

Вы не сказали, какую систему Prolog вы используете, но похоже, что вы ищете что-то вроде global_cardinality/{2,3}, как это имеет SWI: http://www.swi -prolog.org / pldoc / man? Предикат = global_cardinality / 3

Вот пример того, как его использовать:

:- use_module(library(clpfd)).

two_each(Numbers, Vars) :-
    length(Numbers, Len),
    Len2 #= 2*Len,
    length(Vars, Len2),
    bagof(X-2, member(X, Numbers), Pairs),
    global_cardinality(Vars, Pairs).

запрос:

?- two_each([1,2,3], Vars), label(Vars).
Vars = [1, 1, 2, 2, 3, 3] ;
Vars = [1, 1, 2, 3, 2, 3] ;
Vars = [1, 1, 2, 3, 3, 2] 

запрос с подсказками судоку:

?- two_each([1,2,3], Vars), Vars=[_,3,_,1,1,_], label(Vars).
Vars = [2, 3, 2, 1, 1, 3] ;
Vars = [2, 3, 3, 1, 1, 2] ;
Vars = [3, 3, 2, 1, 1, 2].
...