让我们直言不讳。我正在尝试自己创建一个数独的构造解算器(不是与学校相关的)。而且我已经找了几件让它起作用的东西,我遇到了一个问题,也许更多的人有。
例如,如果数据是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.
查询结果为distinct_but_2(1,1,2,2)。这是真的,但它说它还有其他解决方案。这是假的。而我真的不明白为什么。
所以最后一个问题是,如果所有元素都有min和max一个相同的元素,是否可以创建一个检查列表的谓词。
*请注意,我没有创建一个列表,因为我试图让它适用于4个元素,但我应该列入一个列表。
你没有说你正在使用哪种Prolog系统,但似乎你正在寻找像global_cardinality/{2,3}
这样的东西,因为SWI有它:http://www.swi-prolog.org/pldoc/man?predicate=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]
用Sudoku提示查询:
?- 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].