List 为什么prolog在收到错误消息后不回溯?

List 为什么prolog在收到错误消息后不回溯?,list,prolog,clpfd,List,Prolog,Clpfd,我有一个代码,它计算一个数字列表,并返回与模式匹配的列表[G,a],[a,B],[B,C],[C,D],[D,E],[E,F],[F,G]。但是,我希望这些数字只能是唯一的数字。例如:([0,2],[2,4],[4,19],[19,3],[3,5],[5,7],[7,0])。不同的方法根据输入的数字返回true或false。但是,代码仍然返回具有多个相似数字的数字 r5(L,R):- R = [[G,A],[A,B],[B,C],[C,D],[D,E],[E,F],[F,G]],

我有一个代码,它计算一个数字列表,并返回与模式匹配的列表
[G,a],[a,B],[B,C],[C,D],[D,E],[E,F],[F,G]
。但是,我希望这些数字只能是唯一的数字。例如:(
[0,2],[2,4],[4,19],[19,3],[3,5],[5,7],[7,0]
)。不同的方法根据输入的数字返回true或false。但是,代码仍然返回具有多个相似数字的数字

r5(L,R):-
    R = [[G,A],[A,B],[B,C],[C,D],[D,E],[E,F],[F,G]],

    [A,B,C,D,E,F,G] ins 0 .. 27,

    different([A,B,C,D,E,F,G]),

    member([G,A],L),
    member([A,B],L),
    member([B,C],L),
    member([C,D],L),
    member([D,E],L),
    member([E,F],L),
    member([F,G],L),

    label([A,B,C,D,E,F,G]).
这是它返回的部分的示例:

R = [[0, 2], [2, 0], [0, 2], [2, 5], [5, 9], [9, 2], [2, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 5], [5, 23], [23, 17], [17, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 5], [5, 24], [24, 19], [19, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 5], [5, 26], [26, 12], [12, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 9], [9, 5], [5, 2], [2, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 9], [9, 15], [15, 2], [2, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 9], [9, 15], [15, 17], [17, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 9], [9, 15], [15, 19], [19, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 15], [15, 9], [9, 2], [2, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 21], [21, 1], [1, 12], [12, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 21], [21, 1], [1, 20], [20, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 21], [21, 11], [11, 12], [12, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 21], [21, 11], [11, 17], [17, 0]] ;
R = [[0, 2], [2, 0], [0, 2], [2, 21], [21, 24], [24, 19], [19, 0]] ;
R = [[0, 2], [2, 0], [0, 12], [12, 1], [1, 18], [18, 12], [12, 0]] ;
所有这些都无效,因为它们包含重复的数字。以下是输出中进一步向下的两个有效输出:

R = [[0, 2], [2, 9], [9, 4], [4, 8], [8, 23], [23, 17], [17, 0]] ;
R = [[0, 2], [2, 9], [9, 4], [4, 8], [8, 24], [24, 19], [19, 0]] ;
这是不同的方法:

different(X) :-
    sort(X, Sorted),
    length(X, OriginalLength),
    length(Sorted, SortedLength),
    OriginalLength == SortedLength.
这是我最初的电话:

r5_3([[0, 2],[2,0],[0, 12],[12,0],[0, 17],[17,0],[0, 19],[19,0],[0, 20],[20,0],[1, 4],[4,1],[1, 12],[12,1],[1, 18],[18,1],[1, 20],[20,1],[1, 21],[21,1],[2, 5],[5,2],[9, 2],[2,9],[2, 15],[15,2],[2, 21],[21,2],[8, 3],[3,8],[10, 3],[3,10],[16, 3],[3,16],[3, 22],[22,3],[25, 3],[3,25],[8, 4],[4,8],[9, 4],[4,9],[4, 23],[23,4],[26, 4],[4,26],[9, 5],[5,9],[5, 23],[23,5],[24, 5],[5,24],[26, 5],[5,26],[14, 6],[6,14],[17, 6],[6,17],[18, 6],[6,18],[24, 6],[6,24],[25, 6],[6,25],[18, 7],[7,18],[19, 7],[7,19],[22, 7],[7,22],[23, 7],[7,23],[26, 7],[7,26],[8, 14],[14,8],[8, 23],[23,8],[8, 24],[24,8],[9, 15],[15,9],[9, 13],[13,9],[16, 10],[10,16],[10, 20],[20,10],[10, 13],[13,10],[10, 27],[27,10],[11, 12],[12,11],[17, 11],[11,17],[11, 21],[21,11],[25, 11],[11,25],[11, 27],[27,11],[18, 12],[12,18],[26, 12],[12,26],[14, 15],[15,14],[16, 14],[14,16],[26, 14],[14,26],[17, 15],[15,17],[19, 15],[15,19],[16, 20],[20,16],[16, 22],[22,16],[17, 23],[23,17],[18, 27],[27,18],[24, 19],[19,24],[19, 27],[27,19],[25, 20],[20,25],[24, 21],[21,24],[13, 21],[21,13],[25, 22],[22,25],[13, 22],[22,13],[27, 13],[13,27]],R).

