按子列表中的元素对列表进行排序

时间:2014-04-18 06:02:49

标签: prolog

此程序有错误

% Facts:

% the top has no number or directionality
node(top, top, nil).

% messages
node(aleph , 0, out).
node(bet   , 0, in).

node(aleph , 1, out).
node(bet   , 1, in).

node(aleph , 2, out).
node(bet   , 2, in).

node(bottom, bottom, nil).

% predicates/queries
order_nodes(Cpu, Count, [[Cpu | Count] | [] ]) :- node(Cpu, Count, _).
order_nodes(Cpu, Count, [[Cpu | HeadCount] | Rest]) :-
    (   node(Cpu, Count, _),
        integer(HeadCount)
    )
    ->  (   Count < HeadCount,
            order_nodes(Cpu, HeadCount, Rest)
        ),
        true.

错误:

?- order_nodes(aleph, X, List).
X = 0,
List = [[aleph|0]] ;
X = 1,
List = [[aleph|1]] ;
X = 2,
List = [[aleph|2]] ;
false.

关键是要将List与第二个元素按顺序统一节点的值列表。 。好吧,这部分成功,但返回false。执行跟踪表明->运算符在某个点匹配错误条件,这会渗透目标树...

1 个答案:

答案 0 :(得分:0)

你的代码中有很多奇怪的东西,包括一个奇怪的->[A | B]用于看起来像是一对元素。

首先,您可以像这样使用findall/3来收集所有节点,使用第二个元素作为对的第一个元素进行配对(以便稍后对其进行排序):

?- findall(Second-node(First, Third), node(First, Second, Third), All).
All = [top-node(top, nil), 0-node(aleph, out), 0-node(bet, in), 1-node(aleph, out),
1-node(bet, in), 2-node(aleph, out), 2-node(bet, in), bottom-node(..., ...)]

如果您只需要带有第一个元素aleph的节点:

?- First = aleph,
   findall(Second-node(First, Third), node(First, Second, Third), All).
First = aleph,
All = [0-node(aleph, out), 1-node(aleph, out), 2-node(aleph, out)].

它们碰巧被排序,因为这是事实的排序方式,但您可以在对子列表中使用ISO谓词keysort/2

?- First = aleph,
   findall(Second-node(First, Third), node(First, Second, Third), All),
   keysort(All, Sorted).
First = aleph,
All = Sorted, Sorted = [0-node(aleph, out), 1-node(aleph, out), 2-node(aleph, out)].

或者,如果您不关心node/3的第三个参数,

?- First = aleph,
   findall(Second-First, node(First, Second, _), All),
   keysort(All, Sorted).
First = aleph,
All = Sorted, Sorted = [0-aleph, 1-aleph, 2-aleph].

这是你想要实现的目标吗?

PS:您当然可以在findall/3的第二个参数中使用复合目标,例如

findal(Foo, ( node(A, B, C), integer(B) ), Bar)

但我真的不太明白你有node/3事实的原因。