这适用于GNU-Prolog
我无法使某个谓词起作用。它的功能是匹配整数列表
域名为1到N
且没有重复项且长度为N
的域名。基本上我想做的是将其作为输入和输出:
| ?- row_valid(X, 3).
X = [1, 2, 3] ? ;
X = [1, 3, 2] ? ;
X = [2, 1, 3] ? ;
X = [2, 3, 1] ? ;
X = [3, 1, 2] ? ;
X = [3, 2, 1] ? ;
no
| ?- row_valid(X, 2).
X = [1, 2] ? ;
X = [2, 1] ? ;
no
| ?- row_valid(X, 1).
X = [1] ? ;
no
但是现在,这就是发生的事情:
| ?- row_valid(X, 3).
X = [] ? ;
no
这可能是因为我在代码中有row_valid([], _).
谓词。但是,我可以验证谓词是否正确匹配,因为:
| ?- row_valid([1,2,3], 3).
true ?
yes
以下是定义的谓词。你对我如何按照我想要的方式工作有什么建议吗?谢谢你的时间。
% row_valid/2: matches if list of integers has domain of 1 to N and is not duplicated
% 1 - list of integers
% 2 - N
row_valid([], _).
row_valid(Row, N) :-
length(Row, N), % length
no_duplicates_within_domain(Row, 1, N),
row_valid(RestRow, N).
% no_duplicates/1: matches if list doesn't have repeat elements
% 1 - list
no_duplicates([]). % for empty list always true
no_duplicates([Element | RestElements]) :-
\+ member(Element, RestElements), % this element cannot be repeated in the list
no_duplicates(RestElements).
% within_domain/3 : matches if list integers are within a domain
% 1 - list
% 2 - min
% 3 - max
within_domain(Integers, Min, Max) :-
max_list(Integers, Max),
min_list(Integers, Min).
% no_duplicates_within_domain/3: matches if list integers are within a domain and isn't repeated
% 1 - list
% 2 - min
% 3 - max
no_duplicates_within_domain(Integers, Min, Max) :-
no_duplicates(Integers),
within_domain(Integers, Min, Max).
答案 0 :(得分:1)
以下情况如何?
row_valid(Xs,N) :-
length(Xs,N),
fd_domain(Xs,1,N),
fd_all_different(Xs),
fd_labeling(Xs).
使用GNU Prolog 1.4.4运行它:
?- row_valid(Xs,N).
N = 0
Xs = [] ? ;
N = 1
Xs = [1] ? ;
N = 2
Xs = [1,2] ? ;
N = 2
Xs = [2,1] ? ;
N = 3
Xs = [1,2,3] ? ;
N = 3
Xs = [1,3,2] ? ;
N = 3
Xs = [2,1,3] ? ;
N = 3
Xs = [2,3,1] ? ;
N = 3
Xs = [3,1,2] ? ;
N = 3
Xs = [3,2,1] ? ;
N = 4
Xs = [1,2,3,4] ? % ...and so on...
答案 1 :(得分:0)
这是一段在SWI-Prolog中执行此操作的简单代码。我不知道GNU-Prolog是否提供between/3
和permutation/2
,所以也许它不会直接回答你的问题,但也许它仍然可以帮助你进一步。
row_valid(List, N) :-
findall(X, between(1, N, X), Xs),
permutation(Xs, List).
用法示例:
?- row_valid(List, 0).
List = [].
?- row_valid(List, 1).
List = [1] ;
false.
?- row_valid(List, 2).
List = [1, 2] ;
List = [2, 1] ;
false.
?- row_valid(List, 3).
List = [1, 2, 3] ;
List = [2, 1, 3] ;
List = [2, 3, 1] ;
List = [1, 3, 2] ;
List = [3, 1, 2] ;
List = [3, 2, 1] ;
false.