all_different/1
是CLP(FD)库的一部分。只有在调用
different/1
之前执行
label/1
时,您的
different/1
才会起作用

因此,您可以在当前实现中使用
所有不同的/1
(首选),也可以按如下方式重新排列代码:

r5(L,R):-
    R = [[G,A],[A,B],[B,C],[C,D],[D,E],[E,F],[F,G]],

    [A,B,C,D,E,F,G] ins 0 .. 27,

    % all_different([A,B,C,D,E,F,G]), % preferred in place of 'different/1' below

    label([A,B,C,D,E,F,G]),        

    different([A,B,C,D,E,F,G]),

    member([G,A],L),
    member([A,B],L),
    member([B,C],L),
    member([C,D],L),
    member([D,E],L),
    member([E,F],L),
    member([F,G],L).

原始代码中的
L
的用途有点不清楚。更通用的解决方案可能如下所示:

:- use_module(library(clpfd)).

% Define consecutive intervals consisting of Length intervals
%  with elements from 0 to MaxNumber
consecutive_intervals(MaxNumber, Length, Intervals):-
    length(Elements, Length),             % Establish the number of elements
    Elements ins 0 .. Max,                % Establish the range of each element
    all_different(Elements),              % Each element is different
    list_intervals(Elements, Intervals),  % Define consecutive intervals
    label(Elements).

% list_intervals(List, Intervals)
%    Intervals is a complete list of consecutive intervals with elements from List
list_intervals([X1,X2|Xs], [[X1,X2]|T]) :-
    list_intervals([X2|Xs], X1, T).
list_intervals([X2], X1, [[X2,X1]]).
list_intervals([X2,X3|Xs], X1, [[X2,X3]|T]) :-
    list_intervals([X3|Xs], X1, T).
解决方案的数量很多,但这里有一个小的简化示例:

?- consecutive_intervals(4, 3, R).
R = [[0, 1], [1, 2], [2, 0]] ;
R = [[0, 1], [1, 3], [3, 0]] ;
R = [[0, 1], [1, 4], [4, 0]] ;
R = [[0, 2], [2, 1], [1, 0]] ;
R = [[0, 2], [2, 3], [3, 0]] ;
R = [[0, 2], [2, 4], [4, 0]] ;
...
R = [[4, 3], [3, 0], [0, 4]] ;
R = [[4, 3], [3, 1], [1, 4]] ;
R = [[4, 3], [3, 2], [2, 4]] ;
false.

all_different/1
是CLP(FD)库的一部分。只有在调用
different/1
之前执行
label/1
时,您的
different/1
才会起作用

因此,您可以在当前实现中使用
所有不同的/1
(首选),也可以按如下方式重新排列代码:

r5(L,R):-
    R = [[G,A],[A,B],[B,C],[C,D],[D,E],[E,F],[F,G]],

    [A,B,C,D,E,F,G] ins 0 .. 27,

    % all_different([A,B,C,D,E,F,G]), % preferred in place of 'different/1' below

    label([A,B,C,D,E,F,G]),        

    different([A,B,C,D,E,F,G]),

    member([G,A],L),
    member([A,B],L),
    member([B,C],L),
    member([C,D],L),
    member([D,E],L),
    member([E,F],L),
    member([F,G],L).

原始代码中的
L
的用途有点不清楚。更通用的解决方案可能如下所示:

