2010-11-01 10 views
-1

这是GNU-Prolog的谓词以配合没有重复的整数列表(所有的可能性),具有长度N,和是1域内到N

我无法得到一定的谓词上班。它的功能是它匹配一个整数列表 ,其域名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

这是SWI-Prolog中的一段简单代码。我不知道GNU-Prolog是否提供了between/3permutation/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. 
+0

谢谢,我居然找到了一个解决方案已经但是这看起来像它的工作原理呢! GNU-Prolog没有'/ 3 /之间的',但它有'fd_domain/3'。 – axsuul 2010-11-01 11:28:03

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... 
+0

为什么不坚持纯度:'? - A + \(A = N:Xs,row_valid(Xs,N)).' – false 2015-05-26 12:09:51

+0

@false。你可以在GNU Prolog中使用'library(lambda)'吗?那么,我不能... – repeat 2015-05-26 15:01:15

+0

只需包括[实施](http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord#implementation)。 Lambdas是100%的ISO。 – false 2015-05-26 15:09:25

相关问题