:- use_module(library(clpfd)).

% Define consecutive intervals consisting of Length intervals
%  with elements from 0 to MaxNumber
consecutive_intervals(MaxNumber, Length, Intervals):-
    length(Elements, Length),             % Establish the number of elements
    Elements ins 0 .. Max,                % Establish the range of each element
    all_different(Elements),              % Each element is different
    list_intervals(Elements, Intervals),  % Define consecutive intervals
    label(Elements).

% list_intervals(List, Intervals)
%    Intervals is a complete list of consecutive intervals with elements from List
list_intervals([X1,X2|Xs], [[X1,X2]|T]) :-
    list_intervals([X2|Xs], X1, T).
list_intervals([X2], X1, [[X2,X1]]).
list_intervals([X2,X3|Xs], X1, [[X2,X3]|T]) :-
    list_intervals([X3|Xs], X1, T).
解决方案的数量很多,但这里有一个小的简化示例:

?- consecutive_intervals(4, 3, R).
R = [[0, 1], [1, 2], [2, 0]] ;
R = [[0, 1], [1, 3], [3, 0]] ;
R = [[0, 1], [1, 4], [4, 0]] ;
R = [[0, 2], [2, 1], [1, 0]] ;
R = [[0, 2], [2, 3], [3, 0]] ;
R = [[0, 2], [2, 4], [4, 0]] ;
...
R = [[4, 3], [3, 0], [0, 4]] ;
R = [[4, 3], [3, 1], [1, 4]] ;
R = [[4, 3], [3, 2], [2, 4]] ;
false.

哪里定义了
不同/1
?使用
所有不同的([A,B,C,D,E,F,G])
。您说“不同的方法根据输入的数字返回true或false”,但prolog不返回任何内容。谓词要么成功,要么失败。@Enigmativity我添加了我的不同方法,但如果已经存在一个完全不同的/1方法,那么我再发明轮子就没有用了。:)@为了让自己对编码有不同的想法,Prolog是一种非常好的学习语言。当你得到那一刻,你会爱上它。我根本不是专家,甚至不擅长Prolog,但它仍然是我最喜欢的语言之一。@Jordan.McBride你能评论一下我提供的答案中缺少了什么吗?哪里定义了
不同/1
?使用
所有不同的([A,B,C,D,E,F,G])
。您说“不同的方法根据输入的数字返回true或false”,但prolog不返回任何内容。谓词要么成功,要么失败。@Enigmativity我添加了我的不同方法,但如果已经存在一个完全不同的/1方法,那么我再发明轮子就没有用了。:)@为了让自己对编码有不同的想法,Prolog是一种非常好的学习语言。当你得到那一刻,你会爱上它。我不是专家,甚至不擅长Prolog,但它仍然是我最喜欢的语言之一。@Jordan.McBride你能评论一下我提供的答案中缺少了什么吗?为什么所有这些
member/2
目标?一个固定的选择似乎就足够了。@false我只是向OP解释为什么他们看到了他们看到的结果。我没有试图提供最佳的解决方案。当我有机会提供改进时,我将进行更新。@潜伏者L的目的是,它只是存在于0->27范围内的少数对。根据OP之前的问题和评论,
L
是一个大约150对数字的列表,结果(现在)在0到27之间,他们想从中选择一个“在边缘连接”的对序列。这将使得在使用所有不同的
时不需要
标签。示例调用:
r5([1,2],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,0],[2,3],[9,1],[9,2],[9,3],[9,4],[8,2]],X)。
。问题真的不清楚。为什么所有这些
member/2
目标?一个固定的选择似乎就足够了。@false我只是向OP解释为什么他们看到了他们看到的结果。我没有试图提供最佳的解决方案。当我有机会提供改进时,我将进行更新。@潜伏者L的目的是,它只是存在于0->27范围内的少数对。根据OP之前的问题和评论,
L
是一个大约150对数字的列表,结果(现在)在0到27之间,他们想从中选择一个“在边缘连接”的对序列。这将使得在使用所有不同的
时不需要
标签。示例调用:
r5([1,2],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,0],[2,3],[9,1],[9,2],[9,3],[9,4],[8,2]],X)。
。这个问题真的不清楚。